Commit bf06c4f2 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry

Use clipping prevention on 16-bit decode paths.

When we decode using libopus's fixed-point APIs, libopus internally
 applies soft clipping prevention.
When we decode using libopus's floating-point APIs, this behavior
 is disabled.
If we're ultimately planning to output the data to the user in
 fixed-point, we need to apply the clipping prevention ourselves.
parent f8222c99
......@@ -38,6 +38,13 @@ typedef opus_int16 op_sample;
typedef float op_sample;
# endif
/*We're using this define to test for libopus 1.1 or later until libopus
provides a better mechanism.*/
# if defined(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST)
/*Enable soft clipping prevention in 16-bit decodes.*/
# define OP_SOFT_CLIP (1)
# endif
# if OP_GNUC_PREREQ(4,2)
/*Disable excessive warnings about the order of operations.*/
# pragma GCC diagnostic ignored "-Wparentheses"
......@@ -203,8 +210,11 @@ struct OggOpusFile{
int od_buffer_pos;
/*The number of valid samples in the decoded buffer.*/
int od_buffer_size;
/*Internal state for dithering float->short output.*/
/*Internal state for soft clipping and dithering float->short output.*/
#if !defined(OP_FIXED_POINT)
# if defined(OP_SOFT_CLIP)
float clip_state[OP_NCHANNELS_MAX];
# endif
float dither_a[OP_NCHANNELS_MAX*4];
float dither_b[OP_NCHANNELS_MAX*4];
int dither_mute;
......
......@@ -2898,19 +2898,27 @@ static const float OP_FCOEF_A[4]={
};
static void op_shaped_dither16(OggOpusFile *_of,opus_int16 *_dst,
const float *_src,int _nsamples,int _nchannels){
float *_src,int _nsamples,int _nchannels){
opus_uint32 seed;
int mute;
int ci;
int i;
mute=_of->dither_mute;
seed=_of->dither_seed;
if(_of->state_channel_count!=_nchannels)mute=65;
if(_of->state_channel_count!=_nchannels){
mute=65;
# if defined(OP_SOFT_CLIP)
for(ci=0;ci<_nchannels;ci++)_of->clip_state[ci]=0;
# endif
}
# if defined(OP_SOFT_CLIP)
opus_pcm_soft_clip(_src,_nsamples,_nchannels,_of->clip_state);
# endif
/*In order to avoid replacing digital silence with quiet dither noise, we
mute if the output has been silent for a while.*/
if(mute>64)memset(_of->dither_a,0,sizeof(*_of->dither_a)*4*_nchannels);
for(i=0;i<_nsamples;i++){
int silent;
int ci;
silent=1;
for(ci=0;ci<_nchannels;ci++){
float r;
......
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