]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add two PipeWire backend ("pw") settings -- application_name (default: "Shairport...
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Thu, 5 Oct 2023 08:41:21 +0000 (09:41 +0100)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Thu, 5 Oct 2023 08:41:21 +0000 (09:41 +0100)
audio_pw.c
common.h
scripts/shairport-sync.conf

index a053edc7c196898a863bdd4a2d04eab2e1294a14..0dd3893934317812117348db1c7a902c16845f99 100644 (file)
 
 // 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);
 
index 1b9e2f03dc75b73c2195c9b04a08cc8317856211..3a392f684118a3c982b768e4409a1b953ddb3a58 100644 (file)
--- 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;
index 3f4c152f565caf4dd433f18f25f86e18e561bb03..001a88d267532ffa25a540d802defa437e0c72ca 100644 (file)
@@ -154,6 +154,15 @@ sndio =
 //     bufsz = <number>; // 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 = "<application-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 = <number>; // 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 =