aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/test_loopback.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_loopback.cpp')
-rw-r--r--test/test_loopback.cpp323
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);
}