[vlc-devel] [PATCH] Use waveOutSetVolume to set volume instead of pure software gain

Rémi Denis-Courmont remi at remlab.net
Thu Jan 17 23:20:30 CET 2013


	Hello,

You could create/destroy the timer in Open()/Close() and (dis)arm it in 
Pause(). Play() can probably be used to poll while not paused.

In the long term, a timer kinda sucks though. On Windows Vista+, reusing 
mmdevice would be better. On XP, the timer is probably useless anyway, since 
there is no per-application mixer control.

Le jeudi 17 janvier 2013 23:56:24, Denis Charmet a écrit :
> ---
>  modules/audio_output/waveout.c |  166
> +++++++++++++++++++++++++++++++++++++--- 1 file changed, 157
> insertions(+), 9 deletions(-)
> 
> diff --git a/modules/audio_output/waveout.c
> b/modules/audio_output/waveout.c index 6e72d79..05a67dd 100644
> --- a/modules/audio_output/waveout.c
> +++ b/modules/audio_output/waveout.c
> @@ -82,6 +82,10 @@ static uint32_t findDeviceID(char *);
>  static int WaveOutTimeGet(audio_output_t * , mtime_t *);
>  static void WaveOutFlush( audio_output_t *, bool);
>  static void WaveOutPause( audio_output_t *, bool, mtime_t);
> +static int WaveoutVolumeSet(audio_output_t * p_aout, float volume);
> +static int WaveoutMuteSet(audio_output_t * p_aout, bool mute);
> +
> +static void WaveoutPollVolume( void * );
> 
>  static const wchar_t device_name_fmt[] = L"%ls ($%x,$%x)";
> 
> @@ -107,14 +111,16 @@ struct aout_sys_t
>      int i_buffer_size;
> 
>      int i_rate;
> -    bool b_spdif;
> 
>      uint8_t *p_silence_buffer;              /* buffer we use to play
> silence */ +
> +    float f_volume;
> 
> -    float soft_gain;
> -    bool soft_mute;
> -
> +    bool b_spdif;
> +    bool b_mute;
> +    bool b_soft;                            /* Use software gain */
>      uint8_t chans_to_reorder;              /* do we need channel
> reordering */ +
>      uint8_t chan_table[AOUT_CHAN_MAX];
>      vlc_fourcc_t format;
> 
> @@ -124,10 +130,9 @@ struct aout_sys_t
> 
>      vlc_mutex_t lock;
>      vlc_cond_t cond;
> +    vlc_timer_t volume_poll_timer;
>  };
> 
> -#include "volume.h"
> -
>  /*************************************************************************
> **** * Module descriptor
>  
> **************************************************************************
> ***/ @@ -137,6 +142,8 @@ struct aout_sys_t
>                         "to apply.")
>  #define DEFAULT_AUDIO_DEVICE N_("Default Audio Device")
> 
> +#define VOLUME_TEXT N_("Audio volume")
> +
>  vlc_module_begin ()
>      set_shortname( "WaveOut" )
>      set_description( N_("Win32 waveOut extension output") )
> @@ -147,7 +154,9 @@ vlc_module_begin ()
>      add_string( "waveout-audio-device", "wavemapper",
>                   DEVICE_TEXT, DEVICE_LONG, false )
>         change_string_cb( ReloadWaveoutDevices )
> -    add_sw_gain( )
> +
> +    add_float( "waveout-volume", 1.0f, VOLUME_TEXT, NULL, true )
> +         change_float_range(0.0f, 2.0f)
> 
>      add_bool( "waveout-float32", true, FLOAT_TEXT, FLOAT_LONGTEXT, true )
> 
> @@ -168,6 +177,9 @@ static int Start( audio_output_t *p_aout,
> audio_sample_format_t *restrict fmt ) p_aout->pause = WaveOutPause;
>      p_aout->flush = WaveOutFlush;
> 
> +    /* Default behaviour is to use software gain */
> +    p_aout->sys->b_soft = true;
> +
>      /*
>        check for configured audio device!
>      */
> @@ -273,7 +285,13 @@ static int Start( audio_output_t *p_aout,
> audio_sample_format_t *restrict fmt ) aout_FormatPrepare( fmt );
>          p_aout->sys->i_buffer_size = FRAME_SIZE * fmt->i_bytes_per_frame;
> 
> -        aout_SoftVolumeStart( p_aout );
> +        if( waveoutcaps.dwSupport & WAVECAPS_VOLUME )
> +        {
> +            aout_GainRequest( p_aout, 1.0f );
> +            p_aout->sys->b_soft = false;
> +        }
> +
> +        WaveoutMuteSet( p_aout, p_aout->sys->b_mute );
> 
>          p_aout->sys->b_spdif = false;
>      }
> @@ -302,6 +320,15 @@ static int Start( audio_output_t *p_aout,
> audio_sample_format_t *restrict fmt ) p_aout->sys->i_played_length = 0;
>      p_aout->sys->p_free_list = NULL;
> 
> +    /* Create and arm volume polling timer */
> +    if( vlc_timer_create( &p_aout->sys->volume_poll_timer,
> +                          WaveoutPollVolume, p_aout ) )
> +    {
> +        msg_Err( p_aout, "Couldn't create volume polling timer" );
> +        return VLC_ENOMEM;
> +    }
> +    vlc_timer_schedule( p_aout->sys->volume_poll_timer, false, 1, 200000
> ); +
>      return VLC_SUCCESS;
>  }
> 
> @@ -459,6 +486,8 @@ static void Stop( audio_output_t *p_aout )
>  {
>      aout_sys_t *p_sys = p_aout->sys;
> 
> +    vlc_timer_destroy( p_aout->sys->volume_poll_timer );
> +
>      /* Before calling waveOutClose we must reset the device */
>      MMRESULT result = waveOutReset( p_sys->h_waveout );
>      if(result != MMSYSERR_NOERROR)
> @@ -495,6 +524,7 @@ static void Stop( audio_output_t *p_aout )
> 
>      free( p_sys->p_silence_buffer );
>      p_aout->sys->i_played_length = 0;
> +    p_sys->b_soft = true;
>  }
> 
>  /*************************************************************************
> **** @@ -850,7 +880,14 @@ static int Open(vlc_object_t *obj)
>      aout->sys = sys;
>      aout->start = Start;
>      aout->stop = Stop;
> -    aout_SoftVolumeInit(aout);
> +    aout->volume_set = WaveoutVolumeSet;
> +    aout->mute_set = WaveoutMuteSet;
> +
> +    sys->f_volume = var_InheritFloat(aout, "waveout-volume");
> +    sys->b_mute = var_InheritBool(aout, "mute");
> +
> +    aout_MuteReport(aout, sys->b_mute);
> +    aout_VolumeReport(aout, sys->f_volume );
> 
>      vlc_mutex_init( &sys->lock );
>      vlc_cond_init( &sys->cond );
> @@ -932,3 +969,114 @@ static void WaveOutPause( audio_output_t * p_aout,
> bool pause, mtime_t date) }
>      }
>  }
> +
> +static int WaveoutVolumeSet( audio_output_t *p_aout, float volume )
> +{
> +    aout_sys_t *sys = p_aout->sys;
> +
> +    if( sys->b_soft )
> +    {
> +        float gain = volume * volume * volume;
> +        if ( !sys->b_mute && aout_GainRequest( p_aout, gain ) )
> +            return -1;
> +    }
> +    else
> +    {
> +        const HWAVEOUT hwo = sys->h_waveout;
> +
> +        uint32_t vol = lroundf( volume * 0x7fff.fp0 );
> +
> +        if( !sys->b_mute )
> +        {
> +            if( vol > 0xffff )
> +            {
> +                vol = 0xffff;
> +                volume = 2.0f;
> +            }
> +
> +            MMRESULT r = waveOutSetVolume( hwo, vol | ( vol << 16 ) );
> +            if( r != MMSYSERR_NOERROR )
> +            {
> +                msg_Err( p_aout, "waveOutSetVolume failed (%u)", r );
> +                return -1;
> +            }
> +        }
> +    }
> +
> +    vlc_mutex_lock(&p_aout->sys->lock);
> +    sys->f_volume = volume;
> +
> +    if( var_InheritBool( p_aout, "volume-save" ) )
> +        config_PutFloat( p_aout, "waveout-volume", volume );
> +
> +    aout_VolumeReport( p_aout, volume );
> +    vlc_mutex_unlock(&p_aout->sys->lock);
> +
> +    return 0;
> +}
> +
> +static int WaveoutMuteSet( audio_output_t * p_aout, bool mute )
> +{
> +    aout_sys_t *sys = p_aout->sys;
> +
> +    if( sys->b_soft )
> +    {
> +        float gain = sys->f_volume * sys->f_volume * sys->f_volume;
> +        if ( aout_GainRequest( p_aout, mute ? 0.f : gain ) )
> +            return -1;
> +    }
> +    else
> +    {
> +
> +        const HWAVEOUT hwo = sys->h_waveout;
> +        uint32_t vol = mute ? 0 : lroundf( sys->f_volume * 0x7fff.fp0 );
> +
> +        if( vol > 0xffff )
> +            vol = 0xffff;
> +
> +        MMRESULT r = waveOutSetVolume( hwo, vol | ( vol << 16 ) );
> +        if( r != MMSYSERR_NOERROR )
> +        {
> +            msg_Err( p_aout, "waveOutSetVolume failed (%u)", r );
> +            return -1;
> +        }
> +    }
> +
> +    vlc_mutex_lock(&p_aout->sys->lock);
> +    sys->b_mute = mute;
> +    aout_MuteReport( p_aout, mute );
> +    vlc_mutex_unlock(&p_aout->sys->lock);
> +
> +    return 0;
> +}
> +
> +static void WaveoutPollVolume( void * aout )
> +{
> +    audio_output_t * p_aout = (audio_output_t *) aout;
> +    uint32_t vol;
> +
> +    MMRESULT r = waveOutGetVolume( p_aout->sys->h_waveout, (LPDWORD) &vol
> ); +
> +    if( r != MMSYSERR_NOERROR )
> +    {
> +        msg_Err( p_aout, "waveOutGetVolume failed (%u)", r );
> +        return;
> +    }
> +
> +    float volume = (float) ( vol & UINT32_C( 0xffff ) );
> +    volume /= 0x7fff.fp0;
> +
> +    vlc_mutex_lock(&p_aout->sys->lock);
> +    if( !p_aout->sys->b_mute && volume != p_aout->sys->f_volume )
> +    {
> +        p_aout->sys->f_volume = volume;
> +
> +        if( var_InheritBool( p_aout, "volume-save" ) )
> +            config_PutFloat( p_aout, "waveout-volume", volume );
> +
> +        aout_VolumeReport( p_aout, volume );
> +    }
> +    vlc_mutex_unlock(&p_aout->sys->lock);
> +
> +    return;
> +}

-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list