[vlc-devel] [PATCH] DirectSound: apply volume attenuation with DirectSound
Rémi Denis-Courmont
remi at remlab.net
Sun May 6 15:34:10 CEST 2012
This should keep the volume latency under 20 ms. This will break
amplification as DirectSound is only capable of attenuation.
This patch compiles but is otherwise entirely untested.
---
modules/audio_output/directx.c | 41 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/modules/audio_output/directx.c b/modules/audio_output/directx.c
index 4cd8c99..7b36f97 100644
--- a/modules/audio_output/directx.c
+++ b/modules/audio_output/directx.c
@@ -29,6 +29,8 @@
# include "config.h"
#endif
+#include <math.h>
+
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
@@ -73,6 +75,7 @@ struct aout_sys_t
LPDIRECTSOUNDBUFFER p_dsbuffer; /* the sound buffer we use (direct sound
* takes care of mixing all the
* secondary buffers into the primary) */
+ LONG volume;
notification_thread_t notif; /* DirectSoundThread id */
@@ -93,6 +96,7 @@ struct aout_sys_t
static int OpenAudio ( vlc_object_t * );
static void CloseAudio ( vlc_object_t * );
static void Play ( audio_output_t *, block_t * );
+static int VolumeSet ( audio_output_t *, float, bool );
/* local functions */
static void Probe ( audio_output_t * );
@@ -228,6 +232,7 @@ static int OpenAudio( vlc_object_t *p_this )
}
aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB );
+ p_aout->sys->volume = -1;
aout_VolumeNoneInit( p_aout );
}
else
@@ -282,7 +287,7 @@ static int OpenAudio( vlc_object_t *p_this )
/* Calculate the frame size in bytes */
aout_FormatPrepare( &p_aout->format );
aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE );
- aout_VolumeSoftInit( p_aout );
+ aout_VolumeHardInit( p_aout, VolumeSet, true );
}
/* Now we need to setup our DirectSound play notification structure */
@@ -570,6 +575,35 @@ static void Play( audio_output_t *p_aout, block_t *p_buffer )
}
/*****************************************************************************
+ * VolumeSet: change audio device volume
+ *****************************************************************************/
+static int VolumeSet( audio_output_t *p_aout, float vol, bool mute )
+{
+ aout_sys_t *sys = p_aout->sys;
+ LONG volume;
+ float f = vol;
+
+ if( mute )
+ f = 0.;
+ /* Convert UI volume percentage to linear factor (cube) */
+ f = f * f * f;
+
+ /* "DirectSound does not support amplification." -- MSDN */
+ if( f > 1. )
+ f = 1.;
+
+ /* millibels from linear amplification */
+ if( f <= powf(10., DSBVOLUME_MIN / -2000.) )
+ volume = DSBVOLUME_MIN;
+ else
+ volume = lroundf(-2000. * log10f(f));
+
+ InterlockedExchange(&sys->volume, volume);
+ aout_VolumeHardSet( p_aout, vol, mute );
+ return 0;
+}
+
+/*****************************************************************************
* CloseAudio: close the audio device
*****************************************************************************/
static void CloseAudio( vlc_object_t *p_this )
@@ -1031,6 +1065,11 @@ static void* DirectSoundThread( void *data )
mtime_t mtime = mdate();
int i;
+ /* Update volume if required */
+ LONG volume = InterlockedExchange( &p_aout->sys->volume, -1 );
+ if( unlikely(volume != -1) )
+ IDirectSoundBuffer_SetVolume( p_aout->sys->p_dsbuffer, volume );
+
/*
* Fill in as much audio data as we can in our circular buffer
*/
--
1.7.10
More information about the vlc-devel
mailing list