Example #1
0
//! The main function
int main(int argc, char *argv[])
{
  A_ALIGNED static dsp16_t s_input[N/NB_CUTS];
  int f;
  dsp_resampling_t *resampling;
  dsp16_t *output;
  U32 temp;
  dsp16_resampling_options_t options;

  // Initialize options
  memset(&options, 0, sizeof(options));
  options.coefficients_generation = DSP16_RESAMPLING_OPTIONS_USE_DYNAMIC;
  options.dynamic.coefficients_normalization = true;

  // Switch to external Oscillator 0.
  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);

  // Initialize the DSP debug module
  dsp_debug_initialization(FOSC0);

  dsp16_debug_printf("16-bit fixed point signal resampling\n");
  dsp16_debug_printf("Input Fs: %iHz\n", F_INPUT);
  dsp16_debug_printf("Output Fs: %iHz\n", F_OUTPUT);
  dsp16_debug_printf("%i samples to process cut into %i buffers\n", N, NB_CUTS);
  dsp16_debug_printf("Filter order used: %i\n", FILTER_ORDER);

  if (!(resampling = dsp16_resampling_setup(F_INPUT, F_OUTPUT, N/NB_CUTS, FILTER_ORDER, 1, (malloc_fct_t) malloc, &options)))
  {
    dsp16_debug_printf("Unable to allocate enough memory\n");
    return -1;
  }

  if (!(output = (dsp16_t *) malloc(dsp16_resampling_get_output_max_buffer_size(resampling)*sizeof(dsp16_t) + 4)))
  {
    dsp16_debug_printf("Unable to allocate enough memory for the output buffer\n");
    return -1;
  }

  for(f=0; f<NB_CUTS; f++)
  {
    memcpy(s_input, &s[N/NB_CUTS*f], (N/NB_CUTS)*sizeof(dsp16_t));
    temp = Get_sys_count();
    dsp16_resampling_compute(resampling, output, s_input, 0);
    temp = Get_sys_count() - temp;
    dsp16_debug_print_vect(output, dsp16_resampling_get_output_current_buffer_size(resampling));
  }
  dsp16_debug_printf(
    "Cycle count per iteration: %i\n            in total (to compute %i samples): %i\n",
    temp,
    dsp16_resampling_get_output_current_buffer_size(resampling)*NB_CUTS,
    temp*NB_CUTS);

  dsp16_resampling_free(resampling, (free_fct_t) free);

  while(1);
}
static bool usb_stream_process(void)
{
    buffer_t *input_buffer;
#if (defined __GNUC__)
    dsp16_t * volatile dsp16_output_buffer;
#else
    dsp16_t * dsp16_output_buffer;
#endif
    int i, channel, size = 0;

    // If no buffer is ready, then set under flow marker
    if (usb_stream_context->current_full_buffer == -1)
        return false;

    // If the audio DAC is not ready to receive more data, then return
    if (!audio_mixer_dacs_output_direct(NULL, 0))
        return false;

    // Select the current input buffer and make sure it is valid
    input_buffer = usb_stream_context->input_buffers[usb_stream_context->current_full_buffer];

    // Make sure this buffer is not already in the process of resampling
    if (input_buffer->buffer_state != BUFFER_STATE_FULL)
        return false;

    // Mark this buffer as a "resampling" buffer
    input_buffer->buffer_state = BUFFER_STATE_RESAMPLING;

    // Select the current output buffer
    dsp16_output_buffer = (dsp16_t *) usb_stream_context->output_buffers[usb_stream_context->current_output_buffer];

    for (channel=0; channel<usb_stream_context->nb_channels; channel++)
    {
        // Interpolates the current channel buffer
        dsp16_resampling_compute(usb_stream_context->ctx->resampling,
                                 usb_stream_context->output_temp_buffer,
                                 input_buffer->buffer[channel],
                                 channel);
        size = dsp16_resampling_get_output_current_buffer_size(usb_stream_context->ctx->resampling);
        // Fill the array with audio samples and mix the channels
        switch (usb_stream_context->nb_channels)
        {
        case 1:
            memcpy(dsp16_output_buffer, usb_stream_context->output_temp_buffer, usb_stream_context->input_buffer_size);
            break;
        case 2:
            for (i=0; i<size; i++)
                dsp16_output_buffer[i*2] = ((dsp16_t *) usb_stream_context->output_temp_buffer)[i];
            break;
        default:
            for (i=0; i<size; i++)
                dsp16_output_buffer[i*usb_stream_context->nb_channels] = ((dsp16_t *) usb_stream_context->output_temp_buffer)[i];
        }
        // change channel
        dsp16_output_buffer++;
    }

    // Re-selects the current output buffer
    dsp16_output_buffer = (dsp16_t *) usb_stream_context->output_buffers[usb_stream_context->current_output_buffer];

    // Scale the output buffer if the scaling is set
    if (usb_stream_context->ctx->gain)
        dsp16_vect_realdiv(dsp16_output_buffer, dsp16_output_buffer, size * usb_stream_context->nb_channels, usb_stream_context->ctx->gain);

    // Send the buffer to the output channel
    audio_mixer_dacs_output_direct(dsp16_output_buffer, size);

    // Set the current input buffer as an empty buffer
    input_buffer->buffer_state = BUFFER_STATE_EMPTY;

    // Update the current output buffer index
    usb_stream_context->current_output_buffer = (usb_stream_context->current_output_buffer+1)%AUDIO_STREAM_NB_OUTPUT_BUFFERS;

    // Update the current full buffer pointer
    i = (usb_stream_context->current_full_buffer+1)%AUDIO_STREAM_NB_INPUT_BUFFERS;
    input_buffer = usb_stream_context->input_buffers[i];
    if (input_buffer->buffer_state != BUFFER_STATE_FULL)
        i = -1;
    usb_stream_context->current_full_buffer = i;

    return true;
}