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);