(PipeWire) Pass the new_rate to the audio driver (#17508)

Set the supported sample rate after initialization.
Also a few minor fixes.
This commit is contained in:
Viačasłaŭ 2025-02-03 06:30:02 +03:00 committed by GitHub
parent 9b3b75aa93
commit 45586e83da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 39 additions and 45 deletions

View File

@ -203,20 +203,19 @@ void pipewire_core_deinit(pipewire_core_t *pw)
pw_thread_loop_stop(pw->thread_loop);
if (pw->registry)
{
spa_hook_remove(&pw->registry_listener);
pw_proxy_destroy((struct pw_proxy*)pw->registry);
}
if (pw->core)
{
spa_hook_remove(&pw->core_listener);
spa_zero(pw->core_listener);
pw_core_disconnect(pw->core);
}
if (pw->ctx)
pw_context_destroy(pw->ctx);
if (pw->thread_loop)
pw_thread_loop_destroy(pw->thread_loop);
spa_clear_ptr(pw->ctx, pw_context_destroy);
spa_clear_ptr(pw->thread_loop, pw_thread_loop_destroy);
if (pw->devicelist)
string_list_free(pw->devicelist);

View File

@ -33,7 +33,7 @@
#define PW_RARCH_MEDIA_TYPE_VIDEO "Video"
#define PW_RARCH_MEDIA_TYPE_MIDI "Midi"
#define PW_RARCH_MEDIA_CATEGORY_PLAYBACK "Playback"
#define PW_RARCH_MEDIA_CATEGORY_RECORD "Capture"
#define PW_RARCH_MEDIA_CATEGORY_RECORD "Capture"
#define PW_RARCH_MEDIA_ROLE "Game"
typedef struct pipewire_core

View File

@ -61,6 +61,7 @@ static void playback_process_cb(void *data)
uint32_t req, idx, n_bytes;
int32_t avail;
retro_assert(audio);
retro_assert(audio->stream);
if ((b = pw_stream_dequeue_buffer(audio->stream)) == NULL)
@ -132,26 +133,22 @@ static void registry_event_global(void *data, uint32_t id,
union string_list_elem_attr attr;
const struct spa_dict_item *item;
pipewire_core_t *pw = (pipewire_core_t*)data;
const char *media = NULL;
const char *sink = NULL;
if (spa_streq(type, PW_TYPE_INTERFACE_Node))
if (spa_streq(type, PW_TYPE_INTERFACE_Node)
&& spa_streq("Audio/Sink", spa_dict_lookup(props, PW_KEY_MEDIA_CLASS)))
{
media = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
if (media && spa_streq(media, "Audio/Sink"))
sink = spa_dict_lookup(props, PW_KEY_NODE_NAME);
if (sink && pw->devicelist)
{
sink = spa_dict_lookup(props, PW_KEY_NODE_NAME);
if (sink && pw->devicelist)
{
attr.i = id;
string_list_append(pw->devicelist, sink, attr);
RARCH_LOG("[Audio] [PipeWire]: Found Sink Node: %s\n", sink);
}
RARCH_DBG("[Audio] [PipeWire]: Object: id:%u Type:%s/%d\n", id, type, version);
spa_dict_for_each(item, props)
RARCH_DBG("[Audio] [PipeWire]: \t\t%s: \"%s\"\n", item->key, item->value);
attr.i = id;
string_list_append(pw->devicelist, sink, attr);
RARCH_LOG("[Audio] [PipeWire]: Found Sink Node: %s\n", sink);
}
RARCH_DBG("[Audio] [PipeWire]: Object: id:%u Type:%s/%d\n", id, type, version);
spa_dict_for_each(item, props)
RARCH_DBG("[Audio] [PipeWire]: \t\t%s: \"%s\"\n", item->key, item->value);
}
}
@ -225,15 +222,17 @@ static void *pipewire_init(const char *device, unsigned rate,
PW_STREAM_FLAG_MAP_BUFFERS |
PW_STREAM_FLAG_RT_PROCESS,
params, 1);
if (res < 0)
goto unlock_error;
audio->highwater_mark = MIN(RINGBUFFER_SIZE,
latency * (uint64_t)rate / 1000 * audio->frame_size);
pw_thread_loop_wait(audio->pw->thread_loop);
pw_thread_loop_unlock(audio->pw->thread_loop);
*new_rate = audio->info.rate;
return audio;
unlock_error:
@ -384,7 +383,7 @@ static void pipewire_free(void *data)
pipewire_audio_t *audio = (pipewire_audio_t*)data;
if (!audio)
return pw_deinit();
return;
if (audio->stream)
{

View File

@ -72,7 +72,8 @@ static void capture_process_cb(void *data)
uint32_t idx, offs, n_bytes;
pipewire_microphone_t *mic = (pipewire_microphone_t*)data;
assert(mic->stream);
retro_assert(mic);
retro_assert(mic->stream);
if (!(b = pw_stream_dequeue_buffer(mic->stream)))
{
@ -120,28 +121,25 @@ static void registry_event_global(void *data, uint32_t id,
union string_list_elem_attr attr;
const struct spa_dict_item *item;
pipewire_core_t *pw = (pipewire_core_t*)data;
const char *media = NULL;
const char *sink = NULL;
if (!pw)
return;
if (spa_streq(type, PW_TYPE_INTERFACE_Node))
if ( spa_streq(type, PW_TYPE_INTERFACE_Node)
&& spa_streq("Audio/Source", spa_dict_lookup(props, PW_KEY_MEDIA_CLASS)))
{
media = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
if (media && spa_streq(media, "Audio/Source"))
sink = spa_dict_lookup(props, PW_KEY_NODE_NAME);
if (sink && pw->devicelist)
{
if ((sink = spa_dict_lookup(props, PW_KEY_NODE_NAME)) != NULL)
{
attr.i = id;
string_list_append(pw->devicelist, sink, attr);
RARCH_LOG("[Microphone] [PipeWire]: Found Source Node: %s\n", sink);
}
RARCH_DBG("[Microphone] [PipeWire]: Object: id:%u Type:%s/%d\n", id, type, version);
spa_dict_for_each(item, props)
RARCH_DBG("[Microphone] [PipeWire]: \t\t%s: \"%s\"\n", item->key, item->value);
attr.i = id;
string_list_append(pw->devicelist, sink, attr);
RARCH_LOG("[Microphone] [PipeWire]: Found Source Node: %s\n", sink);
}
RARCH_DBG("[Microphone] [PipeWire]: Object: id:%u Type:%s/%d\n", id, type, version);
spa_dict_for_each(item, props)
RARCH_DBG("[Microphone] [PipeWire]: \t\t%s: \"%s\"\n", item->key, item->value);
}
}
@ -285,14 +283,12 @@ static void *pipewire_microphone_open_mic(void *driver_context,
struct pw_properties *props = NULL;
const char *error = NULL;
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
pipewire_microphone_t *mic = calloc(1, sizeof(pipewire_microphone_t));
pipewire_microphone_t *mic = NULL;
retro_assert(driver_context);
if (!mic)
if (!driver_context || (mic = calloc(1, sizeof(pipewire_microphone_t))) == NULL)
goto error;
mic->pw = (pipewire_core_t*)driver_context;
mic->pw = (pipewire_core_t*)driver_context;
pw_thread_loop_lock(mic->pw->thread_loop);
@ -393,7 +389,7 @@ static bool pipewire_microphone_stop_mic(void *driver_context, void *mic_context
return false;
if (pw_stream_get_state(mic->stream, &error) == PW_STREAM_STATE_STREAMING)
res = pipewire_stream_set_active(pw->thread_loop, mic->stream, false);
res = pipewire_stream_set_active(pw->thread_loop, mic->stream, false);
else
/* For other states we assume that the stream is inactive */
res = true;