예제 #1
0
TEST(cubeb, resampler_drain)
{
  cubeb_stream_params output_params;
  int target_rate;

  output_params.rate = 44100;
  output_params.channels = 1;
  output_params.format = CUBEB_SAMPLE_FLOAT32NE;
  target_rate = 48000;

  cubeb_resampler * resampler =
    cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
                           test_drain_data_cb, nullptr,
                           CUBEB_RESAMPLER_QUALITY_VOIP);

  const long out_frames = 128;
  float out_buffer[out_frames];
  long got;

  do {
    got = cubeb_resampler_fill(resampler, nullptr, nullptr,
                               out_buffer, out_frames);
  } while (got == out_frames);

  /* If the above is not an infinite loop, the drain was a success, just mark
   * this test as such. */
  ASSERT_TRUE(true);

  cubeb_resampler_destroy(resampler);
}
예제 #2
0
TEST(cubeb, resampler_output_only_noop)
{
  cubeb_stream_params output_params;
  int target_rate;

  output_params.rate = 44100;
  output_params.channels = 1;
  output_params.format = CUBEB_SAMPLE_FLOAT32NE;
  target_rate = output_params.rate;

  cubeb_resampler * resampler =
    cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
                           test_output_only_noop_data_cb, nullptr,
                           CUBEB_RESAMPLER_QUALITY_VOIP);

  const long out_frames = 128;
  float out_buffer[out_frames];
  long got;

  got = cubeb_resampler_fill(resampler, nullptr, nullptr,
                             out_buffer, out_frames);

  ASSERT_EQ(got, out_frames);

  cubeb_resampler_destroy(resampler);
}
예제 #3
0
static void
cbjack_stream_destroy(cubeb_stream * stream)
{
  pthread_mutex_lock(&stream->mutex);
  stream->ports_ready = false;

  if (stream->devs == DUPLEX || stream->devs == OUT_ONLY) {
    for (unsigned int c = 0; c < stream->out_params.channels; c++) {
      if (stream->output_ports[c]) {
        api_jack_port_unregister (stream->context->jack_client, stream->output_ports[c]);
        stream->output_ports[c] = NULL;
      }
    }
  }

  if (stream->devs == DUPLEX || stream->devs == IN_ONLY) {
    for (unsigned int c = 0; c < stream->in_params.channels; c++) {
      if (stream->input_ports[c]) {
        api_jack_port_unregister (stream->context->jack_client, stream->input_ports[c]);
        stream->input_ports[c] = NULL;
      }
    }
  }

  if (stream->resampler) {
    cubeb_resampler_destroy(stream->resampler);
    stream->resampler = NULL;
  }
  stream->in_use = false;
  pthread_mutex_unlock(&stream->mutex);
}
예제 #4
0
static void
opensl_stream_destroy(cubeb_stream * stm)
{
  if (stm->playerObj)
    (*stm->playerObj)->Destroy(stm->playerObj);
  int i;
  for (i = 0; i < NBUFS; i++) {
    free(stm->queuebuf[i]);
  }

  cubeb_resampler_destroy(stm->resampler);

  free(stm);
}
예제 #5
0
static void
opensl_stream_destroy(cubeb_stream * stm)
{
  if (stm->playerObj) {
    (*stm->bufq)->Clear(stm->bufq);
    (*stm->playerObj)->Destroy(stm->playerObj);
  }
  int i;
  for (i = 0; i < NBUFS; i++) {
    free(stm->queuebuf[i]);
  }
  pthread_mutex_destroy(&stm->mutex);

  cubeb_resampler_destroy(stm->resampler);

  free(stm);
}
예제 #6
0
void test_resampler_duplex(uint32_t input_channels, uint32_t output_channels,
                           uint32_t input_rate, uint32_t output_rate,
                           uint32_t target_rate, float chunk_duration)
{
  cubeb_stream_params input_params;
  cubeb_stream_params output_params;
  osc_state state;

  input_params.format = output_params.format = cubeb_format<T>();
  state.input_channels = input_params.channels = input_channels;
  state.output_channels = output_params.channels = output_channels;
  input_params.rate = input_rate;
  state.output_rate = output_params.rate = output_rate;
  state.target_rate = target_rate;
  long got;

  cubeb_resampler * resampler =
    cubeb_resampler_create((cubeb_stream*)nullptr, &input_params, &output_params, target_rate,
                           data_cb_resampler, (void*)&state, CUBEB_RESAMPLER_QUALITY_VOIP);

  long latency = cubeb_resampler_latency(resampler);

  const uint32_t duration_s = 2;
  int32_t duration_frames = duration_s * target_rate;
  uint32_t input_array_frame_count = ceil(chunk_duration * input_rate / 1000) + ceilf(static_cast<float>(input_rate) / target_rate) * 2;
  uint32_t output_array_frame_count = chunk_duration * output_rate / 1000;
  auto_array<float> input_buffer(input_channels * input_array_frame_count);
  auto_array<float> output_buffer(output_channels * output_array_frame_count);
  auto_array<float> expected_resampled_input(input_channels * duration_frames);
  auto_array<float> expected_resampled_output(output_channels * output_rate * duration_s);

  state.max_output_phase_index = duration_s * target_rate;

  expected_resampled_input.push_silence(input_channels * duration_frames);
  expected_resampled_output.push_silence(output_channels * output_rate * duration_s);

  /* expected output is a 440Hz sine wave at 16kHz */
  fill_with_sine(expected_resampled_input.data() + latency,
                 target_rate, input_channels, duration_frames - latency, 0);
  /* expected output is a 440Hz sine wave at 32kHz */
  fill_with_sine(expected_resampled_output.data() + latency,
                 output_rate, output_channels, output_rate * duration_s - latency, 0);

  while (state.output_phase_index != state.max_output_phase_index) {
    uint32_t leftover_samples = input_buffer.length() * input_channels;
    input_buffer.reserve(input_array_frame_count);
    state.input_phase_index = fill_with_sine(input_buffer.data() + leftover_samples,
                                             input_rate,
                                             input_channels,
                                             input_array_frame_count - leftover_samples,
                                             state.input_phase_index);
    long input_consumed = input_array_frame_count;
    input_buffer.set_length(input_array_frame_count);

    got = cubeb_resampler_fill(resampler,
                               input_buffer.data(), &input_consumed,
                               output_buffer.data(), output_array_frame_count);

    /* handle leftover input */
    if (input_array_frame_count != static_cast<uint32_t>(input_consumed)) {
      input_buffer.pop(nullptr, input_consumed * input_channels);
    } else {
      input_buffer.clear();
    }

    state.output.push(output_buffer.data(), got * state.output_channels);
  }

  dump("input_expected.raw", expected_resampled_input.data(), expected_resampled_input.length());
  dump("output_expected.raw", expected_resampled_output.data(), expected_resampled_output.length());
  dump("input.raw", state.input.data(), state.input.length());
  dump("output.raw", state.output.data(), state.output.length());

  ASSERT_TRUE(array_fuzzy_equal(state.input, expected_resampled_input, epsilon<T>(input_rate/target_rate)));
  ASSERT_TRUE(array_fuzzy_equal(state.output, expected_resampled_output, epsilon<T>(output_rate/target_rate)));

  cubeb_resampler_destroy(resampler);
}