Huw Davies : winealsa: Store the session mute state in the stream volumes.

Alexandre Julliard julliard at winehq.org
Mon Feb 21 16:15:14 CST 2022


Module: wine
Branch: master
Commit: 444d429fcc910765c8942a5447394b8b6e53b3f6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=444d429fcc910765c8942a5447394b8b6e53b3f6

Author: Huw Davies <huw at codeweavers.com>
Date:   Fri Feb 18 08:29:31 2022 +0000

winealsa: Store the session mute state in the stream volumes.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winealsa.drv/mmdevdrv.c | 45 ++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index 959157ade87..14dfbd07acb 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -327,7 +327,8 @@ static void set_stream_volumes(ACImpl *This)
     unsigned int i;
 
     for(i = 0; i < stream->fmt->nChannels; i++)
-        stream->vols[i] = This->vols[i] * This->session->channel_vols[i] * This->session->master_vol;
+        stream->vols[i] = This->session->mute ? 0.0f :
+            This->vols[i] * This->session->channel_vols[i] * This->session->master_vol;
 }
 
 HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, GUID **guids_out,
@@ -1469,30 +1470,32 @@ static BYTE *remap_channels(struct alsa_stream *stream, BYTE *buf, snd_pcm_ufram
     return stream->remapping_buf;
 }
 
-static void adjust_buffer_volume(const ACImpl *This, BYTE *buf, snd_pcm_uframes_t frames, BOOL mute)
+static void adjust_buffer_volume(const ACImpl *This, BYTE *buf, snd_pcm_uframes_t frames)
 {
     struct alsa_stream *stream = This->stream;
     BOOL adjust = FALSE;
-    UINT32 i, channels;
+    UINT32 i, channels, mute = 0;
     BYTE *end;
 
     if (stream->vol_adjusted_frames >= frames)
         return;
     channels = stream->fmt->nChannels;
 
-    if (mute)
+    /* Adjust the buffer based on the volume for each channel */
+    for (i = 0; i < channels; i++)
+    {
+        adjust |= stream->vols[i] != 1.0f;
+        if (stream->vols[i] == 0.0f)
+            mute++;
+    }
+
+    if (mute == channels)
     {
         int err = snd_pcm_format_set_silence(stream->alsa_format, buf, frames * channels);
         if (err < 0)
             WARN("Setting buffer to silence failed: %d (%s)\n", err, snd_strerror(err));
         return;
     }
-
-    /* Adjust the buffer based on the volume for each channel */
-    for (i = 0; i < channels; i++)
-    {
-        adjust |= stream->vols[i] != 1.0f;
-    }
     if (!adjust) return;
 
     /* Skip the frames we've already adjusted before */
@@ -1584,13 +1587,12 @@ static void adjust_buffer_volume(const ACImpl *This, BYTE *buf, snd_pcm_uframes_
     }
 }
 
-static snd_pcm_sframes_t alsa_write_best_effort(ACImpl *This, BYTE *buf,
-        snd_pcm_uframes_t frames, BOOL mute)
+static snd_pcm_sframes_t alsa_write_best_effort(ACImpl *This, BYTE *buf, snd_pcm_uframes_t frames)
 {
     struct alsa_stream *stream = This->stream;
     snd_pcm_sframes_t written;
 
-    adjust_buffer_volume(This, buf, frames, mute);
+    adjust_buffer_volume(This, buf, frames);
 
     /* Mark the frames we've already adjusted */
     if (stream->vol_adjusted_frames < frames)
@@ -1639,7 +1641,7 @@ static snd_pcm_sframes_t alsa_write_buffer_wrap(ACImpl *This, BYTE *buf,
         else
             chunk = to_write;
 
-        tmp = alsa_write_best_effort(This, buf + offs * stream->fmt->nBlockAlign, chunk, This->session->mute);
+        tmp = alsa_write_best_effort(This, buf + offs * stream->fmt->nBlockAlign, chunk);
         if(tmp < 0)
             return ret;
         if(!tmp)
@@ -1722,7 +1724,7 @@ static void alsa_write_data(ACImpl *This)
     if(stream->data_in_alsa_frames == 0 && stream->held_frames < stream->alsa_period_frames)
     {
         alsa_write_best_effort(This, stream->silence_buf,
-                               stream->alsa_period_frames - stream->held_frames, FALSE);
+                               stream->alsa_period_frames - stream->held_frames);
         stream->vol_adjusted_frames = 0;
     }
 
@@ -1766,6 +1768,7 @@ static void alsa_read_data(ACImpl *This)
     struct alsa_stream *stream = This->stream;
     snd_pcm_sframes_t nread;
     UINT32 pos = stream->wri_offs_frames, limit = stream->held_frames;
+    unsigned int i;
 
     if(!stream->started)
         goto exit;
@@ -1799,7 +1802,10 @@ static void alsa_read_data(ACImpl *This)
         }
     }
 
-    if(This->session->mute){
+    for(i = 0; i < stream->fmt->nChannels; i++)
+        if(stream->vols[i] != 0.0f)
+            break;
+    if(i == stream->fmt->nChannels){ /* mute */
         int err;
         if((err = snd_pcm_format_set_silence(stream->alsa_format,
                         stream->local_buffer + pos * stream->fmt->nBlockAlign,
@@ -3129,13 +3135,20 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
 {
     AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
     AudioSession *session = This->session;
+    ACImpl *client;
 
     TRACE("(%p)->(%u, %s)\n", session, mute, debugstr_guid(context));
 
     if(context)
         FIXME("Notifications not supported yet\n");
 
+    EnterCriticalSection(&g_sessions_lock);
+
     session->mute = mute;
+    LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry)
+        set_stream_volumes(client);
+
+    LeaveCriticalSection(&g_sessions_lock);
 
     return S_OK;
 }




More information about the wine-cvs mailing list