Bug 1092859 - Always use soft volume in WinMM cubeb backend. r=padenot, a=lmandel
authorMatthew Gregan <kinetik@flim.org>
Tue, 11 Nov 2014 12:38:54 +1300
changeset 226041 f2dd9f2a084a
parent 226040 4bdf71e69d10
child 226044 e588ff4e326e
push id4119
push userryanvm@gmail.com
push date2014-11-12 22:22 +0000
treeherdermozilla-beta@f2dd9f2a084a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot, lmandel
bugs1092859
milestone34.0
Bug 1092859 - Always use soft volume in WinMM cubeb backend. r=padenot, a=lmandel waveOutSetVolume adjusts the system (or app, on Vista up, but we only use WinMM on XP) "PCM Volume" rather than a per-waveOut volume, which means any audio stream we adjust the volume on has an undesirable higher-level effect. Fix this by dropping the support for waveOutSetVolume and always using the soft volume support. While here, fix a bug in the soft volume code where float32 samples are handled.
media/libcubeb/src/cubeb_winmm.c
--- a/media/libcubeb/src/cubeb_winmm.c
+++ b/media/libcubeb/src/cubeb_winmm.c
@@ -24,19 +24,16 @@
 
 /* This is missing from the MinGW headers. Use a safe fallback. */
 #if !defined(MEMORY_ALLOCATION_ALIGNMENT)
 #define MEMORY_ALLOCATION_ALIGNMENT 16
 #endif
 
 #define CUBEB_STREAM_MAX 32
 #define NBUFS 4
-/* When cubeb_stream.soft_volume is set to this value, the device supports
- * setting the volume. Otherwise, a gain will be applied manually. */
-#define SETTING_VOLUME_SUPPORTED -1.0
 
 const GUID KSDATAFORMAT_SUBTYPE_PCM =
 { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
 const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT =
 { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
 
 struct cubeb_stream_item {
   SLIST_ENTRY head;
@@ -155,19 +152,19 @@ winmm_refill_stream(cubeb_stream * stm)
   }
   stm->written += got;
 
   assert(hdr->dwFlags & WHDR_PREPARED);
 
   hdr->dwBufferLength = got * bytes_per_frame(stm->params);
   assert(hdr->dwBufferLength <= stm->buffer_size);
 
-  if (stm->soft_volume != SETTING_VOLUME_SUPPORTED) {
+  if (stm->soft_volume != -1.0) {
     if (stm->params.format == CUBEB_SAMPLE_FLOAT32NE) {
-      short * b = (short *) hdr->lpData;
+      float * b = (float *) hdr->lpData;
       uint32_t i;
       for (i = 0; i < got * stm->params.channels; i++) {
         b[i] *= stm->soft_volume;
       }
     } else {
       short * b = (short *) hdr->lpData;
       uint32_t i;
       for (i = 0; i < got * stm->params.channels; i++) {
@@ -346,17 +343,16 @@ static int
 winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
                   cubeb_stream_params stream_params, unsigned int latency,
                   cubeb_data_callback data_callback,
                   cubeb_state_callback state_callback,
                   void * user_ptr)
 {
   MMRESULT r;
   WAVEFORMATEXTENSIBLE wfx;
-  WAVEOUTCAPS waveoutcaps;
   cubeb_stream * stm;
   int i;
   size_t bufsz;
 
   assert(context);
   assert(stream);
 
   *stream = NULL;
@@ -433,29 +429,17 @@ winmm_stream_init(cubeb * context, cubeb
   InitializeCriticalSection(&stm->lock);
 
   stm->event = CreateEvent(NULL, FALSE, FALSE, NULL);
   if (!stm->event) {
     winmm_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
-  r = waveOutGetDevCaps(WAVE_MAPPER, &waveoutcaps, sizeof(WAVEOUTCAPS)); 
-  if(r != MMSYSERR_NOERROR) {
-    winmm_stream_destroy(stm);
-    return CUBEB_ERROR;
-  }
-
-  stm->soft_volume = SETTING_VOLUME_SUPPORTED;
-
-  /* if this device does not support setting the volume, do it manually. */
-  if(!(waveoutcaps.dwSupport & WAVECAPS_VOLUME)) {
-    stm->soft_volume = 1.0;
-  }
-
+  stm->soft_volume = -1.0;
 
   /* winmm_buffer_callback will be called during waveOutOpen, so all
      other initialization must be complete before calling it. */
   r = waveOutOpen(&stm->waveout, WAVE_MAPPER, &wfx.Format,
                   (DWORD_PTR) winmm_buffer_callback, (DWORD_PTR) stm,
                   CALLBACK_FUNCTION);
   if (r != MMSYSERR_NOERROR) {
     winmm_stream_destroy(stm);
@@ -663,38 +647,19 @@ winmm_stream_get_latency(cubeb_stream * 
   *latency = written - time.u.sample;
 
   return CUBEB_OK;
 }
 
 static int
 winmm_stream_set_volume(cubeb_stream * stm, float volume)
 {
-  MMRESULT r;
-  DWORD vol;
-
-  if (stm->soft_volume != SETTING_VOLUME_SUPPORTED) {
-    stm->soft_volume = volume;
-    return CUBEB_OK;
-  }
-
-  // lower order word is the left channel, higher order
-  // word is the right channel. Full volume on a channel is 0xffff.
-  vol = volume * 0xffff;
-  vol |= vol << 16;
-
   EnterCriticalSection(&stm->lock);
-  r = waveOutSetVolume(stm->waveout, vol);
-  if (r != MMSYSERR_NOERROR) {
-    stm->soft_volume = volume;
-    LeaveCriticalSection(&stm->lock);
-    return CUBEB_ERROR;
-  }
+  stm->soft_volume = volume;
   LeaveCriticalSection(&stm->lock);
-
   return CUBEB_OK;
 }
 
 static int
 winmm_stream_set_panning(cubeb_stream * stream, float panning)
 {
   assert(0 && "not implemented");
   return CUBEB_OK;