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 @@
# 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 */
......@@ -569,6 +574,35 @@ static void Play( audio_output_t *p_aout, block_t *p_buffer )
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
*****************************************************************************/
......@@ -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
*/
......
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