зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1500377 - Update cubeb to upstream commit a68892d. r=kinetik
Differential Revision: https://phabricator.services.mozilla.com/D9241 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ec9bd73e34
Коммит
bd29f8d97c
|
@ -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 455981555e37a0153e5dd4d4517f073262946519 (2018-10-11 18:48:08 +0300)
|
||||
The git commit ID used was a68892dff73bad5ca2b25008b07d0b06fc850391 (2018-10-19 12:17:40 +0200)
|
||||
|
|
|
@ -93,6 +93,18 @@ void print_log(const char * msg, ...)
|
|||
* override. */
|
||||
int common_init(cubeb ** ctx, char const * ctx_name)
|
||||
{
|
||||
#ifdef ENABLE_NORMAL_LOG
|
||||
if (cubeb_set_log_callback(CUBEB_LOG_NORMAL, print_log) != CUBEB_OK) {
|
||||
fprintf(stderr, "Set normal log callback failed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VERBOSE_LOG
|
||||
if (cubeb_set_log_callback(CUBEB_LOG_VERBOSE, print_log) != CUBEB_OK) {
|
||||
fprintf(stderr, "Set verbose log callback failed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int r;
|
||||
char const * backend;
|
||||
char const * ctx_backend;
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
#include <memory>
|
||||
#include <string.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#include <string>
|
||||
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MAX_NUM_CHANNELS 32
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include <string.h>
|
||||
#include <memory>
|
||||
#include "cubeb/cubeb.h"
|
||||
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
long data_cb_duplex(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
|
|
|
@ -16,15 +16,22 @@
|
|||
#include <math.h>
|
||||
#include <memory>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#include <atomic>
|
||||
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
#define STREAM_FORMAT CUBEB_SAMPLE_FLOAT32LE
|
||||
#define INPUT_CHANNELS 1
|
||||
#define INPUT_LAYOUT CUBEB_LAYOUT_MONO
|
||||
#define OUTPUT_CHANNELS 2
|
||||
#define OUTPUT_LAYOUT CUBEB_LAYOUT_STEREO
|
||||
|
||||
struct user_state_duplex
|
||||
{
|
||||
std::atomic<int> seen_audio{ 0 };
|
||||
std::atomic<int> invalid_audio_value{ 0 };
|
||||
};
|
||||
|
||||
long data_cb_duplex(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
|
@ -32,7 +39,6 @@ long data_cb_duplex(cubeb_stream * stream, void * user, const void * inputbuffer
|
|||
user_state_duplex * u = reinterpret_cast<user_state_duplex*>(user);
|
||||
float *ib = (float *)inputbuffer;
|
||||
float *ob = (float *)outputbuffer;
|
||||
bool seen_audio = 1;
|
||||
|
||||
if (stream == NULL || inputbuffer == NULL || outputbuffer == NULL) {
|
||||
return CUBEB_ERROR;
|
||||
|
@ -42,16 +48,14 @@ long data_cb_duplex(cubeb_stream * stream, void * user, const void * inputbuffer
|
|||
// checking if there is noise in the process.
|
||||
long output_index = 0;
|
||||
for (long i = 0; i < nframes; i++) {
|
||||
if (ib[i] <= -1.0 && ib[i] >= 1.0) {
|
||||
seen_audio = 0;
|
||||
if (ib[i] <= -1.0 || ib[i] >= 1.0) {
|
||||
u->invalid_audio_value = 1;
|
||||
break;
|
||||
}
|
||||
ob[output_index] = ob[output_index + 1] = ib[i];
|
||||
output_index += 2;
|
||||
}
|
||||
|
||||
u->seen_audio |= seen_audio;
|
||||
|
||||
return nframes;
|
||||
}
|
||||
|
||||
|
@ -98,14 +102,14 @@ TEST(cubeb, duplex)
|
|||
|
||||
/* typical user-case: mono input, stereo output, low latency. */
|
||||
input_params.format = STREAM_FORMAT;
|
||||
input_params.rate = 48000;
|
||||
input_params.channels = 1;
|
||||
input_params.layout = CUBEB_LAYOUT_MONO;
|
||||
input_params.rate = SAMPLE_FREQUENCY;
|
||||
input_params.channels = INPUT_CHANNELS;
|
||||
input_params.layout = INPUT_LAYOUT;
|
||||
input_params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
output_params.format = STREAM_FORMAT;
|
||||
output_params.rate = 48000;
|
||||
output_params.channels = 2;
|
||||
output_params.layout = CUBEB_LAYOUT_STEREO;
|
||||
output_params.rate = SAMPLE_FREQUENCY;
|
||||
output_params.channels = OUTPUT_CHANNELS;
|
||||
output_params.layout = OUTPUT_LAYOUT;
|
||||
output_params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
|
||||
r = cubeb_get_min_latency(ctx, &output_params, &latency_frames);
|
||||
|
@ -123,7 +127,7 @@ TEST(cubeb, duplex)
|
|||
delay(500);
|
||||
cubeb_stream_stop(stream);
|
||||
|
||||
ASSERT_TRUE(stream_state.seen_audio.load());
|
||||
ASSERT_FALSE(stream_state.invalid_audio_value.load());
|
||||
}
|
||||
|
||||
void device_collection_changed_callback(cubeb * context, void * user)
|
||||
|
@ -156,14 +160,14 @@ TEST(cubeb, duplex_collection_change)
|
|||
|
||||
/* typical user-case: mono input, stereo output, low latency. */
|
||||
input_params.format = STREAM_FORMAT;
|
||||
input_params.rate = 48000;
|
||||
input_params.channels = 1;
|
||||
input_params.layout = CUBEB_LAYOUT_MONO;
|
||||
input_params.rate = SAMPLE_FREQUENCY;
|
||||
input_params.channels = INPUT_CHANNELS;
|
||||
input_params.layout = INPUT_LAYOUT;
|
||||
input_params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
output_params.format = STREAM_FORMAT;
|
||||
output_params.rate = 48000;
|
||||
output_params.channels = 2;
|
||||
output_params.layout = CUBEB_LAYOUT_STEREO;
|
||||
output_params.rate = SAMPLE_FREQUENCY;
|
||||
output_params.channels = OUTPUT_CHANNELS;
|
||||
output_params.layout = OUTPUT_LAYOUT;
|
||||
output_params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
|
||||
r = cubeb_get_min_latency(ctx, &output_params, &latency_frames);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <memory>
|
||||
#include "cubeb/cubeb.h"
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
TEST(cubeb, latency)
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
#include <mutex>
|
||||
#include <string>
|
||||
#include "cubeb/cubeb.h"
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
const uint32_t SAMPLE_FREQUENCY = 48000;
|
||||
const uint32_t TONE_FREQUENCY = 440;
|
||||
const double OUTPUT_AMPLITUDE = 0.25;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "cubeb/cubeb.h"
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
|
|
|
@ -15,15 +15,18 @@
|
|||
#include <math.h>
|
||||
#include <memory>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#include <atomic>
|
||||
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
#define STREAM_FORMAT CUBEB_SAMPLE_FLOAT32LE
|
||||
|
||||
struct user_state_record
|
||||
{
|
||||
std::atomic<int> seen_audio{ 0 };
|
||||
std::atomic<int> invalid_audio_value{ 0 };
|
||||
};
|
||||
|
||||
long data_cb_record(cubeb_stream * stream, void * user, const void * inputbuffer, void * outputbuffer, long nframes)
|
||||
|
@ -35,16 +38,13 @@ long data_cb_record(cubeb_stream * stream, void * user, const void * inputbuffer
|
|||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
bool seen_audio = 1;
|
||||
for (long i = 0; i < nframes; i++) {
|
||||
if (b[i] <= -1.0 && b[i] >= 1.0) {
|
||||
seen_audio = 0;
|
||||
if (b[i] <= -1.0 || b[i] >= 1.0) {
|
||||
u->invalid_audio_value = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u->seen_audio |= seen_audio;
|
||||
|
||||
return nframes;
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,6 @@ TEST(cubeb, record)
|
|||
// user callback does not arrive in Linux, silence the error
|
||||
fprintf(stderr, "Check is disabled in Linux\n");
|
||||
#else
|
||||
ASSERT_TRUE(stream_state.seen_audio.load());
|
||||
ASSERT_FALSE(stream_state.invalid_audio_value.load());
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
#define STREAM_RATE 44100
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
#include <memory>
|
||||
#include <limits.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "common.h"
|
||||
#include <atomic>
|
||||
|
||||
//#define ENABLE_NORMAL_LOG
|
||||
//#define ENABLE_VERBOSE_LOG
|
||||
#include "common.h"
|
||||
|
||||
|
||||
#define SAMPLE_FREQUENCY 48000
|
||||
#define STREAM_FORMAT CUBEB_SAMPLE_S16LE
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
diff --git a/media/libcubeb/src/cubeb.c b/media/libcubeb/src/cubeb.c
|
||||
index 1db59240e335..241f3cfed041 100644
|
||||
--- a/media/libcubeb/src/cubeb.c
|
||||
+++ b/media/libcubeb/src/cubeb.c
|
||||
@@ -166,6 +166,9 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam
|
||||
* to override all other choices
|
||||
*/
|
||||
init_oneshot,
|
||||
+#if defined(USE_PULSE_RUST)
|
||||
+ pulse_rust_init,
|
||||
+#endif
|
||||
#if defined(USE_PULSE)
|
||||
pulse_init,
|
||||
#endif
|
|
@ -132,11 +132,13 @@ struct cubeb {
|
|||
owned_critical_section mutex;
|
||||
int active_streams = 0;
|
||||
uint32_t global_latency_frames = 0;
|
||||
cubeb_device_collection_changed_callback collection_changed_callback = nullptr;
|
||||
void * collection_changed_user_ptr = nullptr;
|
||||
/* Differentiate input from output devices. */
|
||||
cubeb_device_type collection_changed_devtype = CUBEB_DEVICE_TYPE_UNKNOWN;
|
||||
vector<AudioObjectID> devtype_device_array;
|
||||
cubeb_device_collection_changed_callback input_collection_changed_callback = nullptr;
|
||||
void * input_collection_changed_user_ptr = nullptr;
|
||||
cubeb_device_collection_changed_callback output_collection_changed_callback = nullptr;
|
||||
void * output_collection_changed_user_ptr = nullptr;
|
||||
// Store list of devices to detect changes
|
||||
vector<AudioObjectID> input_device_array;
|
||||
vector<AudioObjectID> output_device_array;
|
||||
// The queue is asynchronously deallocated once all references to it are released
|
||||
dispatch_queue_t serial_queue = dispatch_queue_create(DISPATCH_QUEUE_LABEL, DISPATCH_QUEUE_SERIAL);
|
||||
// Current used channel layout
|
||||
|
@ -1406,7 +1408,7 @@ audiounit_get_current_channel_layout(AudioUnit output_unit)
|
|||
|
||||
static int audiounit_create_unit(AudioUnit * unit, device_info * device);
|
||||
|
||||
static OSStatus audiounit_remove_device_listener(cubeb * context);
|
||||
static OSStatus audiounit_remove_device_listener(cubeb * context, cubeb_device_type devtype);
|
||||
|
||||
static void
|
||||
audiounit_destroy(cubeb * ctx)
|
||||
|
@ -1421,8 +1423,11 @@ audiounit_destroy(cubeb * ctx)
|
|||
}
|
||||
|
||||
/* Unregister the callback if necessary. */
|
||||
if (ctx->collection_changed_callback) {
|
||||
audiounit_remove_device_listener(ctx);
|
||||
if (ctx->input_collection_changed_callback) {
|
||||
audiounit_remove_device_listener(ctx, CUBEB_DEVICE_TYPE_INPUT);
|
||||
}
|
||||
if (ctx->output_collection_changed_callback) {
|
||||
audiounit_remove_device_listener(ctx, CUBEB_DEVICE_TYPE_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1841,8 +1846,8 @@ audiounit_workaround_for_airpod(cubeb_stream * stm)
|
|||
std::string input_name_str(input_device_info.friendly_name);
|
||||
std::string output_name_str(output_device_info.friendly_name);
|
||||
|
||||
if( input_name_str.find("AirPods") != std::string::npos
|
||||
&& output_name_str.find("AirPods") != std::string::npos ) {
|
||||
if(input_name_str.find("AirPods") != std::string::npos &&
|
||||
output_name_str.find("AirPods") != std::string::npos) {
|
||||
uint32_t input_min_rate = 0;
|
||||
uint32_t input_max_rate = 0;
|
||||
uint32_t input_nominal_rate = 0;
|
||||
|
@ -1980,8 +1985,8 @@ audiounit_new_unit_instance(AudioUnit * unit, device_info * device)
|
|||
// 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.
|
||||
if ((device->flags & DEV_SYSTEM_DEFAULT)
|
||||
&& (device->flags & DEV_OUTPUT)) {
|
||||
if ((device->flags & DEV_SYSTEM_DEFAULT) &&
|
||||
(device->flags & DEV_OUTPUT)) {
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
} else {
|
||||
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
|
@ -2041,8 +2046,8 @@ audiounit_create_unit(AudioUnit * unit, device_info * device)
|
|||
}
|
||||
assert(*unit);
|
||||
|
||||
if ((device->flags & DEV_SYSTEM_DEFAULT)
|
||||
&& (device->flags & DEV_OUTPUT)) {
|
||||
if ((device->flags & DEV_SYSTEM_DEFAULT) &&
|
||||
(device->flags & DEV_OUTPUT)) {
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
|
@ -3450,23 +3455,27 @@ audiounit_collection_changed_callback(AudioObjectID /* inObjectID */,
|
|||
// This can be called from inside an AudioUnit function, dispatch to another queue.
|
||||
dispatch_async(context->serial_queue, ^() {
|
||||
auto_lock lock(context->mutex);
|
||||
if (context->collection_changed_callback == NULL) {
|
||||
if (!context->input_collection_changed_callback &&
|
||||
!context->output_collection_changed_callback) {
|
||||
/* Listener removed while waiting in mutex, abort. */
|
||||
return;
|
||||
}
|
||||
|
||||
assert(context->collection_changed_devtype &
|
||||
(CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT));
|
||||
|
||||
vector<AudioObjectID> devices = audiounit_get_devices_of_type(context->collection_changed_devtype);
|
||||
/* The elements in the vector are sorted. */
|
||||
if (context->devtype_device_array == devices) {
|
||||
/* Device changed for the other scope, ignore. */
|
||||
return;
|
||||
if (context->input_collection_changed_callback) {
|
||||
vector<AudioObjectID> devices = audiounit_get_devices_of_type(CUBEB_DEVICE_TYPE_INPUT);
|
||||
/* Elements in the vector expected sorted. */
|
||||
if (context->input_device_array != devices) {
|
||||
context->input_device_array = devices;
|
||||
context->input_collection_changed_callback(context, context->input_collection_changed_user_ptr);
|
||||
}
|
||||
}
|
||||
if (context->output_collection_changed_callback) {
|
||||
vector<AudioObjectID> devices = audiounit_get_devices_of_type(CUBEB_DEVICE_TYPE_OUTPUT);
|
||||
/* Elements in the vector expected sorted. */
|
||||
if (context->output_device_array != devices) {
|
||||
context->output_device_array = devices;
|
||||
context->output_collection_changed_callback(context, context->output_collection_changed_user_ptr);
|
||||
}
|
||||
}
|
||||
/* Device on desired scope has changed. */
|
||||
context->devtype_device_array = devices;
|
||||
context->collection_changed_callback(context, context->collection_changed_user_ptr);
|
||||
});
|
||||
return noErr;
|
||||
}
|
||||
|
@ -3477,45 +3486,65 @@ audiounit_add_device_listener(cubeb * context,
|
|||
cubeb_device_collection_changed_callback collection_changed_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
context->mutex.assert_current_thread_owns();
|
||||
assert(devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT));
|
||||
/* Note: second register without unregister first causes 'nope' error.
|
||||
* Current implementation requires unregister before register a new cb. */
|
||||
assert(context->collection_changed_callback == NULL);
|
||||
assert((devtype & CUBEB_DEVICE_TYPE_INPUT) && !context->input_collection_changed_callback ||
|
||||
(devtype & CUBEB_DEVICE_TYPE_OUTPUT) && !context->output_collection_changed_callback);
|
||||
|
||||
OSStatus ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject,
|
||||
&DEVICES_PROPERTY_ADDRESS,
|
||||
audiounit_collection_changed_callback,
|
||||
context);
|
||||
if (ret == noErr) {
|
||||
/* Expected empty after unregister. */
|
||||
assert(context->devtype_device_array.empty());
|
||||
/* Listener works for input and output.
|
||||
* When requested one of them we need to differentiate. */
|
||||
assert(devtype &
|
||||
(CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT));
|
||||
context->devtype_device_array = audiounit_get_devices_of_type(devtype);
|
||||
context->collection_changed_devtype = devtype;
|
||||
context->collection_changed_callback = collection_changed_callback;
|
||||
context->collection_changed_user_ptr = user_ptr;
|
||||
if (!context->input_collection_changed_callback &&
|
||||
!context->output_collection_changed_callback) {
|
||||
OSStatus ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject,
|
||||
&DEVICES_PROPERTY_ADDRESS,
|
||||
audiounit_collection_changed_callback,
|
||||
context);
|
||||
if (ret != noErr) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
if (devtype & CUBEB_DEVICE_TYPE_INPUT) {
|
||||
/* Expected empty after unregister. */
|
||||
assert(context->input_device_array.empty());
|
||||
context->input_device_array = audiounit_get_devices_of_type(CUBEB_DEVICE_TYPE_INPUT);
|
||||
context->input_collection_changed_callback = collection_changed_callback;
|
||||
context->input_collection_changed_user_ptr = user_ptr;
|
||||
}
|
||||
if (devtype & CUBEB_DEVICE_TYPE_OUTPUT) {
|
||||
/* Expected empty after unregister. */
|
||||
assert(context->output_device_array.empty());
|
||||
context->output_device_array = audiounit_get_devices_of_type(CUBEB_DEVICE_TYPE_OUTPUT);
|
||||
context->output_collection_changed_callback = collection_changed_callback;
|
||||
context->output_collection_changed_user_ptr = user_ptr;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static OSStatus
|
||||
audiounit_remove_device_listener(cubeb * context)
|
||||
audiounit_remove_device_listener(cubeb * context, cubeb_device_type devtype)
|
||||
{
|
||||
/* Note: unregister a non registered cb is not a problem, not checking. */
|
||||
OSStatus ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject,
|
||||
&DEVICES_PROPERTY_ADDRESS,
|
||||
audiounit_collection_changed_callback,
|
||||
context);
|
||||
if (ret == noErr) {
|
||||
/* Reset all values. */
|
||||
context->collection_changed_devtype = CUBEB_DEVICE_TYPE_UNKNOWN;
|
||||
context->collection_changed_callback = NULL;
|
||||
context->collection_changed_user_ptr = NULL;
|
||||
context->devtype_device_array.clear();
|
||||
context->mutex.assert_current_thread_owns();
|
||||
|
||||
if (devtype & CUBEB_DEVICE_TYPE_INPUT) {
|
||||
context->input_collection_changed_callback = nullptr;
|
||||
context->input_collection_changed_user_ptr = nullptr;
|
||||
context->input_device_array.clear();
|
||||
}
|
||||
return ret;
|
||||
if (devtype & CUBEB_DEVICE_TYPE_OUTPUT) {
|
||||
context->output_collection_changed_callback = nullptr;
|
||||
context->output_collection_changed_user_ptr = nullptr;
|
||||
context->output_device_array.clear();
|
||||
}
|
||||
|
||||
if (context->input_collection_changed_callback ||
|
||||
context->output_collection_changed_callback) {
|
||||
return noErr;
|
||||
}
|
||||
/* Note: unregister a non registered cb is not a problem, not checking. */
|
||||
return AudioObjectRemovePropertyListener(kAudioObjectSystemObject,
|
||||
&DEVICES_PROPERTY_ADDRESS,
|
||||
audiounit_collection_changed_callback,
|
||||
context);
|
||||
}
|
||||
|
||||
int audiounit_register_device_collection_changed(cubeb * context,
|
||||
|
@ -3523,14 +3552,18 @@ int audiounit_register_device_collection_changed(cubeb * context,
|
|||
cubeb_device_collection_changed_callback collection_changed_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
if (devtype == CUBEB_DEVICE_TYPE_UNKNOWN) {
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
OSStatus ret;
|
||||
auto_lock lock(context->mutex);
|
||||
if (collection_changed_callback) {
|
||||
ret = audiounit_add_device_listener(context, devtype,
|
||||
ret = audiounit_add_device_listener(context,
|
||||
devtype,
|
||||
collection_changed_callback,
|
||||
user_ptr);
|
||||
} else {
|
||||
ret = audiounit_remove_device_listener(context);
|
||||
ret = audiounit_remove_device_listener(context, devtype);
|
||||
}
|
||||
return (ret == noErr) ? CUBEB_OK : CUBEB_ERROR;
|
||||
}
|
||||
|
|
|
@ -111,8 +111,10 @@ struct cubeb {
|
|||
struct cubeb_default_sink_info * default_sink_info;
|
||||
char * context_name;
|
||||
int error;
|
||||
cubeb_device_collection_changed_callback collection_changed_callback;
|
||||
void * collection_changed_user_ptr;
|
||||
cubeb_device_collection_changed_callback output_collection_changed_callback;
|
||||
void * output_collection_changed_user_ptr;
|
||||
cubeb_device_collection_changed_callback input_collection_changed_callback;
|
||||
void * input_collection_changed_user_ptr;
|
||||
cubeb_strings * device_ids;
|
||||
};
|
||||
|
||||
|
@ -1496,23 +1498,28 @@ pulse_subscribe_callback(pa_context * ctx,
|
|||
if (g_cubeb_log_level) {
|
||||
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE &&
|
||||
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
|
||||
LOG("Removing sink index %d", index);
|
||||
LOG("Removing source index %d", index);
|
||||
} else if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE &&
|
||||
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
|
||||
LOG("Adding sink index %d", index);
|
||||
LOG("Adding source index %d", index);
|
||||
}
|
||||
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK &&
|
||||
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
|
||||
LOG("Removing source index %d", index);
|
||||
LOG("Removing sink index %d", index);
|
||||
} else if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK &&
|
||||
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
|
||||
LOG("Adding source index %d", index);
|
||||
LOG("Adding sink index %d", index);
|
||||
}
|
||||
}
|
||||
|
||||
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE ||
|
||||
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
|
||||
context->collection_changed_callback(context, context->collection_changed_user_ptr);
|
||||
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE) {
|
||||
context->input_collection_changed_callback(context, context->input_collection_changed_user_ptr);
|
||||
}
|
||||
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) {
|
||||
context->output_collection_changed_callback(context, context->output_collection_changed_user_ptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1533,24 +1540,32 @@ pulse_register_device_collection_changed(cubeb * context,
|
|||
cubeb_device_collection_changed_callback collection_changed_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
context->collection_changed_callback = collection_changed_callback;
|
||||
context->collection_changed_user_ptr = user_ptr;
|
||||
if (devtype & CUBEB_DEVICE_TYPE_INPUT) {
|
||||
context->input_collection_changed_callback = collection_changed_callback;
|
||||
context->input_collection_changed_user_ptr = user_ptr;
|
||||
}
|
||||
if (devtype & CUBEB_DEVICE_TYPE_OUTPUT) {
|
||||
context->output_collection_changed_callback = collection_changed_callback;
|
||||
context->output_collection_changed_user_ptr = user_ptr;
|
||||
}
|
||||
|
||||
WRAP(pa_threaded_mainloop_lock)(context->mainloop);
|
||||
|
||||
pa_subscription_mask_t mask;
|
||||
if (context->collection_changed_callback == NULL) {
|
||||
// Unregister subscription
|
||||
WRAP(pa_context_set_subscribe_callback)(context->context, NULL, NULL);
|
||||
mask = PA_SUBSCRIPTION_MASK_NULL;
|
||||
pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_NULL;
|
||||
if (context->input_collection_changed_callback) {
|
||||
mask |= PA_SUBSCRIPTION_MASK_SOURCE;
|
||||
}
|
||||
if (context->output_collection_changed_callback) {
|
||||
mask |= PA_SUBSCRIPTION_MASK_SINK;
|
||||
}
|
||||
|
||||
if (collection_changed_callback == NULL) {
|
||||
// Unregister subscription.
|
||||
if (mask == PA_SUBSCRIPTION_MASK_NULL) {
|
||||
WRAP(pa_context_set_subscribe_callback)(context->context, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
WRAP(pa_context_set_subscribe_callback)(context->context, pulse_subscribe_callback, context);
|
||||
if (devtype == CUBEB_DEVICE_TYPE_INPUT)
|
||||
mask = PA_SUBSCRIPTION_MASK_SOURCE;
|
||||
else if (devtype == CUBEB_DEVICE_TYPE_OUTPUT)
|
||||
mask = PA_SUBSCRIPTION_MASK_SINK;
|
||||
else
|
||||
mask = PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE;
|
||||
}
|
||||
|
||||
pa_operation * o;
|
||||
|
|
|
@ -77,8 +77,5 @@ fi
|
|||
echo "Applying disable-assert.patch on top of $rev"
|
||||
patch -p3 < disable-assert.patch
|
||||
|
||||
echo "Applying prefer-pulse-rust.patch on top of $rev"
|
||||
patch -p3 < prefer-pulse-rust.patch
|
||||
|
||||
echo "Applying disable-device-switching.patch on top of $rev"
|
||||
patch -p3 < disable-device-switching.patch
|
||||
|
|
Загрузка…
Ссылка в новой задаче