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

aout: remove intricate volume/mute transaction system

Volume and mute states are now independant. There is no need to
update them together in a single transaction.

Furthermore, other processes can change the volume and/or mute state
of VLC playback streams asynchronously. Thus volume-up/volume-down
and mute-toggle are not atomic operations even when protected by the
volume lock. We would need to have toggle and up/down provided by the
to the output plugins. That is probably impossible and overkill.
So accept the small race condition and simplify the code.
parent f6d9780e
...@@ -36,13 +36,20 @@ VLC_API int aout_VolumeSet( vlc_object_t *, float ); ...@@ -36,13 +36,20 @@ VLC_API int aout_VolumeSet( vlc_object_t *, float );
VLC_API int aout_VolumeUp( vlc_object_t *, int, float * ); VLC_API int aout_VolumeUp( vlc_object_t *, int, float * );
#define aout_VolumeUp(a, b, c) aout_VolumeUp(VLC_OBJECT(a), b, c) #define aout_VolumeUp(a, b, c) aout_VolumeUp(VLC_OBJECT(a), b, c)
#define aout_VolumeDown(a, b, c) aout_VolumeUp(a, -(b), c) #define aout_VolumeDown(a, b, c) aout_VolumeUp(a, -(b), c)
VLC_API int aout_MuteToggle( vlc_object_t * );
#define aout_MuteToggle(a) aout_MuteToggle(VLC_OBJECT(a))
VLC_API int aout_MuteSet( vlc_object_t *, bool ); VLC_API int aout_MuteSet( vlc_object_t *, bool );
#define aout_MuteSet(a, b) aout_MuteSet(VLC_OBJECT(a), b) #define aout_MuteSet(a, b) aout_MuteSet(VLC_OBJECT(a), b)
VLC_API int aout_MuteGet( vlc_object_t * ); VLC_API int aout_MuteGet( vlc_object_t * );
#define aout_MuteGet(a) aout_MuteGet(VLC_OBJECT(a)) #define aout_MuteGet(a) aout_MuteGet(VLC_OBJECT(a))
static inline int aout_MuteToggle (vlc_object_t *obj)
{
int val = aout_MuteGet (obj);
if (val >= 0)
val = aout_MuteSet (obj, !val);
return val;
}
#define aout_MuteToggle(a) aout_MuteToggle(VLC_OBJECT(a))
VLC_API void aout_EnableFilter( vlc_object_t *, const char *, bool ); VLC_API void aout_EnableFilter( vlc_object_t *, const char *, bool );
#define aout_EnableFilter( o, n, b ) \ #define aout_EnableFilter( o, n, b ) \
aout_EnableFilter( VLC_OBJECT(o), n, b ) aout_EnableFilter( VLC_OBJECT(o), n, b )
......
...@@ -60,104 +60,52 @@ static audio_output_t *findAout (vlc_object_t *obj) ...@@ -60,104 +60,52 @@ static audio_output_t *findAout (vlc_object_t *obj)
} }
#define findAout(o) findAout(VLC_OBJECT(o)) #define findAout(o) findAout(VLC_OBJECT(o))
/** Start a volume change transaction. */ #undef aout_VolumeGet
static void prepareVolume (vlc_object_t *obj, audio_output_t **aoutp, /**
float *vol, bool *mute) * Gets the volume of the output device (independent of mute).
* \return Current audio volume (0 = silent, 1 = nominal),
* or a strictly negative value if undefined.
*/
float aout_VolumeGet (vlc_object_t *obj)
{ {
audio_output_t *aout = findAout (obj); audio_output_t *aout = findAout (obj);
if (aout == NULL)
return -1.f;
/* FIXME: we need interlocking even if aout does not exist! */ long l = var_InheritInteger (aout, "volume");
*aoutp = aout; vlc_object_release (aout);
if (aout != NULL) return l / (float)AOUT_VOLUME_DEFAULT;
{
obj = VLC_OBJECT(aout); /* use aout volume if aout exists */
aout_lock_volume (aout);
}
if (vol != NULL)
*vol = var_InheritInteger (obj, "volume") / (float)AOUT_VOLUME_DEFAULT;
if (mute != NULL)
*mute = var_InheritBool (obj, "mute");
} }
/** Commit a volume change transaction. */ #undef aout_VolumeSet
static int commitVolume (vlc_object_t *obj, audio_output_t *aout, /**
float vol, bool mute) * Sets the volume of the output device.
* \note The mute status is not changed.
*/
int aout_VolumeSet (vlc_object_t *obj, float vol)
{ {
long volume = lroundf (vol * AOUT_VOLUME_DEFAULT); long volume = lroundf (vol * AOUT_VOLUME_DEFAULT);
int ret = 0; int ret = -1;
audio_output_t *aout = findAout (obj);
if (aout != NULL) if (aout != NULL)
{ {
/* apply volume to the pipeline */
aout_lock (aout); aout_lock (aout);
if (aout->mute_set != NULL) if (aout->volume_set != NULL)
ret = aout->mute_set (aout, mute);
else
ret = -1;
if (ret == 0 && aout->volume_set != NULL)
ret = aout->volume_set (aout, vol); ret = aout->volume_set (aout, vol);
aout_unlock (aout); aout_unlock (aout);
if (ret == 0)
{ /* update aout volume if it maintains its own */
var_SetInteger (aout, "volume", volume);
var_SetBool (aout, "mute", mute);
}
aout_unlock_volume (aout);
vlc_object_release (aout); vlc_object_release (aout);
} }
if (ret == 0) if (ret == 0)
{ /* update caller (input manager) volume */ { /* update caller (input manager) volume */
var_SetInteger (obj, "volume", volume); var_SetInteger (obj, "volume", volume);
var_SetBool (obj, "mute", mute);
if (var_InheritBool (obj, "volume-save")) if (var_InheritBool (obj, "volume-save"))
config_PutInt (obj, "volume", volume); config_PutInt (obj, "volume", volume);
} }
return ret; return ret;
} }
/** Cancel a volume change transaction. */
static void cancelVolume (vlc_object_t *obj, audio_output_t *aout)
{
(void) obj;
if (aout != NULL)
{
aout_unlock_volume (aout);
vlc_object_release (aout);
}
}
#undef aout_VolumeGet
/**
* Gets the volume of the output device (independent of mute).
* \return Current audio volume (0 = silent, 1 = nominal),
* or a strictly negative value if undefined.
*/
float aout_VolumeGet (vlc_object_t *obj)
{
audio_output_t *aout;
float vol;
prepareVolume (obj, &aout, &vol, NULL);
cancelVolume (obj, aout);
return vol;
}
#undef aout_VolumeSet
/**
* Sets the volume of the output device.
* The mute status is not changed.
*/
int aout_VolumeSet (vlc_object_t *obj, float vol)
{
audio_output_t *aout;
bool mute;
prepareVolume (obj, &aout, NULL, &mute);
return commitVolume (obj, aout, vol, mute);
}
#undef aout_VolumeUp #undef aout_VolumeUp
/** /**
* Raises the volume. * Raises the volume.
...@@ -166,38 +114,21 @@ int aout_VolumeSet (vlc_object_t *obj, float vol) ...@@ -166,38 +114,21 @@ int aout_VolumeSet (vlc_object_t *obj, float vol)
*/ */
int aout_VolumeUp (vlc_object_t *obj, int value, float *volp) int aout_VolumeUp (vlc_object_t *obj, int value, float *volp)
{ {
audio_output_t *aout;
int ret;
float vol;
bool mute;
value *= var_InheritInteger (obj, "volume-step"); value *= var_InheritInteger (obj, "volume-step");
prepareVolume (obj, &aout, &vol, &mute); float vol = aout_VolumeGet (obj);
if (vol < 0.)
return -1;
vol += value / (float)AOUT_VOLUME_DEFAULT; vol += value / (float)AOUT_VOLUME_DEFAULT;
if (vol < 0.) if (vol < 0.)
vol = 0.; vol = 0.;
if (vol > (AOUT_VOLUME_MAX / AOUT_VOLUME_DEFAULT)) if (vol > 2.)
vol = AOUT_VOLUME_MAX / AOUT_VOLUME_DEFAULT; vol = 2.;
ret = commitVolume (obj, aout, vol, mute);
if (volp != NULL) if (volp != NULL)
*volp = vol; *volp = vol;
return ret;
}
#undef aout_MuteToggle return aout_VolumeSet (obj, vol);
/**
* Toggles the mute state.
*/
int aout_MuteToggle (vlc_object_t *obj)
{
audio_output_t *aout;
float vol;
bool mute;
prepareVolume (obj, &aout, &vol, &mute);
mute = !mute;
return commitVolume (obj, aout, vol, mute);
} }
#undef aout_MuteGet #undef aout_MuteGet
...@@ -207,11 +138,12 @@ int aout_MuteToggle (vlc_object_t *obj) ...@@ -207,11 +138,12 @@ int aout_MuteToggle (vlc_object_t *obj)
*/ */
int aout_MuteGet (vlc_object_t *obj) int aout_MuteGet (vlc_object_t *obj)
{ {
audio_output_t *aout; audio_output_t *aout = findAout (obj);
bool mute; if (aout == NULL)
return -1.f;
prepareVolume (obj, &aout, NULL, &mute); bool mute = var_InheritBool (aout, "mute");
cancelVolume (obj, aout); vlc_object_release (aout);
return mute; return mute;
} }
...@@ -221,11 +153,21 @@ int aout_MuteGet (vlc_object_t *obj) ...@@ -221,11 +153,21 @@ int aout_MuteGet (vlc_object_t *obj)
*/ */
int aout_MuteSet (vlc_object_t *obj, bool mute) int aout_MuteSet (vlc_object_t *obj, bool mute)
{ {
audio_output_t *aout; int ret = -1;
float vol;
prepareVolume (obj, &aout, &vol, NULL); audio_output_t *aout = findAout (obj);
return commitVolume (obj, aout, vol, mute); if (aout != NULL)
{
aout_lock (aout);
if (aout->mute_set != NULL)
ret = aout->mute_set (aout, mute);
aout_unlock (aout);
vlc_object_release (aout);
}
if (ret == 0)
var_SetBool (obj, "mute", mute);
return ret;
} }
......
...@@ -347,6 +347,7 @@ static int aout_SoftVolumeSet (audio_output_t *aout, float volume) ...@@ -347,6 +347,7 @@ static int aout_SoftVolumeSet (audio_output_t *aout, float volume)
* 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;
aout_VolumeReport (aout, volume);
return 0; return 0;
} }
...@@ -356,6 +357,7 @@ static int aout_SoftMuteSet (audio_output_t *aout, bool mute) ...@@ -356,6 +357,7 @@ static int aout_SoftMuteSet (audio_output_t *aout, bool mute)
aout_assert_locked (aout); aout_assert_locked (aout);
owner->volume.mute = mute; owner->volume.mute = mute;
aout_MuteReport (aout, mute);
return 0; return 0;
} }
......
...@@ -17,7 +17,6 @@ aout_MixerRun ...@@ -17,7 +17,6 @@ aout_MixerRun
aout_VolumeGet aout_VolumeGet
aout_VolumeSet aout_VolumeSet
aout_VolumeUp aout_VolumeUp
aout_MuteToggle
aout_MuteSet aout_MuteSet
aout_MuteGet aout_MuteGet
aout_VolumeSoftInit aout_VolumeSoftInit
......
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