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

Reset dither state when API path changes.

The caller can switch between the fixed/float APIs and the
 stereo/multichannel APIs on every call.
Detect this and reset the dither state to avoid potentially
 injecting noise from a very out-of-date state when switching from
 fixed to float back to fixed, or from the wrong channels when
 switching between stereo and multichannel.
Normal applications won't do this stuff, but we should be
 well-behaved if they do.
parent 94b0c98a
......@@ -209,6 +209,11 @@ struct OggOpusFile{
float dither_b[OP_NCHANNELS_MAX*4];
int dither_mute;
opus_uint32 dither_seed;
/*The number of channels represented by the internal state.
This gets set to 0 whenever anything that would prevent state propagation
occurs (switching between the float/short APIs, or between the
stereo/multistream APIs).*/
int state_channel_count;
#endif
};
......
......@@ -2883,9 +2883,9 @@ static opus_uint32 op_rand(opus_uint32 _seed){
The attenuation is probably also helpful to prevent clipping in the DAC
reconstruction filters or downstream resampling, in any case.*/
#define OP_GAIN (32753.0F)
# define OP_GAIN (32753.0F)
#define OP_PRNG_GAIN (1.0F/0xFFFFFFFF)
# define OP_PRNG_GAIN (1.0F/0xFFFFFFFF)
/*48 kHz noise shaping filter, sd=2.34.*/
......@@ -2904,6 +2904,7 @@ static void op_shaped_dither16(OggOpusFile *_of,opus_int16 *_dst,
int i;
mute=_of->dither_mute;
seed=_of->dither_seed;
if(_of->state_channel_count!=_nchannels)mute=65;
/*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);
......@@ -2953,6 +2954,7 @@ static void op_shaped_dither16(OggOpusFile *_of,opus_int16 *_dst,
}
_of->dither_mute=OP_MIN(mute,65);
_of->dither_seed=seed;
_of->state_channel_count=_nchannels;
}
static int op_float2short_filter(OggOpusFile *_of,void *_dst,int _dst_sz,
......@@ -2969,6 +2971,7 @@ int op_read(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size,int *_li){
}
int op_read_float(OggOpusFile *_of,float *_pcm,int _buf_size,int *_li){
_of->state_channel_count=0;
return op_read_native(_of,_pcm,_buf_size,_li);
}
......@@ -3063,6 +3066,7 @@ int op_read_stereo(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size){
}
int op_read_float_stereo(OggOpusFile *_of,float *_pcm,int _buf_size){
_of->state_channel_count=0;
return op_read_native_filter(_of,_pcm,_buf_size,op_stereo_filter,NULL);
}
......
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