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

DirectSound: apply volume attenuation with DirectSound

This should keep the volume latency under 20 ms. This will break
amplification as DirectSound is only capable of attenuation.
Tested-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent a418fa26
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
# include "config.h" # include "config.h"
#endif #endif
#include <math.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_aout.h> #include <vlc_aout.h>
...@@ -73,6 +75,7 @@ struct aout_sys_t ...@@ -73,6 +75,7 @@ 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;
notification_thread_t notif; /* DirectSoundThread id */ notification_thread_t notif; /* DirectSoundThread id */
...@@ -93,6 +96,7 @@ struct aout_sys_t ...@@ -93,6 +96,7 @@ 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 );
/* local functions */ /* local functions */
static void Probe ( audio_output_t * ); static void Probe ( audio_output_t * );
...@@ -228,6 +232,7 @@ static int OpenAudio( vlc_object_t *p_this ) ...@@ -228,6 +232,7 @@ 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;
aout_VolumeNoneInit( p_aout ); aout_VolumeNoneInit( p_aout );
} }
else else
...@@ -282,7 +287,7 @@ static int OpenAudio( vlc_object_t *p_this ) ...@@ -282,7 +287,7 @@ 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_VolumeSoftInit( p_aout ); aout_VolumeHardInit( p_aout, VolumeSet, true );
} }
/* Now we need to setup our DirectSound play notification structure */ /* Now we need to setup our DirectSound play notification structure */
...@@ -569,6 +574,35 @@ static void Play( audio_output_t *p_aout, block_t *p_buffer ) ...@@ -569,6 +574,35 @@ static void Play( audio_output_t *p_aout, block_t *p_buffer )
p_aout->pf_play = aout_PacketPlay; p_aout->pf_play = aout_PacketPlay;
} }
/*****************************************************************************
* 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 * CloseAudio: close the audio device
*****************************************************************************/ *****************************************************************************/
...@@ -1031,6 +1065,11 @@ static void* DirectSoundThread( void *data ) ...@@ -1031,6 +1065,11 @@ static void* DirectSoundThread( void *data )
mtime_t mtime = mdate(); mtime_t mtime = mdate();
int i; 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 * Fill in as much audio data as we can in our circular buffer
*/ */
......
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