From c03d395f6848fe9b2d1185173a9cf5ec8277394f Mon Sep 17 00:00:00 2001 From: gramanas Date: Tue, 21 Nov 2023 14:07:33 +0200 Subject: Crappy fft for spectrum analysis and initial gtk test --- src/synth_engine.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 11 deletions(-) (limited to 'src/synth_engine.c') diff --git a/src/synth_engine.c b/src/synth_engine.c index 517f9d8..b47d510 100644 --- a/src/synth_engine.c +++ b/src/synth_engine.c @@ -167,8 +167,9 @@ make_sample(void *synthData, unsigned int sample_rate, int frame) // if rms == 0 we can deduce there are no notes however notes_active handles // stopping any already playing notes and if we remove it we need to make - // sure that notes stop some other way (it laso happens every frame) - rms = sqrt(rms / n); + // sure that notes stop some other way (it also happens every frame) + rms = sqrt(rms / (float)n); + // printf("rms %f\n", rms); for (int i = 0; i < MIDI_NOTES; i++) { if (!synth->midi_note[i].active) @@ -195,7 +196,7 @@ make_sample(void *synthData, unsigned int sample_rate, int frame) synth->x, sample_rate); - sample += rms * adsr * synth_sample; + sample += synth->midi_note[i].velocity * adsr * synth_sample; } /* filter */ @@ -233,6 +234,16 @@ add_to_viz(synth_t *synth, float sample) } } +void +add_to_fftviz(synth_t *synth, float sample) +{ + synth->fftviz.wave[synth->fftviz.wi++] = sample; + + if (synth->fftviz.wi >= VIZ_BUF) { + synth->fftviz.wi = 0; + } +} + void add_to_delay(synth_t *synth, float sample) { @@ -304,7 +315,30 @@ get_frame(void *outputBuffer, synth_t *synth, int i) #include "fftw3.h" int -process(float * buffer) +get_spectrum(synth_t * synth, float * buffer) +{ + int fft_output_len = FRAMES_PER_BUFFER / 2 + 1; + float input[FRAMES_PER_BUFFER]; + + for( unsigned long i=0; i < FRAMES_PER_BUFFER * 2; i += 2 ) { + input[i / 2] = buffer[i]; + } + fftwf_complex* output = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fft_output_len); + + fftwf_plan forward_plan = fftwf_plan_dft_r2c_1d(fft_output_len, input, output, FFTW_ESTIMATE); + + fftwf_execute(forward_plan); + + for (int i=0; i < fft_output_len - 2*fft_output_len/3; i++ ) { + add_to_fftviz(synth, sqrt(output[i][0] * output[i][0] + output[i][1] * output[i][1])); + } + + fftwf_destroy_plan(forward_plan); + fftwf_free(output); +} + +int +process(synth_t * synth, float * buffer) { int len = FRAMES_PER_BUFFER; @@ -322,6 +356,8 @@ process(float * buffer) fftwf_execute(forward_plan); + // cont: + /* printf("ASDASD!!!\n"); */ /* for (int i=0; i < (len / 2 + 1); i++ ) { */ /* if (frequency_signal[i][0] > 1) { */ /* frequency_signal[i][0] = 0; */ @@ -329,15 +365,16 @@ process(float * buffer) /* if (frequency_signal[i][1] > 1) { */ /* frequency_signal[i][1] = 0; */ /* } */ - /* printf("%f %f | ", sqrt(frequency_signal[i][0] * frequency_signal[i][0] + frequency_signal[i][1] * frequency_signal[i][1]), atan2(frequency_signal[i][1], frequency_signal[i][0])); */ + /* printf("%f %f | \n", sqrt(frequency_signal[i][0] * frequency_signal[i][0] + frequency_signal[i][1] * frequency_signal[i][1]), atan2(frequency_signal[i][1], frequency_signal[i][0])); */ - /* float f = atan2(frequency_signal[i][1], frequency_signal[i][0]); */ - /* if (f > M_PI / 2 && f < 2 * M_PI / 3) { */ - /* frequency_signal[i][0] = 0.0; */ - /* frequency_signal[i][1] = 0.0; */ - /* } */ + /* /\* float f = atan2(frequency_signal[i][1], frequency_signal[i][0]); *\/ */ + /* /\* if (f > M_PI / 2 && f < 2 * M_PI / 3) { *\/ */ + /* /\* frequency_signal[i][0] = 0.0; *\/ */ + /* /\* frequency_signal[i][1] = 0.0; *\/ */ + /* /\* } *\/ */ /* } */ + /* printf("ASDASD!!!\n"); */ fftwf_execute(backward_plan); for (unsigned long i=0; i < len * 2; i += 2) { @@ -401,7 +438,8 @@ sound_gen(const void *inputBuffer, void *outputBuffer, get_frame(buffer, synth, i); } // process buffer - //if (synth->multi) process(buffer); + // process(synth, buffer); + get_spectrum(synth, buffer); // output buffer for( unsigned long i=0; iviz.sample_rate_divider = 1; synth->viz.wi = 0; + synth->fftviz.sample_rate_divider = 1; + synth->fftviz.wi = 0; lpf_init(); synth->fff = create_bw_low_pass_filter(2, SAMPLE_RATE, 400); -- cgit v1.2.3