Beispiel #1
0
static void eq_deinstantiate(struct dsp_module *module)
{
	struct eq_data *data = (struct eq_data *) module->data;
	if (data->eq)
		eq_free(data->eq);
	free(data);
}
/* Generates impulse response */
static void test_ir()
{
    int N = 32768;
    float *data;
    struct eq *eq;
    double NQ = 44100 / 2; /* nyquist frequency */
    struct timespec tp1, tp2;
    int i;
    FILE *ir;

    data = calloc(1, sizeof(float) * N);
    data[0] = 1;

    eq = eq_new();
    eq_append_biquad(eq, BQ_PEAKING, 380/NQ, 3, -10);
    eq_append_biquad(eq, BQ_PEAKING, 720/NQ, 3, -12);
    eq_append_biquad(eq, BQ_PEAKING, 1705/NQ, 3, -8);
    eq_append_biquad(eq, BQ_HIGHPASS, 218/NQ, 0.7, -10.2);
    eq_append_biquad(eq, BQ_PEAKING, 580/NQ, 6, -8);
    eq_append_biquad(eq, BQ_HIGHSHELF, 8000/NQ, 3, 2);

    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp1);
    eq_process(eq, data, N);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp2);
    printf("processing takes %g seconds\n", tp_diff(&tp2, &tp1));
    eq_free(eq);

    ir = fopen("ir.dat", "w");
    for (i = 0; i < N; i++)
        fprintf(ir, "%g\n", data[i]);
    fclose(ir);
    free(data);
}
/* Runs the filters on an input file */
static void test_file(const char *input_filename, const char *output_filename)
{
    size_t frames;
    int i;
    double NQ = 44100 / 2; /* nyquist frequency */
    struct timespec tp1, tp2;
    struct eq *eq;

    float *data = read_raw(input_filename, &frames);

    /* Set some data to 0 to test for denormals. */
    for (i = frames / 10; i < frames; i++)
        data[i] = 0.0;

    /* Left eq chain */
    eq = eq_new();
    eq_append_biquad(eq, BQ_PEAKING, 380/NQ, 3, -10);
    eq_append_biquad(eq, BQ_PEAKING, 720/NQ, 3, -12);
    eq_append_biquad(eq, BQ_PEAKING, 1705/NQ, 3, -8);
    eq_append_biquad(eq, BQ_HIGHPASS, 218/NQ, 0.7, -10.2);
    eq_append_biquad(eq, BQ_PEAKING, 580/NQ, 6, -8);
    eq_append_biquad(eq, BQ_HIGHSHELF, 8000/NQ, 3, 2);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp1);
    process(eq, data, frames);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp2);
    printf("processing takes %g seconds for %zu samples\n",
           tp_diff(&tp2, &tp1), frames);
    eq_free(eq);

    /* Right eq chain */
    eq = eq_new();
    eq_append_biquad(eq, BQ_PEAKING, 450/NQ, 3, -12);
    eq_append_biquad(eq, BQ_PEAKING, 721/NQ, 3, -12);
    eq_append_biquad(eq, BQ_PEAKING, 1800/NQ, 8, -10.2);
    eq_append_biquad(eq, BQ_PEAKING, 580/NQ, 6, -8);
    eq_append_biquad(eq, BQ_HIGHPASS, 250/NQ, 0.6578, 0);
    eq_append_biquad(eq, BQ_HIGHSHELF, 8000/NQ, 0, 2);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp1);
    process(eq, data + frames, frames);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp2);
    printf("processing takes %g seconds for %zu samples\n",
           tp_diff(&tp2, &tp1), frames);
    eq_free(eq);

    write_raw(output_filename, data, frames);
    free(data);
}
Beispiel #4
0
static void *eq_init(const struct dspfilter_info *info,
      const struct dspfilter_config *config, void *userdata)
{
   float *frequencies, *gain;
   unsigned num_freq, num_gain, i, size;
   int size_log2;
   float beta;
   struct eq_gain *gains = NULL;
   char *filter_path = NULL;
   const float default_freq[] = { 0.0f, info->input_rate };
   const float default_gain[] = { 0.0f, 0.0f };
   struct eq_data *eq = (struct eq_data*)calloc(1, sizeof(*eq));
   if (!eq)
      return NULL;


   config->get_float(userdata, "window_beta", &beta, 4.0f);

   config->get_int(userdata, "block_size_log2", &size_log2, 8);
   size = 1 << size_log2;

   config->get_float_array(userdata, "frequencies", &frequencies, &num_freq, default_freq, 2);
   config->get_float_array(userdata, "gains", &gain, &num_gain, default_gain, 2);

   if (!config->get_string(userdata, "impulse_response_output", &filter_path, ""))
   {
      config->free(filter_path);
      filter_path = NULL;
   }

   num_gain = num_freq = MIN(num_gain, num_freq);

   gains = (struct eq_gain*)calloc(num_gain, sizeof(*gains));
   if (!gains)
      goto error;

   for (i = 0; i < num_gain; i++)
   {
      gains[i].freq = frequencies[i] / (0.5f * info->input_rate);
      gains[i].gain = pow(10.0, gain[i] / 20.0);
   }
   config->free(frequencies);
   config->free(gain);

   eq->block_size = size;

   eq->save     = (float*)calloc(    size, 2 * sizeof(*eq->save));
   eq->block    = (float*)calloc(2 * size, 2 * sizeof(*eq->block));
   eq->fftblock = (fft_complex_t*)calloc(2 * size, sizeof(*eq->fftblock));
   eq->filter   = (fft_complex_t*)calloc(2 * size, sizeof(*eq->filter));

   /* Use an FFT which is twice the block size with zero-padding
    * to make circular convolution => proper convolution.
    */
   eq->fft = fft_new(size_log2 + 1);

   if (!eq->fft || !eq->fftblock || !eq->save || !eq->block || !eq->filter)
      goto error;

   create_filter(eq, size_log2, gains, num_gain, beta, filter_path);
   config->free(filter_path);
   filter_path = NULL;

   free(gains);
   return eq;

error:
   free(gains);
   eq_free(eq);
   return NULL;
}