diff options
author | Diogo Franco (Kovensky) <diogomfranco@gmail.com> | 2014-03-11 02:50:49 -0300 |
---|---|---|
committer | Diogo Franco (Kovensky) <diogomfranco@gmail.com> | 2014-03-11 16:37:21 -0300 |
commit | f8bdada77f992410deb4fc12652cf406d95e3657 (patch) | |
tree | 7d47a7100c192cdbba55dbe05962e47d47b52ca6 /audio/out/ao_wasapi.c | |
parent | f3e9b9462210021286bfbe98eef228ab74c8b490 (diff) | |
download | mpv-f8bdada77f992410deb4fc12652cf406d95e3657.tar.bz2 mpv-f8bdada77f992410deb4fc12652cf406d95e3657.tar.xz |
ao_wasapi: Implement per-application mixing
The volume controls in mpv now affect the session's volume (the
application's volume in the mixer). Since we do not request a
non-persistent session, the volume and mute status persist across mpv
invocations and system reboots.
In exclusive mode, WASAPI doesn't have access to a mixer so the endpoint
(sound card)'s master volume is modified instead. Since by definition
mpv is the only thing outputting audio in exclusive mode, this causes no
conflict, and ao_wasapi restores the last user-set volume when it's
uninitialized.
Diffstat (limited to 'audio/out/ao_wasapi.c')
-rw-r--r-- | audio/out/ao_wasapi.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index a496ff9aa6..ec04cedcd6 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -195,6 +195,7 @@ static int init(struct ao *ao) wasapi_enumerate_devices(state->log); } + ao->per_application_mixer = true; if (state->opt_exclusive) { state->share_mode = AUDCLNT_SHAREMODE_EXCLUSIVE; } else { @@ -235,22 +236,54 @@ static int init(struct ao *ao) static int control(struct ao *ao, enum aocontrol cmd, void *arg) { struct wasapi_state *state = (struct wasapi_state *)ao->priv; - if (!state->share_mode && !(state->vol_hw_support & ENDPOINT_HARDWARE_SUPPORT_VOLUME)) { - return CONTROL_UNKNOWN; /* hw does not support volume controls in exclusive mode */ - } - ao_control_vol_t *vol = (ao_control_vol_t *)arg; + BOOL mute; switch (cmd) { case AOCONTROL_GET_VOLUME: - IAudioEndpointVolume_GetMasterVolumeLevelScalar(state->pEndpointVolumeProxy, - &state->audio_volume); + if (state->opt_exclusive) + IAudioEndpointVolume_GetMasterVolumeLevelScalar(state->pEndpointVolumeProxy, + &state->audio_volume); + else + ISimpleAudioVolume_GetMasterVolume(state->pAudioVolumeProxy, + &state->audio_volume); + + /* check to see if user manually changed volume through mixer; + this information is used in exclusive mode for restoring the mixer volume on uninit */ + if (state->audio_volume != state->previous_volume) { + MP_VERBOSE(state, "mixer difference: %.2g now, expected %.2g\n", + state->audio_volume, state->previous_volume); + state->initial_volume = state->audio_volume; + } + vol->left = vol->right = 100.0f * state->audio_volume; return CONTROL_OK; case AOCONTROL_SET_VOLUME: state->audio_volume = vol->left / 100.f; - IAudioEndpointVolume_SetMasterVolumeLevelScalar(state->pEndpointVolumeProxy, - state->audio_volume, NULL); + if (state->opt_exclusive) + IAudioEndpointVolume_SetMasterVolumeLevelScalar(state->pEndpointVolumeProxy, + state->audio_volume, NULL); + else + ISimpleAudioVolume_SetMasterVolume(state->pAudioVolumeProxy, + state->audio_volume, NULL); + + state->previous_volume = state->audio_volume; + return CONTROL_OK; + case AOCONTROL_GET_MUTE: + if (state->opt_exclusive) + IAudioEndpointVolume_GetMute(state->pEndpointVolumeProxy, &mute); + else + ISimpleAudioVolume_GetMute(state->pAudioVolumeProxy, &mute); + *(bool*)arg = mute; + + return CONTROL_OK; + case AOCONTROL_SET_MUTE: + mute = *(bool*)arg; + if (state->opt_exclusive) + IAudioEndpointVolume_SetMute(state->pEndpointVolumeProxy, mute, NULL); + else + ISimpleAudioVolume_SetMute(state->pAudioVolumeProxy, mute, NULL); + return CONTROL_OK; default: return CONTROL_UNKNOWN; |