@@ -406,7 +406,7 @@ static void send_rec_data(pa_stream *s, struct userdata *u, bool discard_overrun
406406 pa_stream_drop (s );
407407}
408408
409- /* This is called whenever new data may is available */
409+ /* This is called whenever new data may be available */
410410static void stream_read_callback (pa_stream * s , size_t length , void * userdata ) {
411411 struct userdata * u = userdata ;
412412
@@ -730,6 +730,8 @@ static bool connect_disconnect_rec_stream(
730730static void context_state_callback (pa_context * c , void * userdata ) {
731731 struct userdata * u = userdata ;
732732 pa_stream_flags_t flags = 0 ;
733+ pa_cvolume cvolume = {1 , {u -> volume }};
734+ pa_cvolume * vol = NULL ;
733735
734736 assert (c );
735737
@@ -769,11 +771,23 @@ static void context_state_callback(pa_context *c, void *userdata) {
769771 pa_stream_set_started_callback (u -> play_stream , stream_started_callback , u );
770772 pa_stream_set_event_callback (u -> play_stream , stream_event_callback , u );
771773 pa_stream_set_buffer_attr_callback (u -> play_stream , stream_buffer_attr_callback , u );
772- flags = PA_STREAM_ADJUST_LATENCY ;
774+ flags |= PA_STREAM_ADJUST_LATENCY ;
775+
776+ if (u -> volume == PA_VOLUME_MUTED ) {
777+ flags |= PA_STREAM_START_MUTED ;
778+ // It is strongly advised to not only mute, but set volume to zero as well
779+ // vol = &cvolume;
780+ // pa_cvolume_mute(vol, 1);
781+ u -> volume = PA_VOLUME_UNTOUCHED ;
782+ } else if (u -> volume != PA_VOLUME_UNTOUCHED ) {
783+ vol = & cvolume ;
784+ u -> volume = PA_VOLUME_UNTOUCHED ;
785+ }
786+
773787 if (verbose > 1 )
774788 flags |= PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING ;
775789
776- if (pa_stream_connect_playback (u -> play_stream , u -> play_device , bufattr , flags , NULL /* volume */ , NULL ) < 0 ) {
790+ if (pa_stream_connect_playback (u -> play_stream , u -> play_device , bufattr , flags , vol /* volume */ , NULL ) < 0 ) {
777791 pacat_log ("pa_stream_connect_playback() failed: %s" , pa_strerror (pa_context_errno (c )));
778792 goto fail ;
779793 }
@@ -1132,6 +1146,7 @@ static _Noreturn void usage(char *arg0, int arg) {
11321146 fprintf (stream , " -v - verbose logging (a lot of output, may affect performance)\n" );
11331147 fprintf (stream , " -t size - target playback buffer fill, implies -l, default %d\n" ,
11341148 custom_bufattr .tlength );
1149+ fprintf (stream , " -V volume - set the target playback volume. Or `mute` to just mute\n" );
11351150 fprintf (stream , " -h - print this message\n" );
11361151 if (fflush (NULL ) || ferror (stdout ) || ferror (stderr ))
11371152 exit (1 );
@@ -1151,9 +1166,10 @@ int main(int argc, char *argv[])
11511166 char * endptr ;
11521167
11531168 memset (& u , 0 , sizeof (u ));
1169+ u .volume = PA_VOLUME_UNTOUCHED ;
11541170 if (argc <= 2 )
11551171 usage (argv [0 ], 1 );
1156- while ((i = getopt (argc , argv , "+lnbvt:h" )) != -1 ) {
1172+ while ((i = getopt (argc , argv , "+lnbvt:V: h" )) != -1 ) {
11571173 switch (i ) {
11581174 case 'l' :
11591175 bufattr = & custom_bufattr ;
@@ -1179,6 +1195,21 @@ int main(int argc, char *argv[])
11791195 bufattr = & custom_bufattr ;
11801196 custom_bufattr .tlength = tlength ;
11811197 break ;
1198+ case 'V' :
1199+ errno = 0 ;
1200+ if (strcmp (optarg , "mute" ) == 0 ) {
1201+ u .volume = PA_VOLUME_MUTED ;
1202+ break ;
1203+ }
1204+ u .volume = strtoul (optarg , & endptr , 0 );
1205+ if (* endptr )
1206+ errx (1 , "Invalid -V argument: %s" , optarg );
1207+ if (u .volume > 150 ) // pluse accepts volume greater than 100%
1208+ errno = ERANGE ;
1209+ if (errno )
1210+ err (1 , "Invalid -V argument: %s" , optarg );
1211+ u .volume = PA_VOLUME_NORM * u .volume / 100 ;
1212+ break ;
11821213 case 'h' :
11831214 usage (argv [0 ], 0 );
11841215 default :
@@ -1205,7 +1236,6 @@ int main(int argc, char *argv[])
12051236 if (create_pidfile (u .domid , & pidfile_path , & pidfile_fd ) < 0 )
12061237 /* error already printed by create_pidfile() */
12071238 exit (1 );
1208- goto main ;
12091239
12101240main :
12111241 u .ret = 1 ;
0 commit comments