pipewire: Hooked up default device change notifications.
parent
a93fcf2444
commit
1dffb72c1d
|
@ -571,8 +571,13 @@ int SDL_InitAudio(const char *driver_name)
|
|||
SDL_AudioDevice *default_capture = NULL;
|
||||
current_audio.impl.DetectDevices(&default_output, &default_capture);
|
||||
|
||||
current_audio.default_output_device_id = default_output ? default_output->instance_id : 0;
|
||||
current_audio.default_capture_device_id = default_capture ? default_capture->instance_id : 0;
|
||||
// these are only set if default_* is non-NULL, in case the backend just called SDL_DefaultAudioDeviceChanged directly during DetectDevices.
|
||||
if (default_output) {
|
||||
current_audio.default_output_device_id = default_output->instance_id;
|
||||
}
|
||||
if (default_capture) {
|
||||
current_audio.default_capture_device_id = default_capture->instance_id;
|
||||
}
|
||||
|
||||
// !!! FIXME: if a default is zero but there are devices available, should we just pick the first one?
|
||||
|
||||
|
|
|
@ -341,31 +341,6 @@ static void io_list_remove(Uint32 id)
|
|||
}
|
||||
}
|
||||
|
||||
static void io_list_sort(void)
|
||||
{
|
||||
struct io_node *default_sink = NULL, *default_source = NULL;
|
||||
struct io_node *n, *temp;
|
||||
|
||||
/* Find and move the default nodes to the beginning of the list */
|
||||
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
|
||||
if (pipewire_default_sink_id != NULL && SDL_strcmp(n->path, pipewire_default_sink_id) == 0) {
|
||||
default_sink = n;
|
||||
spa_list_remove(&n->link);
|
||||
} else if (pipewire_default_source_id != NULL && SDL_strcmp(n->path, pipewire_default_source_id) == 0) {
|
||||
default_source = n;
|
||||
spa_list_remove(&n->link);
|
||||
}
|
||||
}
|
||||
|
||||
if (default_source) {
|
||||
spa_list_prepend(&hotplug_io_list, &default_source->link);
|
||||
}
|
||||
|
||||
if (default_sink) {
|
||||
spa_list_prepend(&hotplug_io_list, &default_sink->link);
|
||||
}
|
||||
}
|
||||
|
||||
static void io_list_clear(void)
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
|
@ -387,19 +362,6 @@ static struct io_node *io_list_get_by_id(Uint32 id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static struct io_node *io_list_get_by_path(char *path)
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
|
||||
if (SDL_strcmp(n->path, path) == 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void node_object_destroy(struct node_object *node)
|
||||
{
|
||||
SDL_assert(node);
|
||||
|
@ -646,6 +608,23 @@ static char *get_name_from_json(const char *json)
|
|||
return SDL_strdup(value);
|
||||
}
|
||||
|
||||
static void change_default_device(const char *path)
|
||||
{
|
||||
if (hotplug_events_enabled) {
|
||||
struct io_node *n, *temp;
|
||||
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
|
||||
if (SDL_strcmp(n->path, path) == 0) {
|
||||
SDL_AudioDevice *device = SDL_ObtainPhysicalAudioDeviceByHandle(PW_ID_TO_HANDLE(n->id));
|
||||
if (device) {
|
||||
SDL_UnlockMutex(device->lock);
|
||||
SDL_DefaultAudioDeviceChanged(device);
|
||||
}
|
||||
return; // found it, we're done.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Metadata node callback */
|
||||
static int metadata_property(void *object, Uint32 subject, const char *key, const char *type, const char *value)
|
||||
{
|
||||
|
@ -658,12 +637,14 @@ static int metadata_property(void *object, Uint32 subject, const char *key, cons
|
|||
}
|
||||
pipewire_default_sink_id = get_name_from_json(value);
|
||||
node->persist = SDL_TRUE;
|
||||
change_default_device(pipewire_default_sink_id);
|
||||
} else if (!SDL_strcmp(key, "default.audio.source")) {
|
||||
if (pipewire_default_source_id != NULL) {
|
||||
SDL_free(pipewire_default_source_id);
|
||||
}
|
||||
pipewire_default_source_id = get_name_from_json(value);
|
||||
node->persist = SDL_TRUE;
|
||||
change_default_device(pipewire_default_source_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -850,14 +831,15 @@ static void PIPEWIRE_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDe
|
|||
PIPEWIRE_pw_thread_loop_wait(hotplug_loop);
|
||||
}
|
||||
|
||||
/* Sort the I/O list so the default source/sink are listed first */
|
||||
io_list_sort();
|
||||
|
||||
spa_list_for_each (io, &hotplug_io_list, link) {
|
||||
SDL_AudioDevice *device = SDL_AddAudioDevice(io->is_capture, io->name, &io->spec, PW_ID_TO_HANDLE(io->id));
|
||||
// !!! FIXME: obviously no
|
||||
if (!io->is_capture && !*default_output) { *default_output = device; }
|
||||
if (io->is_capture && !*default_capture) { *default_capture = device; }
|
||||
if (pipewire_default_sink_id != NULL && SDL_strcmp(io->path, pipewire_default_sink_id) == 0) {
|
||||
SDL_assert(!io->is_capture);
|
||||
*default_output = device;
|
||||
} else if (pipewire_default_source_id != NULL && SDL_strcmp(io->path, pipewire_default_source_id) == 0) {
|
||||
SDL_assert(io->is_capture);
|
||||
*default_capture = device;
|
||||
}
|
||||
}
|
||||
|
||||
hotplug_events_enabled = SDL_TRUE;
|
||||
|
@ -1174,6 +1156,7 @@ static int PIPEWIRE_OpenDevice(SDL_AudioDevice *device)
|
|||
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", device->sample_frames, device->spec.freq);
|
||||
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", device->spec.freq);
|
||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
|
||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DONT_RECONNECT, "true"); // Requesting a specific device, don't migrate to new default hardware.
|
||||
|
||||
/*
|
||||
* Pipewire 0.3.44 introduced PW_KEY_TARGET_OBJECT that takes either a path
|
||||
|
@ -1257,46 +1240,6 @@ static void PIPEWIRE_CloseDevice(SDL_AudioDevice *device)
|
|||
SDL_AudioThreadFinalize(device);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
struct io_node *node;
|
||||
char *target;
|
||||
int ret = 0;
|
||||
|
||||
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
|
||||
|
||||
if (iscapture) {
|
||||
if (pipewire_default_source_id == NULL) {
|
||||
ret = SDL_SetError("PipeWire could not find a default source");
|
||||
goto failed;
|
||||
}
|
||||
target = pipewire_default_source_id;
|
||||
} else {
|
||||
if (pipewire_default_sink_id == NULL) {
|
||||
ret = SDL_SetError("PipeWire could not find a default sink");
|
||||
goto failed;
|
||||
}
|
||||
target = pipewire_default_sink_id;
|
||||
}
|
||||
|
||||
node = io_list_get_by_path(target);
|
||||
if (node == NULL) {
|
||||
ret = SDL_SetError("PipeWire device list is out of sync with defaults");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (name != NULL) {
|
||||
*name = SDL_strdup(node->name);
|
||||
}
|
||||
SDL_copyp(spec, &node->spec);
|
||||
|
||||
failed:
|
||||
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PIPEWIRE_Deinitialize(void)
|
||||
{
|
||||
if (pipewire_initialized) {
|
||||
|
@ -1325,7 +1268,6 @@ static SDL_bool PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
|
|||
impl->DetectDevices = PIPEWIRE_DetectDevices;
|
||||
impl->OpenDevice = PIPEWIRE_OpenDevice;
|
||||
impl->Deinitialize = PIPEWIRE_Deinitialize;
|
||||
//impl->GetDefaultAudioInfo = PIPEWIRE_GetDefaultAudioInfo;
|
||||
impl->PlayDevice = PIPEWIRE_PlayDevice;
|
||||
impl->GetDeviceBuf = PIPEWIRE_GetDeviceBuf;
|
||||
impl->CaptureFromDevice = PIPEWIRE_CaptureFromDevice;
|
||||
|
|
Loading…
Reference in New Issue