зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1314514 - Update libcubeb to 8bab182c. r=padenot
--HG-- rename : media/libcubeb/tests/common.h => media/libcubeb/gtest/common.h rename : media/libcubeb/tests/moz.build => media/libcubeb/gtest/moz.build rename : media/libcubeb/tests/test_audio.cpp => media/libcubeb/gtest/test_audio.cpp rename : media/libcubeb/tests/test_devices.cpp => media/libcubeb/gtest/test_devices.cpp rename : media/libcubeb/tests/test_duplex.cpp => media/libcubeb/gtest/test_duplex.cpp rename : media/libcubeb/tests/test_record.cpp => media/libcubeb/gtest/test_record.cpp rename : media/libcubeb/tests/test_resampler.cpp => media/libcubeb/gtest/test_resampler.cpp rename : media/libcubeb/tests/test_sanity.cpp => media/libcubeb/gtest/test_sanity.cpp rename : media/libcubeb/tests/test_tone.cpp => media/libcubeb/gtest/test_tone.cpp
This commit is contained in:
Родитель
c82aff30be
Коммит
2b9aa95d4c
|
@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
|
|||
|
||||
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
|
||||
|
||||
The git commit ID used was f8467510a8b36793b1b8b7e85461e2e189eb7015.
|
||||
The git commit ID used was 8bab182cd70ff66dec5bbecb69a69422f5d57647.
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#if !defined(TEST_COMMON)
|
||||
#define TEST_COMMON
|
||||
|
||||
#if defined( _WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
|
@ -59,3 +61,4 @@ int has_available_input_device(cubeb * ctx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif /* TEST_COMMON */
|
|
@ -4,26 +4,24 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES['CUBEB_GECKO_BUILD'] = True
|
||||
|
||||
GeckoCppUnitTests([
|
||||
'test_duplex',
|
||||
'test_record',
|
||||
'test_tone',
|
||||
'test_utils'
|
||||
])
|
||||
UNIFIED_SOURCES += [
|
||||
# 'test_duplex.cpp', # DISABLED: See bug 1314514.
|
||||
# 'test_record.cpp', # DISABLED: See bug 1314514.
|
||||
'test_tone.cpp',
|
||||
'test_utils.cpp'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_PULSEAUDIO'] or CONFIG['OS_TARGET'] in ('Darwin', 'WINNT', 'Android'):
|
||||
GeckoCppUnitTests([
|
||||
'test_resampler',
|
||||
])
|
||||
UNIFIED_SOURCES += [
|
||||
'test_resampler.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] != 'Android':
|
||||
GeckoCppUnitTests([
|
||||
'test_audio',
|
||||
'test_latency',
|
||||
'test_sanity'
|
||||
])
|
||||
UNIFIED_SOURCES += [
|
||||
'test_audio.cpp',
|
||||
'test_latency.cpp',
|
||||
'test_sanity.cpp'
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../include',
|
||||
|
@ -78,3 +76,5 @@ else:
|
|||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
|
||||
FINAL_LIBRARY = 'xul-gtest'
|
|
@ -7,21 +7,16 @@
|
|||
|
||||
/* libcubeb api/function exhaustive test. Plays a series of tones in different
|
||||
* conditions. */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include "gtest/gtest.h"
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
#include "TestHarness.h"
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_CHANNELS 32
|
||||
|
||||
|
@ -99,7 +94,7 @@ long data_cb_short(cubeb_stream * /*stream*/, void * user, const void * /*inputb
|
|||
return nframes;
|
||||
}
|
||||
|
||||
void state_cb(cubeb_stream * /*stream*/, void * /*user*/, cubeb_state /*state*/)
|
||||
void state_cb_audio(cubeb_stream * /*stream*/, void * /*user*/, cubeb_state /*state*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -161,7 +156,7 @@ int run_test(int num_channels, int sampling_rate, int is_float)
|
|||
}
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "test tone", NULL, NULL, NULL, ¶ms,
|
||||
4096, is_float ? data_cb_float : data_cb_short, state_cb, synth);
|
||||
4096, is_float ? data_cb_float : data_cb_short, state_cb_audio, synth);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream: %d\n", r);
|
||||
goto cleanup;
|
||||
|
@ -214,7 +209,7 @@ int run_panning_volume_test(int is_float)
|
|||
|
||||
r = cubeb_stream_init(ctx, &stream, "test tone", NULL, NULL, NULL, ¶ms,
|
||||
4096, is_float ? data_cb_float : data_cb_short,
|
||||
state_cb, synth);
|
||||
state_cb_audio, synth);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream: %d\n", r);
|
||||
goto cleanup;
|
||||
|
@ -252,7 +247,17 @@ cleanup:
|
|||
return r;
|
||||
}
|
||||
|
||||
void run_channel_rate_test()
|
||||
TEST(cubeb, run_panning_volume_test_short)
|
||||
{
|
||||
ASSERT_EQ(run_panning_volume_test(0), CUBEB_OK);
|
||||
}
|
||||
|
||||
TEST(cubeb, run_panning_volume_test_float)
|
||||
{
|
||||
ASSERT_EQ(run_panning_volume_test(1), CUBEB_OK);
|
||||
}
|
||||
|
||||
TEST(cubeb, run_channel_rate_test)
|
||||
{
|
||||
int channel_values[] = {
|
||||
1,
|
||||
|
@ -271,24 +276,11 @@ void run_channel_rate_test()
|
|||
|
||||
for(int j = 0; j < NELEMS(channel_values); ++j) {
|
||||
for(int i = 0; i < NELEMS(freq_values); ++i) {
|
||||
assert(channel_values[j] < MAX_NUM_CHANNELS);
|
||||
ASSERT_TRUE(channel_values[j] < MAX_NUM_CHANNELS);
|
||||
fprintf(stderr, "--------------------------\n");
|
||||
assert(run_test(channel_values[j], freq_values[i], 0) == CUBEB_OK);
|
||||
assert(run_test(channel_values[j], freq_values[i], 1) == CUBEB_OK);
|
||||
ASSERT_EQ(run_test(channel_values[j], freq_values[i], 0), CUBEB_OK);
|
||||
ASSERT_EQ(run_test(channel_values[j], freq_values[i], 1), CUBEB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int /*argc*/, char * /*argv*/[])
|
||||
{
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
ScopedXPCOM xpcom("test_audio");
|
||||
#endif
|
||||
|
||||
assert(run_panning_volume_test(0) == CUBEB_OK);
|
||||
assert(run_panning_volume_test(1) == CUBEB_OK);
|
||||
run_channel_rate_test();
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
|
@ -7,17 +7,12 @@
|
|||
|
||||
/* libcubeb enumerate device test/example.
|
||||
* Prints out a list of devices enumerated. */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
|
||||
|
||||
static void
|
||||
print_device_info(cubeb_device_info * info, FILE * f)
|
||||
{
|
||||
|
@ -89,14 +84,14 @@ print_device_info(cubeb_device_info * info, FILE * f)
|
|||
"\tCh: %u\n"
|
||||
"\tFormat: %s (0x%x) (default: %s)\n"
|
||||
"\tRate: %u - %u (default: %u)\n"
|
||||
"\tLatency: lo %ums, hi %ums\n",
|
||||
"\tLatency: lo %u frames, hi %u frames\n",
|
||||
info->device_id, info->preferred ? " (PREFERRED)" : "",
|
||||
info->friendly_name, info->group_id, info->vendor_name,
|
||||
devtype, devstate, info->max_channels,
|
||||
(devfmts[0] == ' ') ? &devfmts[1] : devfmts,
|
||||
(devfmts[0] == '\0') ? devfmts : devfmts + 1,
|
||||
(unsigned int)info->format, devdeffmt,
|
||||
info->min_rate, info->max_rate, info->default_rate,
|
||||
info->latency_lo_ms, info->latency_hi_ms);
|
||||
info->latency_lo, info->latency_hi);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -108,23 +103,28 @@ print_device_collection(cubeb_device_collection * collection, FILE * f)
|
|||
print_device_info(collection->device[i], f);
|
||||
}
|
||||
|
||||
static int
|
||||
run_enumerate_devices(void)
|
||||
TEST(cubeb, enumerate_devices)
|
||||
{
|
||||
int r = CUBEB_OK;
|
||||
int r;
|
||||
cubeb * ctx = NULL;
|
||||
cubeb_device_collection * collection = NULL;
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
fprintf(stdout, "Enumerating input devices for backend %s\n",
|
||||
cubeb_get_backend_id(ctx));
|
||||
|
||||
r = cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_INPUT, &collection);
|
||||
if (r == CUBEB_ERROR_NOT_SUPPORTED) {
|
||||
fprintf(stderr, "Device enumeration not supported"
|
||||
" for this backend, skipping this test.\n");
|
||||
r = CUBEB_OK;
|
||||
goto cleanup;
|
||||
}
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error enumerating devices %d\n", r);
|
||||
goto cleanup;
|
||||
|
@ -149,14 +149,6 @@ run_enumerate_devices(void)
|
|||
|
||||
cleanup:
|
||||
cubeb_destroy(ctx);
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = run_enumerate_devices();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -7,20 +7,15 @@
|
|||
|
||||
/* libcubeb api/function test. Loops input back to output and check audio
|
||||
* is flowing. */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include "gtest/gtest.h"
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
#include "TestHarness.h"
|
||||
#endif
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
|
@ -31,16 +26,14 @@
|
|||
#define SILENT_SAMPLE 0
|
||||
#endif
|
||||
|
||||
struct user_state
|
||||
struct user_state_duplex
|
||||
{
|
||||
bool seen_noise;
|
||||
};
|
||||
|
||||
|
||||
|
||||
long data_cb(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
long data_cb_duplex(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
{
|
||||
user_state * u = reinterpret_cast<user_state*>(user);
|
||||
user_state_duplex * u = reinterpret_cast<user_state_duplex*>(user);
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
float *ib = (float *)inputbuffer;
|
||||
float *ob = (float *)outputbuffer;
|
||||
|
@ -70,7 +63,7 @@ long data_cb(cubeb_stream * stream, void * user, const void * inputbuffer, void
|
|||
return nframes;
|
||||
}
|
||||
|
||||
void state_cb(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
||||
void state_cb_duplex(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
||||
{
|
||||
if (stream == NULL)
|
||||
return;
|
||||
|
@ -89,30 +82,26 @@ void state_cb(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
|||
return;
|
||||
}
|
||||
|
||||
int main(int /*argc*/, char * /*argv*/[])
|
||||
TEST(cubeb, duplex)
|
||||
{
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
ScopedXPCOM xpcom("test_duplex");
|
||||
#endif
|
||||
|
||||
cubeb *ctx;
|
||||
cubeb_stream *stream;
|
||||
cubeb_stream_params input_params;
|
||||
cubeb_stream_params output_params;
|
||||
int r;
|
||||
user_state stream_state = { false };
|
||||
user_state_duplex stream_state = { false };
|
||||
uint32_t latency_frames = 0;
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb duplex example");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
/* This test needs an available input device, skip it if this host does not
|
||||
* have one. */
|
||||
if (!has_available_input_device(ctx)) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* typical user-case: mono input, stereo output, low latency. */
|
||||
|
@ -127,15 +116,15 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Could not get minimal latency\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb duplex",
|
||||
NULL, &input_params, NULL, &output_params,
|
||||
latency_frames, data_cb, state_cb, &stream_state);
|
||||
latency_frames, data_cb_duplex, state_cb_duplex, &stream_state);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
cubeb_stream_start(stream);
|
||||
|
@ -145,7 +134,5 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
cubeb_stream_destroy(stream);
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
assert(stream_state.seen_noise);
|
||||
|
||||
return CUBEB_OK;
|
||||
ASSERT_TRUE(stream_state.seen_noise);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#include "gtest/gtest.h"
|
||||
#include <stdlib.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
|
||||
TEST(cubeb, latency)
|
||||
{
|
||||
cubeb * ctx = NULL;
|
||||
int r;
|
||||
uint32_t max_channels;
|
||||
uint32_t preferred_rate;
|
||||
uint32_t latency_frames;
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
|
||||
r = cubeb_get_max_channel_count(ctx, &max_channels);
|
||||
ASSERT_TRUE(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
ASSERT_GT(max_channels, 0u);
|
||||
}
|
||||
|
||||
r = cubeb_get_preferred_sample_rate(ctx, &preferred_rate);
|
||||
ASSERT_TRUE(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
ASSERT_GT(preferred_rate, 0u);
|
||||
}
|
||||
|
||||
cubeb_stream_params params = {
|
||||
CUBEB_SAMPLE_FLOAT32NE,
|
||||
preferred_rate,
|
||||
max_channels
|
||||
};
|
||||
r = cubeb_get_min_latency(ctx, params, &latency_frames);
|
||||
ASSERT_TRUE(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
ASSERT_GT(latency_frames, 0u);
|
||||
}
|
||||
|
||||
cubeb_destroy(ctx);
|
||||
}
|
|
@ -6,20 +6,15 @@
|
|||
*/
|
||||
|
||||
/* libcubeb api/function test. Record the mic and check there is sound. */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include "gtest/gtest.h"
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
#include "TestHarness.h"
|
||||
#endif
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
|
@ -28,14 +23,14 @@
|
|||
#define STREAM_FORMAT CUBEB_SAMPLE_S16LE
|
||||
#endif
|
||||
|
||||
struct user_state
|
||||
struct user_state_record
|
||||
{
|
||||
bool seen_noise;
|
||||
};
|
||||
|
||||
long data_cb(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
long data_cb_record(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
{
|
||||
user_state * u = reinterpret_cast<user_state*>(user);
|
||||
user_state_record * u = reinterpret_cast<user_state_record*>(user);
|
||||
#if STREAM_FORMAT != CUBEB_SAMPLE_FLOAT32LE
|
||||
short *b = (short *)inputbuffer;
|
||||
#else
|
||||
|
@ -58,7 +53,7 @@ long data_cb(cubeb_stream * stream, void * user, const void * inputbuffer, void
|
|||
return nframes;
|
||||
}
|
||||
|
||||
void state_cb(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
||||
void state_cb_record(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
||||
{
|
||||
if (stream == NULL)
|
||||
return;
|
||||
|
@ -77,28 +72,24 @@ void state_cb(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
|||
return;
|
||||
}
|
||||
|
||||
int main(int /*argc*/, char * /*argv*/[])
|
||||
TEST(cubeb, record)
|
||||
{
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
ScopedXPCOM xpcom("test_record");
|
||||
#endif
|
||||
|
||||
cubeb *ctx;
|
||||
cubeb_stream *stream;
|
||||
cubeb_stream_params params;
|
||||
int r;
|
||||
user_state stream_state = { false };
|
||||
user_state_record stream_state = { false };
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb record example");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
/* This test needs an available input device, skip it if this host does not
|
||||
* have one. */
|
||||
if (!has_available_input_device(ctx)) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
|
@ -106,10 +97,10 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
params.channels = 1;
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb record (mono)", NULL, ¶ms, NULL, nullptr,
|
||||
4096, data_cb, state_cb, &stream_state);
|
||||
4096, data_cb_record, state_cb_record, &stream_state);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
cubeb_stream_start(stream);
|
||||
|
@ -119,7 +110,5 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
cubeb_stream_destroy(stream);
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
assert(stream_state.seen_noise);
|
||||
|
||||
return CUBEB_OK;
|
||||
ASSERT_TRUE(stream_state.seen_noise);
|
||||
}
|
|
@ -7,12 +7,8 @@
|
|||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif // NOMINMAX
|
||||
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include "gtest/gtest.h"
|
||||
#include "cubeb_resampler_internal.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
@ -154,7 +150,7 @@ void test_delay_lines(uint32_t delay_frames, uint32_t channels, uint32_t chunk_m
|
|||
|
||||
// Check the diracs have been shifted by `delay_frames` frames.
|
||||
for (uint32_t i = 0; i < output.length() - delay_frames * channels + 1; i+=100) {
|
||||
assert(output.data()[i + channel + delay_frames * channels] == 0.5);
|
||||
ASSERT_EQ(output.data()[i + channel + delay_frames * channels], 0.5);
|
||||
channel = (channel + 1) % channels;
|
||||
}
|
||||
|
||||
|
@ -232,7 +228,7 @@ void test_resampler_one_way(uint32_t channels, uint32_t source_rate, uint32_t ta
|
|||
fuzzy_equal = false;
|
||||
}
|
||||
}
|
||||
assert(fuzzy_equal);
|
||||
ASSERT_TRUE(fuzzy_equal);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -283,7 +279,7 @@ uint32_t fill_with_sine(float * buf, uint32_t rate, uint32_t channels,
|
|||
return initial_phase;
|
||||
}
|
||||
|
||||
long data_cb(cubeb_stream * /*stm*/, void * user_ptr,
|
||||
long data_cb_resampler(cubeb_stream * /*stm*/, void * user_ptr,
|
||||
const void * input_buffer, void * output_buffer, long frame_count)
|
||||
{
|
||||
osc_state * state = reinterpret_cast<osc_state*>(user_ptr);
|
||||
|
@ -341,7 +337,7 @@ void test_resampler_duplex(uint32_t input_channels, uint32_t output_channels,
|
|||
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, &input_params, &output_params, target_rate,
|
||||
data_cb, (void*)&state, CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
data_cb_resampler, (void*)&state, CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
long latency = cubeb_resampler_latency(resampler);
|
||||
|
||||
|
@ -397,15 +393,15 @@ void test_resampler_duplex(uint32_t input_channels, uint32_t output_channels,
|
|||
dump("input.raw", state.input.data(), state.input.length());
|
||||
dump("output.raw", state.output.data(), state.output.length());
|
||||
|
||||
assert(array_fuzzy_equal(state.input, expected_resampled_input, epsilon<T>(input_rate/target_rate)));
|
||||
assert(array_fuzzy_equal(state.output, expected_resampled_output, epsilon<T>(output_rate/target_rate)));
|
||||
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);
|
||||
}
|
||||
|
||||
#define array_size(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
void test_resamplers_one_way()
|
||||
TEST(cubeb, resampler_one_way)
|
||||
{
|
||||
/* Test one way resamplers */
|
||||
for (uint32_t channels = 1; channels <= max_channels; channels++) {
|
||||
|
@ -422,9 +418,11 @@ void test_resamplers_one_way()
|
|||
}
|
||||
}
|
||||
|
||||
void test_resamplers_duplex()
|
||||
// This is disabled because the latency estimation in the resampler code is
|
||||
// slightly off so we can generate expected vectors.
|
||||
// See https://github.com/kinetiknz/cubeb/issues/93
|
||||
TEST(cubeb, DISABLED_resampler_duplex)
|
||||
{
|
||||
/* Test duplex resamplers */
|
||||
for (uint32_t input_channels = 1; input_channels <= max_channels; input_channels++) {
|
||||
for (uint32_t output_channels = 1; output_channels <= max_channels; output_channels++) {
|
||||
for (uint32_t source_rate_input = 0; source_rate_input < array_size(sample_rates); source_rate_input++) {
|
||||
|
@ -451,7 +449,7 @@ void test_resamplers_duplex()
|
|||
}
|
||||
}
|
||||
|
||||
void test_delay_line()
|
||||
TEST(cubeb, resampler_delay_line)
|
||||
{
|
||||
for (uint32_t channel = 1; channel <= 2; channel++) {
|
||||
for (uint32_t delay_frames = 4; delay_frames <= 40; delay_frames+=chunk_increment) {
|
||||
|
@ -468,12 +466,12 @@ long test_output_only_noop_data_cb(cubeb_stream * /*stm*/, void * /*user_ptr*/,
|
|||
const void * input_buffer,
|
||||
void * output_buffer, long frame_count)
|
||||
{
|
||||
assert(output_buffer);
|
||||
assert(!input_buffer);
|
||||
EXPECT_TRUE(output_buffer);
|
||||
EXPECT_TRUE(!input_buffer);
|
||||
return frame_count;
|
||||
}
|
||||
|
||||
void test_output_only_noop()
|
||||
TEST(cubeb, resampler_output_only_noop)
|
||||
{
|
||||
cubeb_stream_params output_params;
|
||||
int target_rate;
|
||||
|
@ -495,7 +493,7 @@ void test_output_only_noop()
|
|||
got = cubeb_resampler_fill(resampler, nullptr, nullptr,
|
||||
out_buffer, out_frames);
|
||||
|
||||
assert(got == out_frames);
|
||||
ASSERT_EQ(got, out_frames);
|
||||
|
||||
cubeb_resampler_destroy(resampler);
|
||||
}
|
||||
|
@ -504,12 +502,12 @@ long test_drain_data_cb(cubeb_stream * /*stm*/, void * /*user_ptr*/,
|
|||
const void * input_buffer,
|
||||
void * output_buffer, long frame_count)
|
||||
{
|
||||
assert(output_buffer);
|
||||
assert(!input_buffer);
|
||||
EXPECT_TRUE(output_buffer);
|
||||
EXPECT_TRUE(!input_buffer);
|
||||
return frame_count - 10;
|
||||
}
|
||||
|
||||
void test_resampler_drain()
|
||||
TEST(cubeb, resampler_drain)
|
||||
{
|
||||
cubeb_stream_params output_params;
|
||||
int target_rate;
|
||||
|
@ -535,20 +533,8 @@ void test_resampler_drain()
|
|||
|
||||
/* If the above is not an infinite loop, the drain was a success, just mark
|
||||
* this test as such. */
|
||||
assert(true);
|
||||
ASSERT_TRUE(true);
|
||||
|
||||
cubeb_resampler_destroy(resampler);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_resamplers_one_way();
|
||||
test_delay_line();
|
||||
// This is disabled because the latency estimation in the resampler code is
|
||||
// slightly off so we can generate expected vectors.
|
||||
// test_resamplers_duplex();
|
||||
test_output_only_noop();
|
||||
test_resampler_drain();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#include "gtest/gtest.h"
|
||||
#ifdef __APPLE__
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb_ring_array.h"
|
||||
|
||||
TEST(cubeb, ring_array)
|
||||
{
|
||||
ring_array ra;
|
||||
|
||||
ASSERT_EQ(ring_array_init(&ra, 0, 0, 1, 1), CUBEB_ERROR_INVALID_PARAMETER);
|
||||
ASSERT_EQ(ring_array_init(&ra, 1, 0, 0, 1), CUBEB_ERROR_INVALID_PARAMETER);
|
||||
|
||||
unsigned int capacity = 8;
|
||||
ring_array_init(&ra, capacity, sizeof(int), 1, 1);
|
||||
int verify_data[capacity] ;// {1,2,3,4,5,6,7,8};
|
||||
AudioBuffer * p_data = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < capacity; ++i) {
|
||||
verify_data[i] = i; // in case capacity change value
|
||||
*(int*)ra.buffer_array[i].mData = i;
|
||||
ASSERT_EQ(ra.buffer_array[i].mDataByteSize, sizeof(int));
|
||||
ASSERT_EQ(ra.buffer_array[i].mNumberChannels, 1u);
|
||||
}
|
||||
|
||||
/* Get store buffers*/
|
||||
for (unsigned int i = 0; i < capacity; ++i) {
|
||||
p_data = ring_array_get_free_buffer(&ra);
|
||||
ASSERT_NE(p_data, nullptr);
|
||||
ASSERT_EQ(*(int*)p_data->mData, verify_data[i]);
|
||||
}
|
||||
/*Now array is full extra store should give NULL*/
|
||||
ASSERT_EQ(ring_array_get_free_buffer(&ra), nullptr);
|
||||
/* Get fetch buffers*/
|
||||
for (unsigned int i = 0; i < capacity; ++i) {
|
||||
p_data = ring_array_get_data_buffer(&ra);
|
||||
ASSERT_NE(p_data, nullptr);
|
||||
ASSERT_EQ(*(int*)p_data->mData, verify_data[i]);
|
||||
}
|
||||
/*Now array is empty extra fetch should give NULL*/
|
||||
ASSERT_EQ(ring_array_get_data_buffer(&ra), nullptr);
|
||||
|
||||
p_data = NULL;
|
||||
/* Repeated store fetch should can go for ever*/
|
||||
for (unsigned int i = 0; i < 2*capacity; ++i) {
|
||||
p_data = ring_array_get_free_buffer(&ra);
|
||||
ASSERT_NE(p_data, nullptr);
|
||||
ASSERT_EQ(ring_array_get_data_buffer(&ra), p_data);
|
||||
}
|
||||
|
||||
p_data = NULL;
|
||||
/* Verify/modify buffer data*/
|
||||
for (unsigned int i = 0; i < capacity; ++i) {
|
||||
p_data = ring_array_get_free_buffer(&ra);
|
||||
ASSERT_NE(p_data, nullptr);
|
||||
ASSERT_EQ(*((int*)p_data->mData), verify_data[i]);
|
||||
(*((int*)p_data->mData))++; // Modify data
|
||||
}
|
||||
for (unsigned int i = 0; i < capacity; ++i) {
|
||||
p_data = ring_array_get_data_buffer(&ra);
|
||||
ASSERT_NE(p_data, nullptr);
|
||||
ASSERT_EQ(*((int*)p_data->mData), verify_data[i]+1); // Verify modified data
|
||||
}
|
||||
|
||||
ring_array_destroy(&ra);
|
||||
}
|
||||
#else
|
||||
TEST(cubeb, DISABLED_ring_array)
|
||||
{
|
||||
}
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -6,21 +6,16 @@
|
|||
*/
|
||||
|
||||
/* libcubeb api/function test. Plays a simple tone. */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include "gtest/gtest.h"
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
#include "TestHarness.h"
|
||||
#endif
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
|
@ -34,7 +29,7 @@ struct cb_user_data {
|
|||
long position;
|
||||
};
|
||||
|
||||
long data_cb(cubeb_stream *stream, void *user, const void* /*inputbuffer*/, void *outputbuffer, long nframes)
|
||||
long data_cb_tone(cubeb_stream *stream, void *user, const void* /*inputbuffer*/, void *outputbuffer, long nframes)
|
||||
{
|
||||
struct cb_user_data *u = (struct cb_user_data *)user;
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
|
@ -77,7 +72,7 @@ long data_cb(cubeb_stream *stream, void *user, const void* /*inputbuffer*/, void
|
|||
return nframes;
|
||||
}
|
||||
|
||||
void state_cb(cubeb_stream *stream, void *user, cubeb_state state)
|
||||
void state_cb_tone(cubeb_stream *stream, void *user, cubeb_state state)
|
||||
{
|
||||
struct cb_user_data *u = (struct cb_user_data *)user;
|
||||
|
||||
|
@ -98,12 +93,8 @@ void state_cb(cubeb_stream *stream, void *user, cubeb_state state)
|
|||
return;
|
||||
}
|
||||
|
||||
int main(int /*argc*/, char * /*argv*/[])
|
||||
TEST(cubeb, tone)
|
||||
{
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
ScopedXPCOM xpcom("test_tone");
|
||||
#endif
|
||||
|
||||
cubeb *ctx;
|
||||
cubeb_stream *stream;
|
||||
cubeb_stream_params params;
|
||||
|
@ -113,7 +104,7 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
r = cubeb_init(&ctx, "Cubeb tone example");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
|
@ -123,15 +114,15 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
user_data = (struct cb_user_data *) malloc(sizeof(*user_data));
|
||||
if (user_data == NULL) {
|
||||
fprintf(stderr, "Error allocating user data\n");
|
||||
return CUBEB_ERROR;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
user_data->position = 0;
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", NULL, NULL, NULL, ¶ms,
|
||||
4096, data_cb, state_cb, user_data);
|
||||
4096, data_cb_tone, state_cb_tone, user_data);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream\n");
|
||||
return r;
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
cubeb_stream_start(stream);
|
||||
|
@ -141,9 +132,7 @@ int main(int /*argc*/, char * /*argv*/[])
|
|||
cubeb_stream_destroy(stream);
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
assert(user_data->position);
|
||||
ASSERT_TRUE(user_data->position);
|
||||
|
||||
free(user_data);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#include "gtest/gtest.h"
|
||||
#include "cubeb_utils.h"
|
||||
|
||||
TEST(cubeb, auto_array)
|
||||
{
|
||||
auto_array<uint32_t> array;
|
||||
auto_array<uint32_t> array2(10);
|
||||
uint32_t a[10];
|
||||
|
||||
ASSERT_EQ(array2.length(), 0u);
|
||||
ASSERT_EQ(array2.capacity(), 10u);
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
a[i] = i;
|
||||
}
|
||||
|
||||
ASSERT_EQ(array.capacity(), 0u);
|
||||
ASSERT_EQ(array.length(), 0u);
|
||||
|
||||
array.push(a, 10);
|
||||
|
||||
ASSERT_TRUE(!array.reserve(9));
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
ASSERT_EQ(array.data()[i], i);
|
||||
}
|
||||
|
||||
ASSERT_EQ(array.capacity(), 10u);
|
||||
ASSERT_EQ(array.length(), 10u);
|
||||
|
||||
uint32_t b[10];
|
||||
|
||||
array.pop(b, 5);
|
||||
|
||||
ASSERT_EQ(array.capacity(), 10u);
|
||||
ASSERT_EQ(array.length(), 5u);
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
ASSERT_EQ(b[i], i);
|
||||
ASSERT_EQ(array.data()[i], 5 + i);
|
||||
}
|
||||
uint32_t* bb = b + 5;
|
||||
array.pop(bb, 5);
|
||||
|
||||
ASSERT_EQ(array.capacity(), 10u);
|
||||
ASSERT_EQ(array.length(), 0u);
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
ASSERT_EQ(bb[i], 5 + i);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(!array.pop(nullptr, 1));
|
||||
|
||||
array.push(a, 10);
|
||||
array.push(a, 10);
|
||||
|
||||
for (uint32_t j = 0; j < 2; j++) {
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
ASSERT_EQ(array.data()[10 * j + i], i);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(array.length(), 20u);
|
||||
ASSERT_EQ(array.capacity(), 20u);
|
||||
array.pop(nullptr, 5);
|
||||
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
ASSERT_EQ(array.data()[i], 5 + i);
|
||||
}
|
||||
|
||||
ASSERT_EQ(array.length(), 15u);
|
||||
ASSERT_EQ(array.capacity(), 20u);
|
||||
}
|
||||
|
|
@ -167,7 +167,7 @@ typedef enum {
|
|||
|
||||
/** An opaque handle used to refer a particular input or output device
|
||||
* across calls. */
|
||||
typedef void * cubeb_devid;
|
||||
typedef void const * cubeb_devid;
|
||||
|
||||
/** Level (verbosity) of logging for a particular cubeb context. */
|
||||
typedef enum {
|
||||
|
@ -276,10 +276,10 @@ typedef enum {
|
|||
* `cubeb_device_info_destroy`. */
|
||||
typedef struct {
|
||||
cubeb_devid devid; /**< Device identifier handle. */
|
||||
char * device_id; /**< Device identifier which might be presented in a UI. */
|
||||
char * friendly_name; /**< Friendly device name which might be presented in a UI. */
|
||||
char * group_id; /**< Two devices have the same group identifier if they belong to the same physical device; for example a headset and microphone. */
|
||||
char * vendor_name; /**< Optional vendor name, may be NULL. */
|
||||
char const * device_id; /**< Device identifier which might be presented in a UI. */
|
||||
char const * friendly_name; /**< Friendly device name which might be presented in a UI. */
|
||||
char const * group_id; /**< Two devices have the same group identifier if they belong to the same physical device; for example a headset and microphone. */
|
||||
char const * vendor_name; /**< Optional vendor name, may be NULL. */
|
||||
|
||||
cubeb_device_type type; /**< Type of device (Input/Output). */
|
||||
cubeb_device_state state; /**< State of device disabled/enabled/unplugged. */
|
||||
|
@ -322,7 +322,7 @@ typedef struct {
|
|||
and the stream will enter a shutdown state. */
|
||||
typedef long (* cubeb_data_callback)(cubeb_stream * stream,
|
||||
void * user_ptr,
|
||||
const void * input_buffer,
|
||||
void const * input_buffer,
|
||||
void * output_buffer,
|
||||
long nframes);
|
||||
|
||||
|
@ -347,7 +347,7 @@ typedef void (* cubeb_device_collection_changed_callback)(cubeb * context,
|
|||
void * user_ptr);
|
||||
|
||||
/** User supplied callback called when a message needs logging. */
|
||||
typedef void (* cubeb_log_callback)(const char * fmt, ...);
|
||||
typedef void (* cubeb_log_callback)(char const * fmt, ...);
|
||||
|
||||
/** Initialize an application context. This will perform any library or
|
||||
application scoped initialization.
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += ['include', 'src']
|
||||
TEST_DIRS += ['tests']
|
||||
TEST_DIRS += ['gtest']
|
||||
|
||||
|
|
|
@ -514,10 +514,10 @@ int cubeb_device_info_destroy(cubeb_device_info * info)
|
|||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
free(info->device_id);
|
||||
free(info->friendly_name);
|
||||
free(info->group_id);
|
||||
free(info->vendor_name);
|
||||
free((void *) info->device_id);
|
||||
free((void *) info->friendly_name);
|
||||
free((void *) info->group_id);
|
||||
free((void *) info->vendor_name);
|
||||
|
||||
free(info);
|
||||
return CUBEB_OK;
|
||||
|
|
|
@ -168,9 +168,9 @@ struct cubeb_stream {
|
|||
/* Stream creation parameters */
|
||||
cubeb_stream_params input_stream_params;
|
||||
cubeb_stream_params output_stream_params;
|
||||
cubeb_devid input_device;
|
||||
bool is_default_input;
|
||||
cubeb_devid output_device;
|
||||
AudioDeviceID input_device;
|
||||
AudioDeviceID output_device;
|
||||
/* User pointer of data_callback */
|
||||
void * user_ptr;
|
||||
/* Format descriptions */
|
||||
|
@ -192,7 +192,7 @@ struct cubeb_stream {
|
|||
/* Frames on input buffer */
|
||||
std::atomic<uint32_t> input_buffer_frames;
|
||||
/* Frame counters */
|
||||
uint64_t frames_played;
|
||||
std::atomic<uint64_t> frames_played;
|
||||
uint64_t frames_queued;
|
||||
std::atomic<int64_t> frames_read;
|
||||
std::atomic<bool> shutdown;
|
||||
|
@ -601,13 +601,13 @@ audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_coun
|
|||
case kAudioHardwarePropertyDefaultOutputDevice: {
|
||||
LOG("Event[%d] - mSelector == kAudioHardwarePropertyDefaultOutputDevice", i);
|
||||
// Allow restart to choose the new default
|
||||
stm->output_device = nullptr;
|
||||
stm->output_device = 0;
|
||||
}
|
||||
break;
|
||||
case kAudioHardwarePropertyDefaultInputDevice: {
|
||||
LOG("Event[%d] - mSelector == kAudioHardwarePropertyDefaultInputDevice", i);
|
||||
// Allow restart to choose the new default
|
||||
stm->input_device = nullptr;
|
||||
stm->input_device = 0;
|
||||
}
|
||||
break;
|
||||
case kAudioDevicePropertyDeviceIsAlive: {
|
||||
|
@ -619,7 +619,7 @@ audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_coun
|
|||
return noErr;
|
||||
}
|
||||
// Allow restart to choose the new default. Event register only for input.
|
||||
stm->input_device = nullptr;
|
||||
stm->input_device = 0;
|
||||
}
|
||||
break;
|
||||
case kAudioDevicePropertyDataSource:
|
||||
|
@ -758,7 +758,7 @@ audiounit_install_device_changed_callback(cubeb_stream * stm)
|
|||
}
|
||||
|
||||
/* Event to notify when the input is going away. */
|
||||
AudioDeviceID dev = stm->input_device ? reinterpret_cast<intptr_t>(stm->input_device) :
|
||||
AudioDeviceID dev = stm->input_device ? stm->input_device :
|
||||
audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
|
||||
r = audiounit_add_listener(stm, dev, kAudioDevicePropertyDeviceIsAlive,
|
||||
kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
|
||||
|
@ -1043,7 +1043,7 @@ static int
|
|||
audiounit_create_unit(AudioUnit * unit,
|
||||
bool is_input,
|
||||
const cubeb_stream_params * /* stream_params */,
|
||||
cubeb_devid device)
|
||||
AudioDeviceID device)
|
||||
{
|
||||
AudioComponentDescription desc;
|
||||
AudioComponent comp;
|
||||
|
@ -1060,7 +1060,7 @@ audiounit_create_unit(AudioUnit * unit,
|
|||
// so we retain automatic output device switching when the default
|
||||
// changes. Once we have complete support for device notifications
|
||||
// and switching, we can use the AUHAL for everything.
|
||||
bool use_default_output = device == NULL && !is_input;
|
||||
bool use_default_output = device == 0 && !is_input;
|
||||
if (use_default_output) {
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
} else {
|
||||
|
@ -1101,11 +1101,11 @@ audiounit_create_unit(AudioUnit * unit,
|
|||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
if (device == 0) {
|
||||
assert(is_input);
|
||||
devid = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
|
||||
} else {
|
||||
devid = reinterpret_cast<intptr_t>(device);
|
||||
devid = device;
|
||||
}
|
||||
rv = AudioUnitSetProperty(*unit, kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global,
|
||||
|
@ -1560,14 +1560,13 @@ audiounit_stream_init(cubeb * context,
|
|||
stm->device_changed_callback = NULL;
|
||||
if (input_stream_params) {
|
||||
stm->input_stream_params = *input_stream_params;
|
||||
stm->input_device = input_device;
|
||||
stm->is_default_input = input_device == nullptr ||
|
||||
(audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT) ==
|
||||
reinterpret_cast<intptr_t>(input_device));
|
||||
stm->input_device = reinterpret_cast<uintptr_t>(input_device);
|
||||
stm->is_default_input = stm->input_device == 0 ||
|
||||
(audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT) == stm->input_device);
|
||||
}
|
||||
if (output_stream_params) {
|
||||
stm->output_stream_params = *output_stream_params;
|
||||
stm->output_device = output_device;
|
||||
stm->output_device = reinterpret_cast<uintptr_t>(output_device);
|
||||
}
|
||||
|
||||
/* Init data members where necessary */
|
||||
|
@ -1821,7 +1820,7 @@ int audiounit_stream_set_panning(cubeb_stream * stm, float panning)
|
|||
}
|
||||
|
||||
int audiounit_stream_get_current_device(cubeb_stream * stm,
|
||||
cubeb_device ** const device)
|
||||
cubeb_device ** const device)
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
//TODO
|
||||
|
@ -2111,7 +2110,8 @@ audiounit_create_device_from_hwdev(AudioObjectID devid, cubeb_device_type type)
|
|||
adr.mSelector = kAudioDevicePropertyDeviceUID;
|
||||
if (AudioObjectGetPropertyData(devid, &adr, 0, NULL, &size, &str) == noErr && str != NULL) {
|
||||
ret->device_id = audiounit_strref_to_cstr_utf8(str);
|
||||
ret->devid = (cubeb_devid)(size_t)devid;
|
||||
static_assert(sizeof(cubeb_devid) >= sizeof(decltype(devid)), "cubeb_devid can't represent devid");
|
||||
ret->devid = reinterpret_cast<cubeb_devid>(devid);
|
||||
ret->group_id = strdup(ret->device_id);
|
||||
CFRelease(str);
|
||||
}
|
||||
|
|
|
@ -993,9 +993,9 @@ cbjack_enumerate_devices(cubeb * context, cubeb_device_type type,
|
|||
const char * j_out = "JACK playback";
|
||||
|
||||
if (type & CUBEB_DEVICE_TYPE_OUTPUT) {
|
||||
context->devinfo[i] = (cubeb_device_info *)malloc(sizeof(cubeb_device_info));
|
||||
context->devinfo[i] = (cubeb_device_info *) malloc(sizeof(cubeb_device_info));
|
||||
context->devinfo[i]->device_id = strdup(j_out);
|
||||
context->devinfo[i]->devid = context->devinfo[i]->device_id;
|
||||
context->devinfo[i]->devid = (cubeb_devid) context->devinfo[i]->device_id;
|
||||
context->devinfo[i]->friendly_name = strdup(j_out);
|
||||
context->devinfo[i]->group_id = strdup(j_out);
|
||||
context->devinfo[i]->vendor_name = strdup(j_out);
|
||||
|
@ -1014,9 +1014,9 @@ cbjack_enumerate_devices(cubeb * context, cubeb_device_type type,
|
|||
}
|
||||
|
||||
if (type & CUBEB_DEVICE_TYPE_INPUT) {
|
||||
context->devinfo[i] = (cubeb_device_info *)malloc(sizeof(cubeb_device_info));
|
||||
context->devinfo[i] = (cubeb_device_info *) malloc(sizeof(cubeb_device_info));
|
||||
context->devinfo[i]->device_id = strdup(j_in);
|
||||
context->devinfo[i]->devid = context->devinfo[i]->device_id;
|
||||
context->devinfo[i]->devid = (cubeb_devid) context->devinfo[i]->device_id;
|
||||
context->devinfo[i]->friendly_name = strdup(j_in);
|
||||
context->devinfo[i]->group_id = strdup(j_in);
|
||||
context->devinfo[i]->vendor_name = strdup(j_in);
|
||||
|
|
|
@ -181,9 +181,9 @@ static void
|
|||
stream_drain_callback(pa_mainloop_api * a, pa_time_event * e, struct timeval const * tv, void * u)
|
||||
{
|
||||
(void)a;
|
||||
(void)e;
|
||||
(void)tv;
|
||||
cubeb_stream * stm = u;
|
||||
assert(stm->drain_timer == e);
|
||||
stream_state_change_callback(stm, CUBEB_STATE_DRAINED);
|
||||
/* there's no pa_rttime_free, so use this instead. */
|
||||
a->time_free(stm->drain_timer);
|
||||
|
@ -267,6 +267,7 @@ trigger_user_callback(pa_stream * s, void const * input_data, size_t nbytes, cub
|
|||
assert(r == 0 || r == -PA_ERR_NODATA);
|
||||
/* pa_stream_drain is useless, see PA bug# 866. this is a workaround. */
|
||||
/* arbitrary safety margin: double the current latency. */
|
||||
assert(!stm->drain_timer);
|
||||
stm->drain_timer = WRAP(pa_context_rttime_new)(stm->context->context, WRAP(pa_rtclock_now)() + 2 * latency, stream_drain_callback, stm);
|
||||
stm->shutdown = 1;
|
||||
return;
|
||||
|
@ -752,7 +753,7 @@ pulse_stream_init(cubeb * context,
|
|||
|
||||
battr = set_buffering_attribute(latency_frames, &stm->output_sample_spec);
|
||||
WRAP(pa_stream_connect_playback)(stm->output_stream,
|
||||
output_device,
|
||||
(char const *) output_device,
|
||||
&battr,
|
||||
PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING |
|
||||
PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY,
|
||||
|
@ -775,7 +776,7 @@ pulse_stream_init(cubeb * context,
|
|||
|
||||
battr = set_buffering_attribute(latency_frames, &stm->input_sample_spec);
|
||||
WRAP(pa_stream_connect_record)(stm->input_stream,
|
||||
input_device,
|
||||
(char const *) input_device,
|
||||
&battr,
|
||||
PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING |
|
||||
PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY);
|
||||
|
@ -851,6 +852,9 @@ pulse_defer_event_cb(pa_mainloop_api * a, void * userdata)
|
|||
{
|
||||
(void)a;
|
||||
cubeb_stream * stm = userdata;
|
||||
if (stm->shutdown) {
|
||||
return;
|
||||
}
|
||||
size_t writable_size = WRAP(pa_stream_writable_size)(stm->output_stream);
|
||||
trigger_user_callback(stm->output_stream, NULL, writable_size, stm);
|
||||
}
|
||||
|
@ -1070,7 +1074,7 @@ pulse_get_state_from_sink_port(pa_sink_port_info * info)
|
|||
|
||||
static void
|
||||
pulse_sink_info_cb(pa_context * context, const pa_sink_info * info,
|
||||
int eol, void * user_data)
|
||||
int eol, void * user_data)
|
||||
{
|
||||
pulse_dev_list_data * list_data = user_data;
|
||||
cubeb_device_info * devinfo;
|
||||
|
@ -1084,7 +1088,7 @@ pulse_sink_info_cb(pa_context * context, const pa_sink_info * info,
|
|||
devinfo = calloc(1, sizeof(cubeb_device_info));
|
||||
|
||||
devinfo->device_id = strdup(info->name);
|
||||
devinfo->devid = devinfo->device_id;
|
||||
devinfo->devid = (cubeb_devid) devinfo->device_id;
|
||||
devinfo->friendly_name = strdup(info->description);
|
||||
prop = WRAP(pa_proplist_gets)(info->proplist, "sysfs.path");
|
||||
if (prop)
|
||||
|
@ -1144,7 +1148,7 @@ pulse_source_info_cb(pa_context * context, const pa_source_info * info,
|
|||
devinfo = calloc(1, sizeof(cubeb_device_info));
|
||||
|
||||
devinfo->device_id = strdup(info->name);
|
||||
devinfo->devid = devinfo->device_id;
|
||||
devinfo->devid = (cubeb_devid) devinfo->device_id;
|
||||
devinfo->friendly_name = strdup(info->description);
|
||||
prop = WRAP(pa_proplist_gets)(info->proplist, "sysfs.path");
|
||||
if (prop)
|
||||
|
|
|
@ -263,9 +263,15 @@ public:
|
|||
* number of output frames will be exactly equal. */
|
||||
uint32_t input_needed_for_output(uint32_t output_frame_count)
|
||||
{
|
||||
return (uint32_t)ceilf((output_frame_count - samples_to_frames(resampling_out_buffer.length()))
|
||||
* resampling_ratio);
|
||||
|
||||
int32_t unresampled_frames_left = samples_to_frames(resampling_in_buffer.length());
|
||||
int32_t resampled_frames_left = samples_to_frames(resampling_out_buffer.length());
|
||||
float input_frames_needed =
|
||||
(output_frame_count - unresampled_frames_left) * resampling_ratio
|
||||
- resampled_frames_left;
|
||||
if (input_frames_needed < 0) {
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)ceilf(input_frames_needed);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the input buffer, that contains empty space for at
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
#include <atomic>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
|
@ -105,8 +106,8 @@ int wasapi_stream_stop(cubeb_stream * stm);
|
|||
int wasapi_stream_start(cubeb_stream * stm);
|
||||
void close_wasapi_stream(cubeb_stream * stm);
|
||||
int setup_wasapi_stream(cubeb_stream * stm);
|
||||
static char * wstr_to_utf8(const wchar_t * str);
|
||||
static std::unique_ptr<const wchar_t[]> utf8_to_wstr(char* str);
|
||||
static char const * wstr_to_utf8(wchar_t const * str);
|
||||
static std::unique_ptr<wchar_t const []> utf8_to_wstr(char const * str);
|
||||
|
||||
}
|
||||
|
||||
|
@ -144,8 +145,8 @@ struct cubeb_stream
|
|||
cubeb_stream_params input_stream_params;
|
||||
cubeb_stream_params output_stream_params;
|
||||
/* The input and output device, or NULL for default. */
|
||||
cubeb_devid input_device;
|
||||
cubeb_devid output_device;
|
||||
std::unique_ptr<const wchar_t[]> input_device;
|
||||
std::unique_ptr<const wchar_t[]> output_device;
|
||||
/* The latency initially requested for this stream, in frames. */
|
||||
unsigned latency;
|
||||
cubeb_state_callback state_callback;
|
||||
|
@ -220,9 +221,11 @@ struct cubeb_stream
|
|||
float volume;
|
||||
/* True if the stream is draining. */
|
||||
bool draining;
|
||||
/* True when we've destroyed the stream. This pointer is leaked on stream
|
||||
* destruction if we could not join the thread. */
|
||||
std::atomic<std::atomic<bool>*> emergency_bailout;
|
||||
};
|
||||
|
||||
|
||||
class wasapi_endpoint_notification_client : public IMMNotificationClient
|
||||
{
|
||||
public:
|
||||
|
@ -781,6 +784,7 @@ static unsigned int __stdcall
|
|||
wasapi_stream_render_loop(LPVOID stream)
|
||||
{
|
||||
cubeb_stream * stm = static_cast<cubeb_stream *>(stream);
|
||||
std::atomic<bool> * emergency_bailout = stm->emergency_bailout;
|
||||
|
||||
bool is_playing = true;
|
||||
HANDLE wait_array[4] = {
|
||||
|
@ -820,6 +824,10 @@ wasapi_stream_render_loop(LPVOID stream)
|
|||
wait_array,
|
||||
FALSE,
|
||||
1000);
|
||||
if (*emergency_bailout) {
|
||||
delete emergency_bailout;
|
||||
return 0;
|
||||
}
|
||||
if (waitResult != WAIT_TIMEOUT) {
|
||||
timeout_count = 0;
|
||||
}
|
||||
|
@ -1134,12 +1142,13 @@ int wasapi_init(cubeb ** context, char const * context_name)
|
|||
}
|
||||
|
||||
namespace {
|
||||
void stop_and_join_render_thread(cubeb_stream * stm)
|
||||
bool stop_and_join_render_thread(cubeb_stream * stm)
|
||||
{
|
||||
bool rv = true;
|
||||
LOG("Stop and join render thread.");
|
||||
if (!stm->thread) {
|
||||
LOG("No thread present.");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL ok = SetEvent(stm->shutdown_event);
|
||||
|
@ -1153,11 +1162,15 @@ void stop_and_join_render_thread(cubeb_stream * stm)
|
|||
if (r == WAIT_TIMEOUT) {
|
||||
/* Something weird happened, leak the thread and continue the shutdown
|
||||
* process. */
|
||||
*(stm->emergency_bailout) = true;
|
||||
LOG("Destroy WaitForSingleObject on thread timed out,"
|
||||
" leaking the thread: %d", GetLastError());
|
||||
rv = false;
|
||||
}
|
||||
if (r == WAIT_FAILED) {
|
||||
*(stm->emergency_bailout) = true;
|
||||
LOG("Destroy WaitForSingleObject on thread failed: %d", GetLastError());
|
||||
rv = false;
|
||||
}
|
||||
|
||||
LOG("Closing thread.");
|
||||
|
@ -1167,6 +1180,8 @@ void stop_and_join_render_thread(cubeb_stream * stm)
|
|||
|
||||
CloseHandle(stm->shutdown_event);
|
||||
stm->shutdown_event = 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void wasapi_destroy(cubeb * context)
|
||||
|
@ -1395,7 +1410,7 @@ handle_channel_layout(cubeb_stream * stm, WAVEFORMATEX ** mix_format, const cub
|
|||
template<typename T>
|
||||
int setup_wasapi_stream_one_side(cubeb_stream * stm,
|
||||
cubeb_stream_params * stream_params,
|
||||
cubeb_devid devid,
|
||||
wchar_t const * devid,
|
||||
EDataFlow direction,
|
||||
REFIID riid,
|
||||
IAudioClient ** audio_client,
|
||||
|
@ -1414,14 +1429,12 @@ int setup_wasapi_stream_one_side(cubeb_stream * stm,
|
|||
// possibilities.
|
||||
do {
|
||||
if (devid) {
|
||||
std::unique_ptr<const wchar_t[]> id(utf8_to_wstr(reinterpret_cast<char*>(devid)));
|
||||
hr = get_endpoint(&device, id.get());
|
||||
hr = get_endpoint(&device, devid);
|
||||
if (FAILED(hr)) {
|
||||
LOG("Could not get %s endpoint, error: %x\n", DIRECTION_NAME, hr);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
hr = get_default_endpoint(&device, direction);
|
||||
if (FAILED(hr)) {
|
||||
LOG("Could not get default %s endpoint, error: %x\n", DIRECTION_NAME, hr);
|
||||
|
@ -1534,10 +1547,10 @@ int setup_wasapi_stream(cubeb_stream * stm)
|
|||
XASSERT((!stm->output_client || !stm->input_client) && "WASAPI stream already setup, close it first.");
|
||||
|
||||
if (has_input(stm)) {
|
||||
LOG("Setup capture: device=%x", (int)stm->input_device);
|
||||
LOG("(%p) Setup capture: device=%p", stm, stm->input_device.get());
|
||||
rv = setup_wasapi_stream_one_side(stm,
|
||||
&stm->input_stream_params,
|
||||
stm->input_device,
|
||||
stm->input_device.get(),
|
||||
eCapture,
|
||||
__uuidof(IAudioCaptureClient),
|
||||
&stm->input_client,
|
||||
|
@ -1552,10 +1565,10 @@ int setup_wasapi_stream(cubeb_stream * stm)
|
|||
}
|
||||
|
||||
if (has_output(stm)) {
|
||||
LOG("Setup render: device=%x", (int)stm->output_device);
|
||||
LOG("(%p) Setup render: device=%p", stm, stm->output_device.get());
|
||||
rv = setup_wasapi_stream_one_side(stm,
|
||||
&stm->output_stream_params,
|
||||
stm->output_device,
|
||||
stm->output_device.get(),
|
||||
eRender,
|
||||
__uuidof(IAudioRenderClient),
|
||||
&stm->output_client,
|
||||
|
@ -1679,11 +1692,11 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
|
|||
stm->draining = false;
|
||||
if (input_stream_params) {
|
||||
stm->input_stream_params = *input_stream_params;
|
||||
stm->input_device = input_device;
|
||||
stm->input_device = utf8_to_wstr(reinterpret_cast<char const *>(input_device));
|
||||
}
|
||||
if (output_stream_params) {
|
||||
stm->output_stream_params = *output_stream_params;
|
||||
stm->output_device = output_device;
|
||||
stm->output_device = utf8_to_wstr(reinterpret_cast<char const *>(output_device));
|
||||
}
|
||||
|
||||
stm->latency = latency_frames;
|
||||
|
@ -1777,7 +1790,16 @@ void wasapi_stream_destroy(cubeb_stream * stm)
|
|||
{
|
||||
XASSERT(stm);
|
||||
|
||||
stop_and_join_render_thread(stm);
|
||||
// Only free stm->emergency_bailout if we could not join the thread.
|
||||
// If we could not join the thread, stm->emergency_bailout is true
|
||||
// and is still alive until the thread wakes up and exits cleanly.
|
||||
if (stop_and_join_render_thread(stm)) {
|
||||
delete stm->emergency_bailout.load();
|
||||
stm->emergency_bailout = nullptr;
|
||||
} else {
|
||||
// If we're leaking, it must be that this is true.
|
||||
assert(*(stm->emergency_bailout));
|
||||
}
|
||||
|
||||
unregister_notification_client(stm);
|
||||
|
||||
|
@ -1846,6 +1868,8 @@ int wasapi_stream_start(cubeb_stream * stm)
|
|||
|
||||
auto_lock lock(stm->stream_reset_lock);
|
||||
|
||||
stm->emergency_bailout = new std::atomic<bool>(false);
|
||||
|
||||
if (stm->output_client) {
|
||||
int rv = stream_start_one_side(stm, OUTPUT);
|
||||
if (rv != CUBEB_OK) {
|
||||
|
@ -1905,7 +1929,12 @@ int wasapi_stream_stop(cubeb_stream * stm)
|
|||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
|
||||
}
|
||||
|
||||
stop_and_join_render_thread(stm);
|
||||
if (stop_and_join_render_thread(stm)) {
|
||||
if (stm->emergency_bailout.load()) {
|
||||
delete stm->emergency_bailout.load();
|
||||
stm->emergency_bailout = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
@ -1982,33 +2011,29 @@ int wasapi_stream_set_volume(cubeb_stream * stm, float volume)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static char *
|
||||
static char const *
|
||||
wstr_to_utf8(LPCWSTR str)
|
||||
{
|
||||
char * ret = NULL;
|
||||
int size;
|
||||
|
||||
size = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, 0, NULL, NULL);
|
||||
if (size > 0) {
|
||||
ret = static_cast<char *>(malloc(size));
|
||||
::WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, size, NULL, NULL);
|
||||
int size = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, nullptr, 0, NULL, NULL);
|
||||
if (size <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char * ret = static_cast<char *>(malloc(size));
|
||||
::WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, size, NULL, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::unique_ptr<const wchar_t[]>
|
||||
utf8_to_wstr(char* str)
|
||||
static std::unique_ptr<wchar_t const []>
|
||||
utf8_to_wstr(char const * str)
|
||||
{
|
||||
std::unique_ptr<wchar_t[]> ret;
|
||||
int size;
|
||||
|
||||
size = ::MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0);
|
||||
if (size > 0) {
|
||||
ret.reset(new wchar_t[size]);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, str, -1, ret.get(), size);
|
||||
int size = ::MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0);
|
||||
if (size <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<wchar_t []> ret(new wchar_t[size]);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, str, -1, ret.get(), size);
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
|
@ -2089,7 +2114,8 @@ wasapi_create_device(IMMDeviceEnumerator * enumerator, IMMDevice * dev)
|
|||
|
||||
ret = (cubeb_device_info *)calloc(1, sizeof(cubeb_device_info));
|
||||
|
||||
ret->devid = ret->device_id = wstr_to_utf8(device_id);
|
||||
ret->device_id = wstr_to_utf8(device_id);
|
||||
ret->devid = reinterpret_cast<cubeb_devid>(ret->device_id);
|
||||
hr = propstore->GetValue(PKEY_Device_FriendlyName, &propvar);
|
||||
if (SUCCEEDED(hr))
|
||||
ret->friendly_name = wstr_to_utf8(propvar.pwszVal);
|
||||
|
|
|
@ -803,11 +803,11 @@ winmm_query_supported_formats(UINT devid, DWORD formats,
|
|||
static char *
|
||||
guid_to_cstr(LPGUID guid)
|
||||
{
|
||||
char * ret = malloc(sizeof(char) * 40);
|
||||
char * ret = malloc(40);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
_snprintf_s(ret, sizeof(char) * 40, _TRUNCATE,
|
||||
_snprintf_s(ret, 40, _TRUNCATE,
|
||||
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
guid->Data1, guid->Data2, guid->Data3,
|
||||
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
|
||||
|
@ -821,12 +821,12 @@ winmm_query_preferred_out_device(UINT devid)
|
|||
DWORD mmpref = WAVE_MAPPER, compref = WAVE_MAPPER, status;
|
||||
cubeb_device_pref ret = CUBEB_DEVICE_PREF_NONE;
|
||||
|
||||
if (waveOutMessage((HWAVEOUT)(size_t)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET,
|
||||
if (waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET,
|
||||
(DWORD_PTR)&mmpref, (DWORD_PTR)&status) == MMSYSERR_NOERROR &&
|
||||
devid == mmpref)
|
||||
ret |= CUBEB_DEVICE_PREF_MULTIMEDIA | CUBEB_DEVICE_PREF_NOTIFICATION;
|
||||
|
||||
if (waveOutMessage((HWAVEOUT)(size_t)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET,
|
||||
if (waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET,
|
||||
(DWORD_PTR)&compref, (DWORD_PTR)&status) == MMSYSERR_NOERROR &&
|
||||
devid == compref)
|
||||
ret |= CUBEB_DEVICE_PREF_VOICE;
|
||||
|
@ -837,7 +837,7 @@ winmm_query_preferred_out_device(UINT devid)
|
|||
static char *
|
||||
device_id_idx(UINT devid)
|
||||
{
|
||||
char * ret = (char *)malloc(sizeof(char)*16);
|
||||
char * ret = malloc(16);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -854,7 +854,7 @@ winmm_create_device_from_outcaps2(LPWAVEOUTCAPS2A caps, UINT devid)
|
|||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->devid = (cubeb_devid)(size_t)devid;
|
||||
ret->devid = (cubeb_devid) devid;
|
||||
ret->device_id = device_id_idx(devid);
|
||||
ret->friendly_name = _strdup(caps->szPname);
|
||||
ret->group_id = guid_to_cstr(&caps->ProductGuid);
|
||||
|
@ -885,7 +885,7 @@ winmm_create_device_from_outcaps(LPWAVEOUTCAPSA caps, UINT devid)
|
|||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->devid = (cubeb_devid)(size_t)devid;
|
||||
ret->devid = (cubeb_devid) devid;
|
||||
ret->device_id = device_id_idx(devid);
|
||||
ret->friendly_name = _strdup(caps->szPname);
|
||||
ret->group_id = NULL;
|
||||
|
@ -913,12 +913,12 @@ winmm_query_preferred_in_device(UINT devid)
|
|||
DWORD mmpref = WAVE_MAPPER, compref = WAVE_MAPPER, status;
|
||||
cubeb_device_pref ret = CUBEB_DEVICE_PREF_NONE;
|
||||
|
||||
if (waveInMessage((HWAVEIN)(size_t)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET,
|
||||
if (waveInMessage((HWAVEIN) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET,
|
||||
(DWORD_PTR)&mmpref, (DWORD_PTR)&status) == MMSYSERR_NOERROR &&
|
||||
devid == mmpref)
|
||||
ret |= CUBEB_DEVICE_PREF_MULTIMEDIA | CUBEB_DEVICE_PREF_NOTIFICATION;
|
||||
|
||||
if (waveInMessage((HWAVEIN)(size_t)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET,
|
||||
if (waveInMessage((HWAVEIN) WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET,
|
||||
(DWORD_PTR)&compref, (DWORD_PTR)&status) == MMSYSERR_NOERROR &&
|
||||
devid == compref)
|
||||
ret |= CUBEB_DEVICE_PREF_VOICE;
|
||||
|
@ -935,7 +935,7 @@ winmm_create_device_from_incaps2(LPWAVEINCAPS2A caps, UINT devid)
|
|||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->devid = (cubeb_devid)(size_t)devid;
|
||||
ret->devid = (cubeb_devid) devid;
|
||||
ret->device_id = device_id_idx(devid);
|
||||
ret->friendly_name = _strdup(caps->szPname);
|
||||
ret->group_id = guid_to_cstr(&caps->ProductGuid);
|
||||
|
@ -966,7 +966,7 @@ winmm_create_device_from_incaps(LPWAVEINCAPSA caps, UINT devid)
|
|||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->devid = (cubeb_devid)(size_t)devid;
|
||||
ret->devid = (cubeb_devid) devid;
|
||||
ret->device_id = device_id_idx(devid);
|
||||
ret->friendly_name = _strdup(caps->szPname);
|
||||
ret->group_id = NULL;
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
#include "TestHarness.h"
|
||||
#endif
|
||||
|
||||
#define LOG(msg) fprintf(stderr, "%s\n", msg);
|
||||
|
||||
int main(int /*argc*/, char * /*argv*/[])
|
||||
{
|
||||
#ifdef CUBEB_GECKO_BUILD
|
||||
ScopedXPCOM xpcom("test_latency");
|
||||
#endif
|
||||
|
||||
cubeb * ctx = NULL;
|
||||
int r;
|
||||
uint32_t max_channels;
|
||||
uint32_t preferred_rate;
|
||||
uint32_t latency_frames;
|
||||
|
||||
LOG("latency_test start");
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
assert(r == CUBEB_OK && "Cubeb init failed.");
|
||||
LOG("cubeb_init ok");
|
||||
|
||||
r = cubeb_get_max_channel_count(ctx, &max_channels);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(max_channels > 0 && "Invalid max channel count.");
|
||||
LOG("cubeb_get_max_channel_count ok");
|
||||
}
|
||||
|
||||
r = cubeb_get_preferred_sample_rate(ctx, &preferred_rate);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(preferred_rate > 0 && "Invalid preferred sample rate.");
|
||||
LOG("cubeb_get_preferred_sample_rate ok");
|
||||
}
|
||||
|
||||
cubeb_stream_params params = {
|
||||
CUBEB_SAMPLE_FLOAT32NE,
|
||||
preferred_rate,
|
||||
max_channels
|
||||
};
|
||||
r = cubeb_get_min_latency(ctx, params, &latency_frames);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(latency_frames > 0 && "Invalid minimal latency.");
|
||||
LOG("cubeb_get_min_latency ok");
|
||||
}
|
||||
|
||||
cubeb_destroy(ctx);
|
||||
LOG("cubeb_destroy ok");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
#include <cassert>
|
||||
#include "cubeb_utils.h"
|
||||
|
||||
int test_auto_array()
|
||||
{
|
||||
auto_array<uint32_t> array;
|
||||
auto_array<uint32_t> array2(10);
|
||||
uint32_t a[10];
|
||||
|
||||
assert(array2.length() == 0);
|
||||
assert(array2.capacity() == 10);
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
a[i] = i;
|
||||
}
|
||||
|
||||
assert(array.capacity() == 0);
|
||||
assert(array.length() == 0);
|
||||
|
||||
array.push(a, 10);
|
||||
|
||||
assert(!array.reserve(9));
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
assert(array.data()[i] == i);
|
||||
}
|
||||
|
||||
assert(array.capacity() == 10);
|
||||
assert(array.length() == 10);
|
||||
|
||||
uint32_t b[10];
|
||||
|
||||
array.pop(b, 5);
|
||||
|
||||
assert(array.capacity() == 10);
|
||||
assert(array.length() == 5);
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
assert(b[i] == i);
|
||||
assert(array.data()[i] == 5 + i);
|
||||
}
|
||||
uint32_t* bb = b + 5;
|
||||
array.pop(bb, 5);
|
||||
|
||||
assert(array.capacity() == 10);
|
||||
assert(array.length() == 0);
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
assert(bb[i] == 5 + i);
|
||||
}
|
||||
|
||||
assert(!array.pop(nullptr, 1));
|
||||
|
||||
array.push(a, 10);
|
||||
array.push(a, 10);
|
||||
|
||||
for (uint32_t j = 0; j < 2; j++) {
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
assert(array.data()[10 * j + i] == i);
|
||||
}
|
||||
}
|
||||
assert(array.length() == 20);
|
||||
assert(array.capacity() == 20);
|
||||
array.pop(nullptr, 5);
|
||||
|
||||
for (uint32_t i = 0; i < 5; i++) {
|
||||
assert(array.data()[i] == 5 + i);
|
||||
}
|
||||
|
||||
assert(array.length() == 15);
|
||||
assert(array.capacity() == 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test_auto_array();
|
||||
return 0;
|
||||
}
|
|
@ -30,16 +30,17 @@ cp $1/src/cubeb_utils_unix.h src
|
|||
cp $1/src/cubeb_utils_win.h src
|
||||
cp $1/src/cubeb_wasapi.cpp src
|
||||
cp $1/src/cubeb_winmm.c src
|
||||
cp $1/test/common.h tests/common.h
|
||||
cp $1/test/test_audio.cpp tests/test_audio.cpp
|
||||
#cp $1/test/test_devices.c tests/test_devices.cpp
|
||||
cp $1/test/test_duplex.cpp tests/test_duplex.cpp
|
||||
cp $1/test/test_latency.cpp tests/test_latency.cpp
|
||||
cp $1/test/test_record.cpp tests/test_record.cpp
|
||||
cp $1/test/test_resampler.cpp tests/test_resampler.cpp
|
||||
cp $1/test/test_sanity.cpp tests/test_sanity.cpp
|
||||
cp $1/test/test_tone.cpp tests/test_tone.cpp
|
||||
cp $1/test/test_utils.cpp tests/test_utils.cpp
|
||||
cp $1/test/common.h gtest
|
||||
cp $1/test/test_audio.cpp gtest
|
||||
cp $1/test/test_devices.cpp gtest
|
||||
cp $1/test/test_duplex.cpp gtest
|
||||
cp $1/test/test_latency.cpp gtest
|
||||
cp $1/test/test_record.cpp gtest
|
||||
cp $1/test/test_resampler.cpp gtest
|
||||
cp $1/test/test_ring_array.cpp gtest
|
||||
cp $1/test/test_sanity.cpp gtest
|
||||
cp $1/test/test_tone.cpp gtest
|
||||
cp $1/test/test_utils.cpp gtest
|
||||
|
||||
if [ -d $1/.git ]; then
|
||||
rev=$(cd $1 && git rev-parse --verify HEAD)
|
||||
|
|
|
@ -85,17 +85,13 @@ skip-if = os == 'android' # Bug 1147631
|
|||
[test_StatementCache]
|
||||
[test_asyncStatementExecution_transaction]
|
||||
[test_async_callbacks_with_spun_event_loops]
|
||||
[test_audio]
|
||||
[test_binding_params]
|
||||
[test_deadlock_detector]
|
||||
skip-if = os == 'b2g' || (os == 'android' && debug) # Bug 1054249
|
||||
[test_file_perms]
|
||||
[test_latency]
|
||||
[test_mutex]
|
||||
[test_sanity]
|
||||
[test_service_init_background_thread]
|
||||
[test_statement_scoper]
|
||||
[test_tone]
|
||||
[test_transaction_helper]
|
||||
[test_true_async]
|
||||
[test_unlock_notify]
|
||||
|
|
Загрузка…
Ссылка в новой задаче