/* * 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; }
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 }
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; }
/** * 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. **/ }
/* * 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; };
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); }
/* * 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 };
/** * 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. **/ }
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; }
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; }
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; }
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; }
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; }
void F77_FUNC_(rfftw_f77_one,RFFTW_F77_ONE) (fftw_plan *p, fftw_real *in, fftw_real *out) { rfftw_one(*p,in,out); }
/* * 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; }
/* * 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); }
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); }
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 ; } } }
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; }