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