/* * Copyright � 2017 Mozilla Foundation * * This program is made available under an ISC-style license. See the * accompanying file LICENSE for details.
*/
/* libcubeb api/function test. Test that different return values from user
specified callbacks are handled correctly. */ #include"gtest/gtest.h" #if !defined(_XOPEN_SOURCE) #define _XOPEN_SOURCE 600 #endif #include"cubeb/cubeb.h" #include <atomic> #include <memory> #include <string>
// Structure which is used by data callbacks to track the total callbacks // executed vs the number of callbacks expected. struct user_state_callback_ret {
std::atomic<int> cb_count{0};
std::atomic<int> expected_cb_count{0};
std::atomic<int> error_state{0};
};
// Data callback that always returns 0 long
data_cb_ret_zero(cubeb_stream * stream, void * user, constvoid * inputbuffer, void * outputbuffer, long nframes)
{
user_state_callback_ret * u = (user_state_callback_ret *)user; // If this is the first time the callback has been called set our expected // callback count if (u->cb_count == 0) {
u->expected_cb_count = 1;
}
u->cb_count++; if (nframes < 1) { // This shouldn't happen
EXPECT_TRUE(false) << "nframes should not be 0 in data callback!";
} return 0;
}
// Data callback that always returns nframes - 1 long
data_cb_ret_nframes_minus_one(cubeb_stream * stream, void * user, constvoid * inputbuffer, void * outputbuffer, long nframes)
{
user_state_callback_ret * u = (user_state_callback_ret *)user; // If this is the first time the callback has been called set our expected // callback count if (u->cb_count == 0) {
u->expected_cb_count = 1;
}
u->cb_count++; if (nframes < 1) { // This shouldn't happen
EXPECT_TRUE(false) << "nframes should not be 0 in data callback!";
} if (outputbuffer != NULL) { // If we have an output buffer insert silence short * ob = (short *)outputbuffer; for (long i = 0; i < nframes - 1; i++) {
ob[i] = 0;
}
} return nframes - 1;
}
// Data callback that always returns nframes long
data_cb_ret_nframes(cubeb_stream * stream, void * user, constvoid * inputbuffer, void * outputbuffer, long nframes)
{
user_state_callback_ret * u = (user_state_callback_ret *)user;
u->cb_count++; // Every callback returns nframes, so every callback is expected
u->expected_cb_count++; if (nframes < 1) { // This shouldn't happen
EXPECT_TRUE(false) << "nframes should not be 0 in data callback!";
} if (outputbuffer != NULL) { // If we have an output buffer insert silence short * ob = (short *)outputbuffer; for (long i = 0; i < nframes; i++) {
ob[i] = 0;
}
} return nframes;
}
// Data callback that always returns CUBEB_ERROR long
data_cb_ret_error(cubeb_stream * stream, void * user, constvoid * inputbuffer, void * outputbuffer, long nframes)
{
user_state_callback_ret * u = (user_state_callback_ret *)user; // If this is the first time the callback has been called set our expected // callback count if (u->cb_count == 0) {
u->expected_cb_count = 1;
}
u->cb_count++; if (nframes < 1) { // This shouldn't happen
EXPECT_TRUE(false) << "nframes should not be 0 in data callback!";
} return CUBEB_ERROR;
}
if ((direction == INPUT_ONLY || direction == DUPLEX) &&
!can_run_audio_input_test(ctx)) { /* This test needs an available input device, skip it if this host does not
* have one or if the backend doesn't implement input. */ return;
}
// Setup all params, but only pass them later as required by direction
input_params.format = SAMPLE_FORMAT;
input_params.rate = SAMPLE_FREQUENCY;
input_params.channels = 1;
input_params.layout = CUBEB_LAYOUT_MONO;
input_params.prefs = CUBEB_STREAM_PREF_NONE;
output_params = input_params;
r = cubeb_get_min_latency(ctx, &input_params, &latency_frames); if (r != CUBEB_OK) { // not fatal
latency_frames = 1024;
}
switch (direction) { case INPUT_ONLY:
r = cubeb_stream_init(ctx, &stream, "Cubeb callback ret input", NULL,
&input_params, NULL, NULL, latency_frames, data_cb,
state_cb_ret, &user_state); break; case OUTPUT_ONLY:
r = cubeb_stream_init(ctx, &stream, "Cubeb callback ret output", NULL, NULL,
NULL, &output_params, latency_frames, data_cb,
state_cb_ret, &user_state); break; case DUPLEX:
r = cubeb_stream_init(ctx, &stream, "Cubeb callback ret duplex", NULL,
&input_params, NULL, &output_params, latency_frames,
data_cb, state_cb_ret, &user_state); break; default:
ASSERT_TRUE(false) << "Unrecognized test direction!";
}
EXPECT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream";
ASSERT_EQ(user_state.expected_cb_count, user_state.cb_count)
<< "Callback called unexpected number of times for " << test_desc << "!"; // TODO: On some test configurations, the data_callback is never called. if (data_cb == data_cb_ret_error && user_state.cb_count != 0) {
ASSERT_EQ(user_state.error_state, 1) << "Callback expected error state";
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.