diff options
author | Paul Adenot <[email protected]> | 2016-02-05 14:05:39 +0100 |
---|---|---|
committer | Paul Adenot <[email protected]> | 2016-02-06 06:29:25 +0100 |
commit | 1af2676a0e211ff15c69170bd5bcdfa86b4af797 (patch) | |
tree | bdc509f32d5d50e41b0a92ba16d7fd856aae1468 /test/test_duplex.cpp | |
parent | 0def655163768ff1fc0990473ce79796451b3374 (diff) | |
download | cubeb-1af2676a0e211ff15c69170bd5bcdfa86b4af797.tar.gz cubeb-1af2676a0e211ff15c69170bd5bcdfa86b4af797.zip |
Add a test for duplex streams.
This simply checks we have (non-silent) input data with a duplex stream,
and copies it to the output, up-mixing it to stereo.
This allows the duplex code to be exercised with a real callback, but
could be more thorough. `test_resampler.cpp` unit tests the resamplers
so we should be somewhat safe nonetheless.
Diffstat (limited to 'test/test_duplex.cpp')
-rw-r--r-- | test/test_duplex.cpp | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/test/test_duplex.cpp b/test/test_duplex.cpp new file mode 100644 index 0000000..117fa36 --- /dev/null +++ b/test/test_duplex.cpp @@ -0,0 +1,137 @@ +/* + * Copyright © 2016 Mozilla Foundation + * + * This program is made available under an ISC-style license. See the + * accompanying file LICENSE for details. + */ + +/* libcubeb api/function test. Loops input back to output and check audio + * is flowing. */ +#ifdef NDEBUG +#undef NDEBUG +#endif +#define _XOPEN_SOURCE 500 +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <assert.h> + +#include "../include/cubeb/cubeb.h" +#include "common.h" +#ifdef CUBEB_GECKO_BUILD +#include "TestHarness.h" +#endif + +#define SAMPLE_FREQUENCY 48000 +#if (defined(_WIN32) || defined(__WIN32__)) +#define STREAM_FORMAT CUBEB_SAMPLE_FLOAT32LE +#else +#define STREAM_FORMAT CUBEB_SAMPLE_S16LE +#endif + +struct user_state +{ + bool seen_noise; +}; + +long data_cb(cubeb_stream *stream, void *user, const void * inputbuffer, void *outputbuffer, long nframes) +{ + user_state * u = reinterpret_cast<user_state*>(user); + float *ib = (float *)inputbuffer; + float *ob = (float *)outputbuffer; + bool seen_noise = false; + + if (stream == NULL || inputbuffer == NULL || outputbuffer == NULL) { + return CUBEB_ERROR; + } + + // Loop back: upmix the single input channel to the two output channels, + // checking if there is noise in the process. + long output_index = 0; + for (long i = 0; i < nframes; i++) { + if (ib[i] != 0.0) { + seen_noise = true; + } + ob[output_index] = ob[output_index + 1] = ib[i]; + output_index += 2; + } + + u->seen_noise |= seen_noise; + + return nframes; +} + +void state_cb(cubeb_stream *stream, void *user, cubeb_state state) +{ + if (stream == NULL) + return; + + switch (state) { + case CUBEB_STATE_STARTED: + printf("stream started\n"); break; + case CUBEB_STATE_STOPPED: + printf("stream stopped\n"); break; + case CUBEB_STATE_DRAINED: + printf("stream drained\n"); break; + default: + printf("unknown stream state %d\n", state); + } + + return; +} + +int main(int argc, char *argv[]) +{ +#ifdef CUBEB_GECKO_BUILD + ScopedXPCOM xpcom("test_record"); +#endif + + cubeb *ctx; + cubeb_stream *stream; + cubeb_stream_params input_params; + cubeb_stream_params output_params; + int r; + cubeb_device_collection * collection; + user_state stream_state = { false }; + uint32_t latency_ms = 0; + + r = cubeb_init(&ctx, "Cubeb duplex example"); + if (r != CUBEB_OK) { + fprintf(stderr, "Error initializing cubeb library\n"); + return r; + } + + /* typical user-case: mono input, stereo output, low latency. */ + input_params.format = CUBEB_SAMPLE_FLOAT32LE; + input_params.rate = 48000; + input_params.channels = 1; + output_params.format = CUBEB_SAMPLE_FLOAT32LE; + output_params.rate = 48000; + output_params.channels = 2; + + r = cubeb_get_min_latency(ctx, output_params, &latency_ms); + + if (r != CUBEB_OK) { + fprintf(stderr, "Could not get minimal latency\n"); + return r; + } + + r = cubeb_stream_init(ctx, &stream, "Cubeb duplex", + NULL, &input_params, NULL, &output_params, + latency_ms, data_cb, state_cb, &stream_state); + if (r != CUBEB_OK) { + fprintf(stderr, "Error initializing cubeb stream\n"); + return r; + } + + cubeb_stream_start(stream); + delay(500); + cubeb_stream_stop(stream); + + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); + + assert(stream_state.seen_noise); + + return CUBEB_OK; +} |