Пример #1
0
/*
 * Class:     jfftw_real_Plan
 * Method:    transform
 * Signature: ([D)[D
 */
JNIEXPORT jdoubleArray JNICALL Java_jfftw_real_Plan_transform___3D( JNIEnv* env, jobject obj, jdoubleArray in )
{
	jdouble *cin, *cout;
	jdoubleArray out;
	int i;

	jclass clazz = (*env)->GetObjectClass( env, obj );
	jfieldID id = (*env)->GetFieldID( env, clazz, "plan", "[B" );
	jbyteArray arr = (jbyteArray)(*env)->GetObjectField( env, obj, id );
	unsigned char* carr = (*env)->GetByteArrayElements( env, arr, 0 );
	rfftw_plan plan = *(rfftw_plan*)carr;
	if( plan->n != (*env)->GetArrayLength( env, in ) )
	{
		(*env)->ThrowNew( env, (*env)->FindClass( env, "java/lang/IndexOutOfBoundsException" ), "the Plan was created for a different length" );
		(*env)->ReleaseByteArrayElements( env, arr, carr, 0 );
		return NULL;
	}

	cin = (*env)->GetDoubleArrayElements( env, in, 0 );

	if( ! plan->flags & FFTW_THREADSAFE )
	{
		// synchronization
		(*env)->MonitorEnter( env, obj );
	}

	if( plan->flags & FFTW_IN_PLACE )
	{
		out = in;
		rfftw_one( plan, cin, NULL );
	}
	else
	{
		out = (*env)->NewDoubleArray( env, plan->n );
		cout = (*env)->GetDoubleArrayElements( env, out, 0 );

		rfftw_one( plan, cin, cout );

		(*env)->ReleaseDoubleArrayElements( env, out, cout, 0 );
	}

	if( ! plan->flags & FFTW_THREADSAFE )
	{
		// synchronization
		(*env)->MonitorExit( env, obj );
	}

	(*env)->ReleaseDoubleArrayElements( env, in, cin, 0 );
	(*env)->ReleaseByteArrayElements( env, arr, carr, 0 );
	return out;
}
Пример #2
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
}
Пример #3
0
int main(int argc, char** argv) {

  fftw_real out[N], in[N];
  rfftw_plan plan_backward;
  buffer_t buffer[N];

  int i, time = 0;

  song_t* head;
  song_t* next;

  print_prologoue(N, SR);

  next = head = read_song("song.txt");
  dump_song(head);
  plan_backward = rfftw_create_plan(N, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);

  while ( next ) {

	// clear out
	for ( i = 0; i < N; i++ )
		out[i] =  0.0f;

	i = 0;
	while (i < ACCORD_SIZE && next->accord[i] != 0)
	  play_note(next->accord[i++], ADSR(time, next->duration), out);

	rfftw_one(plan_backward, out, in);

	for ( i = 0; i < N; i++ )
	  buffer[i] = limit_output(in[i]);;

  	write(1, buffer, N* sizeof(buffer_t));

	time ++;
	if ( time == next->duration ) {
	  // play next note

	  next = next->next;
	  time = 0;

	  // loop:
	  if (next == NULL) next = head;
	}
  }

  rfftw_destroy_plan(plan_backward);
  free_song(head);
  print_epilogue();
  return 0;
}
Пример #4
0
/**
 * Converts the contents of input_buff from the frequency domain
 * to the time domain, omitting the 1/N factor.
 *
 * input_buff: input in half complex array format.
 * output_buff: output of real values (because the IFFT of a 
 *              halfcomplex (eg symmetric) sequency is purely real.
 * 
 * Since this function uses FFTW to compute the inverse FFT,
 * the result is not scaled by the 1/N factor that it should be.
 * In our implementation, the impulse response of the filter
 * is prescaled scaled by 1/N so we get the correct answer.
 *
 * Note that this function trashes the values in input_buff.
 **/
void convert_from_freq(void* thisptr, float* input_buff, float* output_buff, int size) 
{
  struct rfftw_plan_list *plan;

  /* Start off by finding the plan pair, or creating one. */
  plan = get_plan(size);

  /* Run the backward FFT (destroys the contents of input_buff) */
  // reverse is specified by the plan. Then comes input followed by output.
  
  rfftw_one(plan->ctor_plan, (fftw_real *)input_buff, (fftw_real *)output_buff);
  
  /** and we are done. Return value is the input_buffer parameter. **/
}
Пример #5
0
/*
 * do the Fast Fourier Transform
 */
void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs){
#ifdef FFTW_VERSION_2
    for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i];
    rfftw_one(planfftw,tmpfftdata1,tmpfftdata2);
    for (int i=0;i<fftsize/2;i++) {
	freqs.c[i]=tmpfftdata2[i];
	if (i!=0) freqs.s[i]=tmpfftdata2[fftsize-i];
    };
#else
    for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i];
    fftw_execute(planfftw);
    for (int i=0;i<fftsize/2;i++) {
	freqs.c[i]=tmpfftdata1[i];
	if (i!=0) freqs.s[i]=tmpfftdata1[fftsize-i];
    };
#endif
    tmpfftdata2[fftsize/2]=0.0;
};
Пример #6
0
void
PVS::pvsynthesis(float* signal){
double pha;
int i2;

m_ffttmp[0] = m_input->Output(0); 
m_ffttmp[m_halfsize] = m_input->Output(1);

 for(int i=0;i<m_fftsize; i+=2){ 
    i2 = i/2;
	m_phases[i2] += m_input->Output(i+1) - m_fund*i2; 
    pha = m_phases[i2]*m_factor;
    m_ffttmp[i2] = m_input->Output(i)*cos(pha);
	m_ffttmp[m_fftsize-(i2)] = m_input->Output(i)*sin(pha);
	}

   rfftw_one(m_plan, m_ffttmp, signal);
}
Пример #7
0
/*
 * do the Inverse Fast Fourier Transform
 */
void FFTwrapper::freqs2smps(FFTFREQS freqs,REALTYPE *smps){
    tmpfftdata2[fftsize/2]=0.0;
#ifdef FFTW_VERSION_2
    for (int i=0;i<fftsize/2;i++) {
	tmpfftdata1[i]=freqs.c[i];
	if (i!=0) tmpfftdata1[fftsize-i]=freqs.s[i];
    };
    rfftw_one(planfftw_inv,tmpfftdata1,tmpfftdata2);
    for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i];
#else
    for (int i=0;i<fftsize/2;i++) {
	tmpfftdata2[i]=freqs.c[i];
	if (i!=0) tmpfftdata2[fftsize-i]=freqs.s[i];
    };
    fftw_execute(planfftw_inv);
    for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i];
#endif

};
Пример #8
0
/**
 * Replaces the contents of input_buff with the value of its FFT.
 * input_buff: input (real format)/output (halfcomplex format)
 *
 * Since buff is a assumed completly real, the corresponding complex
 * valued FFT(input_buff) is stored in the "half complex array" format of
 * fftw (see http://www.fftw.org/doc/fftw_2.html#SEC5)
 **/
void convert_to_freq(void* thisptr, float* input_buff, int size) 
{
  struct rfftw_plan_list *plan;
  int i;

  /* Start off by finding the plan pair, or creating one. */
  plan = get_plan(size);

  /* Run the forward FFT on the input buffer, saving the result
     into the plan's buffer. */
  rfftw_one(plan->rtoc_plan, (fftw_real *)input_buff, (fftw_real *)plan->buff);

  /* copy the values from the plan buffer (eg the output) into the 
   * input buffer (return value is passed via input). **/
  for (i=0; i<size; i++) {
    input_buff[i] = plan->buff[i];
  }

  /** and we are done. Return value is the input_buffer parameter. **/
}
Пример #9
0
int main(void) {

  fftw_real out[N], in[N];
  rfftw_plan plan_backward;
  buffer_t buffer[N];

  int i, rd;
  long bytes = 0;

  plan_backward = rfftw_create_plan(N, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);

  print_prologoue(N, SR);

  while ( 1 ) {

	out[0] = 0.0;
	for ( i = 1; i < N/2; i++ ) {
	  if ( i % F_BASE == 0 ){
		out[i] = out[N-i] = N * exp(-10*i/N) / 5.0;
	  }
	  else {
		out[i] = out[N-i] = 0.0f;
	  }
	}

	
	rfftw_one(plan_backward, out, in);

	for ( i = 0; i < N; i++ ) 
	  buffer[i] = in[i]/N;

  	rd = write(1, buffer, N* sizeof(buffer_t));
	bytes += rd;
  }

  rfftw_destroy_plan(plan_backward);

  print_epilogue();

  return 0;
}
Пример #10
0
static void runAddingImp(LADSPA_Handle instance, unsigned long sample_count) {
	Imp *plugin_data = (Imp *)instance;
	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;

	/* Impulse ID (float value) */
	const LADSPA_Data impulse = *(plugin_data->impulse);

	/* High latency mode (float value) */
	const LADSPA_Data high_lat = *(plugin_data->high_lat);

	/* Gain (dB) (float value) */
	const LADSPA_Data gain = *(plugin_data->gain);

	/* Input (array of floats of length sample_count) */
	const LADSPA_Data * const input = plugin_data->input;

	/* Output (array of floats of length sample_count) */
	LADSPA_Data * const output = plugin_data->output;
	fftw_real * block_freq = plugin_data->block_freq;
	fftw_real * block_time = plugin_data->block_time;
	unsigned int count = plugin_data->count;
	fftw_real ** impulse_freq = plugin_data->impulse_freq;
	unsigned long in_ptr = plugin_data->in_ptr;
	fftw_real * op = plugin_data->op;
	LADSPA_Data * opc = plugin_data->opc;
	unsigned long out_ptr = plugin_data->out_ptr;
	LADSPA_Data * overlap = plugin_data->overlap;

	unsigned long i, pos, ipos, limit;
	unsigned int im;
	unsigned int len;
	fftw_real tmp;
	fftw_real *imp_freq;
	float coef;

	im = f_round(impulse) - 1;
	if (im >= IMPULSES) {
	  im = 0;
	}

	coef = pow(10.0f, gain * 0.05f) / (float)fft_length[im];

	imp_freq = impulse_freq[im];

	for (pos = 0; pos < sample_count; pos += SEG_LENGTH) {
	  limit = pos + SEG_LENGTH;

	  for (ipos = pos; ipos < sample_count && ipos<limit; ipos++) {
	    block_time[in_ptr++] = input[ipos];

	    if (in_ptr == SEG_LENGTH) {
#ifdef FFTW3
	      fftwf_execute(plan_rc[im]);
#else
	      rfftw_one(plan_rc[im], block_time, block_freq);
#endif

	      len = fft_length[im];
	      for (i=1; i<fft_length[im]/2; i++) {
	        len--;
	        tmp = block_freq[i] * imp_freq[i] -
	         block_freq[len] * imp_freq[len];
	        block_freq[len] =
	         block_freq[i] * imp_freq[len] +
	         block_freq[len] * imp_freq[i];
	        block_freq[i] = tmp;
	      }

	      block_freq[0] = imp_freq[0] * block_freq[0];
	      block_freq[fft_length[im]/2] = imp_freq[fft_length[im]/2] * block_freq[fft_length[im]/2];

#ifdef FFTW3
	      fftwf_execute(plan_cr[im]);
#else
	      rfftw_one(plan_cr[im], block_freq, op);
#endif

	      for (i=0; i<fft_length[im]-SEG_LENGTH; i++) {
	        op[i] += overlap[i];
	      }
	      for (i=SEG_LENGTH; i<fft_length[im]; i++) {
	        overlap[i-SEG_LENGTH] = op[i];
	      }

	      in_ptr = 0;
	      if (count == 0 && high_lat < 1.0f) {
	        count = 1;
	        plugin_data->count = 1;
	        out_ptr = 0;
	      }
	    }
	  }

	  for (ipos = pos; ipos < sample_count && ipos<limit; ipos++) {
	    buffer_write(output[ipos], opc[out_ptr++] * coef);
	    if (out_ptr == SEG_LENGTH) {
	      for (i=0; i<SEG_LENGTH; i++) {
	        opc[i] = op[i];
	      }
	      out_ptr = 0;
	    }
	  }
	}

	plugin_data->in_ptr = in_ptr;
	plugin_data->out_ptr = out_ptr;

	*(plugin_data->latency) = SEG_LENGTH;
}
Пример #11
0
int 
gmx_fft_1d_real(gmx_fft_t                  fft,
                enum gmx_fft_direction     dir,
                void *                     in_data,
                void *                     out_data)
{
    /* FFTW2 1-dimensional real transforms are special.
     *
     * First, the complex data is stored in a special packed half-complex
     * fashion. To enable a standard common Gromacs interface this forces us
     * to always use out-of-place FFTs, and permute the data after 
     * real-to-complex FFTs or before complex-to-real FFTs.
     *
     * The input is also destroyed for out-of-place complex-to-real FFTs, but
     * this doesn't matter since we need to permute and copy the data into 
     * the work array first anyway.
     */
    real *     work = fft->work;
    t_complex *  data;
    int              n    = fft->nx;
    int              i;
    
    if((fft->ndim != 1) ||
       ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL)))
    {
        gmx_fatal(FARGS,"FFT plan mismatch - bad plan or direction.");
        return EINVAL;
    }
    
    if(dir==GMX_FFT_REAL_TO_COMPLEX) 
    {
        rfftw_one(fft->single[0][1],(fftw_real *)in_data,(fftw_real *)work);
        /* permute it back into data, in standard complex format 
         * instead of halfcomplex...
         */
        data = (t_complex *)out_data;
        
        data[0].re = work[0];
        data[0].im = 0;
        
        for(i=1;i<n/2;i++)
        {
            data[i].re = work[i];
            data[i].im = work[n-i];
        }

        data[i].re=work[i];
        
        if(2*i==n) 
        {
            data[i].im=0;
        }
        else
        {
            data[i].im=work[n-i];
        }
    }
    else
    {
        /* Complex-to-real. First permute standard format into halfcomplex */
        data = (t_complex *)in_data;
        
        work[0]=data[0].re;
        
        for(i=1;i<n/2;i++) 
        {
            work[i]  =data[i].re;
            work[n-i]=data[i].im;
        }      
        
        if(2*i!=n)
        {
            work[n-i]=data[i].im;
        }
        
        rfftw_one(fft->single[0][0],(fftw_real *)work,(fftw_real *)out_data);
    }

    return 0;
}
Пример #12
0
static void runAddingMbeq(LADSPA_Handle instance, unsigned long sample_count) {
	Mbeq *plugin_data = (Mbeq *)instance;
	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;

	/* 50Hz gain (low shelving) (float value) */
	const LADSPA_Data band_1 = *(plugin_data->band_1);

	/* 100Hz gain (float value) */
	const LADSPA_Data band_2 = *(plugin_data->band_2);

	/* 156Hz gain (float value) */
	const LADSPA_Data band_3 = *(plugin_data->band_3);

	/* 220Hz gain (float value) */
	const LADSPA_Data band_4 = *(plugin_data->band_4);

	/* 311Hz gain (float value) */
	const LADSPA_Data band_5 = *(plugin_data->band_5);

	/* 440Hz gain (float value) */
	const LADSPA_Data band_6 = *(plugin_data->band_6);

	/* 622Hz gain (float value) */
	const LADSPA_Data band_7 = *(plugin_data->band_7);

	/* 880Hz gain (float value) */
	const LADSPA_Data band_8 = *(plugin_data->band_8);

	/* 1250Hz gain (float value) */
	const LADSPA_Data band_9 = *(plugin_data->band_9);

	/* 1750Hz gain (float value) */
	const LADSPA_Data band_10 = *(plugin_data->band_10);

	/* 2500Hz gain (float value) */
	const LADSPA_Data band_11 = *(plugin_data->band_11);

	/* 3500Hz gain (float value) */
	const LADSPA_Data band_12 = *(plugin_data->band_12);

	/* 5000Hz gain (float value) */
	const LADSPA_Data band_13 = *(plugin_data->band_13);

	/* 10000Hz gain (float value) */
	const LADSPA_Data band_14 = *(plugin_data->band_14);

	/* 20000Hz gain (float value) */
	const LADSPA_Data band_15 = *(plugin_data->band_15);

	/* Input (array of floats of length sample_count) */
	const LADSPA_Data * const input = plugin_data->input;

	/* Output (array of floats of length sample_count) */
	LADSPA_Data * const output = plugin_data->output;
	int * bin_base = plugin_data->bin_base;
	float * bin_delta = plugin_data->bin_delta;
	fftw_real * comp = plugin_data->comp;
	float * db_table = plugin_data->db_table;
	long fifo_pos = plugin_data->fifo_pos;
	LADSPA_Data * in_fifo = plugin_data->in_fifo;
	LADSPA_Data * out_accum = plugin_data->out_accum;
	LADSPA_Data * out_fifo = plugin_data->out_fifo;
	fftw_real * real = plugin_data->real;
	float * window = plugin_data->window;

#line 125 "mbeq_1197.xml"
	int i, bin, gain_idx;
	static int done;
	float gains[BANDS + 1] =
	  { band_1, band_2, band_3, band_4, band_5, band_6, band_7, band_8, band_9,
	    band_10, band_11, band_12, band_13, band_14, band_15, 0.0f };
	float coefs[FFT_LENGTH / 2];
	unsigned long pos;
	
	int step_size = FFT_LENGTH / OVER_SAMP;
	int fft_latency = FFT_LENGTH - step_size;
	
	// Convert gains from dB to co-efficents
	for (i = 0; i < BANDS; i++) {
	        gain_idx = (int)((gains[i] * 10) + 700);
	        gains[i] = db_table[LIMIT(gain_idx, 0, 999)];
	}
	
	// Calculate coefficients for each bin of FFT
	coefs[0] = 0.0f;
	for (bin=1; bin < (FFT_LENGTH/2-1); bin++) {
	        coefs[bin] = ((1.0f-bin_delta[bin]) * gains[bin_base[bin]])
	                      + (bin_delta[bin] * gains[bin_base[bin]+1]);
	}
	
	if (fifo_pos == 0) {
	        fifo_pos = fft_latency;
	}
	
	for (pos = 0; pos < sample_count; pos++) {
	        in_fifo[fifo_pos] = input[pos];
	        buffer_write(output[pos], out_fifo[fifo_pos-fft_latency]);
	        fifo_pos++;
	
	        // If the FIFO is full
	        if (fifo_pos >= FFT_LENGTH) {
	                fifo_pos = fft_latency;
	
	                // Window input FIFO
	                for (i=0; i < FFT_LENGTH; i++) {
	                        real[i] = in_fifo[i] * window[i];
	                }
	
	                // Run the real->complex transform
	#ifdef FFTW3
	                fftwf_execute(plan_rc);
	#else
	                rfftw_one(plan_rc, real, comp);
	#endif
	
	                // Multiply the bins magnitudes by the coeficients
	                for (i = 0; i < FFT_LENGTH/2; i++) {
	                        comp[i] *= coefs[i];
	                        comp[FFT_LENGTH-i] *= coefs[i];
	                }
	
	                // Run the complex->real transform
	#ifdef FFTW3
	                fftwf_execute(plan_cr);
	#else
	                rfftw_one(plan_cr, comp, real);
	#endif
	
	                // Window into the output accumulator
	                for (i = 0; i < FFT_LENGTH; i++) {
	                        out_accum[i] += 0.9186162f * window[i] * real[i]/(FFT_LENGTH * OVER_SAMP);
	                }
	                for (i = 0; i < step_size; i++) {
	                        out_fifo[i] = out_accum[i];
	                }
	
	                // Shift output accumulator
	                memmove(out_accum, out_accum + step_size, FFT_LENGTH*sizeof(LADSPA_Data));
	
	                // Shift input fifo
	                for (i = 0; i < fft_latency; i++) {
	                        in_fifo[i] = in_fifo[i+step_size];
	                }
	done++;
	        }
	}
	
	// Store the fifo_position
	plugin_data->fifo_pos = fifo_pos;
	
	*(plugin_data->latency) = fft_latency;
}
Пример #13
0
int main (int argc, char** argv)
{
  extern int abs_flg; /* flag for absolute/relative cutoff  */
  extern double adj_pitch;
  extern double pitch_shift;
  extern int n_pitch;

  char *file_midi = NULL;
  char *file_wav = NULL;
  char *file_patch = NULL;

  int i;

  // default value
  double cut_ratio; // log10 of cutoff ratio for scale velocity
  cut_ratio = -5.0;
  double rel_cut_ratio; // log10 of cutoff ratio relative to average
  rel_cut_ratio = 1.0; // this value is ignored when abs_flg == 1
  long len = 2048;
  int flag_window = 3; // hanning window
  /* for 76 keys piano  */
  int notetop = 103; /* G8  */
  int notelow = 28; /* E2  */

  abs_flg = 1;

  long hop = 0;
  int show_help = 0;
  int show_version = 0;
  adj_pitch = 0.0;
  /* to select peaks in a note  */
  int peak_threshold = 128; /* this means no peak search  */

  int flag_phase = 1; // use the phase correction
  int psub_n = 0;
  double psub_f = 0.0;
  double oct_f = 0.0;
  for (i = 1; i < argc; i++)
    {
      if ((strcmp (argv[i], "-input" ) == 0)
	 || (strcmp (argv[i], "-i" ) == 0))
	{
	  if ( i+1 < argc )
	    {
	      file_wav = (char *)malloc (sizeof (char)
					 * (strlen (argv[++i]) + 1));
	      CHECK_MALLOC (file_wav, "main");
	      strcpy (file_wav, argv[i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "-output" ) == 0)
	      || (strcmp (argv[i], "-o" ) == 0))
	{
	  if ( i+1 < argc )
	    {
	      file_midi = (char *)malloc (sizeof (char)
					 * (strlen (argv[++i]) + 1));
	      CHECK_MALLOC (file_midi, "main");
	      strcpy (file_midi, argv[i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--cutoff") == 0)
	       || (strcmp (argv[i], "-c") == 0))
	{
	  if ( i+1 < argc )
	    {
	      cut_ratio = atof (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--top") == 0)
	       || (strcmp (argv[i], "-t") == 0))
	{
	  if ( i+1 < argc )
	    {
	      notetop = atoi( argv[++i] );
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--bottom") == 0)
	       || (strcmp (argv[i], "-b") == 0))
	{
	  if ( i+1 < argc )
	    {
	      notelow = atoi (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--window") == 0)
	       || (strcmp (argv[i], "-w") == 0))
	{
	  if ( i+1 < argc )
	    {
	      flag_window = atoi (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ( strcmp (argv[i], "-n") == 0)
	{
	  if ( i+1 < argc )
	    {
	      len = atoi (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--shift") == 0)
	       || (strcmp (argv[i], "-s") == 0))
	{
	  if ( i+1 < argc )
	    {
	      hop = atoi (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--patch") == 0)
	       || (strcmp (argv[i], "-p") == 0))
	{
	  if ( i+1 < argc )
	    {
	      file_patch = argv[++i];
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--relative") == 0)
	       || (strcmp (argv[i], "-r") == 0))
	{
	  if ( i+1 < argc )
	    {
	      rel_cut_ratio = atof (argv[++i]);
	      abs_flg = 0;
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--peak") == 0)
	       || (strcmp (argv[i], "-k") == 0))
	{
	  if ( i+1 < argc )
	    {
	      peak_threshold = atoi (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--adjust") == 0)
	       || (strcmp (argv[i], "-a") == 0))
	{
	  if ( i+1 < argc )
	    {
	      adj_pitch = atof (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if ((strcmp (argv[i], "--help") == 0)
	       || (strcmp (argv[i], "-h") == 0))
	{
	  show_help = 1;
	  break;
	}
      else if (strcmp (argv[i], "-nophase") == 0)
	{
	  flag_phase = 0;
	}
      else if (strcmp (argv[i], "-psub-n") == 0)
	{
	  if ( i+1 < argc )
	    {
	      psub_n = atoi (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if (strcmp (argv[i], "-psub-f") == 0)
	{
	  if ( i+1 < argc )
	    {
	      psub_f = atof (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if (strcmp (argv[i], "-oct") == 0)
	{
	  if ( i+1 < argc )
	    {
	      oct_f = atof (argv[++i]);
	    }
	  else
	    {
	      show_help = 1;
	      break;
	    }
	}
      else if (strcmp (argv[i], "-v") == 0 ||
	       strcmp (argv[i], "--version") == 0)
	{
	  show_version = 1;
	}
      else
	{
	  show_help = 1;
	}
    }
  if (show_help == 1)
    {
      print_usage (argv[0]);
      exit (1);
    }
  else if (show_version == 1)
    {
      print_version ();
      exit (1);
    }

  if (flag_window < 0 || flag_window > 6)
    {
      flag_window = 0;
    }
  if (hop == 0)
    {
      hop = len / 4;
    }
  if (psub_n == 0) psub_f = 0.0;
  if (psub_f == 0.0) psub_n = 0;


  struct WAON_notes *notes = WAON_notes_init();
  CHECK_MALLOC (notes, "main");
  char vel[128];     // velocity at the current step
  int on_event[128]; // event index of struct WAON_notes.
  for (i = 0; i < 128; i ++)
    {
      vel[i]      = 0;
      on_event[i] = -1;
    }

  // allocate buffers
  double *left  = (double *)malloc (sizeof (double) * len);
  double *right = (double *)malloc (sizeof (double) * len);
  CHECK_MALLOC (left,  "main");
  CHECK_MALLOC (right, "main");

  double *x = NULL; /* wave data for FFT  */
  double *y = NULL; /* spectrum data for FFT */ 
#ifdef FFTW2
  x = (double *)malloc (sizeof (double) * len);
  y = (double *)malloc (sizeof (double) * len);
#else // FFTW3
  x = (double *)fftw_malloc (sizeof (double) * len);
  y = (double *)fftw_malloc (sizeof (double) * len);
#endif // FFTW2
  CHECK_MALLOC (x, "main");
  CHECK_MALLOC (y, "main");

  /* power spectrum  */
  double *p = (double *)malloc (sizeof (double) * (len / 2 + 1));
  CHECK_MALLOC (p, "main");

  double *p0 = NULL;
  double *dphi = NULL;
  double *ph0 = NULL;
  double *ph1 = NULL;
  if (flag_phase != 0)
    {
      p0 = (double *)malloc (sizeof (double) * (len / 2 + 1));
      CHECK_MALLOC (p0, "main");

      dphi = (double *)malloc (sizeof (double) * (len / 2 + 1));
      CHECK_MALLOC (dphi, "main");

      ph0 = (double *)malloc (sizeof (double) * (len/2+1));
      ph1 = (double *)malloc (sizeof (double) * (len/2+1));
      CHECK_MALLOC (ph0, "main");
      CHECK_MALLOC (ph1, "main");
    }

  double *pmidi = (double *)malloc (sizeof (double) * 128);
  CHECK_MALLOC (pmidi, "main");


  // MIDI output
  if (file_midi == NULL)
    {
      file_midi = (char *)malloc (sizeof (char) * (strlen("output.mid") + 1));
      CHECK_MALLOC (file_midi, "main");
      strcpy (file_midi, "output.mid");
    }

  // open input wav file
  if (file_wav == NULL)
    {
      file_wav = (char *) malloc (sizeof (char) * 2);
      CHECK_MALLOC (file_wav, "main");
      file_wav [0] = '-';
    }
  SF_INFO sfinfo;
  SNDFILE *sf = sf_open (file_wav, SFM_READ, &sfinfo);
  if (sf == NULL)
    {
      fprintf (stderr, "Can't open input file %s : %s\n",
	       file_wav, strerror (errno));
      exit (1);
    }
  sndfile_print_info (&sfinfo);


  // check stereo or mono
  if (sfinfo.channels != 2 && sfinfo.channels != 1)
    {
      fprintf (stderr, "only mono and stereo inputs are supported.\n");
      exit (1);
    }


  // time-period for FFT (inverse of smallest frequency)
  double t0 = (double)len/(double)sfinfo.samplerate;

  // weight of window function for FFT
  double den = init_den (len, flag_window);

  /* set range to analyse (search notes) */
  /* -- after 't0' is calculated  */
  int i0 = (int)(mid2freq[notelow]*t0 - 0.5);
  int i1 = (int)(mid2freq[notetop]*t0 - 0.5)+1;
  if (i0 <= 0)
    {
      i0 = 1; // i0=0 means DC component (frequency = 0)
    }
  if (i1 >= (len/2))
    {
      i1 = len/2 - 1;
    }

  // init patch
  init_patch (file_patch, len, flag_window);
  /*                      ^^^ len could be given by option separately  */

  // initialization plan for FFTW
#ifdef FFTW2
  rfftw_plan plan;
  plan = rfftw_create_plan (len, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
#else // FFTW3
  fftw_plan plan;
  plan = fftw_plan_r2r_1d (len, x, y, FFTW_R2HC, FFTW_ESTIMATE);
#endif

  // for first step
  if (hop != len)
    {
      if (sndfile_read (sf, sfinfo,
			left + hop,
			right + hop,
			(len - hop))
	  != (len - hop))
	{
	  fprintf (stderr, "No Wav Data!\n");
	  exit(0);
	}
    }

  /** main loop (icnt) **/
  pitch_shift = 0.0;
  n_pitch = 0;
  int icnt; /* counter  */
  for (icnt=0; ; icnt++)
    {
      // shift
      for (i = 0; i < len - hop; i ++)
	{
	  if (sfinfo.channels == 2) // stereo
	    {
	      left  [i] = left  [i + hop];
	      right [i] = right [i + hop];
	    }
	  else // mono
	    {
	      left  [i] = left  [i + hop];
	    }
	}
      // read from wav
      if (sndfile_read (sf, sfinfo,
			left  + (len - hop),
			right + (len - hop),
			hop)
	  != hop)
	{
	  fprintf (stderr, "WaoN : end of file.\n");
	  break;
	}

      // set double table x[] for FFT
      for (i = 0; i < len; i ++)
	{
	  if (sfinfo.channels == 2) // stereo
	    {
	      x [i] = 0.5 * (left [i] + right [i]);
	    }
	  else // mono
	    {
	      x [i] = left [i];
	    }
	}

      /**
       * stage 1: calc power spectrum
       */
      windowing (len, x, flag_window, 1.0, x);

      /* FFTW library  */
#ifdef FFTW2
      rfftw_one (plan, x, y);
#else // FFTW3
      fftw_execute (plan); // x[] -> y[]
#endif

      if (flag_phase == 0)
	{
	  // no phase-vocoder correction
	  HC_to_amp2 (len, y, den, p);
	}
      else
	{
	  // with phase-vocoder correction
	  HC_to_polar2 (len, y, 0, den, p, ph1);

	  if (icnt == 0) // first step, so no ph0[] yet
	    {
	      for (i = 0; i < (len/2+1); ++i) // full span
		{
		  // no correction
		  dphi[i] = 0.0;

		  // backup the phase for the next step
		  p0  [i] = p   [i];
		  ph0 [i] = ph1 [i];
		}	  
	    }
	  else // icnt > 0
	    {
	      // freq correction by phase difference
	      for (i = 0; i < (len/2+1); ++i) // full span
		{
		  double twopi = 2.0 * M_PI;
		  //double dphi;
		  dphi[i] = ph1[i] - ph0[i]
		    - twopi * (double)i / (double)len * (double)hop;
		  for (; dphi[i] >= M_PI; dphi[i] -= twopi);
		  for (; dphi[i] < -M_PI; dphi[i] += twopi);

		  // frequency correction
		  // NOTE: freq is (i / len + dphi) * samplerate [Hz]
		  dphi[i] = dphi[i] / twopi / (double)hop;

		  // backup the phase for the next step
		  p0  [i] = p   [i];
		  ph0 [i] = ph1 [i];

		  // then, average the power for the analysis
		  p[i] = 0.5 *(sqrt (p[i]) + sqrt (p0[i]));
		  p[i] = p[i] * p[i];
		}
	    }
	}

      // drum-removal process
      if (psub_n != 0)
	{
	  power_subtract_ave (len, p, psub_n, psub_f);
	}

      // octave-removal process
      if (oct_f != 0.0)
	{
	  power_subtract_octave (len, p, oct_f);
	}

      /**
       * stage 2: pickup notes
       */
      /* new code
      if (flag_phase == 0)
	{
	  average_FFT_into_midi (len, (double)sfinfo.samplerate,
				 p, NULL,
				 pmidi);
	}
      else
	{
	  average_FFT_into_midi (len, (double)sfinfo.samplerate,
				 p, dphi,
				 pmidi);
	}
      pickup_notes (pmidi,
		    cut_ratio, rel_cut_ratio,
		    notelow, notetop,
		    vel);
      */

      /* old code */
      if (flag_phase == 0)
	{
	  // no phase-vocoder correction
	  note_intensity (p, NULL,
			  cut_ratio, rel_cut_ratio, i0, i1, t0, vel);
	}
      else
	{
	  // with phase-vocoder correction
	  // make corrected frequency (i / len + dphi) * samplerate [Hz]
	  for (i = 0; i < (len/2+1); ++i) // full span
	    {
	      dphi[i] = ((double)i / (double)len + dphi[i])
		* (double)sfinfo.samplerate;
	    }
	  note_intensity (p, dphi,
			  cut_ratio, rel_cut_ratio, i0, i1, t0, vel);
	}

      /**
       * stage 3: check previous time for note-on/off
       */
      WAON_notes_check (notes, icnt, vel, on_event,
			8, 0, peak_threshold);
    }


  // clean notes
  WAON_notes_regulate (notes);

  WAON_notes_remove_shortnotes (notes, 1, 64);
  WAON_notes_remove_shortnotes (notes, 2, 28);

  WAON_notes_remove_octaves (notes);


  /*
  pitch_shift /= (double) n_pitch;
  fprintf (stderr, "WaoN : difference of pitch = %f ( + %f )\n",
	   -(pitch_shift - 0.5),
	   adj_pitch);
  */

  /* div is the divisions for one beat (quater-note).
   * here we assume 120 BPM, that is, 1 beat is 0.5 sec.
   * note: (hop / ft->rate) = duration for 1 step (sec) */
  long div = (long)(0.5 * (double)sfinfo.samplerate / (double) hop);
  fprintf (stderr, "division = %ld\n", div);
  fprintf (stderr, "WaoN : # of events = %d\n", notes->n);

  WAON_notes_output_midi (notes, div, file_midi);


#ifdef FFTW2
  rfftw_destroy_plan (plan);
#else
  fftw_destroy_plan (plan);
#endif /* FFTW2 */


  WAON_notes_free (notes);
  free (left);
  free (right);
  free (x);
  free (y);
  free (p);
  if (p0 != NULL) free (p0);
  if (dphi != NULL) free (dphi);
  if (ph0 != NULL) free (ph0);
  if (ph1 != NULL) free (ph1);

  if (pmidi != NULL) free (pmidi);

  if (file_wav  != NULL) free (file_wav);
  if (file_midi != NULL) free (file_midi);

  sf_close (sf);

  return 0;
}
Пример #14
0
void F77_FUNC_(rfftw_f77_one,RFFTW_F77_ONE)
(fftw_plan *p, fftw_real *in, fftw_real *out)
{
     rfftw_one(*p,in,out);
}
Пример #15
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;
}
Пример #16
0
/*
 * Function: ComputeKernelUniformGrid
 * ------------------------------------------------------------------
 * Computes the kernel for 316(2n-1)^3 interactions between Uniform
 * Grid nodes. Does not compute SVD.
 */
void H2_3D_Tree::ComputeKernelUniformGrid(double *Kweights, int n, doft *dof, char *Kmat, double alphaAdjust, rfftw_plan p_r2c) {
    
    /* TODO: multi-dof, alphaAdjust */
    
    int i, k1, k2, k3, l1, l2, l3;
    vector3 scenter;
    
    int dof2 = dof->s * dof->f;
    //int dof2n6 = dof2 * (2*n-1)*(2*n-1)*(2*n-1); // Total size
    
    double nodes[n], kernel[dof2];
    vector3 fieldpos, sourcepos;
    
    
    // Compute Chebyshev nodes of T_n(x)
    //double scale = 1+alphaAdjust;
    CalculateNodeLocations(n,nodes,0);
    
    // creat FFT plan
    int vecSize = 2*n-1, reducedMatSize = pow(vecSize, 3);
    int M2LSize = dof2 *reducedMatSize;
    double *MatM2L  = (double*)malloc(M2LSize *sizeof(double));
    double *freqMat = (double*)malloc(316 *M2LSize *sizeof(double));
    
    // Compute the kernel values for interactions with all 316 cells
    int countM2L=0, count, count1;
    int shift1, shift2, shiftGlo, shiftLoc;
    int reducedMatSizeDofs = reducedMatSize *dof->s;
    int f, s;
    
    for (k1=-3;k1<4;k1++) {
        scenter.x = (double)k1;
        for (k2=-3;k2<4;k2++) {
            scenter.y = (double)k2;
            for (k3=-3;k3<4;k3++) {
                scenter.z = (double)k3;
                if (abs(k1) > 1 || abs(k2) > 1 || abs(k3) > 1) {
                    
                    for (count=0, l1=0; l1<vecSize; l1++) {
                        GetPosition(n, l1, &fieldpos.x, &sourcepos.x, nodes);
                        sourcepos.x += scenter.x;
                        for (l2=0; l2<vecSize; l2++) {
                            GetPosition(n, l2, &fieldpos.y, &sourcepos.y, nodes);
                            sourcepos.y += scenter.y;
                            for (l3=0; l3<vecSize; l3++, count++) {
                                GetPosition(n, l3, &fieldpos.z, &sourcepos.z, nodes);
                                sourcepos.z += scenter.z;
                                
                                EvaluateKernel(fieldpos,sourcepos,kernel,dof);
                                
                                // kernel[f x s] in column major
                                // MatM2L[(2n-1)^3 x s x f] in column
                                // major
                                count1 = 0;
                                shift1 = count;
                                for (s=0; s < dof->s; s++) {
                                    for(f=0, shift2=0; f < dof->f; f++) {
                                        MatM2L[shift1 + shift2] =  kernel[count1++];
                                        shift2 += reducedMatSizeDofs;
                                    }
                                    shift1 += reducedMatSize;
                                }
                            }
                        }
                    }
                    
                    // FFT
                    shiftGlo = countM2L *M2LSize;
                    
                    for (i=0, shiftLoc=0; i<dof2; i++) {
                        rfftw_one(p_r2c, MatM2L + shiftLoc, freqMat +
                                  shiftGlo + shiftLoc);
                        shiftLoc += reducedMatSize;
                    }
                    
                
                    
                    countM2L++;
                }
            }
        }
    }
    	
    FILE *ptr_file;
    ptr_file = fopen(Kmat, "wb");
    fwrite(freqMat, sizeof(double),316 *M2LSize, ptr_file);
    fclose(ptr_file);
    
    free(MatM2L);
    free(freqMat);
    
}
void test_in_place(int n, int istride,
		   int howmany, fftw_direction dir,
		   fftw_plan validated_plan, int specific)
{
     fftw_complex *in2, *out2;
     fftw_real *in1, *out1, *out3;
     fftw_plan plan;
     int i, j;
     int ostride = istride;
     int flags = measure_flag | wisdom_flag | FFTW_IN_PLACE;

     if (coinflip())
	  flags |= FFTW_THREADSAFE;

     in1 = (fftw_real *) fftw_malloc(istride * n * sizeof(fftw_real) * howmany);
     in2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     out1 = in1;
     out2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex));
     out3 = (fftw_real *) fftw_malloc(n * sizeof(fftw_real));

     if (!specific)
	  plan = rfftw_create_plan(n, dir, flags);
     else
	  plan = rfftw_create_plan_specific(n, dir, flags,
					    in1, istride, out1, ostride);
     CHECK(plan != NULL, "can't create plan");

     /* generate random inputs */
     fill_random(in1, n, istride);
     for (j = 1; j < howmany; ++j)
	  for (i = 0; i < n; ++i)
	       in1[(j * n + i) * istride] = in1[i * istride];

     /* copy random inputs to complex array for comparison with fftw: */
     if (dir == FFTW_REAL_TO_COMPLEX)
	  for (i = 0; i < n; ++i) {
	       c_re(in2[i]) = in1[i * istride];
	       c_im(in2[i]) = 0.0;
     } else {
	  int n2 = (n + 1) / 2;
	  c_re(in2[0]) = in1[0];
	  c_im(in2[0]) = 0.0;
	  for (i = 1; i < n2; ++i) {
	       c_re(in2[i]) = in1[i * istride];
	       c_im(in2[i]) = in1[(n - i) * istride];
	  }
	  if (n2 * 2 == n) {
	       c_re(in2[n2]) = in1[n2 * istride];
	       c_im(in2[n2]) = 0.0;
	       ++i;
	  }
	  for (; i < n; ++i) {
	       c_re(in2[i]) = c_re(in2[n - i]);
	       c_im(in2[i]) = -c_im(in2[n - i]);
	  }
     }

     /* 
      * fill in other positions of the array, to make sure that
      * rfftw doesn't overwrite them 
      */
     for (j = 1; j < istride; ++j)
	  for (i = 0; i < n * howmany; ++i)
	       in1[i * istride + j] = i * istride + j;

     WHEN_VERBOSE(2, rfftw_print_plan(plan));

     /* fft-ize */
     if (howmany != 1 || istride != 1 || coinflip())
	  rfftw(plan, howmany, in1, istride, n * istride, 0, 0, 0);
     else
	  rfftw_one(plan, in1, NULL);

     rfftw_destroy_plan(plan);

     /* check for overwriting */
     for (j = 1; j < ostride; ++j)
	  for (i = 0; i < n * howmany; ++i)
	       CHECK(out1[i * ostride + j] == i * ostride + j,
		     "output has been overwritten");

     fftw(validated_plan, 1, in2, 1, n, out2, 1, n);

     if (dir == FFTW_REAL_TO_COMPLEX) {
	  int n2 = (n + 1) / 2;
	  out3[0] = c_re(out2[0]);
	  for (i = 1; i < n2; ++i) {
	       out3[i] = c_re(out2[i]);
	       out3[n - i] = c_im(out2[i]);
	  }
	  if (n2 * 2 == n)
	       out3[n2] = c_re(out2[n2]);
     } else {
	  for (i = 0; i < n; ++i)
	       out3[i] = c_re(out2[i]);
     }

     for (j = 0; j < howmany; ++j)
	  CHECK(compute_error(out1 + j * n * ostride, ostride, out3, 1, n)
		< TOLERANCE,
		"test_in_place: wrong answer");
     WHEN_VERBOSE(2, printf("OK\n"));

     fftw_free(in1);
     fftw_free(in2);
     fftw_free(out2);
     fftw_free(out3);
}
Пример #18
0
void CPlotDlg::OnMenu(UINT nID)
{
	static char fullfname[MAX_PATH];
	static CAxis *axSpec(NULL);
	CAxis *localax(gcf->ax[0]); // Following the convention
	CRect rt;
	CSize sz;
	CFont editFont;
	CPosition pos;
	double range, miin(1.e15), maax(-1.e15);
	double width, newmin, newmax;
	int i, len, id1, id2, iSel(-1);
	char errstr[256];
	CSignals signal;
	bool multi;
	static void  *playPoint;
	switch (nID)
	{
	case IDM_FULLVIEW:
		localax->setRange('x',localax->m_ln[0]->xdata[0], localax->m_ln[0]->xdata[localax->m_ln[0]->len-1]);
		localax->setTick('x', 0, localax->m_ln[0]->xdata[localax->m_ln[0]->len-1]/10, 1, 0, "%6.3f");
		// 2/3/2011, commented out by jhpark, because y axis is not affected by zooming.
		//localax->setRange('y', -1, 1);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;

	case IDM_ZOOM_IN:
		width = localax->xlim[1] - localax->xlim[0];
		if (width<0.005) return;
		localax->setRange('x', localax->xlim[0] + width/4., localax->xlim[1] - width/4.);
		width = localax->xtick.a2 - localax->xtick.a1;
		localax->xtick.a2 -= width/4.;
		localax->xtick.a1 += width/4.;
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;

	case IDM_ZOOM_OUT:
		if (localax->xlim[1]==localax->xlimFull[1] && localax->xlim[0]==localax->xlimFull[0]) return;
		for (i=0; i<localax->nLines; i++)
			miin = min(miin, getMin(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		for (i=0; i<localax->nLines; i++)
			maax = max(maax, getMax(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		width = localax->xlim[1] - localax->xlim[0];
		localax->setRange('x', max(miin,localax->xlim[0] - width/2.), min(maax,localax->xlim[1] + width/2.));
		width = localax->xtick.a2 - localax->xtick.a1;
		//Oh, I just realized that a1 and a2 do not need to be within the range==> no need to check, it will still draw the ticks only within the range.
		localax->xtick.a2 += width/2.;
		localax->xtick.a1 -= width/2.;
		if (localax->xtick.a1<0) localax->xtick.a1=0;
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_SCROLL_LEFT:
		for (i=0; i<localax->nLines; i++)
			miin = min(miin, getMin(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmin = max(miin, localax->xlim[0]-range);
		localax->setRange('x', newmin, newmin+range);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_SCROLL_RIGHT:
		for (i=0; i<localax->nLines; i++)
			maax = max(maax, getMax(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmax = min(maax, localax->xlim[1]+range);
		localax->setRange('x', newmax-range, newmax);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_LEFT_STEP:
		for (i=0; i<localax->nLines; i++)
			miin = min(miin, getMin(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmin = max(miin, localax->xlim[0]-range/4.);
		localax->setRange('x', newmin, newmin+range);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_RIGHT_STEP:
		for (i=0; i<localax->nLines; i++)
			maax = max(maax, getMax(localax->m_ln[i]->len, localax->m_ln[i]->xdata));
		range = localax->xlim[1] - localax->xlim[0];
		newmax = min(maax, localax->xlim[1]+range/4.);
		localax->setRange('x', newmax-range, newmax);
		rt = localax->axRect;
		rt.InflateRect(5,0,5,30);
		InvalidateRect(&rt);
		OnMenu(IDM_SPECTRUM_INTERNAL);
		return;
	case IDM_PLAY:
		errstr[0]=0;
		if (!playing)
			if(!GetSignalInRange(signal,1))		MessageBox (errStr);
			else 
			{
				playPoint = signal.PlayArray(devID, WM__SOUND_EVENT, hDlg, &block, errstr);
				playing = true;
			}
		else
		{
			PauseResumePlay(playPoint, paused);
			playing = paused;
			if (paused) paused = false;
		}
		return;
	case IDM_PAUSE:
		errstr[0]=0;
		if (playing)
		{
			PauseResumePlay(playPoint, false);
			paused = true;
		}
		return;
	case IDM_SPECTRUM:
		// To draw a spectrum, first re-adjust the aspect ratio of the client window 
		// so that the width is at least 1.5 times the height.
		if (!specView)
		{
			GetWindowRect(&rt);
			sz = rt.Size();
			if (sz.cx<3*sz.cy/2)
			{
				rt.InflateRect(0, 0, 3*sz.cy/2, 0);
				MoveWindow(&rt, 0);
			}
			//Again, //Assuming that the first axis is the waveform viewer, the second one is for spectrum viewing
			lastPos = gcf->ax[0]->pos;
			gcf->ax[0]->setPos(.08, .1, .62, .8);
			axSpec = gcf->axes(.75, .3, .22, .4);
			axSpec->colorBack = RGB(230, 230, 190);
			OnMenu(IDM_SPECTRUM_INTERNAL);
		}
		else
		{
			deleteObj(axSpec);
			axSpec=NULL;
			gcf->ax[0]->setPos(lastPos);
		}
		specView = !specView;
		break;
	case IDM_SPECTRUM_INTERNAL:
		rfftw_plan plan;
		double *freq, *fft, *mag, *fft2, *mag2, fs, maxx, maxmag, ylim;
		multi = localax->nLines>1 ? true : false;
		if (gcf->nAxes==1) break;
		fs = (double)sig.GetFs();
		for (; gcf->ax[1]->nLines>0;)	
			deleteObj(gcf->ax[1]->m_ln[0]);
		GetIndicesInRange(localax, id1, id2);
		len = id2-id1+1;
		freq = new double[len];
		fft = new double[len];
		mag = new double[len/2];
		for (i=0; i<len; i++)
			freq[i]=(double)i/(double)len*fs;
		plan = rfftw_create_plan(len, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_OUT_OF_PLACE);
		rfftw_one(plan, &localax->m_ln[0]->ydata[id1], fft);
		if (multi) 
		{
			fft2 = new double[len];
			mag2 = new double[len/2];
			rfftw_one(plan, &localax->m_ln[1]->ydata[id1], fft2);
		}
		rfftw_destroy_plan(plan);
		for (i=0; i<len/2; i++)		mag[i] = 20.*log10(fabs(fft[len-i]));
		if (multi) for (i=0; i<len/2; i++)	mag2[i] = 20.*log10(fabs(fft2[len-i]));
		maxmag = getMax(len/2,mag);
		maxx = 5.*(maxmag/5.+1);
		for (int j=0; j<len/2; j++)	mag[j] -= maxx;
		if (multi) 
		{
			maxmag = getMax(len/2,mag2);
			maxx = 5.*(maxmag/5.+1);
			for (int j=0; j<len/2; j++)	mag2[j] -= maxx;
		}
		ylim = 10.*(maxmag/10.+1)-maxx;
		PlotDouble(gcf->ax[1], len/2, freq, mag);
		SetRange(gcf->ax[1], 'x', 0, fs/2);
		SetTick(gcf->ax[1], 'x', 0, 1000, 0, 0, "%2.0lfk", 0.001);
		SetRange(gcf->ax[1], 'y', getMean(len/2,mag)-40, ylim);
		SetTick(gcf->ax[1], 'y', 0, 10);
		gcf->ax[1]->m_ln[0]->color = gcf->ax[0]->m_ln[0]->color;
		if (multi) 
		{
			PlotDouble(gcf->ax[1], len/2, freq, mag2);
			gcf->ax[1]->m_ln[1]->color = gcf->ax[0]->m_ln[1]->color;
			delete[] fft2;
			delete[] mag2;
		}
		delete[] freq;
		delete[] fft;
		delete[] mag;
		break;
	case IDM_WAVWRITE:
		char fname[MAX_PATH];
		CFileDlg fileDlg;
		fileDlg.InitFileDlg(hDlg, hInst, "");
		errstr[0]=0;
		if(!GetSignalInRange(signal,1))
		{	MessageBox (errStr);	return;	}
		if (fileDlg.FileSaveDlg(fullfname, fname, "Wav file (*.WAV)\0*.wav\0", "wav"))
			if (!signal.Wavwrite(fullfname, errstr))	
			{MessageBox (errstr);}
		else
		{
			CStdString str;
			if (GetLastError()!=0) { GetLastErrorStr(str); MessageBox (str.c_str(), "Filesave error");}
		}
		return;
	}
	InvalidateRect(NULL);
}
Пример #19
0
void
IFGram::IFAnalysis(float* signal){

  double powerspec, da,db, a, b, ph,d; 
  int i2, i;

  for(i=0; i<m_fftsize; i++){
    m_diffsig[i] = signal[i]*m_diffwin[i];
    signal[i] = signal[i]*m_table->Lookup(i);
  }




  float tmp1, tmp2;
  for(i=0; i<m_halfsize; i++){
    tmp1 = m_diffsig[i+m_halfsize];
    tmp2 = m_diffsig[i];
    m_diffsig[i] = tmp1;
    m_diffsig[i+m_halfsize] = tmp2;

    tmp1 = signal[i+m_halfsize];
    tmp2 = signal[i];
    signal[i] = tmp1;
    signal[i+m_halfsize] = tmp2;

  }


  rfftw_one(m_plan, signal, m_ffttmp);
  rfftw_one(m_plan, m_diffsig, m_fftdiff);


  m_output[0] = m_ffttmp[0]/m_norm;
  m_output[1] = m_ffttmp[m_halfsize]/m_norm;

 
  for(i=2; i<m_fftsize; i+=2){

    i2 = i/2;
    a = m_ffttmp[i2]*2/m_norm;
    b = m_ffttmp[m_fftsize-(i2)]*2/m_norm;
    da = m_fftdiff[i2]*2/m_norm;
    db = m_fftdiff[m_fftsize-(i2)]*2/m_norm;
    powerspec = a*a+b*b;
	
    if((m_output[i] = (float)sqrt(powerspec)) != 0.f){
      m_output[i+1] = ((a*db - b*da)/powerspec)*m_factor + i2*m_fund;
      ph = (float) atan2(b, a);	
      d = ph - m_phases[i2];
      while(d > PI) d -= TWOPI;
      while(d < -PI) d += TWOPI;
      m_phases[i2] += d;
	
		 

    }
    else {
      m_output[i+1] = i2*m_fund;
      m_phases[i2] = 0.f ;
    }
  }

}
Пример #20
0
	void OneDataMultiplierMHT::apply(deque<double>& buff)
	{
		if(buff.size()<(size_t)(m_length+1))	return;

		ofstream file_in("test_mult_in.dat");

		for(int i=0; i<m_size; i++)					// input interpolation
		{
			double x = i*double(m_length)/m_size;
			double y1 = buff[int(x)];
			double y2 = buff[1+int(x)];

			double d = x-int(x);

			m_in[i] = (y1*(1.0-d) + y2*d)/2;
			//		m_in[i] *= win_sinc(double(i)/m_size,2);

			file_in << i << " " << m_in[i] << endl;
		}

		rfftw_one(m_fwd_plan, m_in, m_out);			// transformation

		//	m_out[0] = m_out[0];	// done modify it

		/*	int factor = FACTOR;								// dilatation
			for(int k=m_size/2-1; k>=1; k--)
			{
			if(k%factor==0)
			{
			int i = k/factor;
			m_out[k] = m_out[i];
			m_out[m_size-k] = m_out[m_size-i];
			}
			else
			{
			m_out[k] = 0.0;
			m_out[m_size-k] = 0.0;
			}
			}*/

		double factor = FACTOR;								// dilatation with interpolation
		int k = m_size/2-1;
		for(;k>=1; k--)
		{
			double drk = k/factor;
			if(int(drk)==0)
			{
				m_out[k] = 0.0;
				m_out[m_size-k] = 0.0;
			}
			else
			{
				double dr = drk-int(drk);
				m_out[k] = (m_out[int(drk)]*(1.0-dr) + m_out[int(drk)+1]*dr)/2;

				double dik = m_size - drk;
				double di = dik-int(dik);
				m_out[m_size-k] = (m_out[int(dik)]*(1.0-di) + m_out[int(dik)-1]*di)/2;
			}
		}

		/*	int decal = 31;								// decal
			int k = m_size/2-1;
			for(;k>=1+decal; k--)
			{
			m_out[k] = m_out[k-decal];
			m_out[m_size-k] = m_out[m_size-(k-decal)];
			}
			for(;k>0; k--)
			{
			m_out[k] = 0.0;
			m_out[m_size-k] = 0.0;
			}*/

		rfftw_one(m_bck_plan, m_out, m_in);			// inverse transformation

		deque<double> mult_buff(m_size);			// fill a biger buffer

		ofstream file_out("test_mult_out.dat");
		for(int i=0; i<m_size; i++)
		{
			mult_buff[i] = m_in[i]/m_size;
			//		mult_buff[i] = m_in[i];
			file_out << i << " " << mult_buff[i] << endl;
		}

		for(size_t h=0; h<m_convolutions.size(); h++)			// do the convolutions
		{
			m_convolutions[h]->apply(mult_buff);
			m_components[h] = m_convolutions[h]->m_trans;
			//		cout << sqrt(norm(m_components[h])) << ":";
		}
		//	cout << endl;
	}