early-access version 2840
This commit is contained in:
10
externals/cubeb/.github/workflows/build.yml
vendored
10
externals/cubeb/.github/workflows/build.yml
vendored
@@ -9,11 +9,11 @@ jobs:
|
||||
BUILD_TYPE: ${{ matrix.type }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
os: [ubuntu-20.04, windows-2019, macos-10.15]
|
||||
type: [Release, Debug]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -46,13 +46,13 @@ jobs:
|
||||
matrix:
|
||||
type: [Release, Debug]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=android-28
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=android-26
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
check_format:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
|
25
externals/cubeb/CMakeLists.txt
vendored
25
externals/cubeb/CMakeLists.txt
vendored
@@ -139,7 +139,7 @@ if(NOT BUNDLE_SPEEX)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET speex)
|
||||
add_library(speex OBJECT subprojects/speex/resample.c)
|
||||
add_library(speex STATIC subprojects/speex/resample.c)
|
||||
set_target_properties(speex PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
target_include_directories(speex INTERFACE subprojects)
|
||||
target_compile_definitions(speex PUBLIC
|
||||
@@ -259,7 +259,7 @@ if(USE_WASAPI)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_wasapi.cpp)
|
||||
target_compile_definitions(cubeb PRIVATE USE_WASAPI)
|
||||
target_link_libraries(cubeb PRIVATE avrt ole32 ksuser)
|
||||
target_link_libraries(cubeb PRIVATE avrt ole32)
|
||||
endif()
|
||||
|
||||
check_include_files("windows.h;mmsystem.h" USE_WINMM)
|
||||
@@ -284,22 +284,9 @@ if(HAVE_SYS_SOUNDCARD_H)
|
||||
try_compile(USE_OSS "${PROJECT_BINARY_DIR}/compile_tests"
|
||||
${PROJECT_SOURCE_DIR}/cmake/compile_tests/oss_is_v4.c)
|
||||
if(USE_OSS)
|
||||
# strlcpy is not available on BSD systems that use glibc,
|
||||
# like Debian kfreebsd, so try using libbsd if available
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(strlcpy string.h HAVE_STRLCPY)
|
||||
if(NOT HAVE_STRLCPY)
|
||||
pkg_check_modules(libbsd-overlay IMPORTED_TARGET libbsd-overlay)
|
||||
if(libbsd-overlay_FOUND)
|
||||
target_link_libraries(cubeb PRIVATE PkgConfig::libbsd-overlay)
|
||||
set(HAVE_STRLCPY true)
|
||||
endif()
|
||||
endif()
|
||||
if (HAVE_STRLCPY)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_oss.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_OSS)
|
||||
endif()
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_oss.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_OSS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -380,7 +367,7 @@ if(BUILD_TESTS)
|
||||
add_executable(test_${NAME} test/test_${NAME}.cpp)
|
||||
target_include_directories(test_${NAME} PRIVATE ${gtest_SOURCE_DIR}/include src)
|
||||
target_link_libraries(test_${NAME} PRIVATE cubeb gtest_main)
|
||||
add_test(${NAME} test_${NAME} --gtest_death_test_style=threadsafe)
|
||||
add_test(${NAME} test_${NAME})
|
||||
add_sanitizers(test_${NAME})
|
||||
install(TARGETS test_${NAME})
|
||||
endmacro(cubeb_add_test)
|
||||
|
12
externals/cubeb/INSTALL.md
vendored
12
externals/cubeb/INSTALL.md
vendored
@@ -2,12 +2,12 @@
|
||||
|
||||
You must have CMake v3.1 or later installed.
|
||||
|
||||
1. `git clone --recursive https://github.com/mozilla/cubeb.git`
|
||||
1. `git clone --recursive https://github.com/kinetiknz/cubeb.git`
|
||||
2. `mkdir cubeb-build`
|
||||
3. `cd cubeb-build`
|
||||
4. `cmake ../cubeb`
|
||||
5. `cmake --build .`
|
||||
6. `ctest`
|
||||
3. `cmake ../cubeb`
|
||||
4. `cmake --build .`
|
||||
5. `ctest`
|
||||
|
||||
# Windows build notes
|
||||
|
||||
@@ -41,6 +41,6 @@ To build with MinGW-w64, install the following items:
|
||||
- Download and install MinGW-w64 with Win32 threads.
|
||||
- Download and install CMake.
|
||||
- Run MinGW-w64 Terminal from the Start Menu.
|
||||
- Follow the build steps at the top of this file, but at step 4 run:
|
||||
`cmake -G "MinGW Makefiles" ../cubeb`
|
||||
- Follow the build steps at the top of this file, but at step 3 run:
|
||||
`cmake -G "MinGW Makefiles" ..`
|
||||
- Continue the build steps at the top of this file.
|
||||
|
2
externals/cubeb/README.md
vendored
2
externals/cubeb/README.md
vendored
@@ -2,6 +2,6 @@
|
||||
|
||||
See INSTALL.md for build instructions.
|
||||
|
||||
See [Backend Support](https://github.com/mozilla/cubeb/wiki/Backend-Support) in the wiki for the support level of each backend.
|
||||
See [Backend Support](https://github.com/kinetiknz/cubeb/wiki/Backend-Support) in the wiki for the support level of each backend.
|
||||
|
||||
Licensed under an ISC-style license. See LICENSE for details.
|
||||
|
3
externals/cubeb/src/cubeb_aaudio.cpp
vendored
3
externals/cubeb/src/cubeb_aaudio.cpp
vendored
@@ -935,8 +935,7 @@ aaudio_stream_init_impl(cubeb_stream * stm, cubeb_devid input_device,
|
||||
stm->resampler = cubeb_resampler_create(
|
||||
stm, input_stream_params ? &in_params : NULL,
|
||||
output_stream_params ? &out_params : NULL, target_sample_rate,
|
||||
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT);
|
||||
|
||||
if (!stm->resampler) {
|
||||
LOG("Failed to create resampler");
|
||||
|
17
externals/cubeb/src/cubeb_audiounit.cpp
vendored
17
externals/cubeb/src/cubeb_audiounit.cpp
vendored
@@ -541,13 +541,6 @@ audiounit_input_callback(void * user_ptr, AudioUnitRenderActionFlags * flags,
|
||||
long outframes = cubeb_resampler_fill(stm->resampler.get(),
|
||||
stm->input_linear_buffer->data(),
|
||||
&total_input_frames, NULL, 0);
|
||||
if (outframes < 0) {
|
||||
stm->shutdown = true;
|
||||
OSStatus r = AudioOutputUnitStop(stm->input_unit);
|
||||
assert(r == 0);
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
return noErr;
|
||||
}
|
||||
stm->draining = outframes < total_input_frames;
|
||||
|
||||
// Reset input buffer
|
||||
@@ -1449,13 +1442,6 @@ audiounit_destroy(cubeb * ctx)
|
||||
audiounit_active_streams(ctx));
|
||||
}
|
||||
|
||||
// Destroying a cubeb context with device collection callbacks registered
|
||||
// is misuse of the API, assert then attempt to clean up.
|
||||
assert(!ctx->input_collection_changed_callback &&
|
||||
!ctx->input_collection_changed_user_ptr &&
|
||||
!ctx->output_collection_changed_callback &&
|
||||
!ctx->output_collection_changed_user_ptr);
|
||||
|
||||
/* Unregister the callback if necessary. */
|
||||
if (ctx->input_collection_changed_callback) {
|
||||
audiounit_remove_device_listener(ctx, CUBEB_DEVICE_TYPE_INPUT);
|
||||
@@ -2714,8 +2700,7 @@ audiounit_setup_stream(cubeb_stream * stm)
|
||||
stm->resampler.reset(cubeb_resampler_create(
|
||||
stm, has_input(stm) ? &input_unconverted_params : NULL,
|
||||
has_output(stm) ? &stm->output_stream_params : NULL, target_sample_rate,
|
||||
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE));
|
||||
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP));
|
||||
if (!stm->resampler) {
|
||||
LOG("(%p) Could not create resampler.", stm);
|
||||
return CUBEB_ERROR;
|
||||
|
9
externals/cubeb/src/cubeb_jack.cpp
vendored
9
externals/cubeb/src/cubeb_jack.cpp
vendored
@@ -925,18 +925,15 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
if (stm->devs == DUPLEX) {
|
||||
stm->resampler = cubeb_resampler_create(
|
||||
stm, &stm->in_params, &stm->out_params, stream_actual_rate,
|
||||
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP);
|
||||
} else if (stm->devs == IN_ONLY) {
|
||||
stm->resampler = cubeb_resampler_create(
|
||||
stm, &stm->in_params, nullptr, stream_actual_rate, stm->data_callback,
|
||||
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP);
|
||||
} else if (stm->devs == OUT_ONLY) {
|
||||
stm->resampler = cubeb_resampler_create(
|
||||
stm, nullptr, &stm->out_params, stream_actual_rate, stm->data_callback,
|
||||
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP);
|
||||
}
|
||||
|
||||
if (!stm->resampler) {
|
||||
|
2
externals/cubeb/src/cubeb_log.cpp
vendored
2
externals/cubeb/src/cubeb_log.cpp
vendored
@@ -123,7 +123,7 @@ cubeb_async_log(char const * fmt, ...)
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_async_log_reset_threads(void)
|
||||
cubeb_async_log_reset_threads()
|
||||
{
|
||||
if (!g_cubeb_log_callback) {
|
||||
return;
|
||||
|
2
externals/cubeb/src/cubeb_log.h
vendored
2
externals/cubeb/src/cubeb_log.h
vendored
@@ -35,7 +35,7 @@ extern cubeb_log_callback g_cubeb_log_callback PRINTF_FORMAT(1, 2);
|
||||
void
|
||||
cubeb_async_log(const char * fmt, ...);
|
||||
void
|
||||
cubeb_async_log_reset_threads(void);
|
||||
cubeb_async_log_reset_threads();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
3
externals/cubeb/src/cubeb_opensl.c
vendored
3
externals/cubeb/src/cubeb_opensl.c
vendored
@@ -1479,8 +1479,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream,
|
||||
stm->resampler = cubeb_resampler_create(
|
||||
stm, input_stream_params ? &input_params : NULL,
|
||||
output_stream_params ? &output_params : NULL, target_sample_rate,
|
||||
data_callback, user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
data_callback, user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT);
|
||||
if (!stm->resampler) {
|
||||
LOG("Failed to create resampler");
|
||||
opensl_stream_destroy(stm);
|
||||
|
68
externals/cubeb/src/cubeb_oss.c
vendored
68
externals/cubeb/src/cubeb_oss.c
vendored
@@ -96,8 +96,9 @@ struct oss_stream {
|
||||
oss_devnode_t name;
|
||||
int fd;
|
||||
void * buf;
|
||||
unsigned int nfr; /* Number of frames allocated */
|
||||
unsigned int nfrags;
|
||||
unsigned int bufframes;
|
||||
unsigned int maxframes;
|
||||
|
||||
struct stream_info {
|
||||
int channels;
|
||||
@@ -823,9 +824,9 @@ retry:
|
||||
pfds[0].fd = s->play.fd;
|
||||
pfds[1].fd = -1;
|
||||
goto retry;
|
||||
} else if (tnfr > (long)s->play.maxframes) {
|
||||
} else if (tnfr > (long)s->play.bufframes) {
|
||||
/* too many frames available - limit */
|
||||
tnfr = (long)s->play.maxframes;
|
||||
tnfr = (long)s->play.bufframes;
|
||||
}
|
||||
if (nfr > tnfr) {
|
||||
nfr = tnfr;
|
||||
@@ -841,9 +842,9 @@ retry:
|
||||
pfds[0].fd = -1;
|
||||
pfds[1].fd = s->record.fd;
|
||||
goto retry;
|
||||
} else if (tnfr > (long)s->record.maxframes) {
|
||||
} else if (tnfr > (long)s->record.bufframes) {
|
||||
/* too many frames available - limit */
|
||||
tnfr = (long)s->record.maxframes;
|
||||
tnfr = (long)s->record.bufframes;
|
||||
}
|
||||
if (nfr > tnfr) {
|
||||
nfr = tnfr;
|
||||
@@ -1060,8 +1061,6 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
}
|
||||
if (input_stream_params != NULL) {
|
||||
unsigned int nb_channels;
|
||||
uint32_t minframes;
|
||||
|
||||
if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
|
||||
LOG("Loopback not supported");
|
||||
ret = CUBEB_ERROR_NOT_SUPPORTED;
|
||||
@@ -1090,17 +1089,18 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
(input_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
|
||||
s->record.frame_size =
|
||||
s->record.info.channels * (s->record.info.precision / 8);
|
||||
s->record.bufframes = latency_frames;
|
||||
|
||||
oss_get_min_latency(context, *input_stream_params, &minframes);
|
||||
if (s->record.bufframes < minframes) {
|
||||
s->record.bufframes = minframes;
|
||||
s->record.nfrags = OSS_NFRAGS;
|
||||
s->record.nfr = latency_frames / OSS_NFRAGS;
|
||||
s->record.bufframes = s->record.nfrags * s->record.nfr;
|
||||
uint32_t minnfr;
|
||||
oss_get_min_latency(context, *input_stream_params, &minnfr);
|
||||
if (s->record.nfr < minnfr) {
|
||||
s->record.nfr = minnfr;
|
||||
s->record.nfrags = latency_frames / minnfr;
|
||||
}
|
||||
}
|
||||
if (output_stream_params != NULL) {
|
||||
unsigned int nb_channels;
|
||||
uint32_t minframes;
|
||||
|
||||
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
|
||||
LOG("Loopback not supported");
|
||||
ret = CUBEB_ERROR_NOT_SUPPORTED;
|
||||
@@ -1128,16 +1128,19 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
}
|
||||
s->play.floating = (output_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
|
||||
s->play.frame_size = s->play.info.channels * (s->play.info.precision / 8);
|
||||
s->play.bufframes = latency_frames;
|
||||
|
||||
oss_get_min_latency(context, *output_stream_params, &minframes);
|
||||
if (s->play.bufframes < minframes) {
|
||||
s->play.bufframes = minframes;
|
||||
s->play.nfrags = OSS_NFRAGS;
|
||||
s->play.nfr = latency_frames / OSS_NFRAGS;
|
||||
uint32_t minnfr;
|
||||
oss_get_min_latency(context, *output_stream_params, &minnfr);
|
||||
if (s->play.nfr < minnfr) {
|
||||
s->play.nfr = minnfr;
|
||||
s->play.nfrags = latency_frames / minnfr;
|
||||
}
|
||||
s->play.bufframes = s->play.nfrags * s->play.nfr;
|
||||
}
|
||||
if (s->play.fd != -1) {
|
||||
int frag = oss_get_frag_params(
|
||||
oss_calc_frag_shift(s->play.bufframes, s->play.frame_size));
|
||||
oss_calc_frag_shift(s->play.nfr, s->play.frame_size));
|
||||
if (ioctl(s->play.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
|
||||
LOG("Failed to set play fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
|
||||
frag);
|
||||
@@ -1145,28 +1148,19 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi))
|
||||
LOG("Failed to get play fd's buffer info.");
|
||||
else {
|
||||
s->play.bufframes = (bi.fragsize * bi.fragstotal) / s->play.frame_size;
|
||||
s->play.nfr = bi.fragsize / s->play.frame_size;
|
||||
s->play.nfrags = bi.fragments;
|
||||
s->play.bufframes = s->play.nfr * s->play.nfrags;
|
||||
}
|
||||
int lw;
|
||||
|
||||
/*
|
||||
* Force 32 ms service intervals at most, or when recording is
|
||||
* active, use the recording service intervals as a reference.
|
||||
*/
|
||||
s->play.maxframes = (32 * output_stream_params->rate) / 1000;
|
||||
if (s->record.fd != -1 || s->play.maxframes >= s->play.bufframes) {
|
||||
lw = s->play.frame_size; /* Feed data when possible. */
|
||||
s->play.maxframes = s->play.bufframes;
|
||||
} else {
|
||||
lw = (s->play.bufframes - s->play.maxframes) * s->play.frame_size;
|
||||
}
|
||||
int lw = s->play.frame_size;
|
||||
if (ioctl(s->play.fd, SNDCTL_DSP_LOW_WATER, &lw))
|
||||
LOG("Audio device \"%s\" (play) could not set trigger threshold",
|
||||
s->play.name);
|
||||
}
|
||||
if (s->record.fd != -1) {
|
||||
int frag = oss_get_frag_params(
|
||||
oss_calc_frag_shift(s->record.bufframes, s->record.frame_size));
|
||||
oss_calc_frag_shift(s->record.nfr, s->record.frame_size));
|
||||
if (ioctl(s->record.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
|
||||
LOG("Failed to set record fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
|
||||
frag);
|
||||
@@ -1174,11 +1168,11 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi))
|
||||
LOG("Failed to get record fd's buffer info.");
|
||||
else {
|
||||
s->record.bufframes =
|
||||
(bi.fragsize * bi.fragstotal) / s->record.frame_size;
|
||||
s->record.nfr = bi.fragsize / s->record.frame_size;
|
||||
s->record.nfrags = bi.fragments;
|
||||
s->record.bufframes = s->record.nfr * s->record.nfrags;
|
||||
}
|
||||
|
||||
s->record.maxframes = s->record.bufframes;
|
||||
int lw = s->record.frame_size;
|
||||
if (ioctl(s->record.fd, SNDCTL_DSP_LOW_WATER, &lw))
|
||||
LOG("Audio device \"%s\" (record) could not set trigger threshold",
|
||||
|
8
externals/cubeb/src/cubeb_pulse.c
vendored
8
externals/cubeb/src/cubeb_pulse.c
vendored
@@ -280,7 +280,6 @@ trigger_user_callback(pa_stream * s, void const * input_data, size_t nbytes,
|
||||
if (got < 0) {
|
||||
WRAP(pa_stream_cancel_write)(s);
|
||||
stm->shutdown = 1;
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
// If more iterations move offset of read buffer
|
||||
@@ -393,9 +392,6 @@ stream_read_callback(pa_stream * s, size_t nbytes, void * u)
|
||||
if (got < 0 || (size_t)got != read_frames) {
|
||||
WRAP(pa_stream_cancel_write)(s);
|
||||
stm->shutdown = 1;
|
||||
if (got < 0) {
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -787,10 +783,6 @@ pulse_context_destroy(cubeb * ctx)
|
||||
static void
|
||||
pulse_destroy(cubeb * ctx)
|
||||
{
|
||||
assert(!ctx->input_collection_changed_callback &&
|
||||
!ctx->input_collection_changed_user_ptr &&
|
||||
!ctx->output_collection_changed_callback &&
|
||||
!ctx->output_collection_changed_user_ptr);
|
||||
free(ctx->context_name);
|
||||
if (ctx->context) {
|
||||
pulse_context_destroy(ctx);
|
||||
|
15
externals/cubeb/src/cubeb_resampler.cpp
vendored
15
externals/cubeb/src/cubeb_resampler.cpp
vendored
@@ -323,8 +323,7 @@ cubeb_resampler_create(cubeb_stream * stream,
|
||||
cubeb_stream_params * input_params,
|
||||
cubeb_stream_params * output_params,
|
||||
unsigned int target_rate, cubeb_data_callback callback,
|
||||
void * user_ptr, cubeb_resampler_quality quality,
|
||||
cubeb_resampler_reclock reclock)
|
||||
void * user_ptr, cubeb_resampler_quality quality)
|
||||
{
|
||||
cubeb_sample_format format;
|
||||
|
||||
@@ -338,13 +337,13 @@ cubeb_resampler_create(cubeb_stream * stream,
|
||||
|
||||
switch (format) {
|
||||
case CUBEB_SAMPLE_S16NE:
|
||||
return cubeb_resampler_create_internal<short>(
|
||||
stream, input_params, output_params, target_rate, callback, user_ptr,
|
||||
quality, reclock);
|
||||
return cubeb_resampler_create_internal<short>(stream, input_params,
|
||||
output_params, target_rate,
|
||||
callback, user_ptr, quality);
|
||||
case CUBEB_SAMPLE_FLOAT32NE:
|
||||
return cubeb_resampler_create_internal<float>(
|
||||
stream, input_params, output_params, target_rate, callback, user_ptr,
|
||||
quality, reclock);
|
||||
return cubeb_resampler_create_internal<float>(stream, input_params,
|
||||
output_params, target_rate,
|
||||
callback, user_ptr, quality);
|
||||
default:
|
||||
assert(false);
|
||||
return nullptr;
|
||||
|
8
externals/cubeb/src/cubeb_resampler.h
vendored
8
externals/cubeb/src/cubeb_resampler.h
vendored
@@ -21,11 +21,6 @@ typedef enum {
|
||||
CUBEB_RESAMPLER_QUALITY_DESKTOP
|
||||
} cubeb_resampler_quality;
|
||||
|
||||
typedef enum {
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE,
|
||||
CUBEB_RESAMPLER_RECLOCK_INPUT
|
||||
} cubeb_resampler_reclock;
|
||||
|
||||
/**
|
||||
* Create a resampler to adapt the requested sample rate into something that
|
||||
* is accepted by the audio backend.
|
||||
@@ -49,8 +44,7 @@ cubeb_resampler_create(cubeb_stream * stream,
|
||||
cubeb_stream_params * input_params,
|
||||
cubeb_stream_params * output_params,
|
||||
unsigned int target_rate, cubeb_data_callback callback,
|
||||
void * user_ptr, cubeb_resampler_quality quality,
|
||||
cubeb_resampler_reclock reclock);
|
||||
void * user_ptr, cubeb_resampler_quality quality);
|
||||
|
||||
/**
|
||||
* Fill the buffer with frames acquired using the data callback. Resampling will
|
||||
|
@@ -496,8 +496,7 @@ cubeb_resampler_create_internal(cubeb_stream * stream,
|
||||
cubeb_stream_params * output_params,
|
||||
unsigned int target_rate,
|
||||
cubeb_data_callback callback, void * user_ptr,
|
||||
cubeb_resampler_quality quality,
|
||||
cubeb_resampler_reclock reclock)
|
||||
cubeb_resampler_quality quality)
|
||||
{
|
||||
std::unique_ptr<cubeb_resampler_speex_one_way<T>> input_resampler = nullptr;
|
||||
std::unique_ptr<cubeb_resampler_speex_one_way<T>> output_resampler = nullptr;
|
||||
|
10
externals/cubeb/src/cubeb_ringbuffer.h
vendored
10
externals/cubeb/src/cubeb_ringbuffer.h
vendored
@@ -110,8 +110,8 @@ public:
|
||||
assert_correct_thread(producer_id);
|
||||
#endif
|
||||
|
||||
int rd_idx = read_index_.load(std::memory_order_relaxed);
|
||||
int wr_idx = write_index_.load(std::memory_order_relaxed);
|
||||
int rd_idx = read_index_.load(std::memory_order_acquire);
|
||||
|
||||
if (full_internal(rd_idx, wr_idx)) {
|
||||
return 0;
|
||||
@@ -154,8 +154,8 @@ public:
|
||||
assert_correct_thread(consumer_id);
|
||||
#endif
|
||||
|
||||
int rd_idx = read_index_.load(std::memory_order_relaxed);
|
||||
int wr_idx = write_index_.load(std::memory_order_acquire);
|
||||
int rd_idx = read_index_.load(std::memory_order_relaxed);
|
||||
|
||||
if (empty_internal(rd_idx, wr_idx)) {
|
||||
return 0;
|
||||
@@ -172,7 +172,7 @@ public:
|
||||
}
|
||||
|
||||
read_index_.store(increment_index(rd_idx, to_read),
|
||||
std::memory_order_release);
|
||||
std::memory_order_relaxed);
|
||||
|
||||
return to_read;
|
||||
}
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
#endif
|
||||
return available_read_internal(
|
||||
read_index_.load(std::memory_order_relaxed),
|
||||
write_index_.load(std::memory_order_acquire));
|
||||
write_index_.load(std::memory_order_relaxed));
|
||||
}
|
||||
/**
|
||||
* Get the number of available elements for consuming.
|
||||
@@ -205,7 +205,7 @@ public:
|
||||
assert_correct_thread(producer_id);
|
||||
#endif
|
||||
return available_write_internal(
|
||||
read_index_.load(std::memory_order_acquire),
|
||||
read_index_.load(std::memory_order_relaxed),
|
||||
write_index_.load(std::memory_order_relaxed));
|
||||
}
|
||||
/**
|
||||
|
17
externals/cubeb/src/cubeb_utils_win.h
vendored
17
externals/cubeb/src/cubeb_utils_win.h
vendored
@@ -11,23 +11,24 @@
|
||||
#include "cubeb-internal.h"
|
||||
#include <windows.h>
|
||||
|
||||
/* This wraps an SRWLock to track the owner in debug mode, adapted from
|
||||
/* This wraps a critical section to track the owner in debug mode, adapted from
|
||||
NSPR and http://blogs.msdn.com/b/oldnewthing/archive/2013/07/12/10433554.aspx
|
||||
*/
|
||||
class owned_critical_section {
|
||||
public:
|
||||
owned_critical_section()
|
||||
: srwlock(SRWLOCK_INIT)
|
||||
#ifndef NDEBUG
|
||||
,
|
||||
owner(0)
|
||||
: owner(0)
|
||||
#endif
|
||||
{
|
||||
InitializeCriticalSection(&critical_section);
|
||||
}
|
||||
|
||||
~owned_critical_section() { DeleteCriticalSection(&critical_section); }
|
||||
|
||||
void lock()
|
||||
{
|
||||
AcquireSRWLockExclusive(&srwlock);
|
||||
EnterCriticalSection(&critical_section);
|
||||
#ifndef NDEBUG
|
||||
XASSERT(owner != GetCurrentThreadId() && "recursive locking");
|
||||
owner = GetCurrentThreadId();
|
||||
@@ -40,7 +41,7 @@ public:
|
||||
/* GetCurrentThreadId cannot return 0: it is not a the valid thread id */
|
||||
owner = 0;
|
||||
#endif
|
||||
ReleaseSRWLockExclusive(&srwlock);
|
||||
LeaveCriticalSection(&critical_section);
|
||||
}
|
||||
|
||||
/* This is guaranteed to have the good behaviour if it succeeds. The behaviour
|
||||
@@ -54,12 +55,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
SRWLOCK srwlock;
|
||||
CRITICAL_SECTION critical_section;
|
||||
#ifndef NDEBUG
|
||||
DWORD owner;
|
||||
#endif
|
||||
|
||||
// Disallow copy and assignment because SRWLock cannot be copied.
|
||||
// Disallow copy and assignment because CRICICAL_SECTION cannot be copied.
|
||||
owned_critical_section(const owned_critical_section &);
|
||||
owned_critical_section & operator=(const owned_critical_section &);
|
||||
};
|
||||
|
593
externals/cubeb/src/cubeb_wasapi.cpp
vendored
593
externals/cubeb/src/cubeb_wasapi.cpp
vendored
File diff suppressed because it is too large
Load Diff
11
externals/cubeb/src/cubeb_winmm.c
vendored
11
externals/cubeb/src/cubeb_winmm.c
vendored
@@ -73,6 +73,17 @@
|
||||
#define CUBEB_STREAM_MAX 32
|
||||
#define NBUFS 4
|
||||
|
||||
const GUID KSDATAFORMAT_SUBTYPE_PCM = {
|
||||
0x00000001,
|
||||
0x0000,
|
||||
0x0010,
|
||||
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {
|
||||
0x00000003,
|
||||
0x0000,
|
||||
0x0010,
|
||||
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
|
||||
struct cubeb_stream_item {
|
||||
SLIST_ENTRY head;
|
||||
cubeb_stream * stream;
|
||||
|
38
externals/cubeb/test/test_callback_ret.cpp
vendored
38
externals/cubeb/test/test_callback_ret.cpp
vendored
@@ -34,7 +34,6 @@ enum test_direction {
|
||||
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
|
||||
@@ -99,30 +98,10 @@ long data_cb_ret_nframes(cubeb_stream * stream, void * user, const void * inputb
|
||||
return nframes;
|
||||
}
|
||||
|
||||
// Data callback that always returns CUBEB_ERROR
|
||||
long
|
||||
data_cb_ret_error(cubeb_stream * stream, void * user, const void * 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;
|
||||
}
|
||||
|
||||
void state_cb_ret(cubeb_stream * stream, void * user, cubeb_state state)
|
||||
void state_cb_ret(cubeb_stream * stream, void * /*user*/, cubeb_state state)
|
||||
{
|
||||
if (stream == NULL)
|
||||
return;
|
||||
user_state_callback_ret * u = (user_state_callback_ret *)user;
|
||||
|
||||
switch (state) {
|
||||
case CUBEB_STATE_STARTED:
|
||||
@@ -131,13 +110,11 @@ void state_cb_ret(cubeb_stream * stream, void * user, cubeb_state state)
|
||||
fprintf(stderr, "stream stopped\n"); break;
|
||||
case CUBEB_STATE_DRAINED:
|
||||
fprintf(stderr, "stream drained\n"); break;
|
||||
case CUBEB_STATE_ERROR:
|
||||
fprintf(stderr, "stream error\n");
|
||||
u->error_state.fetch_add(1);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown stream state %d\n", state);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void run_test_callback(test_direction direction,
|
||||
@@ -206,10 +183,6 @@ void run_test_callback(test_direction direction,
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(cubeb, test_input_callback)
|
||||
@@ -217,8 +190,6 @@ TEST(cubeb, test_input_callback)
|
||||
run_test_callback(INPUT_ONLY, data_cb_ret_zero, "input only, return 0");
|
||||
run_test_callback(INPUT_ONLY, data_cb_ret_nframes_minus_one, "input only, return nframes - 1");
|
||||
run_test_callback(INPUT_ONLY, data_cb_ret_nframes, "input only, return nframes");
|
||||
run_test_callback(INPUT_ONLY, data_cb_ret_error,
|
||||
"input only, return CUBEB_ERROR");
|
||||
}
|
||||
|
||||
TEST(cubeb, test_output_callback)
|
||||
@@ -226,8 +197,6 @@ TEST(cubeb, test_output_callback)
|
||||
run_test_callback(OUTPUT_ONLY, data_cb_ret_zero, "output only, return 0");
|
||||
run_test_callback(OUTPUT_ONLY, data_cb_ret_nframes_minus_one, "output only, return nframes - 1");
|
||||
run_test_callback(OUTPUT_ONLY, data_cb_ret_nframes, "output only, return nframes");
|
||||
run_test_callback(OUTPUT_ONLY, data_cb_ret_error,
|
||||
"output only, return CUBEB_ERROR");
|
||||
}
|
||||
|
||||
TEST(cubeb, test_duplex_callback)
|
||||
@@ -235,5 +204,4 @@ TEST(cubeb, test_duplex_callback)
|
||||
run_test_callback(DUPLEX, data_cb_ret_zero, "duplex, return 0");
|
||||
run_test_callback(DUPLEX, data_cb_ret_nframes_minus_one, "duplex, return nframes - 1");
|
||||
run_test_callback(DUPLEX, data_cb_ret_nframes, "duplex, return nframes");
|
||||
run_test_callback(DUPLEX, data_cb_ret_error, "duplex, return CUBEB_ERROR");
|
||||
}
|
||||
|
54
externals/cubeb/test/test_duplex.cpp
vendored
54
externals/cubeb/test/test_duplex.cpp
vendored
@@ -137,20 +137,26 @@ void device_collection_changed_callback(cubeb * context, void * user)
|
||||
" called when opening a stream";
|
||||
}
|
||||
|
||||
void
|
||||
duplex_collection_change_impl(cubeb * ctx)
|
||||
TEST(cubeb, duplex_collection_change)
|
||||
{
|
||||
cubeb_stream * stream;
|
||||
cubeb *ctx;
|
||||
cubeb_stream *stream;
|
||||
cubeb_stream_params input_params;
|
||||
cubeb_stream_params output_params;
|
||||
int r;
|
||||
uint32_t latency_frames = 0;
|
||||
|
||||
r = cubeb_register_device_collection_changed(
|
||||
ctx, static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT),
|
||||
device_collection_changed_callback, nullptr);
|
||||
r = common_init(&ctx, "Cubeb duplex example with collection change");
|
||||
ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library";
|
||||
|
||||
r = cubeb_register_device_collection_changed(ctx,
|
||||
static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT),
|
||||
device_collection_changed_callback,
|
||||
nullptr);
|
||||
ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream";
|
||||
|
||||
std::unique_ptr<cubeb, decltype(&cubeb_destroy)>
|
||||
cleanup_cubeb_at_exit(ctx, cubeb_destroy);
|
||||
|
||||
/* typical user-case: mono input, stereo output, low latency. */
|
||||
input_params.format = STREAM_FORMAT;
|
||||
@@ -167,43 +173,13 @@ duplex_collection_change_impl(cubeb * ctx)
|
||||
r = cubeb_get_min_latency(ctx, &output_params, &latency_frames);
|
||||
ASSERT_EQ(r, CUBEB_OK) << "Could not get minimal latency";
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb duplex", NULL, &input_params, NULL,
|
||||
&output_params, latency_frames, data_cb_duplex,
|
||||
state_cb_duplex, nullptr);
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb duplex",
|
||||
NULL, &input_params, NULL, &output_params,
|
||||
latency_frames, data_cb_duplex, state_cb_duplex, nullptr);
|
||||
ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream";
|
||||
cubeb_stream_destroy(stream);
|
||||
}
|
||||
|
||||
TEST(cubeb, duplex_collection_change)
|
||||
{
|
||||
cubeb * ctx;
|
||||
int r;
|
||||
|
||||
r = common_init(&ctx, "Cubeb duplex example with collection change");
|
||||
ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library";
|
||||
std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit(
|
||||
ctx, cubeb_destroy);
|
||||
|
||||
duplex_collection_change_impl(ctx);
|
||||
r = cubeb_register_device_collection_changed(
|
||||
ctx, static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT), nullptr,
|
||||
nullptr);
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
}
|
||||
|
||||
TEST(cubeb, duplex_collection_change_no_unregister)
|
||||
{
|
||||
cubeb * ctx;
|
||||
int r;
|
||||
|
||||
r = common_init(&ctx, "Cubeb duplex example with collection change");
|
||||
ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library";
|
||||
std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit(
|
||||
ctx, [](cubeb * p) noexcept { EXPECT_DEATH(cubeb_destroy(p), ""); });
|
||||
|
||||
duplex_collection_change_impl(ctx);
|
||||
}
|
||||
|
||||
long data_cb_input(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
{
|
||||
if (stream == NULL || inputbuffer == NULL || outputbuffer != NULL) {
|
||||
|
21
externals/cubeb/test/test_resampler.cpp
vendored
21
externals/cubeb/test/test_resampler.cpp
vendored
@@ -338,8 +338,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_resampler, (void*)&state, CUBEB_RESAMPLER_QUALITY_VOIP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
data_cb_resampler, (void*)&state, CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
long latency = cubeb_resampler_latency(resampler);
|
||||
|
||||
@@ -485,8 +484,8 @@ TEST(cubeb, resampler_output_only_noop)
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
|
||||
test_output_only_noop_data_cb, nullptr,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
const long out_frames = 128;
|
||||
float out_buffer[out_frames];
|
||||
long got;
|
||||
@@ -524,8 +523,7 @@ TEST(cubeb, resampler_drain)
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
|
||||
test_drain_data_cb, &cb_count,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
const long out_frames = 128;
|
||||
float out_buffer[out_frames];
|
||||
@@ -574,8 +572,7 @@ TEST(cubeb, resampler_passthrough_output_only)
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params,
|
||||
target_rate, cb_passthrough_resampler_output, nullptr,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
float output_buffer[output_channels * 256];
|
||||
|
||||
@@ -619,8 +616,7 @@ TEST(cubeb, resampler_passthrough_input_only)
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, &input_params, nullptr,
|
||||
target_rate, cb_passthrough_resampler_input, nullptr,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
float input_buffer[input_channels * 256];
|
||||
|
||||
@@ -741,8 +737,7 @@ TEST(cubeb, resampler_passthrough_duplex_callback_reordering)
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, &input_params, &output_params,
|
||||
target_rate, cb_passthrough_resampler_duplex, &c,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP,
|
||||
CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
const long BUF_BASE_SIZE = 256;
|
||||
float input_buffer_prebuffer[input_channels * BUF_BASE_SIZE * 2];
|
||||
@@ -825,7 +820,7 @@ TEST(cubeb, resampler_drift_drop_data)
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, &input_params, &output_params,
|
||||
target_rate, cb_passthrough_resampler_duplex, &c,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP, CUBEB_RESAMPLER_RECLOCK_NONE);
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
const long BUF_BASE_SIZE = 256;
|
||||
|
||||
|
87
externals/cubeb/tools/cubeb-test.cpp
vendored
87
externals/cubeb/tools/cubeb-test.cpp
vendored
@@ -7,7 +7,6 @@
|
||||
#include <cstring>
|
||||
#include <inttypes.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#ifdef _WIN32
|
||||
#include <objbase.h> // Used by CoInitialize()
|
||||
#endif
|
||||
@@ -36,32 +35,6 @@ static const char* state_to_string(cubeb_state state) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char* device_type_to_string(cubeb_device_type type) {
|
||||
switch (type) {
|
||||
case CUBEB_DEVICE_TYPE_INPUT:
|
||||
return "input";
|
||||
case CUBEB_DEVICE_TYPE_OUTPUT:
|
||||
return "output";
|
||||
case CUBEB_DEVICE_TYPE_UNKNOWN:
|
||||
return "unknown";
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* device_state_to_string(cubeb_device_state state) {
|
||||
switch (state) {
|
||||
case CUBEB_DEVICE_STATE_DISABLED:
|
||||
return "disabled";
|
||||
case CUBEB_DEVICE_STATE_UNPLUGGED:
|
||||
return "unplugged";
|
||||
case CUBEB_DEVICE_STATE_ENABLED:
|
||||
return "enabled";
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void print_log(const char* msg, ...) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
@@ -75,7 +48,6 @@ public:
|
||||
~cubeb_client() {}
|
||||
|
||||
bool init(char const * backend_name = nullptr);
|
||||
cubeb_devid select_device(cubeb_device_type type) const;
|
||||
bool init_stream();
|
||||
bool start_stream();
|
||||
bool stop_stream();
|
||||
@@ -98,10 +70,7 @@ public:
|
||||
bool unregister_device_collection_changed(cubeb_device_type devtype) const;
|
||||
|
||||
cubeb_stream_params output_params = {};
|
||||
cubeb_devid output_device = nullptr;
|
||||
|
||||
cubeb_stream_params input_params = {};
|
||||
cubeb_devid input_device = nullptr;
|
||||
|
||||
void force_drain() { _force_drain = true; }
|
||||
|
||||
@@ -112,6 +81,8 @@ private:
|
||||
cubeb* context = nullptr;
|
||||
|
||||
cubeb_stream* stream = nullptr;
|
||||
cubeb_devid output_device = nullptr;
|
||||
cubeb_devid input_device = nullptr;
|
||||
|
||||
/* Accessed only from client and audio thread. */
|
||||
std::atomic<uint32_t> _rate = {0};
|
||||
@@ -521,56 +492,6 @@ bool choose_action(cubeb_client& cl, operation_data * op, int c) {
|
||||
return true; // Loop up
|
||||
}
|
||||
|
||||
cubeb_devid cubeb_client::select_device(cubeb_device_type type) const
|
||||
{
|
||||
assert(type == CUBEB_DEVICE_TYPE_INPUT || type == CUBEB_DEVICE_TYPE_OUTPUT);
|
||||
|
||||
cubeb_device_collection collection;
|
||||
if (cubeb_enumerate_devices(context, type, &collection) ==
|
||||
CUBEB_ERROR_NOT_SUPPORTED) {
|
||||
fprintf(stderr,
|
||||
"Not support %s device selection. Force to use default device\n",
|
||||
device_type_to_string(type));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assert(collection.count);
|
||||
fprintf(stderr, "Found %zu %s devices. Choose one:\n", collection.count,
|
||||
device_type_to_string(type));
|
||||
|
||||
std::vector<cubeb_devid> devices;
|
||||
devices.emplace_back(nullptr);
|
||||
fprintf(stderr, "# 0\n\tname: system default device\n");
|
||||
for (size_t i = 0; i < collection.count; i++) {
|
||||
assert(collection.device[i].type == type);
|
||||
fprintf(stderr,
|
||||
"# %zu %s\n"
|
||||
"\tname: %s\n"
|
||||
"\tdevice id: %s\n"
|
||||
"\tmax channels: %u\n"
|
||||
"\tstate: %s\n",
|
||||
devices.size(),
|
||||
collection.device[i].preferred ? " (PREFERRED)" : "",
|
||||
collection.device[i].friendly_name, collection.device[i].device_id,
|
||||
collection.device[i].max_channels,
|
||||
device_state_to_string(collection.device[i].state));
|
||||
devices.emplace_back(collection.device[i].devid);
|
||||
}
|
||||
|
||||
cubeb_device_collection_destroy(context, &collection);
|
||||
|
||||
size_t number;
|
||||
std::cout << "Enter device number: ";
|
||||
std::cin >> number;
|
||||
while (!std::cin || number >= devices.size()) {
|
||||
std::cin.clear();
|
||||
std::cin.ignore(100, '\n');
|
||||
std::cout << "Error: Please enter a valid numeric input. Enter again: ";
|
||||
std::cin >> number;
|
||||
}
|
||||
return devices[number];
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef _WIN32
|
||||
CoInitialize(nullptr);
|
||||
@@ -602,7 +523,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
bool res = false;
|
||||
cubeb_client cl;
|
||||
cl.activate_log(CUBEB_LOG_NORMAL);
|
||||
cl.activate_log(CUBEB_LOG_DISABLED);
|
||||
fprintf(stderr, "Log level is DISABLED\n");
|
||||
cl.init(/* default backend */);
|
||||
|
||||
@@ -619,12 +540,10 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
} else {
|
||||
if (op.pm == PLAYBACK || op.pm == DUPLEX || op.pm == LATENCY_TESTING) {
|
||||
cl.output_device = cl.select_device(CUBEB_DEVICE_TYPE_OUTPUT);
|
||||
cl.output_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_OUTPUT_CHANNELS,
|
||||
CUBEB_LAYOUT_STEREO, CUBEB_STREAM_PREF_NONE};
|
||||
}
|
||||
if (op.pm == RECORD || op.pm == DUPLEX || op.pm == LATENCY_TESTING) {
|
||||
cl.input_device = cl.select_device(CUBEB_DEVICE_TYPE_INPUT);
|
||||
cl.input_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_INPUT_CHANNELS, CUBEB_LAYOUT_UNDEFINED, CUBEB_STREAM_PREF_NONE};
|
||||
}
|
||||
if (op.pm == LATENCY_TESTING) {
|
||||
|
Reference in New Issue
Block a user