Ejemplo n.º 1
0
Archivo: eq.c Proyecto: OV2/RetroArch
static void create_filter(struct eq_data *eq, unsigned size_log2,
      struct eq_gain *gains, unsigned num_gains, double beta)
{
   int i;
   int half_block_size = eq->block_size >> 1;
   double window_mod = 1.0 / kaiser_window(0.0, beta);

   fft_t *fft = fft_new(size_log2);
   float *time_filter = (float*)calloc(eq->block_size * 2, sizeof(*time_filter));
   if (!fft || !time_filter)
      goto end;

   // Make sure bands are in correct order.
   qsort(gains, num_gains, sizeof(*gains), gains_cmp);

   // Compute desired filter response.
   generate_response(eq->filter, gains, num_gains, half_block_size);

   // Get equivalent time-domain filter.
   fft_process_inverse(fft, time_filter, eq->filter, 1);

   // ifftshift() to create the correct linear phase filter.
   // The filter response was designed with zero phase, which won't work unless we compensate
   // for the repeating property of the FFT here by flipping left and right blocks.
   for (i = 0; i < half_block_size; i++)
   {
      float tmp = time_filter[i + half_block_size];
      time_filter[i + half_block_size] = time_filter[i];
      time_filter[i] = tmp;
   }

   // Apply a window to smooth out the frequency repsonse.
   for (i = 0; i < (int)eq->block_size; i++)
   {
      // Kaiser window.
      double phase = (double)i / (eq->block_size - 1);
      phase = 2.0 * (phase - 0.5);
      time_filter[i] *= window_mod * kaiser_window(phase, beta);
   }

   // Debugging.
#if 0
   FILE *file = fopen("/tmp/test.txt", "w");
   if (file)
   {
      for (i = 0; i < (int)eq->block_size; i++)
         fprintf(file, "%.6f\n", time_filter[i]);
      fclose(file);
   }
#endif

   // Padded FFT to create our FFT filter.
   fft_process_forward(eq->fft, eq->filter, time_filter, 1);

end:
   fft_free(fft);
   free(time_filter);
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
static void create_filter(struct eq_data *eq, unsigned size_log2,
      struct eq_gain *gains, unsigned num_gains, double beta, const char *filter_path)
{
   int i;
   int half_block_size = eq->block_size >> 1;
   double window_mod = 1.0 / kaiser_window_function(0.0, beta);

   fft_t *fft = fft_new(size_log2);
   float *time_filter = (float*)calloc(eq->block_size * 2 + 1, sizeof(*time_filter));
   if (!fft || !time_filter)
      goto end;

   /* Make sure bands are in correct order. */
   qsort(gains, num_gains, sizeof(*gains), gains_cmp);

   /* Compute desired filter response. */
   generate_response(eq->filter, gains, num_gains, half_block_size);

   /* Get equivalent time-domain filter. */
   fft_process_inverse(fft, time_filter, eq->filter, 1);

   // ifftshift() to create the correct linear phase filter.
   // The filter response was designed with zero phase, which won't work unless we compensate
   // for the repeating property of the FFT here by flipping left and right blocks.
   for (i = 0; i < half_block_size; i++)
   {
      float tmp = time_filter[i + half_block_size];
      time_filter[i + half_block_size] = time_filter[i];
      time_filter[i] = tmp;
   }

   /* Apply a window to smooth out the frequency repsonse. */
   for (i = 0; i < (int)eq->block_size; i++)
   {
      /* Kaiser window. */
      double phase = (double)i / eq->block_size;
      phase = 2.0 * (phase - 0.5);
      time_filter[i] *= window_mod * kaiser_window_function(phase, beta);
   }

   /* Debugging. */
   if (filter_path)
   {
      FILE *file = fopen(filter_path, "w");
      if (file)
      {
         for (i = 0; i < (int)eq->block_size - 1; i++)
            fprintf(file, "%.8f\n", time_filter[i + 1]);
         fclose(file);
      }
   }

   /* Padded FFT to create our FFT filter.
    * Make our even-length filter odd by discarding the first coefficient.
    * For some interesting reason, this allows us to design an odd-length linear phase filter.
    */
   fft_process_forward(eq->fft, eq->filter, time_filter + 1, 1);

end:
   fft_free(fft);
   free(time_filter);
}
Ejemplo n.º 4
0
struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(void)
{
    struct FDMDV *f;
    int           c, i;
    float         carrier_freq;

    assert(FDMDV_BITS_PER_FRAME == NC*NB);
    assert(FDMDV_NOM_SAMPLES_PER_FRAME == M);
    assert(FDMDV_MAX_SAMPLES_PER_FRAME == (M+M/P));

    f = (struct FDMDV*)malloc(sizeof(struct FDMDV));
    if (f == NULL)
	return NULL;
    
    f->current_test_bit = 0;
    for(i=0; i<NTEST_BITS; i++)
	f->rx_test_bits_mem[i] = 0;

    f->tx_pilot_bit = 0;

    for(c=0; c<NC+1; c++) {
	f->prev_tx_symbols[c].real = 1.0;
	f->prev_tx_symbols[c].imag = 0.0;
	f->prev_rx_symbols[c].real = 1.0;
	f->prev_rx_symbols[c].imag = 0.0;

	init_comp_array(f->tx_filter_memory[c], NSYM);
	init_comp_array(f->rx_filter_memory[c], NFILTER);

	/* Spread initial FDM carrier phase out as far as possible.
           This helped PAPR for a few dB.  We don't need to adjust rx
           phase as DQPSK takes care of that. */
	
	f->phase_tx[c].real = cosf(2.0*PI*c/(NC+1));
 	f->phase_tx[c].imag = sinf(2.0*PI*c/(NC+1));

	f->phase_rx[c].real = 1.0;
 	f->phase_rx[c].imag = 0.0;

	init_comp_array(f->rx_filter_mem_timing[c], NT*P);
	init_comp_array(f->rx_baseband_mem_timing[c], NFILTERTIMING);
  }
    
    /* Set up frequency of each carrier */

    for(c=0; c<NC/2; c++) {
	carrier_freq = (-NC/2 + c)*FSEP + FCENTRE;
	f->freq[c].real = cosf(2.0*PI*carrier_freq/FS);
 	f->freq[c].imag = sinf(2.0*PI*carrier_freq/FS);
    }

    for(c=NC/2; c<NC; c++) {
	carrier_freq = (-NC/2 + c + 1)*FSEP + FCENTRE;
	f->freq[c].real = cosf(2.0*PI*carrier_freq/FS);
 	f->freq[c].imag = sinf(2.0*PI*carrier_freq/FS);
    }
	
    f->freq[NC].real = cosf(2.0*PI*FCENTRE/FS);
    f->freq[NC].imag = sinf(2.0*PI*FCENTRE/FS);

    /* Generate DBPSK pilot Look Up Table (LUT) */

    generate_pilot_lut(f->pilot_lut, &f->freq[NC]);

    /* freq Offset estimation states */

    f->fft_pilot_cfg = fft_new (MPILOTFFT, 0);
    assert(f->fft_pilot_cfg != NULL);

    init_comp_array(f->pilot_baseband1, NPILOTBASEBAND);
    init_comp_array(f->pilot_baseband2, NPILOTBASEBAND);

    f->pilot_lut_index = 0;
    f->prev_pilot_lut_index = 3*M;
    
    init_comp_array(f->pilot_lpf1, NPILOTLPF);
    init_comp_array(f->pilot_lpf2, NPILOTLPF);

    f->foff = 0.0;
    f->foff_rect.real = 1.0;
    f->foff_rect.imag = 0.0;
    f->foff_phase_rect.real = 1.0;
    f->foff_phase_rect.imag = 0.0;

    f->fest_state = 0;
    f->coarse_fine = COARSE;
 
    for(c=0; c<NC+1; c++) {
	f->sig_est[c] = 0.0;
	f->noise_est[c] = 0.0;
    }

    for(i=0; i<2*FDMDV_NSPEC; i++)
	f->fft_buf[i] = 0.0;
    f->fft_cfg = fft_new (2*FDMDV_NSPEC, 0);
    assert(f->fft_cfg != NULL);


    return f;
}
Ejemplo n.º 5
0
int main(void)
{
    PaStreamParameters inputParameters, outputParameters;
    PaStream *stream;
    PaError err;
    
    err = Pa_Initialize();
    if( err != paNoError ) goto error;
    
    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
    if (inputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default input device.\n");
        goto error;
    }
    inputParameters.channelCount = 2;       /* stereo input */
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;
    
    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    if (outputParameters.device == paNoDevice) {
        fprintf(stderr,"Error: No default output device.\n");
        goto error;
    }
    outputParameters.channelCount = 2;       /* stereo output */
    outputParameters.sampleFormat = PA_SAMPLE_TYPE;
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    outputParameters.hostApiSpecificStreamInfo = NULL;
    
    /* Instantiate FFT */
    fft_new(&fft, FRAMES_PER_BUFFER);
    spectrum = malloc(FRAMES_PER_BUFFER * sizeof(double));
    
    /* Instantiate Spectral Features */
    spectralFeatures_new(&features, FRAMES_PER_BUFFER);
    
    err = Pa_OpenStream(
                        &stream,
                        &inputParameters,
                        &outputParameters,
                        SAMPLE_RATE,
                        FRAMES_PER_BUFFER,
                        0, /* paClipOff, */  /* we won't output out of range samples so don't bother clipping them */
                        onsetCallback,
                        NULL );
    if( err != paNoError ) goto error;
    
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Hit ENTER to stop program.\n");
    getchar();
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    
    printf("Finished. gNumNoInputs = %d\n", gNumNoInputs );
    Pa_Terminate();
    return 0;
    
error:
    Pa_Terminate();
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return -1;
}