Commit f6d9780e authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

aout: separate volume and mute callbacks

parent c45103a6
...@@ -134,8 +134,6 @@ typedef int32_t vlc_fixed_t; ...@@ -134,8 +134,6 @@ typedef int32_t vlc_fixed_t;
/* FIXME to remove once aout.h is cleaned a bit more */ /* FIXME to remove once aout.h is cleaned a bit more */
#include <vlc_block.h> #include <vlc_block.h>
typedef int (*aout_volume_cb) (audio_output_t *, float, bool);
/** Audio output object */ /** Audio output object */
struct audio_output struct audio_output
{ {
...@@ -150,7 +148,8 @@ struct audio_output ...@@ -150,7 +148,8 @@ struct audio_output
callback (optional, may be NULL) */ callback (optional, may be NULL) */
void (* pf_flush)( audio_output_t *, bool ); /**< Flush/drain callback void (* pf_flush)( audio_output_t *, bool ); /**< Flush/drain callback
(optional, may be NULL) */ (optional, may be NULL) */
aout_volume_cb pf_volume_set; /**< Volume setter (or NULL) */ int (*volume_set)(audio_output_t *, float); /**< Volume setter (or NULL) */
int (*mute_set)(audio_output_t *, bool); /**< Mute setter (or NULL) */
struct { struct {
void (*time_report)(audio_output_t *, mtime_t); void (*time_report)(audio_output_t *, mtime_t);
...@@ -224,12 +223,15 @@ VLC_API void aout_FormatPrint(vlc_object_t *, const char *, ...@@ -224,12 +223,15 @@ VLC_API void aout_FormatPrint(vlc_object_t *, const char *,
VLC_API const char * aout_FormatPrintChannels( const audio_sample_format_t * ) VLC_USED; VLC_API const char * aout_FormatPrintChannels( const audio_sample_format_t * ) VLC_USED;
VLC_API void aout_VolumeSoftInit( audio_output_t * ); VLC_API void aout_VolumeSoftInit( audio_output_t * );
VLC_API void aout_VolumeHardInit( audio_output_t *, aout_volume_cb, bool );
static inline void aout_VolumeHardSet(audio_output_t *aout, float v, bool m) static inline void aout_VolumeReport(audio_output_t *aout, float volume)
{
aout->event.volume_report(aout, volume);
}
static inline void aout_MuteReport(audio_output_t *aout, bool mute)
{ {
aout->event.volume_report(aout, v); aout->event.mute_report(aout, mute);
aout->event.mute_report(aout, m);
} }
static inline void aout_TimeReport(audio_output_t *aout, mtime_t date) static inline void aout_TimeReport(audio_output_t *aout, mtime_t date)
......
...@@ -516,7 +516,8 @@ static int Open (vlc_object_t *obj) ...@@ -516,7 +516,8 @@ static int Open (vlc_object_t *obj)
{ {
aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE; aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
aout->format.i_frame_length = A52_FRAME_NB; aout->format.i_frame_length = A52_FRAME_NB;
aout->pf_volume_set = NULL; aout->volume_set = NULL;
aout->mute_set = NULL;
} }
else else
{ {
......
...@@ -62,6 +62,8 @@ struct aout_sys_t ...@@ -62,6 +62,8 @@ struct aout_sys_t
void (*drain) (void *opaque); void (*drain) (void *opaque);
int (*set_volume) (void *opaque, float vol, bool mute); int (*set_volume) (void *opaque, float vol, bool mute);
void (*cleanup) (void *opaque); void (*cleanup) (void *opaque);
float volume;
bool mute;
}; };
static void Play (audio_output_t *aout, block_t *block) static void Play (audio_output_t *aout, block_t *block)
...@@ -91,11 +93,20 @@ static void Flush (audio_output_t *aout, bool wait) ...@@ -91,11 +93,20 @@ static void Flush (audio_output_t *aout, bool wait)
cb (sys->opaque); cb (sys->opaque);
} }
static int VolumeSet (audio_output_t *aout, float vol, bool mute) static int VolumeSet (audio_output_t *aout, float vol)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
return sys->set_volume (sys->opaque, vol, mute) ? -1 : 0; sys->volume = vol;
return sys->set_volume (sys->opaque, vol, sys->mute) ? -1 : 0;
}
static int MuteSet (audio_output_t *aout, bool mute)
{
aout_sys_t *sys = aout->sys;
sys->mute = mute;
return sys->set_volume (sys->opaque, sys->volume, mute) ? -1 : 0;
} }
typedef int (*vlc_audio_format_cb) (void **, char *, unsigned *, unsigned *); typedef int (*vlc_audio_format_cb) (void **, char *, unsigned *, unsigned *);
...@@ -116,6 +127,8 @@ static int Open (vlc_object_t *obj) ...@@ -116,6 +127,8 @@ static int Open (vlc_object_t *obj)
sys->drain = var_InheritAddress (obj, "amem-drain"); sys->drain = var_InheritAddress (obj, "amem-drain");
sys->set_volume = var_InheritAddress (obj, "amem-set-volume"); sys->set_volume = var_InheritAddress (obj, "amem-set-volume");
sys->cleanup = NULL; /* defer */ sys->cleanup = NULL; /* defer */
sys->volume = 1.;
sys->mute = false;
if (sys->play == NULL) if (sys->play == NULL)
goto error; goto error;
...@@ -203,7 +216,10 @@ static int Open (vlc_object_t *obj) ...@@ -203,7 +216,10 @@ static int Open (vlc_object_t *obj)
aout->pf_pause = Pause; aout->pf_pause = Pause;
aout->pf_flush = Flush; aout->pf_flush = Flush;
if (sys->set_volume != NULL) if (sys->set_volume != NULL)
aout->pf_volume_set = VolumeSet; {
aout->volume_set = VolumeSet;
aout->mute_set = MuteSet;
}
else else
aout_VolumeSoftInit (aout); aout_VolumeSoftInit (aout);
return VLC_SUCCESS; return VLC_SUCCESS;
......
...@@ -787,7 +787,8 @@ static int OpenSPDIF( audio_output_t * p_aout ) ...@@ -787,7 +787,8 @@ static int OpenSPDIF( audio_output_t * p_aout )
p_aout->format.i_rate = (unsigned int)p_sys->stream_format.mSampleRate; p_aout->format.i_rate = (unsigned int)p_sys->stream_format.mSampleRate;
aout_FormatPrepare( &p_aout->format ); aout_FormatPrepare( &p_aout->format );
aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB ); aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB );
p_aout->pf_volume_set = NULL; p_aout->volume_set = NULL;
p_aout->mute_set = NULL;
/* Add IOProc callback */ /* Add IOProc callback */
err = AudioDeviceCreateIOProcID( p_sys->i_selected_dev, err = AudioDeviceCreateIOProcID( p_sys->i_selected_dev,
......
...@@ -75,7 +75,12 @@ struct aout_sys_t ...@@ -75,7 +75,12 @@ struct aout_sys_t
LPDIRECTSOUNDBUFFER p_dsbuffer; /* the sound buffer we use (direct sound LPDIRECTSOUNDBUFFER p_dsbuffer; /* the sound buffer we use (direct sound
* takes care of mixing all the * takes care of mixing all the
* secondary buffers into the primary) */ * secondary buffers into the primary) */
LONG volume; struct
{
LONG volume;
LONG mb;
bool mute;
} volume;
notification_thread_t notif; /* DirectSoundThread id */ notification_thread_t notif; /* DirectSoundThread id */
...@@ -96,7 +101,8 @@ struct aout_sys_t ...@@ -96,7 +101,8 @@ struct aout_sys_t
static int OpenAudio ( vlc_object_t * ); static int OpenAudio ( vlc_object_t * );
static void CloseAudio ( vlc_object_t * ); static void CloseAudio ( vlc_object_t * );
static void Play ( audio_output_t *, block_t * ); static void Play ( audio_output_t *, block_t * );
static int VolumeSet ( audio_output_t *, float, bool ); static int VolumeSet ( audio_output_t *, float );
static int MuteSet ( audio_output_t *, bool );
/* local functions */ /* local functions */
static void Probe ( audio_output_t * ); static void Probe ( audio_output_t * );
...@@ -232,8 +238,6 @@ static int OpenAudio( vlc_object_t *p_this ) ...@@ -232,8 +238,6 @@ static int OpenAudio( vlc_object_t *p_this )
} }
aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB ); aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB );
p_aout->sys->volume = -1;
p_aout->pf_volume_set = NULL;
} }
else else
{ {
...@@ -287,9 +291,10 @@ static int OpenAudio( vlc_object_t *p_this ) ...@@ -287,9 +291,10 @@ static int OpenAudio( vlc_object_t *p_this )
/* Calculate the frame size in bytes */ /* Calculate the frame size in bytes */
aout_FormatPrepare( &p_aout->format ); aout_FormatPrepare( &p_aout->format );
aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE ); aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE );
aout_VolumeHardInit( p_aout, VolumeSet, true );
} }
p_aout->sys->volume.volume = -1;
/* Now we need to setup our DirectSound play notification structure */ /* Now we need to setup our DirectSound play notification structure */
vlc_atomic_set(&p_aout->sys->notif.abort, 0); vlc_atomic_set(&p_aout->sys->notif.abort, 0);
p_aout->sys->notif.event = CreateEvent( 0, FALSE, FALSE, 0 ); p_aout->sys->notif.event = CreateEvent( 0, FALSE, FALSE, 0 );
...@@ -313,6 +318,19 @@ static int OpenAudio( vlc_object_t *p_this ) ...@@ -313,6 +318,19 @@ static int OpenAudio( vlc_object_t *p_this )
p_aout->pf_pause = aout_PacketPause; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = aout_PacketFlush; p_aout->pf_flush = aout_PacketFlush;
/* Volume */
if( val.i_int == AOUT_VAR_SPDIF )
{
p_aout->volume_set = NULL;
p_aout->mute_set = NULL;
}
else
{
p_aout->sys->volume.mb = 0;
p_aout->sys->volume.mute = false;
p_aout->volume_set = VolumeSet;
p_aout->mute_set = MuteSet;
}
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
...@@ -573,12 +591,10 @@ static void Play( audio_output_t *p_aout, block_t *p_buffer ) ...@@ -573,12 +591,10 @@ static void Play( audio_output_t *p_aout, block_t *p_buffer )
p_aout->pf_play = aout_PacketPlay; p_aout->pf_play = aout_PacketPlay;
} }
/***************************************************************************** static int VolumeSet( audio_output_t *p_aout, float vol )
* VolumeSet: change audio device volume
*****************************************************************************/
static int VolumeSet( audio_output_t *p_aout, float vol, bool mute )
{ {
aout_sys_t *sys = p_aout->sys; aout_sys_t *sys = p_aout->sys;
int ret = 0;
/* Convert UI volume to linear factor (cube) */ /* Convert UI volume to linear factor (cube) */
vol = vol * vol * vol; vol = vol * vol * vol;
...@@ -589,15 +605,32 @@ static int VolumeSet( audio_output_t *p_aout, float vol, bool mute ) ...@@ -589,15 +605,32 @@ static int VolumeSet( audio_output_t *p_aout, float vol, bool mute )
/* Clamp to allowed DirectSound range */ /* Clamp to allowed DirectSound range */
static_assert( DSBVOLUME_MIN < DSBVOLUME_MAX, "DSBVOLUME_* confused" ); static_assert( DSBVOLUME_MIN < DSBVOLUME_MAX, "DSBVOLUME_* confused" );
if( mb >= DSBVOLUME_MAX ) if( mb >= DSBVOLUME_MAX )
{
mb = DSBVOLUME_MAX; mb = DSBVOLUME_MAX;
ret = -1;
}
if( mb <= DSBVOLUME_MIN ) if( mb <= DSBVOLUME_MIN )
mb = DSBVOLUME_MIN; mb = DSBVOLUME_MIN;
InterlockedExchange(&sys->volume, mute ? DSBVOLUME_MIN : mb); sys->volume.mb = mb;
if (!sys->volume.mute)
InterlockedExchange(&sys->volume.volume, mb);
/* Convert back to UI volume */ /* Convert back to UI volume */
vol = cbrtf(powf(10.f, ((float)mb) / -2000.f)); vol = cbrtf(powf(10.f, ((float)mb) / -2000.f));
aout_VolumeHardSet( p_aout, vol, mute ); aout_VolumeReport( p_aout, vol );
return ret;
}
static int MuteSet( audio_output_t *p_aout, bool mute )
{
aout_sys_t *sys = p_aout->sys;
sys->volume.mute = mute;
InterlockedExchange(&sys->volume.volume,
mute ? DSBVOLUME_MIN : sys->volume.mb);
aout_MuteReport( p_aout, mute );
return 0; return 0;
} }
...@@ -1064,7 +1097,7 @@ static void* DirectSoundThread( void *data ) ...@@ -1064,7 +1097,7 @@ static void* DirectSoundThread( void *data )
int i; int i;
/* Update volume if required */ /* Update volume if required */
LONG volume = InterlockedExchange( &p_aout->sys->volume, -1 ); LONG volume = InterlockedExchange( &p_aout->sys->volume.volume, -1 );
if( unlikely(volume != -1) ) if( unlikely(volume != -1) )
IDirectSoundBuffer_SetVolume( p_aout->sys->p_dsbuffer, volume ); IDirectSoundBuffer_SetVolume( p_aout->sys->p_dsbuffer, volume );
......
...@@ -194,7 +194,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -194,7 +194,8 @@ static int Open( vlc_object_t * p_this )
p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
p_aout->format.i_frame_length = A52_FRAME_NB; p_aout->format.i_frame_length = A52_FRAME_NB;
} }
p_aout->pf_volume_set = NULL; p_aout->volume_set = NULL;
p_aout->mute_set = NULL;
/* Channels number */ /* Channels number */
i_channels = var_CreateGetInteger( p_this, "audiofile-channels" ); i_channels = var_CreateGetInteger( p_this, "audiofile-channels" );
......
...@@ -368,7 +368,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -368,7 +368,8 @@ static int Open( vlc_object_t *p_this )
p_aout->format.i_frame_length = A52_FRAME_NB; p_aout->format.i_frame_length = A52_FRAME_NB;
aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB ); aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB );
p_aout->pf_volume_set = NULL; p_aout->volume_set = NULL;
p_aout->mute_set = NULL;
} }
else else
{ {
......
...@@ -481,7 +481,8 @@ static void sink_input_info_cb(pa_context *ctx, const pa_sink_input_info *i, ...@@ -481,7 +481,8 @@ static void sink_input_info_cb(pa_context *ctx, const pa_sink_input_info *i,
pa_volume_t volume = pa_cvolume_max(&i->volume); pa_volume_t volume = pa_cvolume_max(&i->volume);
volume = pa_sw_volume_divide(volume, sys->base_volume); volume = pa_sw_volume_divide(volume, sys->base_volume);
aout_VolumeHardSet(aout, (float)volume / PA_VOLUME_NORM, i->mute); aout_VolumeReport(aout, (float)volume / PA_VOLUME_NORM);
aout_MuteReport(aout, i->mute);
} }
...@@ -601,7 +602,7 @@ static void Flush(audio_output_t *aout, bool wait) ...@@ -601,7 +602,7 @@ static void Flush(audio_output_t *aout, bool wait)
pa_threaded_mainloop_unlock(sys->mainloop); pa_threaded_mainloop_unlock(sys->mainloop);
} }
static int VolumeSet(audio_output_t *aout, float vol, bool mute) static int VolumeSet(audio_output_t *aout, float vol)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
pa_operation *op; pa_operation *op;
...@@ -626,6 +627,18 @@ static int VolumeSet(audio_output_t *aout, float vol, bool mute) ...@@ -626,6 +627,18 @@ static int VolumeSet(audio_output_t *aout, float vol, bool mute)
op = pa_context_set_sink_input_volume(sys->context, idx, &cvolume, NULL, NULL); op = pa_context_set_sink_input_volume(sys->context, idx, &cvolume, NULL, NULL);
if (likely(op != NULL)) if (likely(op != NULL))
pa_operation_unref(op); pa_operation_unref(op);
pa_threaded_mainloop_unlock(sys->mainloop);
return 0;
}
static int MuteSet(audio_output_t *aout, bool mute)
{
aout_sys_t *sys = aout->sys;
pa_operation *op;
uint32_t idx = pa_stream_get_index(sys->stream);
pa_threaded_mainloop_lock(sys->mainloop);
op = pa_context_set_sink_input_mute(sys->context, idx, mute, NULL, NULL); op = pa_context_set_sink_input_mute(sys->context, idx, mute, NULL, NULL);
if (likely(op != NULL)) if (likely(op != NULL))
pa_operation_unref(op); pa_operation_unref(op);
...@@ -946,7 +959,8 @@ static int Open(vlc_object_t *obj) ...@@ -946,7 +959,8 @@ static int Open(vlc_object_t *obj)
aout->pf_play = Play; aout->pf_play = Play;
aout->pf_pause = Pause; aout->pf_pause = Pause;
aout->pf_flush = Flush; aout->pf_flush = Flush;
aout_VolumeHardInit (aout, VolumeSet, false); aout->volume_set = VolumeSet;
aout->mute_set = MuteSet;
return VLC_SUCCESS; return VLC_SUCCESS;
fail: fail:
......
...@@ -179,7 +179,7 @@ static void Flush(audio_output_t *aout, bool wait) ...@@ -179,7 +179,7 @@ static void Flush(audio_output_t *aout, bool wait)
Leave(); Leave();
} }
static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute) static int SimpleVolumeSet(audio_output_t *aout, float vol)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
HRESULT hr; HRESULT hr;
...@@ -188,26 +188,24 @@ static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute) ...@@ -188,26 +188,24 @@ static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute)
vol = 1.; vol = 1.;
Enter(); Enter();
/* NOTE: better change volume while muted (if mute is toggled) */
if (mute)
{
hr = ISimpleAudioVolume_SetMute(sys->volume.simple, true, NULL);
if (FAILED(hr))
msg_Warn(aout, "cannot mute session (error 0x%lx)", hr);
}
hr = ISimpleAudioVolume_SetMasterVolume(sys->volume.simple, vol, NULL); hr = ISimpleAudioVolume_SetMasterVolume(sys->volume.simple, vol, NULL);
if (FAILED(hr)) if (FAILED(hr))
msg_Warn(aout, "cannot set session volume (error 0x%lx)", hr); msg_Warn(aout, "cannot set session volume (error 0x%lx)", hr);
Leave();
return FAILED(hr) ? -1 : 0;
}
if (!mute) static int SimpleMuteSet(audio_output_t *aout, bool mute)
{ {
hr = ISimpleAudioVolume_SetMute(sys->volume.simple, false, NULL); aout_sys_t *sys = aout->sys;
if (FAILED(hr)) HRESULT hr;
msg_Warn(aout, "cannot unmute session (error 0x%lx)", hr);
} Enter();
hr = ISimpleAudioVolume_SetMute(sys->volume.simple, mute, NULL);
if (FAILED(hr))
msg_Warn(aout, "cannot mute session (error 0x%lx)", hr);
Leave(); Leave();
return 0; return FAILED(hr) ? -1 : 0;
} }
static void vlc_ToWave(WAVEFORMATEXTENSIBLE *restrict wf, static void vlc_ToWave(WAVEFORMATEXTENSIBLE *restrict wf,
...@@ -477,7 +475,10 @@ static int Open(vlc_object_t *obj) ...@@ -477,7 +475,10 @@ static int Open(vlc_object_t *obj)
aout->pf_pause = Pause; aout->pf_pause = Pause;
aout->pf_flush = Flush; aout->pf_flush = Flush;
/*if (AOUT_FMT_LINEAR(&format) && !exclusive)*/ /*if (AOUT_FMT_LINEAR(&format) && !exclusive)*/
aout_VolumeHardInit(aout, SimpleVolumeSet, false); {
aout->volume_set = SimpleVolumeSet;
aout->mute_set = SimpleMuteSet;
}
Leave(); Leave();
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
......
...@@ -68,7 +68,8 @@ static int PlayWaveOut ( audio_output_t *, HWAVEOUT, WAVEHDR *, ...@@ -68,7 +68,8 @@ static int PlayWaveOut ( audio_output_t *, HWAVEOUT, WAVEHDR *,
static void CALLBACK WaveOutCallback ( HWAVEOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR ); static void CALLBACK WaveOutCallback ( HWAVEOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR );
static void* WaveOutThread( void * ); static void* WaveOutThread( void * );
static int VolumeSet( audio_output_t *, float, bool ); static int VolumeSet( audio_output_t *, float );
static int MuteSet( audio_output_t *, bool );
static int WaveOutClearDoneBuffers(aout_sys_t *p_sys); static int WaveOutClearDoneBuffers(aout_sys_t *p_sys);
...@@ -140,6 +141,9 @@ struct aout_sys_t ...@@ -140,6 +141,9 @@ struct aout_sys_t
uint8_t *p_silence_buffer; /* buffer we use to play silence */ uint8_t *p_silence_buffer; /* buffer we use to play silence */
float volume;
bool mute;
bool b_chan_reorder; /* do we need channel reordering */ bool b_chan_reorder; /* do we need channel reordering */
int pi_chan_table[AOUT_CHAN_MAX]; int pi_chan_table[AOUT_CHAN_MAX];
}; };
...@@ -169,7 +173,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -169,7 +173,6 @@ static int Open( vlc_object_t *p_this )
*/ */
ReloadWaveoutDevices( p_this, "waveout-audio-device", val, val, NULL); ReloadWaveoutDevices( p_this, "waveout-audio-device", val, val, NULL);
/* /*
check for configured audio device! check for configured audio device!
*/ */
...@@ -246,7 +249,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -246,7 +249,8 @@ static int Open( vlc_object_t *p_this )
p_aout->format.i_bytes_per_frame; p_aout->format.i_bytes_per_frame;
aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB ); aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB );
p_aout->pf_volume_set = NULL; p_aout->volume_set = NULL;
p_aout->mute_set = NULL;
} }
else else
{ {
...@@ -293,16 +297,22 @@ static int Open( vlc_object_t *p_this ) ...@@ -293,16 +297,22 @@ static int Open( vlc_object_t *p_this )
aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE ); aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE );
#ifndef UNDER_CE
/* Check for hardware volume support */ /* Check for hardware volume support */
if( waveOutGetDevCaps( (UINT_PTR)p_aout->sys->h_waveout, if( waveOutGetDevCaps( (UINT_PTR)p_aout->sys->h_waveout,
&wocaps, sizeof(wocaps) ) == MMSYSERR_NOERROR &wocaps, sizeof(wocaps) ) == MMSYSERR_NOERROR
&& (wocaps.dwSupport & WAVECAPS_VOLUME) ) && (wocaps.dwSupport & WAVECAPS_VOLUME) )
aout_VolumeHardInit( p_aout, VolumeSet, false /* ?? */ ); {
p_aout->volume_set = VolumeSet;
p_aout->mute_set = MuteSet;
p_aout->sys->volume = 0xffff.fp0;
p_aout->sys->mute = false;
}
else else
#endif
aout_VolumeSoftInit( p_aout ); aout_VolumeSoftInit( p_aout );
} }
waveOutReset( p_aout->sys->h_waveout ); waveOutReset( p_aout->sys->h_waveout );
/* Allocate silence buffer */ /* Allocate silence buffer */
...@@ -992,26 +1002,37 @@ static void* WaveOutThread( void *data ) ...@@ -992,26 +1002,37 @@ static void* WaveOutThread( void *data )
return NULL; return NULL;
} }
static int VolumeSet( audio_output_t * p_aout, float volume, bool mute )
{
#ifndef UNDER_CE #ifndef UNDER_CE
const HWAVEOUT hwo = p_aout->sys->h_waveout; static int VolumeSet( audio_output_t *aout, float volume )
#else {
const HWAVEOUT hwo = 0; aout_sys_t *sys = aout->sys;
#endif const HWAVEOUT hwo = sys->h_waveout;
const float full = 0xffff.fp0; const float full = 0xffff.fp0;
if( mute )
volume = 0.;
volume *= full; volume *= full;
if( volume >= full ) if( volume >= full )
volume = full; return -1;
sys->volume = volume;
if( sys->mute )
return 0;
uint16_t vol = lroundf(volume); uint16_t vol = lroundf(volume);
waveOutSetVolume( hwo, vol | (vol << 16) ); waveOutSetVolume( hwo, vol | (vol << 16) );
return 0; return 0;
} }
static int MuteSet( audio_output_t * p_aout, bool mute )
{
aout_sys_t *sys = p_aout->sys;
const HWAVEOUT hwo = sys->h_waveout;
uint16_t vol = mute ? 0 : lroundf(sys->volume);
sys->mute = mute;
waveOutSetVolume( hwo, vol | (vol << 16) );
return 0;
}
#endif
/* /*
reload the configuration drop down list, of the Audio Devices reload the configuration drop down list, of the Audio Devices
......
...@@ -67,7 +67,8 @@ audio_output_t *aout_New( vlc_object_t * p_parent ) ...@@ -67,7 +67,8 @@ audio_output_t *aout_New( vlc_object_t * p_parent )
owner->volume.mixer = NULL; owner->volume.mixer = NULL;
aout->pf_play = aout_DecDeleteBuffer; aout->pf_play = aout_DecDeleteBuffer;
aout->pf_volume_set = NULL; aout->volume_set = NULL;
aout->mute_set = NULL;
vlc_object_set_destructor (aout, aout_Destructor); vlc_object_set_destructor (aout, aout_Destructor);
/* /*
......
...@@ -90,8 +90,12 @@ static int commitVolume (vlc_object_t *obj, audio_output_t *aout, ...@@ -90,8 +90,12 @@ static int commitVolume (vlc_object_t *obj, audio_output_t *aout,
{ {
/* apply volume to the pipeline */ /* apply volume to the pipeline */
aout_lock (aout); aout_lock (aout);
if (aout->pf_volume_set != NULL) if (aout->mute_set != NULL)
ret = aout->pf_volume_set (aout, vol, mute); ret = aout->mute_set (aout, mute);
else
ret = -1;
if (ret == 0 && aout->volume_set != NULL)
ret = aout->volume_set (aout, vol);
aout_unlock (aout); aout_unlock (aout);
if (ret == 0) if (ret == 0)
......
...@@ -277,7 +277,8 @@ void aout_OutputDelete (audio_output_t *aout) ...@@ -277,7 +277,8 @@ void aout_OutputDelete (audio_output_t *aout)
aout->pf_play = aout_DecDeleteBuffer; /* gruik */ aout->pf_play = aout_DecDeleteBuffer; /* gruik */
aout->pf_pause = NULL; aout->pf_pause = NULL;
aout->pf_flush = NULL; aout->pf_flush = NULL;
aout->pf_volume_set = NULL; aout->volume_set = NULL;
aout->mute_set = NULL;
owner->module = NULL; owner->module = NULL;
owner->volume.amp = 1.f; owner->volume.amp = 1.f;
owner->volume.mute = false; owner->volume.mute = false;
...@@ -334,15 +335,11 @@ void aout_OutputFlush( audio_output_t *aout, bool wait ) ...@@ -334,15 +335,11 @@ void aout_OutputFlush( audio_output_t *aout, bool wait )
/*** Volume handling ***/ /*** Volume handling ***/
/** static int aout_SoftVolumeSet (audio_output_t *aout, float volume)
* Volume setter for software volume.
*/
static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute)
{ {
aout_owner_t *owner = aout_owner (aout); aout_owner_t *owner = aout_owner (aout);
aout_assert_locked (aout); aout_assert_locked (aout);
/* Cubic mapping from software volume to amplification factor. /* Cubic mapping from software volume to amplification factor.
* This provides a good tradeoff between low and high volume ranges. * This provides a good tradeoff between low and high volume ranges.
* *
...@@ -350,6 +347,14 @@ static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute) ...@@ -350,6 +347,14 @@ static int aout_VolumeSoftSet (audio_output_t *aout, float volume, bool mute)
* formula, be sure to update the aout_VolumeHardInit()-based plugins also. * formula, be sure to update the aout_VolumeHardInit()-based plugins also.
*/ */
owner->volume.amp = volume * volume * volume; owner->volume.amp = volume * volume * volume;
return 0;
}
static int aout_SoftMuteSet (audio_output_t *aout, bool mute)
{
aout_owner_t *owner = aout_owner (aout);
aout_assert_locked (aout);
owner->volume.mute = mute; owner->volume.mute = mute;
return 0; return 0;
} }
...@@ -366,26 +371,8 @@ void aout_VolumeSoftInit (audio_output_t *aout) ...@@ -366,26 +371,8 @@ void aout_VolumeSoftInit (audio_output_t *aout)
bool mute = var_GetBool (aout, "mute"); bool mute = var_GetBool (aout, "mute");
aout_assert_locked (aout); aout_assert_locked (aout);
aout->pf_volume_set = aout_VolumeSoftSet; aout->volume_set = aout_SoftVolumeSet;
aout_VolumeSoftSet (aout, volume / (float)AOUT_VOLUME_DEFAULT, mute); aout->mute_set = aout_SoftMuteSet;
} aout_SoftVolumeSet (aout, volume / (float)AOUT_VOLUME_DEFAULT);
aout_SoftMuteSet (aout, mute);
/**
* Configures a custom volume setter. This is used by audio outputs that can
* control the hardware volume directly and/or emulate it internally.
* @param setter volume setter callback
* @param restore apply volume from VLC configuration immediately
*/
void aout_VolumeHardInit (audio_output_t *aout, aout_volume_cb setter,
bool restore)
{
aout_assert_locked (aout);
aout->pf_volume_set = setter;
if (restore)
{
float vol = var_GetInteger (aout, "volume")
/ (float)AOUT_VOLUME_DEFAULT;
setter (aout, vol, var_GetBool (aout, "mute"));
}
} }
...@@ -21,7 +21,6 @@ aout_MuteToggle ...@@ -21,7 +21,6 @@ aout_MuteToggle
aout_MuteSet aout_MuteSet
aout_MuteGet aout_MuteGet
aout_VolumeSoftInit aout_VolumeSoftInit
aout_VolumeHardInit
block_Alloc block_Alloc
block_FifoCount block_FifoCount
block_FifoEmpty block_FifoEmpty
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment