Skip to content

Commit 39aa7d9

Browse files
author
Uoti Urpala
committed
mixer: support native audio driver mute
Make mixer support setting the mute attribute at audio driver level, if one exists separately from volume. As of this commit, no libao2 driver exposes such an attribute yet; that will be added in later commits. Since the mute status can now be set externally, it's no longer completely obvious when the player should automatically disable mute when uninitializing an audio output. The implemented behavior is to turn mute off at uninitialization if we turned it on and haven't noticed it turn off (by external means) since.
1 parent 9624f10 commit 39aa7d9

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

libao2/audio_out.h

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ enum aocontrol {
3535
// If there's only one volume, SET should use average of left/right.
3636
AOCONTROL_GET_VOLUME,
3737
AOCONTROL_SET_VOLUME,
38+
// _MUTE commands take a pointer to bool
39+
AOCONTROL_GET_MUTE,
40+
AOCONTROL_SET_MUTE,
3841
};
3942

4043
#define AOPLAY_FINAL_CHUNK 1

mixer.c

+24-7
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static void checkvolume(struct mixer *mixer)
4949
}
5050
float l = mixer->vol_l;
5151
float r = mixer->vol_r;
52-
if (mixer->muted)
52+
if (mixer->muted_using_volume)
5353
l = r = 0;
5454
/* Try to detect cases where the volume has been changed by some external
5555
* action (such as something else changing a shared system-wide volume).
@@ -61,8 +61,14 @@ static void checkvolume(struct mixer *mixer)
6161
if (FFABS(vol.left - l) >= 3 || FFABS(vol.right - r) >= 3) {
6262
mixer->vol_l = vol.left;
6363
mixer->vol_r = vol.right;
64-
mixer->muted = false;
64+
if (mixer->muted_using_volume)
65+
mixer->muted = false;
6566
}
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;
6672
}
6773

6874
void mixer_getvolume(mixer_t *mixer, float *l, float *r)
@@ -130,8 +136,15 @@ void mixer_setmute(struct mixer *mixer, bool mute)
130136
{
131137
checkvolume(mixer);
132138
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+
}
133146
mixer->muted = mute;
134-
setvolume_internal(mixer, mixer->vol_l * !mute, mixer->vol_r * !mute);
147+
mixer->muted_by_us = mute;
135148
}
136149
}
137150

@@ -227,7 +240,7 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
227240
/* Use checkvolume() to see if softvol needs to be enabled because of
228241
* lacking AO support, but first store values it could overwrite. */
229242
float left = mixer->vol_l, right = mixer->vol_r;
230-
bool muted = mixer->muted;
243+
bool muted = mixer->muted_by_us;
231244
checkvolume(mixer);
232245
/* Try to avoid restoring volume stored from one control method with
233246
* another. Especially, restoring softvol volume (typically high) on
@@ -237,7 +250,11 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
237250
if (mixer->restore_volume && !strcmp(mixer->restore_volume,
238251
restore_reason))
239252
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);
241258
if (mixer->balance != 0)
242259
mixer_setbalance(mixer, mixer->balance);
243260
}
@@ -249,7 +266,7 @@ void mixer_reinit(struct mixer *mixer, struct ao *ao)
249266
void mixer_uninit(struct mixer *mixer)
250267
{
251268
checkvolume(mixer);
252-
if (mixer->muted) {
269+
if (mixer->muted_by_us) {
253270
/* Current audio output API combines playing the remaining buffered
254271
* audio and uninitializing the AO into one operation, even though
255272
* ideally unmute would happen between those two steps. We can't do
@@ -260,7 +277,7 @@ void mixer_uninit(struct mixer *mixer)
260277
mixer_setmute(mixer, false);
261278
/* We remember mute status and re-enable it if we play more audio
262279
* in the same process. */
263-
mixer->muted = true;
280+
mixer->muted_by_us = true;
264281
}
265282
mixer->ao = NULL;
266283
}

mixer.h

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ typedef struct mixer {
3131
bool softvol;
3232
float softvol_max;
3333
bool muted;
34+
bool muted_by_us;
35+
bool muted_using_volume;
3436
float vol_l, vol_r;
3537
/* Contains ao driver name or "softvol" if volume is not persistent
3638
* and needs to be restored after the driver is reinitialized. */

0 commit comments

Comments
 (0)