Example #1
0
inline void impulse2freq(int id, float *imp, unsigned int length, fftw_real *out)
{
  fftw_real impulse_time[MAX_FFT_LENGTH];
#ifdef FFTW3
  fft_plan tmp_plan;
#endif
  unsigned int i, fftl = 128;

  while (fftl < length+SEG_LENGTH) {
          fftl *= 2;
  }

  fft_length[id] = fftl;
#ifdef FFTW3
  plan_rc[id] = fftwf_plan_r2r_1d(fftl, real_in, comp_out, FFTW_R2HC, FFTW_MEASURE);
  plan_cr[id] = fftwf_plan_r2r_1d(fftl, comp_in, real_out, FFTW_HC2R, FFTW_MEASURE);
  tmp_plan = fftwf_plan_r2r_1d(fftl, impulse_time, out, FFTW_R2HC, FFTW_MEASURE);
#else
  plan_rc[id] = rfftw_create_plan(fftl, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
  plan_cr[id] = rfftw_create_plan(fftl, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
#endif

  for (i=0; i<length; i++) {
    impulse_time[i] = imp[i];
  }
  for (; i<fftl; i++) {
    impulse_time[i] = 0.0f;
  }
#ifdef FFTW3
  fftwf_execute(tmp_plan);
  fftwf_destroy_plan(tmp_plan);
#else
  rfftw_one(plan_rc[id], impulse_time, out);
#endif
}
Example #2
0
FFT::FFT(int nsamples_){
	nsamples=nsamples_;
	if (nsamples%2!=0) {
		nsamples+=1;
		printf("WARNING: Odd sample size on FFT::FFT() (%d)",nsamples);
	};
	smp=new REALTYPE[nsamples];for (int i=0;i<nsamples;i++) smp[i]=0.0;
	freq=new REALTYPE[nsamples/2+1];for (int i=0;i<nsamples/2+1;i++) freq[i]=0.0;
	window.data=new REALTYPE[nsamples];for (int i=0;i<nsamples;i++) window.data[i]=0.707;
	window.type=W_RECTANGULAR;

#ifdef KISSFFT
	datar=new kiss_fft_scalar[nsamples+2];
	for (int i=0;i<nsamples+2;i++) datar[i]=0.0;
	datac=new kiss_fft_cpx[nsamples/2+2];
	for (int i=0;i<nsamples/2+2;i++) datac[i].r=datac[i].i=0.0;
	plankfft = kiss_fftr_alloc(nsamples,0,0,0);
	plankifft = kiss_fftr_alloc(nsamples,1,0,0);
#else
	data=new REALTYPE[nsamples];for (int i=0;i<nsamples;i++) data[i]=0.0;
	planfftw=fftwf_plan_r2r_1d(nsamples,data,data,FFTW_R2HC,FFTW_ESTIMATE);
	planifftw=fftwf_plan_r2r_1d(nsamples,data,data,FFTW_HC2R,FFTW_ESTIMATE);
#endif
	rand_seed=start_rand_seed;
	start_rand_seed+=161103;
};
Example #3
0
bool PitchTracker::setParameters(int priority, int policy, int sampleRate, int buffersize) {
    assert(buffersize <= FFT_SIZE);

    if (error) {
        return false;
    }
    m_sampleRate = fixed_sampleRate / DOWNSAMPLE;
    resamp.setup(sampleRate, m_sampleRate, 1, 16); // 16 == least quality

    if (m_buffersize != buffersize) {
        m_buffersize = buffersize;
        m_fftSize = m_buffersize + (m_buffersize+1) / 2;
        fftwf_destroy_plan(m_fftwPlanFFT);
        fftwf_destroy_plan(m_fftwPlanIFFT);
        m_fftwPlanFFT = fftwf_plan_r2r_1d(
                            m_fftSize, m_fftwBufferTime, m_fftwBufferFreq,
                            FFTW_R2HC, FFTW_ESTIMATE);
        m_fftwPlanIFFT = fftwf_plan_r2r_1d(
                             m_fftSize, m_fftwBufferFreq, m_fftwBufferTime,
                             FFTW_HC2R, FFTW_ESTIMATE);
    }

    if (!m_fftwPlanFFT || !m_fftwPlanIFFT) {
        error = true;
        return false;
    }

    if (!m_pthr) {
        start_thread(priority, policy);
    }
    return !error;
}
Example #4
0
/** init() Initalises the parameters of a class instance. This must be called before use
  @param n_ The size of the data windows to be processed
  @param k_ The number of outputs wanted (autocorr size = n_ + k_). Set k_ = 0, to get default n_/2
  @param rate_ The sampling rate of the incoming signal to process
  @param threshold_ The ratio of highest peak to the first peak allowed to be chosen
*/
void MyTransforms::init(int n_, int k_, double rate_, /*float threshold_, */bool equalLoudness_, int numHarmonics_)
{
  const int myFFTMode = FFTW_ESTIMATE;
  //const int myFFTMode = FFTW_MEASURE;
  //const int myFFTMode = FFTW_PATIENT;
  uninit();
  if(k_ == 0) k_ = (n_ + 1) / 2;
  
  n = n_;
  k = k_;
  size = n + k;
  rate = rate_;
  //_threshold = threshold_;
  equalLoudness = equalLoudness_;
  numHarmonics = numHarmonics_;

  dataTemp = (float*)fftwf_malloc(sizeof(float) * n);
  dataTime = (float*)fftwf_malloc(sizeof(float) * n);
  dataFFT  =  (float*)fftwf_malloc(sizeof(float) * n);
  autocorrTime = (float*)fftwf_malloc(sizeof(float) * size);
  autocorrFFT  = (float*)fftwf_malloc(sizeof(float) * size);
  //storeFFT  = (float*)fftwf_malloc(sizeof(float) * size);
  //equalLoudnessTable = (float*)fftwf_malloc(sizeof(float) * n);
  hanningCoeff  = (float*)fftwf_malloc(sizeof(float) * n);

  planAutocorrTime2FFT = fftwf_plan_r2r_1d(size, autocorrTime, autocorrFFT, FFTW_R2HC, myFFTMode);
  planAutocorrFFT2Time = fftwf_plan_r2r_1d(size, autocorrFFT, autocorrTime, FFTW_HC2R, myFFTMode);
  
  planDataTime2FFT = fftwf_plan_r2r_1d(n, dataTime, dataFFT, FFTW_R2HC, myFFTMode);
  planDataFFT2Time = fftwf_plan_r2r_1d(n, dataFFT, dataTime, FFTW_HC2R, myFFTMode); //???

  harmonicsAmpLeft = (float*)fftwf_malloc(numHarmonics * sizeof(float));
  harmonicsPhaseLeft = (float*)fftwf_malloc(numHarmonics * sizeof(float));
  harmonicsAmpCenter = (float*)fftwf_malloc(numHarmonics * sizeof(float));
  harmonicsPhaseCenter = (float*)fftwf_malloc(numHarmonics * sizeof(float));
  harmonicsAmpRight = (float*)fftwf_malloc(numHarmonics * sizeof(float));
  harmonicsPhaseRight = (float*)fftwf_malloc(numHarmonics * sizeof(float));
  //storeFFTAmp1 = (float*)malloc(n/2 * sizeof(float));
  //storeFFTAmp2 = (float*)malloc(n/2 * sizeof(float));
  
  freqPerBin = rate / double(size);
  //buildEqualLoudnessTable(50.0);
  //init hanningCoeff. The hanning windowing function
  hanningScalar = 0;
  for(int j=0; j<n; j++) {
    hanningCoeff[j] = (1.0 - cos(double(j+1) / double(n+1) * twoPI)) / 2.0;
    hanningScalar += hanningCoeff[j];
  }
  hanningScalar /= 2; //to normalise the FFT coefficients we divide by the sum of the hanning window / 2

  fastSmooth = new fast_smooth(n/8);
  //printf("fast_smooth size = %d\n", n/8);
  beenInit = true;
}
Example #5
0
File: dct.cpp Project: bbsun/Seis
DCT::DCT(int n, unsigned flags)
{
  sqrt2   = sqrt(2.0f);
  this->n = n;
  cd = 1.0f/(n*2)*sqrt2/2.0f;
  tmpf = MyAlloc<float>::alc(n);
  tmpi = MyAlloc<float>::alc(n);
  pf = fftwf_plan_r2r_1d(n,tmpf,tmpf,FFTW_REDFT10,flags);
  pi = fftwf_plan_r2r_1d(n,tmpi,tmpi,FFTW_REDFT01,flags);
  check(pf,"can not initialize pf in DCT(int n, unsigned flags) ");
  check(pi,"can not initialize pi in DCT(int n, unsigned flags) ");
}
Example #6
0
FFTwrapper::FFTwrapper(int fftsize_){
    fftsize=fftsize_;
    tmpfftdata1=new fftw_real[fftsize];
    tmpfftdata2=new fftw_real[fftsize];
#ifdef FFTW_VERSION_2
    planfftw=rfftw_create_plan(fftsize,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE|FFTW_IN_PLACE);
    planfftw_inv=rfftw_create_plan(fftsize,FFTW_COMPLEX_TO_REAL,FFTW_ESTIMATE|FFTW_IN_PLACE);
#else
    planfftw=fftwf_plan_r2r_1d(fftsize,tmpfftdata1,tmpfftdata1,FFTW_R2HC,FFTW_ESTIMATE);
    planfftw_inv=fftwf_plan_r2r_1d(fftsize,tmpfftdata2,tmpfftdata2,FFTW_HC2R,FFTW_ESTIMATE);
#endif
};
Example #7
0
File: MF.cpp Project: mitll/MatchIT
// TODO make this run automatically from the pipeline
extern "C" void init_globals() {
    filter_filepath = new Field<char, -1, 0, VariableStorage>();
    audio = new Field<float, -1, 0, VariableStorage>();
    audio_length = new Field<int>();
    segment_offset = new Field<int>();
    fft = new Field<float, fft_size>();
    clipped = new Field<float, dim>();
    float dummy_seg_size[seg_size];
    float dummy_fft_size[fft_size];
    fft_plan = (fftwf_plan*)malloc(sizeof(fftwf_plan));
    ifft_plan = (fftwf_plan*)malloc(sizeof(fftwf_plan));
    *fft_plan = fftwf_plan_r2r_1d(fft_size, dummy_seg_size, dummy_seg_size, FFTW_R2HC, FFTW_ESTIMATE);
    *ifft_plan = fftwf_plan_r2r_1d(fft_size, dummy_fft_size, dummy_fft_size, FFTW_HC2R, FFTW_ESTIMATE);
}
Example #8
0
int
padsynth_init(void)
{
    global.padsynth_table_size = -1;
    global.padsynth_outfreqs = NULL;
    global.padsynth_outsamples = NULL;
    global.padsynth_fft_plan = NULL;
    global.padsynth_ifft_plan = NULL;

    /* allocate input FFT buffer */
    global.padsynth_inbuf = (float *)fftwf_malloc(WAVETABLE_POINTS * sizeof(float));
    if (!global.padsynth_inbuf) {
        return 0;
    }

    /* create input FFTW plan */
#ifdef FFTW_VERSION_2
    global.padsynth_fft_plan  = (void *)rfftw_create_plan(WAVETABLE_POINTS,
                                                          FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
#else
    global.padsynth_fft_plan  = (void *)fftwf_plan_r2r_1d(WAVETABLE_POINTS,
                                                          global.padsynth_inbuf,
                                                          global.padsynth_inbuf,
                                                          FFTW_R2HC, FFTW_ESTIMATE);
#endif
    if (!global.padsynth_fft_plan) {
        padsynth_fini();
        return 0;
    }

    return 1;
}
Example #9
0
FFTX_FN_PREFIX
void fftx_init(struct FFTAnalysis *ft, uint32_t window_size, double rate, double fps) {
	ft->rate        = rate;
	ft->window_size = window_size;
	ft->data_size   = window_size / 2;
	ft->hann_window = NULL;
	ft->rboff = 0;
	ft->smps = 0;
	ft->step = 0;
	ft->sps = (fps > 0) ? ceil(rate / fps) : 0;
	ft->freq_per_bin = ft->rate / ft->data_size / 2.f;
	ft->phasediff_step = M_PI / ft->data_size;
	ft->phasediff_bin = 0;

	ft->ringbuf = (float *) malloc(window_size * sizeof(float));
	ft->fft_in  = (float *) fftwf_malloc(sizeof(float) * window_size);
	ft->fft_out = (float *) fftwf_malloc(sizeof(float) * window_size);
	ft->power   = (float *) malloc(ft->data_size * sizeof(float));
	ft->phase   = (float *) malloc(ft->data_size * sizeof(float));
	ft->phase_h = (float *) malloc(ft->data_size * sizeof(float));

	fftx_reset(ft);

	ft->fftplan = fftwf_plan_r2r_1d(window_size, ft->fft_in, ft->fft_out, FFTW_R2HC, FFTW_MEASURE);
}
Example #10
0
void ofxFftw::setup(int signalSize, fftWindowType windowType) {
	ofxFft::setup(signalSize, windowType);

	// more info on setting up a forward r2r fft here:
	// http://www.fftw.org/fftw3_doc/Real_002dto_002dReal-Transforms.html
	fftIn = (float*) fftwf_malloc(sizeof(float) * signalSize);
	fftOut = (float*) fftwf_malloc(sizeof(float) * signalSize);
	fftPlan = fftwf_plan_r2r_1d(signalSize, fftIn, fftOut, FFTW_R2HC,
	                            FFTW_DESTROY_INPUT | FFTW_MEASURE);

	// the difference between setting up an r2r ifft and fft
	// is using the flag/kind FFTW_HC2R instead of FFTW_R2HC:
	// http://www.fftw.org/fftw3_doc/Real_002dto_002dReal-Transform-Kinds.html
	ifftIn = (float*) fftwf_malloc(sizeof(float) * signalSize);
	ifftOut = (float*) fftwf_malloc(sizeof(float) * signalSize);
	ifftPlan = fftwf_plan_r2r_1d(signalSize, ifftIn, ifftOut, FFTW_HC2R,
	                             FFTW_DESTROY_INPUT | FFTW_MEASURE);
}
Example #11
0
void
MyMFCC::myUpdate(MarControlPtr sender)
{
    static const double fh = 0.5;
    static const double fl = 0;

    mrs_natural filterCount = inObservations_;

    //mrs_natural filterCount = getControl("mrs_natural/coefficients")->to<mrs_natural>();
    //mrs_natural windowSize = 2 * (inObservations_ - 1);
    //mrs_real sampleRate = israte_ * windowSize;

    if (filterCount < 1 ) //|| windowSize < 1)
    {
         // skip unnecessary updates
        m_filterCount = filterCount;
        //m_win = windowSize;
        //m_sr = sampleRate;
        return;
    }

    //cout << "*** MyMFCC: sampleRate = " << sampleRate << endl;
/*
    if (filterCount != m_filterCount || windowSize != m_win || sampleRate != m_sr)
    {
        initMelFilters(filterCount, windowSize, sampleRate, fl, fh);
    }
*/
    if (filterCount != m_filterCount)
    {
        fftwf_free(m_dctIn);
        fftwf_free(m_dctOut);
        fftwf_destroy_plan(m_plan);

        m_dctIn = fftwf_alloc_real(filterCount);
        m_dctOut = fftwf_alloc_real(filterCount);
        m_plan = fftwf_plan_r2r_1d(filterCount, m_dctIn, m_dctOut,
                                    FFTW_REDFT10, FFTW_ESTIMATE);
    }
    /*
    if ( windowSize != m_win )
    {
        m_buf.allocate( inObservations_ );
    }
    */

    setControl("mrs_natural/onObservations", filterCount);
    setControl("mrs_natural/onSamples", inSamples_);

    m_filterCount = filterCount;
    //m_win = windowSize;
    //m_sr = sampleRate;
}
Example #12
0
int srslte_dft_replan_r(srslte_dft_plan_t *plan, const int new_dft_points) {
  int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_R2HC : FFTW_HC2R;
  if (plan->p) {
    fftwf_destroy_plan(plan->p);
    plan->p = NULL;
  }
  plan->p = fftwf_plan_r2r_1d(new_dft_points, plan->in, plan->out, sign, FFTW_TYPE);
  if (!plan->p) {
    return -1;
  }
  plan->size = new_dft_points;
  return 0;
}
Example #13
0
static rfftw_info *rfftw_getplan(int n,int fwd)
{
    rfftw_info *info;
    int logn = ilog2(n);
    if (logn < MINFFT || logn > MAXFFT)
        return (0);
    info = (fwd?rfftw_fwd:rfftw_bwd)+(logn-MINFFT);
    if (!info->plan)
    {
        info->in = (float*) fftwf_malloc(sizeof(float) * n);
        info->out = (float*) fftwf_malloc(sizeof(float) * n);
        info->plan = fftwf_plan_r2r_1d(n, info->in, info->out, fwd?FFTW_R2HC:FFTW_HC2R, FFTW_MEASURE);
    }
    return info;
}
Example #14
0
int dft_plan_r2r(const int dft_points, dft_dir_t dir, dft_plan_t *plan) {
	int sign;
	sign = (dir == FORWARD) ? FFTW_R2HC : FFTW_HC2R;

	allocate(plan,sizeof(float),sizeof(float), dft_points);

	plan->p = fftwf_plan_r2r_1d(dft_points, plan->in, plan->out, sign, 0U);
	if (!plan->p) {
		return -1;
	}

	plan->size = dft_points;
	plan->mode = REAL_2_REAL;

	return 0;
}
Example #15
0
/**
 * Do all necessary initializations
 * @param  settings  Pointer to the global settings
 */
void TaskCoreFFTW::prepare(swspect_settings_t* settings)
{
   /* get settings and prepare buffers */
   this->cfg                  = settings;
   this->windowfct            = (fftw_real*)memalign(128, sizeof(fftw_real)*cfg->fft_points);
   this->unpacked_re          = (fftw_real*)memalign(128, sizeof(fftw_real)*cfg->fft_points);
   this->fft_result_reim      = new fftw_real*[cfg->num_sources];
   this->fft_accu_reim        = new fftw_real*[cfg->num_sources];
   this->num_ffts_accumulated   = 0;
   this->num_spectra_calculated = 0;
   for (int s=0; s<cfg->num_sources; s++) {
      this->fft_result_reim[s] = (fftw_real*)memalign(128, sizeof(fftw_real)*cfg->fft_points); // 4*fft_points*2 if c2c dft
      this->fft_accu_reim[s]   = (fftw_real*)memalign(128, sizeof(fftw_real)*cfg->fft_points);
   }
   this->fft_result_reim_conj = (fftw_real*)memalign(128, sizeof(fftw_real)*cfg->fft_points); // 4*fft_points*2 if c2c dft
   this->spectrum_scalevector = (fftw_real*)memalign(128, sizeof(fftw_real)*cfg->fft_points);
   this->processing_stage     = STAGE_NONE;
   this->total_runtime        = 0.0;
   this->total_ffts           = 0;
   reset_spectrum();

   /* windowing function */
   for (int i=0; i<(cfg->fft_points); i++) {
      fftw_real w = sin(fftw_real(i) * M_PI/(cfg->fft_points - 1.0));
      windowfct[i] = w*w;
   }
 
   /* FFT setup */
   // fftwPlan = fftw_create_plan(cfg->fft_points, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); // IPP_FFT_DIV_INV_BY_N, ippAlgHintFast
   fftwPlans = new fftwf_plan[cfg->num_sources];
   for (int s=0; s<cfg->num_sources; s++) {
      fftwPlans[s] = fftwf_plan_r2r_1d(cfg->fft_points, this->unpacked_re, this->fft_result_reim[s], FFTW_R2HC, FFTW_ESTIMATE);
   }

   /* prepare fixed scale/normalization factor */
   vecSet(fftw_real(1.0/cfg->integrated_ffts), spectrum_scalevector, cfg->fft_points);

   /* init mutexeds and start the worker thread */
   terminate_worker = false;
   pthread_mutex_init(&mmutex, NULL);
   pthread_mutex_lock(&mmutex);
   pthread_create(&wthread, NULL, taskcorefft_worker, (void*)this);

   return;
}
Example #16
0
int srslte_dft_plan_r(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) {
  allocate(plan,sizeof(float),sizeof(float), dft_points);
  int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_R2HC : FFTW_HC2R;
  plan->p = fftwf_plan_r2r_1d(dft_points, plan->in, plan->out, sign, 0U);
  if (!plan->p) {
    return -1;
  }
  plan->size = dft_points;
  plan->mode = SRSLTE_REAL;
  plan->dir = dir;
  plan->forward = (dir==SRSLTE_DFT_FORWARD)?true:false;
  plan->mirror = false;
  plan->db = false;
  plan->norm = false;
  plan->dc = false;

  return 0;
}
Example #17
0
    PowerSpectrum( int windowSize ):
        m_windowSize(windowSize)
    {
        m_inBuffer = fftwf_alloc_real(windowSize);
        m_outBuffer = fftwf_alloc_real(windowSize);
        m_plan = fftwf_plan_r2r_1d(windowSize, m_inBuffer, m_outBuffer,
                                   FFTW_R2HC, FFTW_ESTIMATE);

        double pi = Segmenter::pi();

        m_window = new float[windowSize];

        float sumWindow = 0.f;
        for (int idx=0; idx < windowSize; ++idx) {
            // hamming window:
            m_window[idx] = 0.54 - 0.46 * std::cos(2 * pi * idx / (windowSize-1) );
            sumWindow += m_window[idx];
        }

        m_outputScale = 2.f / sumWindow;
        m_outputScale *= m_outputScale; // square, because we'll be multiplying power instead of raw spectrum

        m_output.resize(windowSize / 2 + 1);
    }
MirageAudio*
mirageaudio_initialize(gint rate, gint seconds, gint winsize)
{
    MirageAudio *ma;
    gint i;

    ma = g_new0(MirageAudio, 1);
    ma->rate = rate;
    ma->seconds = seconds;
    ma->hops = rate*seconds/winsize;
    ma->out = malloc(ma->hops*((winsize/2)+1)*sizeof(float));

    // FFTW
    ma->winsize = winsize;
    ma->fftwsize = 2 * ma->winsize;
    ma->fftw = (float*)fftwf_malloc(ma->fftwsize * sizeof(float));
    ma->fftwplan = fftwf_plan_r2r_1d((2*ma->winsize), ma->fftw, ma->fftw, FFTW_R2HC,
                    FFTW_ESTIMATE | FFTW_DESTROY_INPUT);

    // Hann Window
    ma->window = malloc(ma->winsize*sizeof(float));
    for (i = 0; i < ma->winsize; i++) {
            ma->window[i] = (float)(0.5 * (1.0 - cos((2.0*M_PI *(double)i)/(double)(ma->winsize-1))));
    }

    // Samplingrate converter
    int error;
    ma->src_state = src_new(SRC_ZERO_ORDER_HOLD, 1, &error);
    ma->src_data.data_out = malloc(SRC_BUFFERLENGTH*sizeof(float));
    ma->src_data.output_frames = SRC_BUFFERLENGTH;

    // cancel decoding mutex
    ma->decoding_mutex = g_mutex_new();

    return ma;
}
Example #19
0
int main(int argc, char*argv[])
{
#ifdef HAVE_FFTW3_H
    unsigned int n = 32;    // transform size
    unsigned int d = 4;     // number of elements to print each line

    int dopt;
    while ((dopt = getopt(argc,argv,"uhn:")) != EOF) {
        switch (dopt) {
        case 'u':
        case 'h':   usage();    return 0;
        case 'n': n = atoi(optarg); break;
        default:
            exit(1);
        }
    }

    // validate input
    if ( n < 2 ) {
        fprintf(stderr,"error: input transform size must be at least 2\n");
        exit(1);
    }

    // create and initialize data arrays
    float x[n];
    float y[n];
    unsigned int i;
    for (i=0; i<n; i++)
        x[i] = cosf(2*M_PI*i/((float)n)) * expf(-4.0f*i*i/((float)n*n));

    // create fftw plans
    fftwf_plan plan[8];
    plan[0] = fftwf_plan_r2r_1d(n, x, y, FFTW_REDFT00, FFTW_ESTIMATE);
    plan[1] = fftwf_plan_r2r_1d(n, x, y, FFTW_REDFT10, FFTW_ESTIMATE);
    plan[2] = fftwf_plan_r2r_1d(n, x, y, FFTW_REDFT01, FFTW_ESTIMATE);
    plan[3] = fftwf_plan_r2r_1d(n, x, y, FFTW_REDFT11, FFTW_ESTIMATE);

    plan[4] = fftwf_plan_r2r_1d(n, x, y, FFTW_RODFT00, FFTW_ESTIMATE);
    plan[5] = fftwf_plan_r2r_1d(n, x, y, FFTW_RODFT10, FFTW_ESTIMATE);
    plan[6] = fftwf_plan_r2r_1d(n, x, y, FFTW_RODFT01, FFTW_ESTIMATE);
    plan[7] = fftwf_plan_r2r_1d(n, x, y, FFTW_RODFT11, FFTW_ESTIMATE);

    char plan_name[][8] = {"REDFT00",
                           "REDFT10",
                           "REDFT01",
                           "REDFT11",
                           "RODFT00",
                           "RODFT10",
                           "RODFT01",
                           "RODFT11"};

    unsigned int j;
    printf("// %u-point real even/odd dft data\n", n);
    printf("float fftdata_r2r_n%u[] = {\n    ", n);
    for (j=0; j<n; j++) {
        //printf("  %16.10f%s\n", y[j], j==(n-1) ? "};" : ",");
        printf("%16.8e", x[j]);
        if ( j==n-1 )
            printf(" ");
        else if ( ((j+1)%d)==0 )
            printf(",\n    ");
        else
            printf(", ");
    }
    printf("};\n\n");

    // execute plans and print
    for (i=0; i<8; i++) {
        fftwf_execute(plan[i]);

        printf("\n");
        printf("// %s\n", plan_name[i]);
        printf("float fftdata_r2r_%s_n%u[] = {\n    ", plan_name[i], n);
        for (j=0; j<n; j++) {
            //printf("  %16.10f%s\n", y[j], j==(n-1) ? "};" : ",");
            printf("%16.8e", y[j]);
            if ( j==n-1 )
                printf(" ");
            else if ( ((j+1)%d)==0 )
                printf(",\n    ");
            else
                printf(", ");
        }
        printf("};\n\n");
    }

    // destroy plans
    for (i=0; i<8; i++)
        fftwf_destroy_plan(plan[i]);
#else
    printf("please install fftw and try again\n");
#endif

    return 0;
}
Example #20
0
/** Initialize the convolver. 
 * It also sets the filter to be a Dirac. Thus, if no filter is specified
 * the audio data are not affected. However, quite some computational 
 * load for nothing...
 *
 * You should use create() instead of directly using this constructor.
 * @throw std::bad_alloc if not enough memory could be allocated
 * @throw std::runtime_error if sizeof(float) != 4
 **/
Convolver::Convolver(const nframes_t nframes, const crossfade_t crossfade_type)
		throw (std::bad_alloc, std::runtime_error) :
		_frame_size(nframes), _partition_size(nframes + nframes), _crossfade_type(
				crossfade_type), _no_of_partitions_to_process(0), _old_weighting_factor(
				0)
{
	// make sure that SIMD instructions can be used properly
	if (sizeof(float) != 4)
	{
		throw(std::runtime_error("sizeof(float) on your computer is not 4! "
				" The convolution can not take place properly."));
	}

	_signal.clear();
	_waiting_queue.clear();

	// allocate memory and initialize to 0
	_fft_buffer.resize(_partition_size, 0.0f);
	_ifft_buffer.resize(_partition_size, 0.0f);

	// create first partition
	//_filter_coefficients.resize(_partition_size, 0.0f);

	_zeros.resize(_partition_size, 0.0f);

	_output_buffer.resize(_frame_size, 0.0f);

	// create fades if required
	if (_crossfade_type != none)
	{
		// init memory
		_fade_in.resize(_frame_size, 0.0f);
		_fade_out.resize(_frame_size, 0.0f);

		// this is the ifft normalization factor (fftw3 does not normalize)
		const float norm = 1.0f / _partition_size;

		// raised cosine fade
		if (_crossfade_type == raised_cosine)
		{
			// create fades
			for (unsigned int n = 0u; n < _frame_size; n++)
			{
				_fade_in[n] = norm
						* (0.5f
								+ 0.5f
										* cos(
												static_cast<float>(_frame_size
														- n) / _frame_size
														* pi_float));
				_fade_out[n] = norm
						* (0.5f
								+ 0.5f
										* cos(
												static_cast<float>(n)
														/ _frame_size
														* pi_float));
			} // for
		} // if

		// linear fade
		else if (_crossfade_type == linear)
		{
			// create fades
			for (unsigned int n = 0u; n < _frame_size; n++)
			{
				_fade_in[n] = norm * (static_cast<float>(n) / _frame_size);
				_fade_out[n] = norm
						* (static_cast<float>(_frame_size - n) / _frame_size);
			} // for
		} // else if

	} // if

	// create fft plans for halfcomplex data format
	_fft_plan = fftwf_plan_r2r_1d(_partition_size, &_fft_buffer[0],
			&_fft_buffer[0], FFTW_R2HC, FFTW_PATIENT);
	_ifft_plan = fftwf_plan_r2r_1d(_partition_size, &_ifft_buffer[0],
			&_ifft_buffer[0], FFTW_HC2R, FFTW_PATIENT);

	// calculate transfer function of a dirac
	std::copy(_zeros.begin(), _zeros.end(), _fft_buffer.begin());

	_fft_buffer[0] = 1.0f;
	_fft();

	// store dirac
	_neutral_filter = _fft_buffer;

	// clear _fft_buffer
	std::copy(_zeros.begin(), _zeros.end(), _fft_buffer.begin());

	// set dirac as default filter
	set_neutral_filter();
}
Example #21
0
/** This is an autarc function to precalculate the frequency 
 * domain filter partitions that a \b Convolver needs. It does 
 * not require an instantiation of a \b Convolver. However, it is 
 * not very efficient since an FFT plan is created with every call.
 * @param container place to store the partitions.
 * @param filter impulse response of the filter
 * @param filter_size size of the impulse response
 * @param partition_size size of the partitions (this is the 
 * partition size that the outside world sees, internally it is twice as long)
 */
void Convolver::prepare_impulse_response(data_t& container, const float *filter,
		const unsigned int filter_size, const unsigned int partition_size)
{

	// find out how many complete partitions we have
	unsigned int no_of_partitions = filter_size / partition_size;

	// if there is even one more
	if (filter_size % partition_size)
		no_of_partitions++;

	// empty container
	container.clear();

	// allocate memory
	container.resize(2 * no_of_partitions * partition_size, 0.0f);

	// define temporary buffers
	data_t fft_buffer;
	data_t zeros;

	// allocate memory and initialize to 0
	fft_buffer.resize(2 * partition_size, 0.0f);
	zeros.resize(2 * partition_size, 0.0f);

	// create fft plans for halfcomplex data format
	fftwf_plan fft_plan = fftwf_plan_r2r_1d(2 * partition_size, &fft_buffer[0],
			&fft_buffer[0], FFTW_R2HC, FFTW_ESTIMATE);

	// convert filter partitionwise to frequency domain

	/////// process complete partitions //////////////

	for (unsigned int partition = 0u; partition < no_of_partitions - 1;
			partition++)
	{
		std::copy(filter + partition * partition_size,
				filter + (partition + 1) * partition_size, fft_buffer.begin());

		// zero pad
		std::copy(zeros.begin(), zeros.begin() + partition_size,
				fft_buffer.begin() + partition_size);

		// fft
		fftwf_execute(fft_plan);
		sort_coefficients(fft_buffer, 2 * partition_size);

		// add the partition to the filter
		std::copy(fft_buffer.begin(), fft_buffer.begin() + 2 * partition_size,
				container.begin() + 2 * partition * partition_size);

	}

	////// end process complete partitions

	//// process potentially incomplete last partition ////////////

	// zeros
	std::copy(zeros.begin(), zeros.end(), fft_buffer.begin());

	// add filter coefficients
	std::copy(filter + (no_of_partitions - 1) * partition_size,
			filter + filter_size, fft_buffer.begin());

	// fft
	fftwf_execute(fft_plan);
	sort_coefficients(fft_buffer, 2 * partition_size);

	// add the partition to the filter
	std::copy(fft_buffer.begin(), fft_buffer.end(),
			container.begin() + 2 * (no_of_partitions - 1) * partition_size);

	///// end process potentially incomplete partition ////////

	// clean up
	fftwf_destroy_plan(fft_plan);
}
Example #22
0
/**
* Instantiates the plugin.
*/
static LV2_Handle
instantiate(const LV2_Descriptor *descriptor, double rate, const char *bundle_path,
			const LV2_Feature *const *features)
{
	//Actual struct declaration
	Nrepel *self = (Nrepel *)calloc(1, sizeof(Nrepel));

	//Retrieve the URID map callback, and needed URIDs
	for (int i = 0; features[i]; ++i)
	{
		if (!strcmp(features[i]->URI, LV2_URID__map))
		{
			self->map = (LV2_URID_Map *)features[i]->data;
		}
	}
	if (!self->map)
	{
		//bail out: host does not support urid:map
		free(self);
		return NULL;
	}

	//For lv2 state (noise profile saving)
	self->atom_Vector = self->map->map(self->map->handle, LV2_ATOM__Vector);
	self->atom_Int = self->map->map(self->map->handle, LV2_ATOM__Int);
	self->atom_Float = self->map->map(self->map->handle, LV2_ATOM__Float);
	self->prop_fftsize = self->map->map(self->map->handle, NREPEL_URI "#fftsize");
	self->prop_nwindow = self->map->map(self->map->handle, NREPEL_URI "#nwindow");
	self->prop_FFTp2 = self->map->map(self->map->handle, NREPEL_URI "#FFTp2");

	//Sampling related
	self->samp_rate = (float)rate;

	//FFT related
	self->fft_size = FFT_SIZE;
	self->fft_size_2 = self->fft_size / 2;
	self->input_fft_buffer = (float *)calloc(self->fft_size, sizeof(float));
	self->output_fft_buffer = (float *)calloc(self->fft_size, sizeof(float));
	self->forward = fftwf_plan_r2r_1d(self->fft_size, self->input_fft_buffer, self->output_fft_buffer, FFTW_R2HC, FFTW_ESTIMATE);
	self->backward = fftwf_plan_r2r_1d(self->fft_size, self->output_fft_buffer, self->input_fft_buffer, FFTW_HC2R, FFTW_ESTIMATE);

	//STFT window related
	self->window_option_input = INPUT_WINDOW;
	self->window_option_output = OUTPUT_WINDOW;
	self->input_window = (float *)calloc(self->fft_size, sizeof(float));
	self->output_window = (float *)calloc(self->fft_size, sizeof(float));

	//buffers for OLA
	self->in_fifo = (float *)calloc(self->fft_size, sizeof(float));
	self->out_fifo = (float *)calloc(self->fft_size, sizeof(float));
	self->output_accum = (float *)calloc(self->fft_size * 2, sizeof(float));
	self->overlap_factor = OVERLAP_FACTOR;
	self->hop = self->fft_size / self->overlap_factor;
	self->input_latency = self->fft_size - self->hop;
	self->read_ptr = self->input_latency; //the initial position because we are that many samples ahead

	//soft bypass
	self->tau = (1.f - expf(-2.f * M_PI * 25.f * 64.f / self->samp_rate));
	self->wet_dry = 0.f;

	//Arrays for getting bins info
	self->fft_p2 = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->fft_magnitude = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->fft_phase = (float *)calloc((self->fft_size_2 + 1), sizeof(float));

	//noise threshold related
	self->noise_thresholds_p2 = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->noise_thresholds_scaled = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->noise_window_count = 0.f;
	self->noise_thresholds_availables = false;

	//noise adaptive estimation related
	self->auto_thresholds = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->prev_noise_thresholds = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->s_pow_spec = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->prev_s_pow_spec = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->p_min = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->prev_p_min = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->speech_p_p = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->prev_speech_p_p = (float *)calloc((self->fft_size_2 + 1), sizeof(float));

	//smoothing related
	self->smoothed_spectrum = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->smoothed_spectrum_prev = (float *)calloc((self->fft_size_2 + 1), sizeof(float));

	//transient preservation
	self->transient_preserv_prev = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->tp_window_count = 0.f;
	self->tp_r_mean = 0.f;
	self->transient_present = false;

	//masking related
	self->bark_z = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->absolute_thresholds = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->unity_gain_bark_spectrum = (float *)calloc(N_BARK_BANDS, sizeof(float));
	self->spreaded_unity_gain_bark_spectrum = (float *)calloc(N_BARK_BANDS, sizeof(float));
	self->spl_reference_values = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->alpha_masking = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->beta_masking = (float *)calloc((self->fft_size_2 + 1), sizeof(float));
	self->SSF = (float *)calloc((N_BARK_BANDS * N_BARK_BANDS), sizeof(float));
	self->input_fft_buffer_at = (float *)calloc(self->fft_size, sizeof(float));
	self->output_fft_buffer_at = (float *)calloc(self->fft_size, sizeof(float));
	self->forward_at = fftwf_plan_r2r_1d(self->fft_size, self->input_fft_buffer_at, self->output_fft_buffer_at, FFTW_R2HC, FFTW_ESTIMATE);

	//reduction gains related
	self->Gk = (float *)calloc((self->fft_size), sizeof(float));

	//whitening related
	self->residual_max_spectrum = (float *)calloc((self->fft_size), sizeof(float));
	self->max_decay_rate = expf(-1000.f / (((WHITENING_DECAY_RATE)*self->samp_rate) / self->hop));
	self->whitening_window_count = 0.f;

	//final ensemble related
	self->residual_spectrum = (float *)calloc((self->fft_size), sizeof(float));
	self->denoised_spectrum = (float *)calloc((self->fft_size), sizeof(float));
	self->final_spectrum = (float *)calloc((self->fft_size), sizeof(float));

	//Window combination initialization (pre processing window post processing window)
	fft_pre_and_post_window(self->input_window, self->output_window,
							self->fft_size, self->window_option_input,
							self->window_option_output, &self->overlap_scale_factor);

	//Set initial gain as unity for the positive part
	initialize_array(self->Gk, 1.f, self->fft_size);

	//Compute adaptive initial thresholds
	compute_auto_thresholds(self->auto_thresholds, self->fft_size, self->fft_size_2,
							self->samp_rate);

	//MASKING initializations
	compute_bark_mapping(self->bark_z, self->fft_size_2, self->samp_rate);
	compute_absolute_thresholds(self->absolute_thresholds, self->fft_size_2,
								self->samp_rate);
	spl_reference(self->spl_reference_values, self->fft_size_2, self->samp_rate,
				  self->input_fft_buffer_at, self->output_fft_buffer_at,
				  &self->forward_at);
	compute_SSF(self->SSF);

	//Initializing unity gain values for offset normalization
	initialize_array(self->unity_gain_bark_spectrum, 1.f, N_BARK_BANDS);
	//Convolve unitary energy bark spectrum with SSF
	convolve_with_SSF(self->SSF, self->unity_gain_bark_spectrum,
					  self->spreaded_unity_gain_bark_spectrum);

	initialize_array(self->alpha_masking, 1.f, self->fft_size_2 + 1);
	initialize_array(self->beta_masking, 0.f, self->fft_size_2 + 1);

	return (LV2_Handle)self;
}
Example #23
0
static LADSPA_Handle instantiateMbeq(
 const LADSPA_Descriptor *descriptor,
 unsigned long s_rate) {
	Mbeq *plugin_data = (Mbeq *)malloc(sizeof(Mbeq));
	int *bin_base = NULL;
	float *bin_delta = NULL;
	fftw_real *comp = NULL;
	float *db_table = NULL;
	long fifo_pos;
	LADSPA_Data *in_fifo = NULL;
	LADSPA_Data *out_accum = NULL;
	LADSPA_Data *out_fifo = NULL;
	fftw_real *real = NULL;
	float *window = NULL;

#line 52 "mbeq_1197.xml"
	int i, bin;
	float last_bin, next_bin;
	float db;
	float hz_per_bin = (float)s_rate / (float)FFT_LENGTH;
	
	in_fifo = calloc(FFT_LENGTH, sizeof(LADSPA_Data));
	out_fifo = calloc(FFT_LENGTH, sizeof(LADSPA_Data));
	out_accum = calloc(FFT_LENGTH * 2, sizeof(LADSPA_Data));
	real = calloc(FFT_LENGTH, sizeof(fftw_real));
	comp = calloc(FFT_LENGTH, sizeof(fftw_real));
	window = calloc(FFT_LENGTH, sizeof(float));
	bin_base = calloc(FFT_LENGTH/2, sizeof(int));
	bin_delta = calloc(FFT_LENGTH/2, sizeof(float));
	fifo_pos = 0;
	
	#ifdef FFTW3
	plan_rc = fftwf_plan_r2r_1d(FFT_LENGTH, real, comp, FFTW_R2HC, FFTW_MEASURE);
	plan_cr = fftwf_plan_r2r_1d(FFT_LENGTH, comp, real, FFTW_HC2R, FFTW_MEASURE);
	#else
	plan_rc = rfftw_create_plan(FFT_LENGTH, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
	plan_cr = rfftw_create_plan(FFT_LENGTH, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
	#endif
	
	// Create raised cosine window table
	for (i=0; i < FFT_LENGTH; i++) {
	        window[i] = -0.5f*cos(2.0f*M_PI*(double)i/(double)FFT_LENGTH)+0.5f;
	}
	
	// Create db->coeffiecnt lookup table
	db_table = malloc(1000 * sizeof(float));
	for (i=0; i < 1000; i++) {
	        db = ((float)i/10) - 70;
	        db_table[i] = pow(10.0f, db/20.0f);
	}
	
	// Create FFT bin -> band + delta tables
	bin = 0;
	while (bin <= bands[0]/hz_per_bin) {
	        bin_base[bin] = 0;
	        bin_delta[bin++] = 0.0f;
	}
	for (i = 1; 1 < BANDS-1 && bin < (FFT_LENGTH/2)-1 && bands[i+1] < s_rate/2; i++) {
	        last_bin = bin;
	        next_bin = (bands[i+1])/hz_per_bin;
	        while (bin <= next_bin) {
	                bin_base[bin] = i;
	                bin_delta[bin] = (float)(bin - last_bin) / (float)(next_bin - last_bin);
	                bin++;
	        }
	}
	for (; bin < (FFT_LENGTH/2); bin++) {
	        bin_base[bin] = BANDS-1;
	        bin_delta[bin] = 0.0f;
	}

	plugin_data->bin_base = bin_base;
	plugin_data->bin_delta = bin_delta;
	plugin_data->comp = comp;
	plugin_data->db_table = db_table;
	plugin_data->fifo_pos = fifo_pos;
	plugin_data->in_fifo = in_fifo;
	plugin_data->out_accum = out_accum;
	plugin_data->out_fifo = out_fifo;
	plugin_data->real = real;
	plugin_data->window = window;

	return (LADSPA_Handle)plugin_data;
}
Example #24
0
/*
 *  PADsynth-ize a WhySynth wavetable.
 */
int
padsynth_render(y_sample_t *sample)
{
    int N, i, fc0, nh, plimit_low, plimit_high, rndlim_low, rndlim_high;
    float bw, stretch, bwscale, damping;
    float f, max, samplerate, bw0_Hz, relf;
    float *inbuf = global.padsynth_inbuf;
    float *outfreqs, *smp;

    /* handle the special case where the sample key limit is 256 -- these
     * don't get rendered because they're usually just sine waves, and are
     * played at very high frequency */
    if (sample->max_key == 256) {
        sample->data = (signed short *)malloc((WAVETABLE_POINTS + 8) * sizeof(signed short));
        if (!sample->data)
            return 0;
        sample->data += 4; /* guard points */
        memcpy(sample->data - 4, sample->source - 4,
               (WAVETABLE_POINTS + 8) * sizeof(signed short)); /* including guard points */
        sample->length = WAVETABLE_POINTS;
        sample->period = (float)WAVETABLE_POINTS;
        return 1;
    }

    /* calculate the output table size */
    i = lrintf((float)global.sample_rate * 2.5f);  /* at least 2.5 seconds long -FIX- this should be configurable */
    N = WAVETABLE_POINTS * 2;
    while (N < i) {
        if (N * 5 / 4 >= i) { N = N * 5 / 4; break; }
        if (N * 3 / 2 >= i) { N = N * 3 / 2; break; }
        N <<= 1;
    }

    /* check temporary memory and IFFT plan, allocate if needed */
    if (global.padsynth_table_size != N) {
        padsynth_free_temp();
        if (global.padsynth_ifft_plan) {
#ifdef FFTW_VERSION_2
            rfftw_destroy_plan(global.padsynth_ifft_plan);
#else
            fftwf_destroy_plan(global.padsynth_ifft_plan);
#endif
            global.padsynth_ifft_plan = NULL;
        }
        global.padsynth_table_size = N;
    }
    if (!global.padsynth_outfreqs)
        global.padsynth_outfreqs = (float *)fftwf_malloc(N * sizeof(float));
    if (!global.padsynth_outsamples)
        global.padsynth_outsamples = (float *)fftwf_malloc(N * sizeof(float));
    if (!global.padsynth_outfreqs || !global.padsynth_outsamples)
        return 0;
    outfreqs = global.padsynth_outfreqs;
    smp = global.padsynth_outsamples;
    if (!global.padsynth_ifft_plan)
        global.padsynth_ifft_plan =
#ifdef FFTW_VERSION_2
            (void *)rfftw_create_plan(N, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
#else
            (void *)fftwf_plan_r2r_1d(N, global.padsynth_outfreqs,
                                      global.padsynth_outsamples,
                                      FFTW_HC2R, FFTW_ESTIMATE);
#endif
    if (!global.padsynth_ifft_plan)
        return 0;

    /* allocate sample memory */
    sample->data = (signed short *)malloc((N + 8) * sizeof(signed short));
    if (!sample->data)
        return 0;
    sample->data += 4; /* guard points */
    sample->length = N;

    /* condition parameters */
    bw = (sample->param1 ? (float)(sample->param1 * 2) : 1.0f); /* partial width: 1, or 2 to 100 cents by 2 */
    stretch = (float)(sample->param2 - 10) / 10.0f;
    stretch *= stretch * stretch / 10.0f;                       /* partial stretch: -10% to +10% */
    switch (sample->param3) {
      default:
      case  0:  bwscale = 1.0f;   break;                        /* width scale: 10% to 250% */
      case  2:  bwscale = 0.5f;   break;
      case  4:  bwscale = 0.25f;  break;
      case  6:  bwscale = 0.1f;   break;
      case  8:  bwscale = 1.5f;   break;
      case 10:  bwscale = 2.0f;   break;
      case 12:  bwscale = 2.5f;   break;
      case 14:  bwscale = 0.75f;  break;
    }
    damping = (float)sample->param4 / 20.0f;
    damping = damping * damping * -6.0f * logf(10.0f) / 20.0f;  /* damping: 0 to -6dB per partial */

    /* obtain spectrum of input wavetable */
    YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: analyzing input table\n");
    for (i = 0; i < WAVETABLE_POINTS; i++)
        inbuf[i] = (float)sample->source[i] / 32768.0f;
#ifdef FFTW_VERSION_2
    rfftw_one((rfftw_plan)global.padsynth_fft_plan, inbuf, inbuf);
#else
    fftwf_execute((const fftwf_plan)global.padsynth_fft_plan);  /* transform inbuf in-place */
#endif
    max = 0.0f;
    if (damping > -1e-3f) { /* no damping */
        for (i = 1; i < WAVETABLE_POINTS / 2; i++) {
            inbuf[i] = sqrtf(inbuf[i] * inbuf[i] +
                             inbuf[WAVETABLE_POINTS - i] * inbuf[WAVETABLE_POINTS - i]);
            if (fabsf(inbuf[i]) > max) max = fabsf(inbuf[i]);
        }
        if (fabsf(inbuf[WAVETABLE_POINTS / 2]) > max) max = fabsf(inbuf[WAVETABLE_POINTS / 2]);
    } else {  /* damping */
        for (i = 1; i < WAVETABLE_POINTS / 2; i++) {
            inbuf[i] = sqrtf(inbuf[i] * inbuf[i] +
                             inbuf[WAVETABLE_POINTS - i] * inbuf[WAVETABLE_POINTS - i]) *
                       expf((float)i * damping);
            if (fabsf(inbuf[i]) > max) max = fabsf(inbuf[i]);
        }
        inbuf[WAVETABLE_POINTS / 2] = 0.0f;  /* lazy */
    }
    if (max < 1e-5f) max = 1e-5f;
    for (i = 1; i <= WAVETABLE_POINTS / 2; i++)
        inbuf[i] /= max;

    /* create new frequency profile */
    YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: creating frequency profile\n");
    memset(outfreqs, 0, N * sizeof(float));

    /* render the fundamental at 4 semitones below the key limit */
    f = 440.0f * y_pitch[sample->max_key - 4];

    /* Find a nominal samplerate close to the real samplerate such that the
     * input partials fall exactly at integer output partials. This ensures
     * that especially the lower partials are not out of tune. Example:
     *    N = 131072
     *    global.samplerate = 44100
     *    f = 261.625565
     *    fi = f / global.samplerate = 0.00593255
     *    fc0 = int(fi * N) = int(777.592) = 778
     * so we find a new 'samplerate' that will result in fi * N being exactly 778:
     *    samplerate = f * N / fc = 44076.8
     */
    fc0 = lrintf(f / (float)global.sample_rate * (float)N);
    sample->period = (float)N / (float)fc0;  /* frames per period */
    samplerate = f * sample->period;
    /* YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: size = %d, f = %f, fc0 = %d, period = %f\n", N, f, fc0, sample->period); */

    bw0_Hz = (powf(2.0f, bw / 1200.0f) - 1.0f) * f;

    /* Find the limits of the harmonics to be used in the output table. These
     * are 20Hz and Nyquist, corrected for the nominal-to-actual sample rate
     * difference, with the latter also corrected  for the 4-semitone shift in
     * the fundamental frequency.
     * lower partial limit:
     *   (20Hz * samplerate / global.sample_rate) / samplerate * N
     * 4-semitone shift:
     *   (2 ^ -12) ^ 4
     * upper partial limit:
     *   ((global.sample_rate / 2) * samplerate / global.sample_rate) / samplerate * N / shift
     */
    plimit_low = lrintf(20.0f / (float)global.sample_rate * (float)N);
    /* plimit_high = lrintf(20000.0f / (float)global.sample_rate * (float)N / 1.25992f); */
    plimit_high = lrintf((float)N / 2 / 1.25992f);
    /* YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: nominal rate = %f, plimit low = %d, plimit high = %d\n", samplerate, plimit_low, plimit_high); */

    rndlim_low = N / 2;
    rndlim_high = 0;
    for (nh = 1; nh <= WAVETABLE_POINTS / 2; nh++) {
        int fc, contributed;
        float bw_Hz;  /* bandwidth of the current harmonic measured in Hz */
        float bwi;
        float fi;
        float plimit_amp;

        if (inbuf[nh] < 1e-5f)
            continue;

        relf = relF(nh, stretch);
        if (relf < 1e-10f)
            continue;

        bw_Hz = bw0_Hz * powf(relf, bwscale);
        
        bwi = bw_Hz / (2.0f * samplerate);
        fi = f * relf / samplerate;
        fc = lrintf(fi * (float)N);
        /* printf("...... kl = %d, nh = %d, fn = %f, fc = %d, bwi*N = %f\n", sample->max_key, nh, f * relf, fc, bwi * (float)N); */

        /* set plimit_amp such that we don't calculate harmonics -100dB or more
         * below the profile peak for this harmonic */
        plimit_amp = profile(0.0f, bwi) * 1e-5f / inbuf[nh];
        /* printf("...... (nh = %d, fc = %d, prof(0) = %e, plimit_amp = %e, amp = %e)\n", nh, fc, profile(0.0f, bwi), plimit_amp, inbuf[nh]); */

        /* scan profile and add partial's contribution to outfreqs */
        contributed = 0;
        for (i = (fc < plimit_high ? fc : plimit_high); i >= plimit_low; i--) {
            float hprofile = profile(((float)i / (float)N) - fi, bwi);
            if (hprofile < plimit_amp) {
                /* printf("...... (i = %d, profile = %e)\n", i, hprofile); */
                break;
            }
            outfreqs[i] += hprofile * inbuf[nh];
            contributed = 1;
        }
        if (contributed && rndlim_low > i + 1) rndlim_low = i + 1;
        contributed = 0;
        for (i = (fc + 1 > plimit_low ? fc + 1 : plimit_low); i <= plimit_high; i++) {
            float hprofile = profile(((float)i / (float)N) - fi, bwi);
            if (hprofile < plimit_amp) {
                /* printf("...... (i = %d, profile = %e)\n", i, hprofile); */
                break;
            }
            outfreqs[i] += hprofile * inbuf[nh];
            contributed = 1;
        }
        if (contributed && rndlim_high < i - 1) rndlim_high = i - 1;
    };
    if (rndlim_low > rndlim_high) {  /* somehow, outfreqs is still empty */
        YDB_MESSAGE(YDB_SAMPLE, " padsynth_render WARNING: empty output table (key limit = %d)\n", sample->max_key);
        rndlim_low = rndlim_high = fc0;
        outfreqs[fc0] = 1.0f;
    }

    /* randomize the phases */
    /* YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: randomizing phases (%d to %d, kl=%d)\n", rndlim_low, rndlim_high, sample->max_key); */
    YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: randomizing phases\n");
    if (rndlim_high >= N / 2) rndlim_high = N / 2 - 1;
    for (i = rndlim_low; i < rndlim_high; i++) {
        float phase = RND() * 2.0f * M_PI_F;
        outfreqs[N - i] = outfreqs[i] * cosf(phase);
        outfreqs[i]     = outfreqs[i] * sinf(phase);
    };

    /* inverse FFT back to time domain */
    YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: performing inverse FFT\n");
#ifdef FFTW_VERSION_2
    rfftw_one((rfftw_plan)global.padsynth_ifft_plan, outfreqs, smp);
#else
    /* remember restrictions on FFTW3 'guru' execute: buffers must be the same
     * sizes, same in-place-ness or out-of-place-ness, and same alignment as
     * when plan was created. */
    fftwf_execute_r2r((const fftwf_plan)global.padsynth_ifft_plan, outfreqs, smp);
#endif

    /* normalize and convert output data */
    YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: normalizing output\n");
    max = 0.0f;
    for (i = 0; i < N; i++) if (fabsf(smp[i]) > max) max = fabsf(smp[i]);
    if (max < 1e-5f) max = 1e-5f;
    max = 32767.0f / max;
    for (i = 0; i < N; i++)
         sample->data[i] = lrintf(smp[i] * max);

    /* copy guard points */
    for (i = -4; i < 0; i++)
        sample->data[i] = sample->data[i + N];
    for (i = 0; i < 4; i++)
        sample->data[N + i] = sample->data[i];

    YDB_MESSAGE(YDB_SAMPLE, " padsynth_render: done\n");

    return 1;
}
Example #25
0
void lib_object_update(obj_t *obj)
{
	assert( obj != NULL );

	clutter_circle_set_angle_stop(
		CLUTTER_CIRCLE(obj->circle_volume),
		(uint) (obj->audio->volume * 360.0f)
	);

	clutter_circle_set_angle_stop(
		CLUTTER_CIRCLE(obj->circle_position),
		(uint) (obj->audio->position * 360.0f)
	);

	if ( ! (obj->flags & OBJ_FL_HIDE_BARGRAPH) )
	{
		/* bar graph
		 */
		if ( obj->audio->input != NULL && obj->audio->input->data != NULL )
		{
			static float			v, *tmp;
			static int				n, i;

			n = obj->audio->input->size;

			/* allocate memory
			 * reajust if we got big sound.
			 */
			if ( bargraph_datasize != n )
			{
				tmp		= realloc(bargraph_data, sizeof(float) * n);
				if ( tmp == NULL )
					return;
				bargraph_data		= tmp;
				bargraph_datasize	= n;
			}

			/* execute fast fourier plan
			 */
			if ( obj->fftpl == NULL )
			{
				obj->fftpl	= fftwf_plan_r2r_1d(n,
					obj->audio->input->data, bargraph_data,
					FFTW_R2HC, FFTW_FORWARD | FFTW_PRESERVE_INPUT
				);
			}

			fftwf_execute(obj->fftpl);

			/* and ajust bargraph !
			 */
			for ( i = 0; i < n && i < BAR_COUNT; i++ )
			{
				v = sqrtf(bargraph_data[i] * bargraph_data[i]) * 30;
				if ( v > 50 )
					v = 50;
				clutter_circle_set_width(CLUTTER_CIRCLE(obj->bars[i]), v);
			}
		}
	}
}