@@ -49,7 +49,7 @@ static void checkvolume(struct mixer *mixer)
49
49
}
50
50
float l = mixer -> vol_l ;
51
51
float r = mixer -> vol_r ;
52
- if (mixer -> muted )
52
+ if (mixer -> muted_using_volume )
53
53
l = r = 0 ;
54
54
/* Try to detect cases where the volume has been changed by some external
55
55
* action (such as something else changing a shared system-wide volume).
@@ -61,8 +61,14 @@ static void checkvolume(struct mixer *mixer)
61
61
if (FFABS (vol .left - l ) >= 3 || FFABS (vol .right - r ) >= 3 ) {
62
62
mixer -> vol_l = vol .left ;
63
63
mixer -> vol_r = vol .right ;
64
- mixer -> muted = false;
64
+ if (mixer -> muted_using_volume )
65
+ mixer -> muted = false;
65
66
}
67
+ if (!mixer -> softvol )
68
+ // Rely on the value not changing if the query is not supported
69
+ ao_control (mixer -> ao , AOCONTROL_GET_MUTE , & mixer -> muted );
70
+ mixer -> muted_by_us &= mixer -> muted ;
71
+ mixer -> muted_using_volume &= mixer -> muted ;
66
72
}
67
73
68
74
void mixer_getvolume (mixer_t * mixer , float * l , float * r )
@@ -130,8 +136,15 @@ void mixer_setmute(struct mixer *mixer, bool mute)
130
136
{
131
137
checkvolume (mixer );
132
138
if (mute != mixer -> muted ) {
139
+ if (!mixer -> softvol && !mixer -> muted_using_volume && ao_control (
140
+ mixer -> ao , AOCONTROL_SET_MUTE , & mute ) == CONTROL_OK ) {
141
+ mixer -> muted_using_volume = false;
142
+ } else {
143
+ setvolume_internal (mixer , mixer -> vol_l * !mute , mixer -> vol_r * !mute );
144
+ mixer -> muted_using_volume = mute ;
145
+ }
133
146
mixer -> muted = mute ;
134
- setvolume_internal ( mixer , mixer -> vol_l * ! mute , mixer -> vol_r * ! mute ) ;
147
+ mixer -> muted_by_us = mute ;
135
148
}
136
149
}
137
150
@@ -227,7 +240,7 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
227
240
/* Use checkvolume() to see if softvol needs to be enabled because of
228
241
* lacking AO support, but first store values it could overwrite. */
229
242
float left = mixer -> vol_l , right = mixer -> vol_r ;
230
- bool muted = mixer -> muted ;
243
+ bool muted = mixer -> muted_by_us ;
231
244
checkvolume (mixer );
232
245
/* Try to avoid restoring volume stored from one control method with
233
246
* another. Especially, restoring softvol volume (typically high) on
@@ -237,7 +250,11 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
237
250
if (mixer -> restore_volume && !strcmp (mixer -> restore_volume ,
238
251
restore_reason ))
239
252
mixer_setvolume (mixer , left , right );
240
- mixer_setmute (mixer , muted );
253
+ /* We turn mute off at AO uninit, so it has to be restored (unless
254
+ * we're reinitializing filter chain while keeping AO); but we only
255
+ * enable mute, not turn external mute off. */
256
+ if (muted )
257
+ mixer_setmute (mixer , true);
241
258
if (mixer -> balance != 0 )
242
259
mixer_setbalance (mixer , mixer -> balance );
243
260
}
@@ -249,7 +266,7 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
249
266
void mixer_uninit (struct mixer * mixer )
250
267
{
251
268
checkvolume (mixer );
252
- if (mixer -> muted ) {
269
+ if (mixer -> muted_by_us ) {
253
270
/* Current audio output API combines playing the remaining buffered
254
271
* audio and uninitializing the AO into one operation, even though
255
272
* ideally unmute would happen between those two steps. We can't do
@@ -260,7 +277,7 @@ void mixer_uninit(struct mixer *mixer)
260
277
mixer_setmute (mixer , false);
261
278
/* We remember mute status and re-enable it if we play more audio
262
279
* in the same process. */
263
- mixer -> muted = true;
280
+ mixer -> muted_by_us = true;
264
281
}
265
282
mixer -> ao = NULL ;
266
283
}
0 commit comments