From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Thu, 5 Oct 2023 08:41:21 +0000 (+0100) Subject: Add two PipeWire backend ("pw") settings -- application_name (default: "Shairport... X-Git-Tag: 4.3.2^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3763b321b8bd122eb340985c3c52471638bf384b;p=thirdparty%2Fshairport-sync.git Add two PipeWire backend ("pw") settings -- application_name (default: "Shairport Sync") and node_name (default: "shairport-sync"). --- diff --git a/audio_pw.c b/audio_pw.c index a053edc7..0dd38939 100644 --- a/audio_pw.c +++ b/audio_pw.c @@ -41,11 +41,14 @@ // note -- these are hardwired into this code. #define DEFAULT_FORMAT SPA_AUDIO_FORMAT_S16_LE +#define DEFAULT_BYTES_PER_SAMPLE 2 + #define DEFAULT_RATE 44100 #define DEFAULT_CHANNELS 2 +#define DEFAULT_BUFFER_SIZE_IN_SECONDS 4 // Four seconds buffer -- should be plenty -#define buffer_allocation 44100 * 4 * 2 * 2 +#define buffer_allocation DEFAULT_RATE * DEFAULT_BUFFER_SIZE_IN_SECONDS * DEFAULT_BYTES_PER_SAMPLE * DEFAULT_CHANNELS static pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -101,7 +104,7 @@ static void on_process(void *userdata) { struct spa_buffer *buf = b->buffer; uint8_t *dest = buf->datas[0].data; if (dest != NULL) { - int stride = sizeof(int16_t) * DEFAULT_CHANNELS; + int stride = DEFAULT_BYTES_PER_SAMPLE * DEFAULT_CHANNELS; // note: the requested field is the number of frames, not bytes, requested int max_possible_frames = SPA_MIN(b->requested, buf->datas[0].maxsize / stride); @@ -170,6 +173,13 @@ static void deinit(void) { pw_thread_loop_destroy(data.loop); pw_deinit(); free(audio_lmb); // deallocate that buffer + if (config.pw_application_name) + free(config.pw_application_name); + if (config.pw_node_name) + free(config.pw_node_name); + config.pw_application_name = config.pw_node_name = NULL; + + } static int init(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) { @@ -187,12 +197,22 @@ static int init(__attribute__((unused)) int argc, __attribute__((unused)) char * // do the "general" audio options. Note, these options are in the "general" stanza! parse_general_audio_options(); - /* + // now any PipeWire-specific options if (config.cfg != NULL) { const char *str; + + /* Get the Application Name. */ + if (config_lookup_string(config.cfg, "pw.application_name", &str)) { + config.pw_application_name = (char *)str; + } + + /* Get the PulseAudio node name. */ + if (config_lookup_string(config.cfg, "pa.node_name", &str)) { + config.pw_node_name = (char *)str; + } } - */ + // finished collecting settings // allocate space for the audio buffer @@ -219,17 +239,28 @@ static int init(__attribute__((unused)) int argc, __attribute__((unused)) char * pw_thread_loop_lock(data.loop); pw_thread_loop_start(data.loop); + + char* appname = config.pw_application_name; + if (appname == NULL) + appname = "Shairport Sync"; + + char* nodename = config.pw_node_name; + if (nodename == NULL) + nodename = config.appName; + + props = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio", PW_KEY_MEDIA_CATEGORY, "Playback", - PW_KEY_MEDIA_ROLE, "Music", PW_KEY_APP_NAME, "Shairport Sync", NULL); + PW_KEY_MEDIA_ROLE, "Music", PW_KEY_APP_NAME, appname, + PW_KEY_NODE_NAME, nodename, NULL); - data.stream = pw_stream_new_simple(pw_thread_loop_get_loop(data.loop), "shairport-sync", props, + data.stream = pw_stream_new_simple(pw_thread_loop_get_loop(data.loop), config.appName, props, &stream_events, &data); /* Make one parameter with the supported formats. The SPA_PARAM_EnumFormat * id means that this is a format enumeration (of 1 value). */ params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, - &SPA_AUDIO_INFO_RAW_INIT(.format = SPA_AUDIO_FORMAT_S16_LE, + &SPA_AUDIO_INFO_RAW_INIT(.format = DEFAULT_FORMAT, .channels = DEFAULT_CHANNELS, .rate = DEFAULT_RATE)); @@ -303,7 +334,7 @@ int delay(long *the_delay) { delay_in_ns = delay_in_ns / timing_data.time_info.rate.denom; int64_t total_delay_now_ns = delay_in_ns - interval_from_process_time_to_now; - int64_t total_delay_now_frames = (total_delay_now_ns * 44100) / 1000000000 + timing_data.frames; + int64_t total_delay_now_frames = (total_delay_now_ns * DEFAULT_RATE) / 1000000000 + timing_data.frames; total_delay_now_frames_long = total_delay_now_frames; debug(3, "total delay in frames: %ld.", total_delay_now_frames_long); diff --git a/common.h b/common.h index 1b9e2f03..3a392f68 100644 --- a/common.h +++ b/common.h @@ -139,10 +139,17 @@ typedef struct { char *pa_server; // the pulseaudio server address that Shairport Sync will play on. char *pa_application_name; // the name under which Shairport Sync shows up as an "Application" in // the Sound Preferences in most desktop Linuxes. - // Defaults to "Shairport Sync". Shairport Sync must be playing to see it. + // Defaults to "Shairport Sync". char *pa_sink; // the name (or id) of the sink that Shairport Sync will play on. #endif +#ifdef CONFIG_PW + char *pw_application_name; // the name under which Shairport Sync shows up as an "Application" in + // the Sound Preferences in most desktop Linuxes. + // Defaults to "Shairport Sync". + + char *pw_node_name; // defaults to the application's name, usually "shairport-sync". +#endif #ifdef CONFIG_METADATA int metadata_enabled; char *metadata_pipename; diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf index 3f4c152f..001a88d2 100644 --- a/scripts/shairport-sync.conf +++ b/scripts/shairport-sync.conf @@ -154,6 +154,15 @@ sndio = // bufsz = ; // advanced optional setting to set the buffer size near to this value }; +// Parameters for the "pw" PipeWire backend. +// For this section to be operative, Shairport Sync must be built with the following configuration flag: +// --with-pw +pw = +{ +// application_name = "Shairport Sync"; // Set this to the name that should appear in the Sounds "Applications". +// node_name = ""; // This is normally "shairport-sync". +}; + // Parameters for the "pa" PulseAudio backend. // For this section to be operative, Shairport Sync must be built with the following configuration flag: // --with-pa @@ -181,7 +190,7 @@ jack = // bufsz = ; // advanced optional setting to set the buffer size to this value }; -// Parameters for the "pipe" audio back end, a back end that directs raw CD-style audio output to a pipe. No interpolation is done. +// Parameters for the "pipe" audio back end, a back end that directs raw CD-format audio output to a pipe. No interpolation is done. // For this section to be operative, Shairport Sync must have been built with the following configuration flag: // --with-pipe pipe =