Maybe you've noticed that somtimes sound volume in firefox doesn't
match the volume indicator until you touch it.

This is because the firefox audio API has no volume getter and assumes
the initial volume is 1, while sndio saves volumes and allows volume
to be controlled externally, which makes firefox use a wrong
representation of the actual volume.

The workaround is to do like alsa, pulseaudio and other backends: stop
using the native volume control and adjust the volume of the signal in
firefox.

OK?

Index: Makefile
===================================================================
RCS file: /cvs/ports/www/mozilla-firefox/Makefile,v
retrieving revision 1.350
diff -u -p -r1.350 Makefile
--- Makefile    11 May 2018 20:09:01 -0000      1.350
+++ Makefile    15 May 2018 21:08:56 -0000
@@ -2,6 +2,7 @@
 
 COMMENT =      Mozilla web browser
 ONLY_FOR_ARCHS =       amd64 i386
+REVISION =     0
 
 # Don't forget to bump www/firefox-i18n after updates.
 
Index: patches/patch-media_libcubeb_src_cubeb_sndio_c
===================================================================
RCS file: patches/patch-media_libcubeb_src_cubeb_sndio_c
diff -N patches/patch-media_libcubeb_src_cubeb_sndio_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-media_libcubeb_src_cubeb_sndio_c      15 May 2018 21:08:56 
-0000
@@ -0,0 +1,82 @@
+$OpenBSD$
+
+Apply volume in software as do other backends. This is necessary
+because sndio volume may be controlled externally and there's no
+volume getter in libcubeb to notify the caller about volume
+changes.
+
+Index: media/libcubeb/src/cubeb_sndio.c
+--- media/libcubeb/src/cubeb_sndio.c.orig
++++ media/libcubeb/src/cubeb_sndio.c
+@@ -51,17 +51,33 @@ struct cubeb_stream {
+   uint64_t swpos;                 /* number of frames produced/consumed */
+   cubeb_data_callback data_cb;    /* cb to preapare data */
+   cubeb_state_callback state_cb;  /* cb to notify about state changes */
++  float volume;                         /* current volume */
+ };
+ 
+ static void
+-float_to_s16(void *ptr, long nsamp)
++s16_setvol(void *ptr, long nsamp, float volume)
+ {
+   int16_t *dst = ptr;
++  int32_t mult = volume * 32768;
++  int32_t s;
++
++  while (nsamp-- > 0) {
++    s = *dst;
++    s = (s * mult) >> 15;
++    *(dst++) = s;
++  }
++}
++
++static void
++float_to_s16(void *ptr, long nsamp, float volume)
++{
++  int16_t *dst = ptr;
+   float *src = ptr;
++  float mult = volume * 32768;
+   int s;
+ 
+   while (nsamp-- > 0) {
+-    s = lrintf(*(src++) * 32768);
++    s = lrintf(*(src++) * mult);
+     if (s < -32768)
+       s = -32768;
+     else if (s > 32767)
+@@ -169,8 +185,12 @@ sndio_mainloop(void *arg)
+       if (prime > 0)
+         prime--;
+ 
+-      if ((s->mode & SIO_PLAY) && s->conv)
+-          float_to_s16(s->pbuf, nfr * s->pchan);
++      if (s->mode & SIO_PLAY) {
++        if (s->conv)
++          float_to_s16(s->pbuf, nfr * s->pchan, s->volume);
++        else
++          s16_setvol(s->pbuf, nfr * s->pchan, s->volume);
++      }
+ 
+       if (s->mode & SIO_REC)
+         rstart = 0;
+@@ -372,6 +392,7 @@ sndio_stream_init(cubeb * context,
+     if (s->rbuf == NULL)
+       goto err;
+   }
++  s->volume = 1.;
+   *stream = s;
+   DPR("sndio_stream_init() end, ok\n");
+   (void)context;
+@@ -476,7 +497,11 @@ sndio_stream_set_volume(cubeb_stream *s, float volume)
+ {
+   DPR("sndio_stream_set_volume(%f)\n", volume);
+   pthread_mutex_lock(&s->mtx);
+-  sio_setvol(s->hdl, SIO_MAXVOL * volume);
++  if (volume < 0.)
++    volume = 0.;
++  else if (volume > 1.0)
++    volume = 1.;
++  s->volume = volume;
+   pthread_mutex_unlock(&s->mtx);
+   return CUBEB_OK;
+ }

Reply via email to