diff options
Diffstat (limited to 'test/test_loopback.cpp')
-rw-r--r-- | test/test_loopback.cpp | 323 |
1 files changed, 203 insertions, 120 deletions
diff --git a/test/test_loopback.cpp b/test/test_loopback.cpp index bbb9409..7410bed 100644 --- a/test/test_loopback.cpp +++ b/test/test_loopback.cpp @@ -5,41 +5,66 @@ * accompanying file LICENSE for details. */ - /* libcubeb api/function test. Requests a loopback device and checks that - output is being looped back to input. NOTE: Usage of output devices while - performing this test will cause flakey results! */ +/* libcubeb api/function test. Requests a loopback device and checks that + output is being looped back to input. NOTE: Usage of output devices while + performing this test will cause flakey results! */ #include "gtest/gtest.h" #if !defined(_XOPEN_SOURCE) #define _XOPEN_SOURCE 600 #endif -#include <stdio.h> -#include <stdlib.h> -#include <math.h> +#include "cubeb/cubeb.h" #include <algorithm> +#include <math.h> #include <memory> #include <mutex> +#include <stdio.h> +#include <stdlib.h> #include <string> -#include "cubeb/cubeb.h" -//#define ENABLE_NORMAL_LOG -//#define ENABLE_VERBOSE_LOG +// #define ENABLE_NORMAL_LOG +// #define ENABLE_VERBOSE_LOG #include "common.h" const uint32_t SAMPLE_FREQUENCY = 48000; const uint32_t TONE_FREQUENCY = 440; const double OUTPUT_AMPLITUDE = 0.25; -const int32_t NUM_FRAMES_TO_OUTPUT = SAMPLE_FREQUENCY / 20; /* play ~50ms of samples */ - -template<typename T> T ConvertSampleToOutput(double input); -template<> float ConvertSampleToOutput(double input) { return float(input); } -template<> short ConvertSampleToOutput(double input) { return short(input * 32767.0f); } +const int32_t NUM_FRAMES_TO_OUTPUT = + SAMPLE_FREQUENCY / 20; /* play ~50ms of samples */ + +template <typename T> +T +ConvertSampleToOutput(double input); +template <> +float +ConvertSampleToOutput(double input) +{ + return float(input); +} +template <> +short +ConvertSampleToOutput(double input) +{ + return short(input * 32767.0f); +} -template<typename T> double ConvertSampleFromOutput(T sample); -template<> double ConvertSampleFromOutput(float sample) { return double(sample); } -template<> double ConvertSampleFromOutput(short sample) { return double(sample / 32767.0); } +template <typename T> +double +ConvertSampleFromOutput(T sample); +template <> +double +ConvertSampleFromOutput(float sample) +{ + return double(sample); +} +template <> +double +ConvertSampleFromOutput(short sample) +{ + return double(sample / 32767.0); +} /* Simple cross correlation to help find phase shift. Not a performant impl */ -std::vector<double> cross_correlate(std::vector<double> & f, - std::vector<double> & g, - size_t signal_length) +std::vector<double> +cross_correlate(std::vector<double> & f, std::vector<double> & g, + size_t signal_length) { /* the length we sweep our window through to find the cross correlation */ size_t sweep_length = f.size() - signal_length + 1; @@ -56,11 +81,12 @@ std::vector<double> cross_correlate(std::vector<double> & f, } /* best effort discovery of phase shift between output and (looped) input*/ -size_t find_phase(std::vector<double> & output_frames, - std::vector<double> & input_frames, - size_t signal_length) +size_t +find_phase(std::vector<double> & output_frames, + std::vector<double> & input_frames, size_t signal_length) { - std::vector<double> correlation = cross_correlate(output_frames, input_frames, signal_length); + std::vector<double> correlation = + cross_correlate(output_frames, input_frames, signal_length); size_t phase = 0; double max_correlation = correlation.at(0); for (size_t i = 1; i < correlation.size(); i++) { @@ -72,9 +98,12 @@ size_t find_phase(std::vector<double> & output_frames, return phase; } -std::vector<double> normalize_frames(std::vector<double> & frames) { - double max = abs(*std::max_element(frames.begin(), frames.end(), - [](double a, double b) { return abs(a) < abs(b); })); +std::vector<double> +normalize_frames(std::vector<double> & frames) +{ + double max = abs( + *std::max_element(frames.begin(), frames.end(), + [](double a, double b) { return abs(a) < abs(b); })); std::vector<double> normalized_frames; normalized_frames.reserve(frames.size()); for (const double frame : frames) { @@ -83,13 +112,17 @@ std::vector<double> normalize_frames(std::vector<double> & frames) { return normalized_frames; } -/* heuristic comparison of aligned output and input signals, gets flaky if TONE_FREQUENCY is too high */ -void compare_signals(std::vector<double> & output_frames, - std::vector<double> & input_frames) +/* heuristic comparison of aligned output and input signals, gets flaky if + * TONE_FREQUENCY is too high */ +void +compare_signals(std::vector<double> & output_frames, + std::vector<double> & input_frames) { - ASSERT_EQ(output_frames.size(), input_frames.size()) << "#Output frames != #input frames"; + ASSERT_EQ(output_frames.size(), input_frames.size()) + << "#Output frames != #input frames"; size_t num_frames = output_frames.size(); - std::vector<double> normalized_output_frames = normalize_frames(output_frames); + std::vector<double> normalized_output_frames = + normalize_frames(output_frames); std::vector<double> normalized_input_frames = normalize_frames(input_frames); /* calculate mean absolute errors */ @@ -100,7 +133,8 @@ void compare_signals(std::vector<double> & output_frames, /* mean absolute errors between input and silence */ double input_silence_mas = 0.0; for (size_t i = 0; i < num_frames; i++) { - io_mas += abs(normalized_output_frames.at(i) - normalized_input_frames.at(i)); + io_mas += + abs(normalized_output_frames.at(i) - normalized_input_frames.at(i)); output_silence_mas += abs(normalized_output_frames.at(i)); input_silence_mas += abs(normalized_input_frames.at(i)); } @@ -109,13 +143,16 @@ void compare_signals(std::vector<double> & output_frames, input_silence_mas /= num_frames; ASSERT_LT(io_mas, output_silence_mas) - << "Error between output and input should be less than output and silence!"; + << "Error between output and input should be less than output and " + "silence!"; ASSERT_LT(io_mas, input_silence_mas) - << "Error between output and input should be less than output and silence!"; + << "Error between output and input should be less than output and " + "silence!"; /* make sure extrema are in (roughly) correct location */ /* number of maxima + minama expected in the frames*/ - const long NUM_EXTREMA = 2 * TONE_FREQUENCY * NUM_FRAMES_TO_OUTPUT / SAMPLE_FREQUENCY; + const long NUM_EXTREMA = + 2 * TONE_FREQUENCY * NUM_FRAMES_TO_OUTPUT / SAMPLE_FREQUENCY; /* expected index of first maxima */ const long FIRST_MAXIMUM_INDEX = SAMPLE_FREQUENCY / TONE_FREQUENCY / 4; /* Threshold we expect all maxima and minima to be above or below. Ideally @@ -128,15 +165,19 @@ void compare_signals(std::vector<double> & output_frames, /* expected offset to current extreme: i * stide between extrema */ size_t offset = i * SAMPLE_FREQUENCY / TONE_FREQUENCY / 2; if (is_maximum) { - ASSERT_GT(normalized_output_frames.at(FIRST_MAXIMUM_INDEX + offset), THRESHOLD) - << "Output frames have unexpected missing maximum!"; - ASSERT_GT(normalized_input_frames.at(FIRST_MAXIMUM_INDEX + offset), THRESHOLD) - << "Input frames have unexpected missing maximum!"; + ASSERT_GT(normalized_output_frames.at(FIRST_MAXIMUM_INDEX + offset), + THRESHOLD) + << "Output frames have unexpected missing maximum!"; + ASSERT_GT(normalized_input_frames.at(FIRST_MAXIMUM_INDEX + offset), + THRESHOLD) + << "Input frames have unexpected missing maximum!"; } else { - ASSERT_LT(normalized_output_frames.at(FIRST_MAXIMUM_INDEX + offset), -THRESHOLD) - << "Output frames have unexpected missing minimum!"; - ASSERT_LT(normalized_input_frames.at(FIRST_MAXIMUM_INDEX + offset), -THRESHOLD) - << "Input frames have unexpected missing minimum!"; + ASSERT_LT(normalized_output_frames.at(FIRST_MAXIMUM_INDEX + offset), + -THRESHOLD) + << "Output frames have unexpected missing minimum!"; + ASSERT_LT(normalized_input_frames.at(FIRST_MAXIMUM_INDEX + offset), + -THRESHOLD) + << "Input frames have unexpected missing minimum!"; } } } @@ -150,12 +191,14 @@ struct user_state_loopback { std::vector<double> input_frames; }; -template<typename T> -long data_cb_loop_duplex(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes) +template <typename T> +long +data_cb_loop_duplex(cubeb_stream * stream, void * user, + const void * inputbuffer, void * outputbuffer, long nframes) { - struct user_state_loopback * u = (struct user_state_loopback *) user; - T * ib = (T *) inputbuffer; - T * ob = (T *) outputbuffer; + struct user_state_loopback * u = (struct user_state_loopback *)user; + T * ib = (T *)inputbuffer; + T * ob = (T *)outputbuffer; if (stream == NULL || inputbuffer == NULL || outputbuffer == NULL) { return CUBEB_ERROR; @@ -167,7 +210,8 @@ long data_cb_loop_duplex(cubeb_stream * stream, void * user, const void * inputb double tone = 0.0; if (u->position + i < NUM_FRAMES_TO_OUTPUT) { /* generate sine wave */ - tone = sin(2 * M_PI*(i + u->position) * TONE_FREQUENCY / SAMPLE_FREQUENCY); + tone = + sin(2 * M_PI * (i + u->position) * TONE_FREQUENCY / SAMPLE_FREQUENCY); tone *= OUTPUT_AMPLITUDE; } ob[i] = ConvertSampleToOutput<T>(tone); @@ -181,15 +225,19 @@ long data_cb_loop_duplex(cubeb_stream * stream, void * user, const void * inputb return nframes; } -template<typename T> -long data_cb_loop_input_only(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes) +template <typename T> +long +data_cb_loop_input_only(cubeb_stream * stream, void * user, + const void * inputbuffer, void * outputbuffer, + long nframes) { - struct user_state_loopback * u = (struct user_state_loopback *) user; - T * ib = (T *) inputbuffer; + struct user_state_loopback * u = (struct user_state_loopback *)user; + T * ib = (T *)inputbuffer; if (outputbuffer != NULL) { // Can't assert as it needs to return, so expect to fail instead - EXPECT_EQ(outputbuffer, (void *) NULL) << "outputbuffer should be null in input only callback"; + EXPECT_EQ(outputbuffer, (void *)NULL) + << "outputbuffer should be null in input only callback"; return CUBEB_ERROR; } @@ -205,11 +253,13 @@ long data_cb_loop_input_only(cubeb_stream * stream, void * user, const void * in return nframes; } -template<typename T> -long data_cb_playback(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes) +template <typename T> +long +data_cb_playback(cubeb_stream * stream, void * user, const void * inputbuffer, + void * outputbuffer, long nframes) { - struct user_state_loopback * u = (struct user_state_loopback *) user; - T * ob = (T *) outputbuffer; + struct user_state_loopback * u = (struct user_state_loopback *)user; + T * ob = (T *)outputbuffer; if (stream == NULL || outputbuffer == NULL) { return CUBEB_ERROR; @@ -221,7 +271,8 @@ long data_cb_playback(cubeb_stream * stream, void * user, const void * inputbuff double tone = 0.0; if (u->position + i < NUM_FRAMES_TO_OUTPUT) { /* generate sine wave */ - tone = sin(2 * M_PI*(i + u->position) * TONE_FREQUENCY / SAMPLE_FREQUENCY); + tone = + sin(2 * M_PI * (i + u->position) * TONE_FREQUENCY / SAMPLE_FREQUENCY); tone *= OUTPUT_AMPLITUDE; } ob[i] = ConvertSampleToOutput<T>(tone); @@ -233,18 +284,22 @@ long data_cb_playback(cubeb_stream * stream, void * user, const void * inputbuff return nframes; } -void state_cb_loop(cubeb_stream * stream, void * /*user*/, cubeb_state state) +void +state_cb_loop(cubeb_stream * stream, void * /*user*/, cubeb_state state) { if (stream == NULL) return; switch (state) { case CUBEB_STATE_STARTED: - fprintf(stderr, "stream started\n"); break; + fprintf(stderr, "stream started\n"); + break; case CUBEB_STATE_STOPPED: - fprintf(stderr, "stream stopped\n"); break; + fprintf(stderr, "stream stopped\n"); + break; case CUBEB_STATE_DRAINED: - fprintf(stderr, "stream drained\n"); break; + fprintf(stderr, "stream drained\n"); + break; default: fprintf(stderr, "unknown stream state %d\n", state); } @@ -252,7 +307,8 @@ void state_cb_loop(cubeb_stream * stream, void * /*user*/, cubeb_state state) return; } -void run_loopback_duplex_test(bool is_float) +void +run_loopback_duplex_test(bool is_float) { cubeb * ctx; cubeb_stream * stream; @@ -264,8 +320,8 @@ void run_loopback_duplex_test(bool is_float) r = common_init(&ctx, "Cubeb loopback example: duplex stream"); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library"; - std::unique_ptr<cubeb, decltype(&cubeb_destroy)> - cleanup_cubeb_at_exit(ctx, cubeb_destroy); + std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit( + ctx, cubeb_destroy); /* This test needs an available input device, skip it if this host does not * have one. */ @@ -291,35 +347,41 @@ void run_loopback_duplex_test(bool is_float) ASSERT_EQ(r, CUBEB_OK) << "Could not get minimal latency"; /* setup a duplex stream with loopback */ - r = cubeb_stream_init(ctx, &stream, "Cubeb loopback", - NULL, &input_params, NULL, &output_params, latency_frames, - is_float ? data_cb_loop_duplex<float> : data_cb_loop_duplex<short>, + r = cubeb_stream_init(ctx, &stream, "Cubeb loopback", NULL, &input_params, + NULL, &output_params, latency_frames, + is_float ? data_cb_loop_duplex<float> + : data_cb_loop_duplex<short>, state_cb_loop, user_data.get()); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream"; std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)> - cleanup_stream_at_exit(stream, cubeb_stream_destroy); + cleanup_stream_at_exit(stream, cubeb_stream_destroy); cubeb_stream_start(stream); delay(300); cubeb_stream_stop(stream); - /* access after stop should not happen, but lock just in case and to appease sanitization tools */ + /* access after stop should not happen, but lock just in case and to appease + * sanitization tools */ std::lock_guard<std::mutex> lock(user_data->user_state_mutex); std::vector<double> & output_frames = user_data->output_frames; std::vector<double> & input_frames = user_data->input_frames; ASSERT_EQ(output_frames.size(), input_frames.size()) - << "#Output frames != #input frames"; + << "#Output frames != #input frames"; - size_t phase = find_phase(user_data->output_frames, user_data->input_frames, NUM_FRAMES_TO_OUTPUT); + size_t phase = find_phase(user_data->output_frames, user_data->input_frames, + NUM_FRAMES_TO_OUTPUT); /* extract vectors of just the relevant signal from output and input */ auto output_frames_signal_start = output_frames.begin(); auto output_frames_signal_end = output_frames.begin() + NUM_FRAMES_TO_OUTPUT; - std::vector<double> trimmed_output_frames(output_frames_signal_start, output_frames_signal_end); + std::vector<double> trimmed_output_frames(output_frames_signal_start, + output_frames_signal_end); auto input_frames_signal_start = input_frames.begin() + phase; - auto input_frames_signal_end = input_frames.begin() + phase + NUM_FRAMES_TO_OUTPUT; - std::vector<double> trimmed_input_frames(input_frames_signal_start, input_frames_signal_end); + auto input_frames_signal_end = + input_frames.begin() + phase + NUM_FRAMES_TO_OUTPUT; + std::vector<double> trimmed_input_frames(input_frames_signal_start, + input_frames_signal_end); compare_signals(trimmed_output_frames, trimmed_input_frames); } @@ -330,7 +392,8 @@ TEST(cubeb, loopback_duplex) run_loopback_duplex_test(false); } -void run_loopback_separate_streams_test(bool is_float) +void +run_loopback_separate_streams_test(bool is_float) { cubeb * ctx; cubeb_stream * input_stream; @@ -343,8 +406,8 @@ void run_loopback_separate_streams_test(bool is_float) r = common_init(&ctx, "Cubeb loopback example: separate streams"); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library"; - std::unique_ptr<cubeb, decltype(&cubeb_destroy)> - cleanup_cubeb_at_exit(ctx, cubeb_destroy); + std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit( + ctx, cubeb_destroy); if (!can_run_audio_input_test(ctx)) { return; @@ -368,24 +431,26 @@ void run_loopback_separate_streams_test(bool is_float) ASSERT_EQ(r, CUBEB_OK) << "Could not get minimal latency"; /* setup an input stream with loopback */ - r = cubeb_stream_init(ctx, &input_stream, "Cubeb loopback input only", - NULL, &input_params, NULL, NULL, latency_frames, - is_float ? data_cb_loop_input_only<float> : data_cb_loop_input_only<short>, + r = cubeb_stream_init(ctx, &input_stream, "Cubeb loopback input only", NULL, + &input_params, NULL, NULL, latency_frames, + is_float ? data_cb_loop_input_only<float> + : data_cb_loop_input_only<short>, state_cb_loop, user_data.get()); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream"; std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)> - cleanup_input_stream_at_exit(input_stream, cubeb_stream_destroy); + cleanup_input_stream_at_exit(input_stream, cubeb_stream_destroy); /* setup an output stream */ - r = cubeb_stream_init(ctx, &output_stream, "Cubeb loopback output only", - NULL, NULL, NULL, &output_params, latency_frames, - is_float ? data_cb_playback<float> : data_cb_playback<short>, + r = cubeb_stream_init(ctx, &output_stream, "Cubeb loopback output only", NULL, + NULL, NULL, &output_params, latency_frames, + is_float ? data_cb_playback<float> + : data_cb_playback<short>, state_cb_loop, user_data.get()); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream"; std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)> - cleanup_output_stream_at_exit(output_stream, cubeb_stream_destroy); + cleanup_output_stream_at_exit(output_stream, cubeb_stream_destroy); cubeb_stream_start(input_stream); cubeb_stream_start(output_stream); @@ -393,22 +458,27 @@ void run_loopback_separate_streams_test(bool is_float) cubeb_stream_stop(output_stream); cubeb_stream_stop(input_stream); - /* access after stop should not happen, but lock just in case and to appease sanitization tools */ + /* access after stop should not happen, but lock just in case and to appease + * sanitization tools */ std::lock_guard<std::mutex> lock(user_data->user_state_mutex); std::vector<double> & output_frames = user_data->output_frames; std::vector<double> & input_frames = user_data->input_frames; ASSERT_LE(output_frames.size(), input_frames.size()) - << "#Output frames should be less or equal to #input frames"; + << "#Output frames should be less or equal to #input frames"; - size_t phase = find_phase(user_data->output_frames, user_data->input_frames, NUM_FRAMES_TO_OUTPUT); + size_t phase = find_phase(user_data->output_frames, user_data->input_frames, + NUM_FRAMES_TO_OUTPUT); /* extract vectors of just the relevant signal from output and input */ auto output_frames_signal_start = output_frames.begin(); auto output_frames_signal_end = output_frames.begin() + NUM_FRAMES_TO_OUTPUT; - std::vector<double> trimmed_output_frames(output_frames_signal_start, output_frames_signal_end); + std::vector<double> trimmed_output_frames(output_frames_signal_start, + output_frames_signal_end); auto input_frames_signal_start = input_frames.begin() + phase; - auto input_frames_signal_end = input_frames.begin() + phase + NUM_FRAMES_TO_OUTPUT; - std::vector<double> trimmed_input_frames(input_frames_signal_start, input_frames_signal_end); + auto input_frames_signal_end = + input_frames.begin() + phase + NUM_FRAMES_TO_OUTPUT; + std::vector<double> trimmed_input_frames(input_frames_signal_start, + input_frames_signal_end); compare_signals(trimmed_output_frames, trimmed_input_frames); } @@ -419,7 +489,8 @@ TEST(cubeb, loopback_separate_streams) run_loopback_separate_streams_test(false); } -void run_loopback_silence_test(bool is_float) +void +run_loopback_silence_test(bool is_float) { cubeb * ctx; cubeb_stream * input_stream; @@ -430,8 +501,8 @@ void run_loopback_silence_test(bool is_float) r = common_init(&ctx, "Cubeb loopback example: record silence"); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library"; - std::unique_ptr<cubeb, decltype(&cubeb_destroy)> - cleanup_cubeb_at_exit(ctx, cubeb_destroy); + std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit( + ctx, cubeb_destroy); if (!can_run_audio_input_test(ctx)) { return; @@ -450,20 +521,22 @@ void run_loopback_silence_test(bool is_float) ASSERT_EQ(r, CUBEB_OK) << "Could not get minimal latency"; /* setup an input stream with loopback */ - r = cubeb_stream_init(ctx, &input_stream, "Cubeb loopback input only", - NULL, &input_params, NULL, NULL, latency_frames, - is_float ? data_cb_loop_input_only<float> : data_cb_loop_input_only<short>, + r = cubeb_stream_init(ctx, &input_stream, "Cubeb loopback input only", NULL, + &input_params, NULL, NULL, latency_frames, + is_float ? data_cb_loop_input_only<float> + : data_cb_loop_input_only<short>, state_cb_loop, user_data.get()); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream"; std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)> - cleanup_input_stream_at_exit(input_stream, cubeb_stream_destroy); + cleanup_input_stream_at_exit(input_stream, cubeb_stream_destroy); cubeb_stream_start(input_stream); delay(300); cubeb_stream_stop(input_stream); - /* access after stop should not happen, but lock just in case and to appease sanitization tools */ + /* access after stop should not happen, but lock just in case and to appease + * sanitization tools */ std::lock_guard<std::mutex> lock(user_data->user_state_mutex); std::vector<double> & input_frames = user_data->input_frames; @@ -483,7 +556,8 @@ TEST(cubeb, loopback_silence) run_loopback_silence_test(false); } -void run_loopback_device_selection_test(bool is_float) +void +run_loopback_device_selection_test(bool is_float) { cubeb * ctx; cubeb_device_collection collection; @@ -494,11 +568,12 @@ void run_loopback_device_selection_test(bool is_float) int r; uint32_t latency_frames = 0; - r = common_init(&ctx, "Cubeb loopback example: device selection, separate streams"); + r = common_init(&ctx, + "Cubeb loopback example: device selection, separate streams"); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library"; - std::unique_ptr<cubeb, decltype(&cubeb_destroy)> - cleanup_cubeb_at_exit(ctx, cubeb_destroy); + std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit( + ctx, cubeb_destroy); if (!can_run_audio_input_test(ctx)) { return; @@ -507,7 +582,7 @@ void run_loopback_device_selection_test(bool is_float) r = cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection); if (r == CUBEB_ERROR_NOT_SUPPORTED) { fprintf(stderr, "Device enumeration not supported" - " for this backend, skipping this test.\n"); + " for this backend, skipping this test.\n"); return; } @@ -545,23 +620,26 @@ void run_loopback_device_selection_test(bool is_float) /* setup an input stream with loopback */ r = cubeb_stream_init(ctx, &input_stream, "Cubeb loopback input only", - device_id.c_str(), &input_params, NULL, NULL, latency_frames, - is_float ? data_cb_loop_input_only<float> : data_cb_loop_input_only<short>, + device_id.c_str(), &input_params, NULL, NULL, + latency_frames, + is_float ? data_cb_loop_input_only<float> + : data_cb_loop_input_only<short>, state_cb_loop, user_data.get()); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream"; std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)> - cleanup_input_stream_at_exit(input_stream, cubeb_stream_destroy); + cleanup_input_stream_at_exit(input_stream, cubeb_stream_destroy); /* setup an output stream */ - r = cubeb_stream_init(ctx, &output_stream, "Cubeb loopback output only", - NULL, NULL, device_id.c_str(), &output_params, latency_frames, - is_float ? data_cb_playback<float> : data_cb_playback<short>, + r = cubeb_stream_init(ctx, &output_stream, "Cubeb loopback output only", NULL, + NULL, device_id.c_str(), &output_params, latency_frames, + is_float ? data_cb_playback<float> + : data_cb_playback<short>, state_cb_loop, user_data.get()); ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream"; std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)> - cleanup_output_stream_at_exit(output_stream, cubeb_stream_destroy); + cleanup_output_stream_at_exit(output_stream, cubeb_stream_destroy); cubeb_stream_start(input_stream); cubeb_stream_start(output_stream); @@ -569,22 +647,27 @@ void run_loopback_device_selection_test(bool is_float) cubeb_stream_stop(output_stream); cubeb_stream_stop(input_stream); - /* access after stop should not happen, but lock just in case and to appease sanitization tools */ + /* access after stop should not happen, but lock just in case and to appease + * sanitization tools */ std::lock_guard<std::mutex> lock(user_data->user_state_mutex); std::vector<double> & output_frames = user_data->output_frames; std::vector<double> & input_frames = user_data->input_frames; ASSERT_LE(output_frames.size(), input_frames.size()) - << "#Output frames should be less or equal to #input frames"; + << "#Output frames should be less or equal to #input frames"; - size_t phase = find_phase(user_data->output_frames, user_data->input_frames, NUM_FRAMES_TO_OUTPUT); + size_t phase = find_phase(user_data->output_frames, user_data->input_frames, + NUM_FRAMES_TO_OUTPUT); /* extract vectors of just the relevant signal from output and input */ auto output_frames_signal_start = output_frames.begin(); auto output_frames_signal_end = output_frames.begin() + NUM_FRAMES_TO_OUTPUT; - std::vector<double> trimmed_output_frames(output_frames_signal_start, output_frames_signal_end); + std::vector<double> trimmed_output_frames(output_frames_signal_start, + output_frames_signal_end); auto input_frames_signal_start = input_frames.begin() + phase; - auto input_frames_signal_end = input_frames.begin() + phase + NUM_FRAMES_TO_OUTPUT; - std::vector<double> trimmed_input_frames(input_frames_signal_start, input_frames_signal_end); + auto input_frames_signal_end = + input_frames.begin() + phase + NUM_FRAMES_TO_OUTPUT; + std::vector<double> trimmed_input_frames(input_frames_signal_start, + input_frames_signal_end); compare_signals(trimmed_output_frames, trimmed_input_frames); } |