From 7a224dfa15fe5fced0886afd8f88f5076cc8fc7d Mon Sep 17 00:00:00 2001 From: karlstav Date: Wed, 20 Nov 2019 22:31:39 +0100 Subject: [PATCH] Devided bass, midtones and treble in to separate fftw operations this commit involves some major and perhaps braking changes audio sorting is now done by a common function in fifo.c all other input plugins send a s16le interleaved audio buffer here, reformating might be done here in the future. Audio is put in to three buffers of different lenght, shorter buffers for higher frequencies. FFT is aplied separetly and the ouput is combined toghether in the separate_freq_bans function. This creates better responsivnes for higher frequencies while still beeing able to pick up the lower ones. --- cava.c | 295 ++++++++++++++++++++++++++++++++++++---------- input/alsa.c | 112 +++++++----------- input/fifo.c | 133 ++++++++++----------- input/fifo.h | 1 + input/portaudio.c | 14 ++- input/pulse.c | 24 ++-- input/shmem.c | 3 + input/sndio.c | 9 +- 8 files changed, 367 insertions(+), 224 deletions(-) diff --git a/cava.c b/cava.c index 73b79e3..4b53586 100644 --- a/cava.c +++ b/cava.c @@ -153,24 +153,35 @@ static bool directory_exists(const char * path) { #endif -int * separate_freq_bands(int FFTbufferSize, fftw_complex out[FFTbufferSize / 2 + 1], +int * separate_freq_bands(int FFTbassbufferSize, fftw_complex out_bass[FFTbassbufferSize / 2 + 1], + int FFTmidbufferSize, fftw_complex out_mid[FFTmidbufferSize / 2 + 1], + int FFTtreblebufferSize, fftw_complex out_treble[FFTtreblebufferSize / 2 + 1], + int bass_cut_off_bar, int treble_cut_off_bar, int bars, int lcf[200], int hcf[200], double k[200], int channel, double sens, double ignore) { - int o,i; + int o, i; double peak[201]; static int fl[200]; static int fr[200]; - double y[FFTbufferSize / 2 + 1]; + double y[FFTbassbufferSize / 2 + 1]; double temp; // process: separate frequency bands for (o = 0; o < bars; o++) { peak[o] = 0; + i = 0; // process: get peaks for (i = lcf[o]; i <= hcf[o]; i++) { - y[i] = hypot(out[i][0], out[i][1]); + if (o <= bass_cut_off_bar) { + y[i] = hypot(out_bass[i][0], out_bass[i][1]); + } else if (o > bass_cut_off_bar && o <= treble_cut_off_bar) { + y[i] = hypot(out_mid[i][0], out_mid[i][1]); + } else if (o > treble_cut_off_bar) { + y[i] = hypot(out_treble[i][0], out_treble[i][1]); + } + peak[o] += y[i]; //adding upp band } @@ -281,8 +292,12 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co int sourceIsAuto = 1; double smh; - double *inr, *inl; - fftw_complex *outl, *outr; + double *in_bass_r, *in_bass_l; + fftw_complex *out_bass_l, *out_bass_r; + double *in_mid_r, *in_mid_l; + fftw_complex *out_mid_l, *out_mid_r; + double *in_treble_r, *in_treble_l; + fftw_complex *out_treble_l, *out_treble_r; struct audio_data audio; struct config_params p; @@ -346,6 +361,9 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co // general: main loop while (1) { + #ifdef DEBUG + printf("loading config\n"); + #endif //config: load struct error_s error; error.length = 0; @@ -354,17 +372,6 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co exit(EXIT_FAILURE); } - audio.FFTbufferSize = p.FFTbufferSize; - - - inr = malloc(2 * (p.FFTbufferSize / 2 + 1) * sizeof(double)); - inl = malloc(2 * (p.FFTbufferSize / 2 + 1) * sizeof(double)); - - outl = malloc(2 * (p.FFTbufferSize / 2 + 1) * sizeof(fftw_complex)); - outr = malloc(2 * (p.FFTbufferSize / 2 + 1) * sizeof(fftw_complex)); - - fftw_plan pl = fftw_plan_dft_r2c_1d(p.FFTbufferSize, inl, outl, FFTW_MEASURE); - fftw_plan pr = fftw_plan_dft_r2c_1d(p.FFTbufferSize, inr, outr, FFTW_MEASURE); output_mode = p.om; @@ -382,11 +389,17 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co //input: init + int bass_cut_off = 150; + int treble_cut_off = 1500; + audio.source = malloc(1 + strlen(p.audio_source)); strcpy(audio.source, p.audio_source); audio.format = -1; audio.rate = 0; + audio.FFTbassbufferSize = 4096; + audio.FFTmidbufferSize = 1024; + audio.FFTtreblebufferSize = 512; audio.terminate = 0; if (p.stereo) audio.channels = 2; if (!p.stereo) audio.channels = 1; @@ -396,20 +409,14 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co if (strcmp(p.mono_option, "average") == 0) audio.average = true; if (strcmp(p.mono_option, "left") == 0) audio.left = true; if (strcmp(p.mono_option, "right") == 0) audio.right = true; + audio.bass_index = 0; + audio.mid_index = 0; + audio.treble_index = 0; - for (i = 0; i < (p.FFTbufferSize / 2 + 1); i++) { - if (i < p.FFTbufferSize) { - audio.audio_out_l[i] = 0; - audio.audio_out_r[i] = 0; - } - inl[i] = 0; - inr[i] = 0; - for (n = 0; n < 2; n++) { - outl[i][n] = 0; - outr[i][n] = 0; - } - } + #ifdef DEBUG + printf("starting audio thread\n"); + #endif #ifdef ALSA // input_alsa: wait for the input to be ready if (p.im == 1) { @@ -497,6 +504,83 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co exit(EXIT_FAILURE); } + //BASS + //audio.FFTbassbufferSize = audio.rate / 20; // audio.FFTbassbufferSize; + + in_bass_r = malloc(2 * (audio.FFTbassbufferSize / 2 + 1) * sizeof(double)); + in_bass_l = malloc(2 * (audio.FFTbassbufferSize / 2 + 1) * sizeof(double)); + + out_bass_l = malloc(2 * (audio.FFTbassbufferSize / 2 + 1) * sizeof(fftw_complex)); + out_bass_r = malloc(2 * (audio.FFTbassbufferSize / 2 + 1) * sizeof(fftw_complex)); + + fftw_plan p_bass_l = fftw_plan_dft_r2c_1d(audio.FFTbassbufferSize, in_bass_l, out_bass_l, FFTW_MEASURE); + fftw_plan p_bass_r = fftw_plan_dft_r2c_1d(audio.FFTbassbufferSize, in_bass_r, out_bass_r, FFTW_MEASURE); + + //MID + //audio.FFTmidbufferSize = audio.rate / bass_cut_off; // audio.FFTbassbufferSize; + in_mid_r = malloc(2 * (audio.FFTmidbufferSize / 2 + 1) * sizeof(double)); + in_mid_l = malloc(2 * (audio.FFTmidbufferSize / 2 + 1) * sizeof(double)); + + out_mid_l = malloc(2 * (audio.FFTmidbufferSize / 2 + 1) * sizeof(fftw_complex)); + out_mid_r = malloc(2 * (audio.FFTmidbufferSize / 2 + 1) * sizeof(fftw_complex)); + + fftw_plan p_mid_l = fftw_plan_dft_r2c_1d(audio.FFTmidbufferSize, in_mid_l, out_mid_l, FFTW_MEASURE); + fftw_plan p_mid_r = fftw_plan_dft_r2c_1d(audio.FFTmidbufferSize, in_mid_r, out_mid_r, FFTW_MEASURE); + + //TRIEBLE + //audio.FFTtreblebufferSize = audio.rate / treble_cut_off; // audio.FFTbassbufferSize; + in_treble_r = malloc(2 * (audio.FFTtreblebufferSize / 2 + 1) * sizeof(double)); + in_treble_l = malloc(2 * (audio.FFTtreblebufferSize / 2 + 1) * sizeof(double)); + + out_treble_l = malloc(2 * (audio.FFTtreblebufferSize / 2 + 1) * sizeof(fftw_complex)); + out_treble_r = malloc(2 * (audio.FFTtreblebufferSize / 2 + 1) * sizeof(fftw_complex)); + + fftw_plan p_treble_l = fftw_plan_dft_r2c_1d(audio.FFTtreblebufferSize, in_treble_l, out_treble_l, FFTW_MEASURE); + fftw_plan p_treble_r = fftw_plan_dft_r2c_1d(audio.FFTtreblebufferSize, in_treble_r, out_treble_r, FFTW_MEASURE); + + #ifdef DEBUG + printf("got buffer size: %d, %d, %d", audio.FFTbassbufferSize, audio.FFTmidbufferSize, audio.FFTtreblebufferSize); + printf("zeroing buffers\n"); + #endif + for (i = 0; i < (audio.FFTbassbufferSize / 2 + 1); i++) { + if (i < audio.FFTbassbufferSize) { + audio.audio_out_bass_l[i] = 0; + audio.audio_out_bass_r[i] = 0; + } + in_bass_l[i] = 0; + in_bass_r[i] = 0; + for (n = 0; n < 2; n++) { + out_bass_l[i][n] = 0; + out_bass_r[i][n] = 0; + } + } + + for (i = 0; i < (audio.FFTmidbufferSize / 2 + 1); i++) { + if (i < audio.FFTmidbufferSize) { + audio.audio_out_mid_l[i] = 0; + audio.audio_out_mid_r[i] = 0; + } + in_mid_l[i] = 0; + in_mid_r[i] = 0; + for (n = 0; n < 2; n++) { + out_mid_l[i][n] = 0; + out_mid_r[i][n] = 0; + } + } + + for (i = 0; i < (audio.FFTtreblebufferSize / 2 + 1); i++) { + if (i < audio.FFTtreblebufferSize) { + audio.audio_out_treble_l[i] = 0; + audio.audio_out_treble_r[i] = 0; + } + in_treble_l[i] = 0; + in_treble_r[i] = 0; + for (n = 0; n < 2; n++) { + out_treble_l[i][n] = 0; + out_treble_r[i][n] = 0; + } + } + bool reloadConf = false; @@ -625,6 +709,10 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co //freqconst = -2; // process: calculate cutoff frequencies + int bass_cut_off_bar = -1; + int treble_cut_off_bar = -1; + bool first_bar = false; + int first_treble_bar = 0; for (n = 0; n < bars + 1; n++) { double pot = freqconst * (-1); pot += ((float)n + 1) / ((float)bars + 1) * freqconst; @@ -634,30 +722,61 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co //and nyquist freq in M/2 but testing shows it is not... //or maybe the nq freq is in M/4 + k[n] = pow(fc[n],1); + k[n] *= (float)height / pow(2,28); + k[n] *= p.smooth[(int)floor(((double)n) * smh)]; + k[n] /= log2(audio.FFTbassbufferSize); //lfc stores the lower cut frequency foo each bar in the fft out buffer - lcf[n] = fre[n] * (p.FFTbufferSize /2) + 1; - if (n != 0) { + if (fc[n] < bass_cut_off ) { + lcf[n] = fre[n] * (audio.FFTbassbufferSize /2) + 1; + bass_cut_off_bar++; + treble_cut_off_bar++; + k[n] *= log2(audio.FFTbassbufferSize); + } else if (fc[n] > bass_cut_off && fc[n] < treble_cut_off) { + lcf[n] = fre[n] * (audio.FFTmidbufferSize /2) + 1; + treble_cut_off_bar++; + if ((treble_cut_off_bar - bass_cut_off_bar) == 1) { + first_bar = true; + hcf[n - 1] = fre[n] * (audio.FFTbassbufferSize /2); + if (hcf[n - 1] < lcf[n - 1]) hcf[n - 1] = lcf[n - 1]; + } else { + first_bar = false; + } + + k[n] *= log2(audio.FFTmidbufferSize); + } else { + lcf[n] = fre[n] * (audio.FFTtreblebufferSize /2) + 1; + first_treble_bar++; + if (first_treble_bar == 1) { + first_bar = true; + hcf[n - 1] = fre[n] * (audio.FFTmidbufferSize /2); + if (hcf[n - 1] < lcf[n - 1]) hcf[n - 1] = lcf[n - 1]; + } else { + first_bar = false; + } + + k[n] *= log2(audio.FFTtreblebufferSize); + } + + if (n != 0 && !first_bar) { hcf[n - 1] = lcf[n] - 1; - + //pushing the spectrum up if the expe function gets "clumped" if (lcf[n] <= lcf[n - 1])lcf[n] = lcf[n - 1] + 1; hcf[n - 1] = lcf[n] - 1; } - #ifdef DEBUG - if (n != 0) { - mvprintw(n,0,"%d: %f -> %f (%d -> %d) \n", n, +#ifdef DEBUG + if (n != 0) { + mvprintw(n,0,"%d: %f -> %f (%d -> %d) bass: %d, treble:%d \n", n, fc[n - 1], fc[n], lcf[n - 1], - hcf[n - 1]); - } - #endif + hcf[n - 1], bass_cut_off_bar, treble_cut_off_bar); + } +#endif } // process: weigh signal to frequencies height and EQ for (n = 0; n < bars; n++) { - k[n] = pow(fc[n],0.85); - k[n] *= (float)height / pow(2,28); - k[n] *= p.smooth[(int)floor(((double)n) * smh)]; } if (p.stereo) bars = bars * 2; @@ -737,17 +856,36 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co // process: populate input buffer and check if input is present silence = true; - for (i = 0; i < (2 * (p.FFTbufferSize / 2 + 1)); i++) { - if (i < p.FFTbufferSize) { - inl[i] = audio.audio_out_l[i]; - if (p.stereo) inr[i] = audio.audio_out_r[i]; - if (inl[i] || inr[i]) silence = false; + for (i = 0; i < (2 * (audio.FFTbassbufferSize / 2 + 1)); i++) { + if (i < audio.FFTbassbufferSize) { + in_bass_l[i] = audio.audio_out_bass_l[i]; + if (p.stereo) in_bass_r[i] = audio.audio_out_bass_r[i]; + if (in_bass_l[i] || in_bass_r[i]) silence = false; + } else { + in_bass_l[i] = 0; + if (p.stereo) in_bass_r[i] = 0; + } + } + + for (i = 0; i < (2 * (audio.FFTmidbufferSize / 2 + 1)); i++) { + if (i < audio.FFTmidbufferSize) { + in_mid_l[i] = audio.audio_out_mid_l[i]; + if (p.stereo) in_mid_r[i] = audio.audio_out_mid_r[i]; } else { - inl[i] = 0; - if (p.stereo) inr[i] = 0; + in_mid_l[i] = 0; + if (p.stereo) in_mid_r[i] = 0; } } + for (i = 0; i < (2 * (audio.FFTtreblebufferSize / 2 + 1)); i++) { + if (i < audio.FFTtreblebufferSize) { + in_treble_l[i] = audio.audio_out_treble_l[i]; + if (p.stereo) in_treble_r[i] = audio.audio_out_treble_r[i]; + } else { + in_treble_l[i] = 0; + if (p.stereo) in_treble_r[i] = 0; + } + } if (silence) sleep++; else sleep = 0; @@ -756,17 +894,34 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co // process: execute FFT and sort frequency bands if (p.stereo) { - fftw_execute(pl); - fftw_execute(pr); + fftw_execute(p_bass_l); + fftw_execute(p_bass_r); + fftw_execute(p_mid_l); + fftw_execute(p_mid_r); + fftw_execute(p_treble_l); + fftw_execute(p_treble_r); + + fl = separate_freq_bands(audio.FFTbassbufferSize, out_bass_l, + audio.FFTmidbufferSize, out_mid_l, + audio.FFTtreblebufferSize, out_treble_l, + bass_cut_off_bar, treble_cut_off_bar, + bars/2, lcf, hcf, k, 1, p.sens, p.ignore); + + fr = separate_freq_bands(audio.FFTbassbufferSize, out_bass_r, + audio.FFTmidbufferSize, out_mid_r, + audio.FFTtreblebufferSize, out_treble_r, + bass_cut_off_bar, treble_cut_off_bar, + bars/2, lcf, hcf, k, 1, p.sens, p.ignore); - fl = separate_freq_bands(p.FFTbufferSize, outl,bars/2, - lcf,hcf, k, 1, p.sens, p.ignore); - fr = separate_freq_bands(p.FFTbufferSize, outr,bars/2, - lcf,hcf, k, 2, p.sens, p.ignore); } else { - fftw_execute(pl); - fl = separate_freq_bands(p.FFTbufferSize, outl,bars, - lcf,hcf, k, 1, p.sens, p.ignore); + fftw_execute(p_bass_l); + fftw_execute(p_mid_l); + fftw_execute(p_treble_l); + fl = separate_freq_bands(audio.FFTbassbufferSize, out_bass_l, + audio.FFTmidbufferSize, out_mid_l, + audio.FFTtreblebufferSize, out_treble_l, + bass_cut_off_bar, treble_cut_off_bar, + bars, lcf, hcf, k, 1, p.sens, p.ignore); } @@ -932,12 +1087,26 @@ as of 0.4.0 all options are specified in config file, see in '/home/username/.co if (p.customEQ) free(p.smooth); if (sourceIsAuto) free(audio.source); - free(inr); - free(inl); - fftw_free(outr); - fftw_free(outl); - fftw_destroy_plan(pl); - fftw_destroy_plan(pr); + free(in_bass_r); + free(in_bass_l); + fftw_free(out_bass_r); + fftw_free(out_bass_l); + fftw_destroy_plan(p_bass_l); + fftw_destroy_plan(p_bass_r); + + free(in_mid_r); + free(in_mid_l); + fftw_free(out_mid_r); + fftw_free(out_mid_l); + fftw_destroy_plan(p_mid_l); + fftw_destroy_plan(p_mid_r); + + free(in_treble_r); + free(in_treble_l); + fftw_free(out_treble_r); + fftw_free(out_treble_l); + fftw_destroy_plan(p_treble_l); + fftw_destroy_plan(p_treble_r); cleanup(); diff --git a/input/alsa.c b/input/alsa.c index 39d972a..15b625b 100644 --- a/input/alsa.c +++ b/input/alsa.c @@ -67,7 +67,7 @@ static int get_certain_frame(signed char* buffer, int buffer_index, int adjustme temp -= lo; return temp; } - +/* static void fill_audio_outs(struct audio_data* audio, signed char* buffer, const int size) { int radj = audio->format / 4; // adjustments for interleaved @@ -92,7 +92,7 @@ const int size) { audio_out_buffer_index %= audio->FFTbufferSize; } } - +*/ #define FRAMES_NUMBER 256 void* input_alsa(void* data) { @@ -105,7 +105,9 @@ void* input_alsa(void* data) { initialize_audio_parameters(&handle, audio, &frames); snd_pcm_get_params(handle, &buffer_size, &period_size); - + + int radj = audio->format / 4; // adjustments for interleaved + int ladj = audio->format / 8; int16_t buf[period_size]; int32_t buffer32[period_size]; frames = period_size / ((audio->format / 8) * CHANNELS_COUNT); @@ -115,80 +117,50 @@ void* input_alsa(void* data) { // frames * bits/8 * channels //const int size = frames * (audio->format / 8) * CHANNELS_COUNT; signed char* buffer = malloc(period_size); - int n = 0; while (1) { - switch (audio->format) { - case 16: - err = snd_pcm_readi(handle, buf, frames); - for (uint16_t i = 0; i < frames * 2; i += 2) { - if (audio->channels == 1){ - if (audio->average) { - audio->audio_out_l[n] = (buf[i] + buf[i + 1]) / 2; - } - if (audio->left) { - audio->audio_out_l[n] = buf[i]; - } - if (audio->right) { - audio->audio_out_l[n] = buf[i + 1]; - } - } - //stereo storing channels in buffer - if (audio->channels == 2) { - audio->audio_out_l[n] = buf[i]; - audio->audio_out_r[n] = buf[i + 1]; - } - n++; - if (n == audio->FFTbufferSize - 1) n = 0; - } - break; - case 32: - err = snd_pcm_readi(handle, buffer32, frames); - for (uint16_t i = 0; i < frames * 2; i += 2) { - if (audio->channels == 1) { - if (audio->average) { - audio->audio_out_l[n] = (buffer32[i] / pow(2,16)) / 2; - audio->audio_out_l[n] += (buffer32[i + 1] / pow(2,16)) / 2; + switch (audio->format) { + case 16: + err = snd_pcm_readi(handle, buf, frames); + break; + case 32: + err = snd_pcm_readi(handle, buffer32, frames); + for (uint16_t i = 0; i < frames * 2; i++) { + buf[i] = buffer32[i] / pow(2,16); } - if (audio->left) { - audio->audio_out_l[n] = (buffer32[i] / pow(2,16)); - } - if (audio->right) { - audio->audio_out_l[n] = (buffer32[i + 1] / pow(2,16)); + break; + default: + err = snd_pcm_readi(handle, buffer, frames); + // sorting out one channel and only biggest octet + for (uint16_t i = 0; i < period_size * 2; i += ladj * 2) { + // first channel + buf[i] = get_certain_frame(buffer, i, ladj); + // second channel + buf[i + 1] = get_certain_frame(buffer, i, radj); + } - } - //stereo storing channels in buffer - if (audio->channels == 2) { - audio->audio_out_l[n] = buffer32[i] / pow(2,16); - audio->audio_out_r[n] = buffer32[i + 1] / pow(2,16); - } - n++; - if (n == audio->FFTbufferSize - 1) n = 0; + //fill_audio_outs(audio, buffer, period_size); + break; + } + + if (err == -EPIPE) { + /* EPIPE means overrun */ +#ifdef DEBUG + fprintf(stderr, "overrun occurred\n"); +#endif + snd_pcm_prepare(handle); + } else if (err < 0) { +#ifdef DEBUG + fprintf(stderr, "error from read: %s\n", snd_strerror(err)); +#endif + } else if (err != (int)frames) { +#ifdef DEBUG + fprintf(stderr, "short read, read %d %d frames\n", err, (int)frames); +#endif } - break; - default: - err = snd_pcm_readi(handle, buffer, frames); - fill_audio_outs(audio, buffer, period_size); - break; - } - - if (err == -EPIPE) { - /* EPIPE means overrun */ - #ifdef DEBUG - fprintf(stderr, "overrun occurred\n"); - #endif - snd_pcm_prepare(handle); - } else if (err < 0) { - #ifdef DEBUG - fprintf(stderr, "error from read: %s\n", snd_strerror(err)); - #endif - } else if (err != (int)frames) { - #ifdef DEBUG - fprintf(stderr, "short read, read %d %d frames\n", err, (int)frames); - #endif - } + write_to_fftw_input_buffers(buf, frames, data); if (audio->terminate == 1) { diff --git a/input/fifo.c b/input/fifo.c index 0a1cbb1..ee2ebde 100644 --- a/input/fifo.c +++ b/input/fifo.c @@ -5,19 +5,69 @@ int rc; struct audio_data { - int FFTbufferSize; - int16_t audio_out_r[65536]; - int16_t audio_out_l[65536]; - int format; - unsigned int rate ; - char *source; //alsa device, fifo path or pulse source - int im; //input mode alsa, fifo or pulse - int channels; + int FFTbassbufferSize; + int FFTmidbufferSize; + int FFTtreblebufferSize; + int bass_index; + int mid_index; + int treble_index; + int16_t audio_out_bass_r[65536]; + int16_t audio_out_bass_l[65536]; + int16_t audio_out_mid_r[65536]; + int16_t audio_out_mid_l[65536]; + int16_t audio_out_treble_r[65536]; + int16_t audio_out_treble_l[65536]; + int format; + unsigned int rate ; + char *source; //alsa device, fifo path or pulse source + int im; //input mode alsa, fifo or pulse + int channels; bool left, right, average; int terminate; // shared variable used to terminate audio thread - char error_message[1024]; + char error_message[1024]; }; +int write_to_fftw_input_buffers(int16_t buf[], int16_t frames, void* data) { + + struct audio_data* audio = (struct audio_data*)data; + + for (uint16_t i = 0; i < frames * 2; i += 2) { + if (audio->channels == 1){ + if (audio->average) { + audio->audio_out_bass_l[audio->bass_index] = (buf[i] + buf[i + 1]) / 2; + } + if (audio->left) { + audio->audio_out_bass_l[audio->bass_index] = buf[i]; + } + if (audio->right) { + audio->audio_out_bass_l[audio->bass_index] = buf[i + 1]; + } + } + //stereo storing channels in buffer + if (audio->channels == 2) { + audio->audio_out_bass_l[audio->bass_index] = buf[i]; + audio->audio_out_bass_r[audio->bass_index] = buf[i + 1]; + + audio->audio_out_mid_r[audio->mid_index] = audio->audio_out_bass_r[audio->bass_index]; + audio->audio_out_treble_r[audio->treble_index] = audio->audio_out_bass_r[audio->bass_index]; + } + + audio->audio_out_mid_l[audio->mid_index] = audio->audio_out_bass_l[audio->bass_index]; + audio->audio_out_treble_l[audio->treble_index] = audio->audio_out_bass_l[audio->bass_index]; + + audio->bass_index++; + audio->mid_index++; + audio->treble_index++; + if (audio->bass_index == audio->FFTbassbufferSize - 1) audio->bass_index = 0; + if (audio->mid_index == audio->FFTmidbufferSize - 1) audio->mid_index = 0; + if (audio->treble_index == audio->FFTtreblebufferSize - 1) audio->treble_index = 0; + } + + return 0; + + +} + int open_fifo(const char *path) { int fd = open(path, O_RDONLY); @@ -32,18 +82,12 @@ void* input_fifo(void* data) { struct audio_data *audio = (struct audio_data *)data; int fd; - int n = 0; - //signed char buf[1024]; - //int tempr, templ, lo, q; int i; int t = 0; - //int size = 1024; int bytes = 0; int16_t buf[BUFSIZE / 2]; struct timespec req = { .tv_sec = 0, .tv_nsec = 10000000 }; - - - + uint16_t frames = BUFSIZE / 4; fd = open_fifo(audio->source); @@ -55,8 +99,12 @@ void* input_fifo(void* data) nanosleep (&req, NULL); t++; if (t > 10) { - for (i = 0; i < audio->FFTbufferSize; i++)audio->audio_out_l[i] = 0; - for (i = 0; i < audio->FFTbufferSize; i++)audio->audio_out_r[i] = 0; + for (i = 0; i < audio->FFTbassbufferSize; i++)audio->audio_out_bass_l[i] = 0; + for (i = 0; i < audio->FFTbassbufferSize; i++)audio->audio_out_bass_r[i] = 0; + for (i = 0; i < audio->FFTmidbufferSize; i++)audio->audio_out_mid_l[i] = 0; + for (i = 0; i < audio->FFTmidbufferSize; i++)audio->audio_out_mid_l[i] = 0; + for (i = 0; i < audio->FFTtreblebufferSize; i++)audio->audio_out_treble_r[i] = 0; + for (i = 0; i < audio->FFTtreblebufferSize; i++)audio->audio_out_treble_r[i] = 0; close(fd); fd = open_fifo(audio->source); t = 0; @@ -64,54 +112,7 @@ void* input_fifo(void* data) } else { //if bytes read go ahead t = 0; - for (i = 0; i < BUFSIZE / 2; i += 2) { - - if (audio->channels == 1) audio->audio_out_l[n] = (buf[i] + buf[i + 1]) / 2; - - //stereo storing channels in buffer - if (audio->channels == 2) { - audio->audio_out_l[n] = buf[i]; - audio->audio_out_r[n] = buf[i + 1]; - } - - n++; - if (n == audio->FFTbufferSize - 1) n = 0; - } - -/* - for (q = 0; q < (size / 4); q++) { - - tempr = ( buf[ 4 * q + 3] << 2); - - lo = ( buf[4 * q + 2] >> 6); - if (lo < 0)lo = abs(lo) + 1; - if (tempr >= 0)tempr = tempr + lo; - else tempr = tempr - lo; - - templ = ( buf[ 4 * q + 1] << 2); - - lo = ( buf[ 4 * q] >> 6); - if (lo < 0)lo = abs(lo) + 1; - if (templ >= 0)templ = templ + lo; - else templ = templ - lo; - - if (audio->channels == 1) audio->audio_out_l[n] = (tempr + -templ) / -2; - - - //stereo storing channels in buffer - if (audio->channels == 2) { - audio->audio_out_l[n] = templ; - audio->audio_out_r[n] = tempr; - } - - - - n++; - if (n == 2048 - 1)n = 0; - } -*/ + write_to_fftw_input_buffers(buf, frames, audio); } if (audio->terminate == 1) { diff --git a/input/fifo.h b/input/fifo.h index 5e23fb3..e43826b 100644 --- a/input/fifo.h +++ b/input/fifo.h @@ -1,2 +1,3 @@ //header files for fifo, part of cava void* input_fifo(void* data); +int write_to_fftw_input_buffers(int16_t buf[], int16_t frames, void* data); diff --git a/input/portaudio.c b/input/portaudio.c index 3289f8e..328e89c 100644 --- a/input/portaudio.c +++ b/input/portaudio.c @@ -17,18 +17,18 @@ typedef struct { } paTestData; static struct audio_data *audio; -static int n = 0; +//static int n = 0; static int recordCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { paTestData *data = (paTestData*)userData; - const SAMPLE *rptr = (const SAMPLE*)inputBuffer; + SAMPLE *rptr = (SAMPLE*)inputBuffer; long framesToCalc; - long i; + //long i; int finished; unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; - + int16_t silence_buffer[BUFSIZE] = { SAMPLE_SILENCE }; (void) outputBuffer; // Prevent unused variable warnings. (void) timeInfo; (void) statusFlags; @@ -43,6 +43,8 @@ static int recordCallback(const void *inputBuffer, void *outputBuffer, } if(inputBuffer == NULL) { + write_to_fftw_input_buffers(silence_buffer, framesToCalc, audio); +/* for(i=0; ichannels == 1) audio->audio_out_l[n] = SAMPLE_SILENCE; if(audio->channels == 2) { @@ -51,7 +53,10 @@ static int recordCallback(const void *inputBuffer, void *outputBuffer, } if(n == BUFSIZE-1) n = 0; } +*/ } else { + write_to_fftw_input_buffers(rptr, framesToCalc, audio); +/* for(i=0; ichannels == 1) { audio->audio_out_l[n] = (rptr[0] + rptr[1]) / 2; @@ -64,6 +69,7 @@ static int recordCallback(const void *inputBuffer, void *outputBuffer, n++; if(n == BUFSIZE-1) n = 0; } +*/ } data->frameIndex += framesToCalc; diff --git a/input/pulse.c b/input/pulse.c index b57efab..f5874de 100644 --- a/input/pulse.c +++ b/input/pulse.c @@ -112,7 +112,6 @@ void getPulseDefaultSink(void* data) { void* input_pulse(void* data) { struct audio_data *audio = (struct audio_data *)data; - int i, n; int16_t buf[BUFFERSIZE / 2]; /* The sample type to use */ @@ -121,11 +120,17 @@ void* input_pulse(void* data) { .rate = 44100, .channels = 2 }; + + audio->format = 16; + static const pa_buffer_attr pb = { .maxlength = (uint32_t) -1, //BUFSIZE * 2, .fragsize = BUFFERSIZE }; + + uint16_t frames = BUFFERSIZE / 4; + pa_simple *s = NULL; int error; @@ -140,7 +145,6 @@ void* input_pulse(void* data) { pthread_exit(NULL); } - n = 0; while (1) { if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) { @@ -152,21 +156,7 @@ void* input_pulse(void* data) { //sorting out channels - for (i = 0; i < BUFFERSIZE / 2; i += 2) { - - if (audio->channels == 1) { - audio->audio_out_l[n] = (buf[i] + buf[i + 1]) / 2; - } - - //stereo storing channels in buffer - if (audio->channels == 2) { - audio->audio_out_l[n] = buf[i]; - audio->audio_out_r[n] = buf[i + 1]; - } - - n++; - if (n == audio->FFTbufferSize - 1) n = 0; - } + write_to_fftw_input_buffers(buf, frames, data); if (audio->terminate == 1) { pa_simple_free(s); diff --git a/input/shmem.c b/input/shmem.c index 64d20ae..48ea90c 100644 --- a/input/shmem.c +++ b/input/shmem.c @@ -60,6 +60,8 @@ void* input_shmem(void* data) audio->rate = mmap_area->rate; while (1) { + write_to_fftw_input_buffers(mmap_area->buffer, BUFSIZE, audio); +/* for (i = VB_OFFSET; i < BUFSIZE+VB_OFFSET; i += 2) { if (audio->channels == 1) { audio->audio_out_l[n] = (mmap_area->buffer[i] + mmap_area->buffer[i + 1]) / 2; @@ -70,6 +72,7 @@ void* input_shmem(void* data) n++; if (n == audio->FFTbufferSize - 1) n = 0; } +*/| if (audio->terminate == 1) { break; } diff --git a/input/sndio.c b/input/sndio.c index f6dbe5d..d4d5d2f 100644 --- a/input/sndio.c +++ b/input/sndio.c @@ -11,15 +11,12 @@ void* input_sndio(void* data) int16_t buf[256]; unsigned int i, n, channels; - assert(audio->channels > 0); - channels = audio->channels; - sio_initpar(&par); par.sig = 1; par.bits = 16; par.le = 1; par.rate = 44100; - par.rchan = channels; + par.rchan = 2; par.appbufsz = sizeof(buf) / channels; if ((hdl = sio_open(audio->source, SIO_REC, 0)) == NULL) { @@ -38,12 +35,15 @@ void* input_sndio(void* data) } n = 0; + uint16_t frames = (sizeof(buf)/sizeof(buf[0]))/channels; while (audio->terminate != 1) { if (sio_read(hdl, buf, sizeof(buf)) == 0) { fprintf(stderr, __FILE__": sio_read() failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } + write_to_fftw_input_buffers(buf, frames, audio); +/* for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i += 2) { if (par.rchan == 1) { // sndiod has already taken care of averaging the samples @@ -54,6 +54,7 @@ void* input_sndio(void* data) } n = (n + 1) % audio->FFTbufferSize; } +*/ } sio_stop(hdl);