[vlc-devel] [PATCH] opus: apply soft clipping when decoding

Tristan Matthews tmatth at videolan.org
Wed Jun 28 09:43:56 CEST 2017


On Wed, Jun 28, 2017 at 2:37 AM, Steve Lhomme <robux4 at gmail.com> wrote:
> On Tue, Jun 27, 2017 at 7:37 PM, Tristan Matthews <tmatth at videolan.org> wrote:
>> This patch uses Opus' soft clipping API to avoid clipping when decoding.
>> This is preferable to hard clipping which will introduce undesired
>> harmonics.
>>
>> ---
>>  modules/codec/opus.c | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/modules/codec/opus.c b/modules/codec/opus.c
>> index a5953bc..10645a9 100644
>> --- a/modules/codec/opus.c
>> +++ b/modules/codec/opus.c
>> @@ -89,6 +89,7 @@ struct decoder_sys_t
>>       */
>>      OpusHeader header;
>>      OpusMSDecoder *p_st;
>> +    float *p_softclip_state;
>>
>>      /*
>>       * Common properties
>> @@ -190,6 +191,7 @@ static int OpenDecoder( vlc_object_t *p_this )
>>      p_dec->pf_flush     = Flush;
>>
>>      p_sys->p_st = NULL;
>> +    p_sys->p_softclip_state = NULL;
>>
>>      return VLC_SUCCESS;
>>  }
>> @@ -343,6 +345,12 @@ static int ProcessInitialHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
>>      p_dec->fmt_out.audio.i_channels = p_header->channels;
>>      p_dec->fmt_out.audio.i_rate = 48000;
>>
>> +    /* State memory for the soft clipping process, 1 float/channel */
>> +    p_sys->p_softclip_state = calloc( p_header->channels, sizeof(float) );
>> +    if( !p_sys->p_softclip_state ) {
>> +        return VLC_ENOMEM;
>> +    }
>> +
>>      if( p_header->channels>2 )
>>      {
>>          static const uint32_t *pi_ch[6] = { pi_3channels_in, pi_4channels_in,
>> @@ -492,6 +500,8 @@ static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
>>              buf[i] *= gain;
>>      }
>>  #endif
>> +    opus_pcm_soft_clip((float *)p_aout_buffer->p_buffer, i_nb_samples,
>
> Is  opus_pcm_soft_clip() available in all Opus versions or should we
> do a check ?

It's been available since 1.1 (released end of 2013), I could add that
as a minimum version to configure.ac

I'm going to push a different patch set that adds this functionality
via an audio_filter plugin instead of in the Opus decoder plugin.

Is there a simple way to ensure that this filter is downstream of the
last audio resampler before the audio output? I've done so in testing
by hacking this new filter into src/audio_output/filters.c and using
it if it could be successfully loaded there, but this seems gross
(also it only supports FL32 input/output).

Best,
-t

>
>> +        p_sys->header.channels, p_sys->p_softclip_state);
>>      p_aout_buffer->i_nb_samples = i_nb_samples;
>>      p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
>>      p_aout_buffer->i_length = date_Increment( &p_sys->end_date, i_nb_samples )
>> @@ -507,6 +517,7 @@ static void CloseDecoder( vlc_object_t *p_this )
>>      decoder_t * p_dec = (decoder_t *)p_this;
>>      decoder_sys_t *p_sys = p_dec->p_sys;
>>
>> +    free( p_sys->p_softclip_state );
>>      if( p_sys->p_st ) opus_multistream_decoder_destroy(p_sys->p_st);
>>
>>      free( p_sys );
>> --
>> 2.7.4
>>
>> _______________________________________________
>> vlc-devel mailing list
>> To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list