Commit 45763924 authored by Laurent Aimar's avatar Laurent Aimar Committed by Jean-Baptiste Kempf

Fixed bandlimited audio filter with low output samplerate.

It closes #3543.
(cherry picked from commit f9f6f88c53d72b8b1cf2b05a37e5ced786a2fbbf)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 1dae4565
...@@ -57,7 +57,7 @@ static void CloseFilter( vlc_object_t * ); ...@@ -57,7 +57,7 @@ static void CloseFilter( vlc_object_t * );
static block_t *Resample( filter_t *, block_t * ); static block_t *Resample( filter_t *, block_t * );
static void ResampleFloat( filter_t *p_filter, static void ResampleFloat( filter_t *p_filter,
block_t *p_out_buf, size_t *pi_out, block_t **pp_out_buf, size_t *pi_out,
float **pp_in, float **pp_in,
int i_in, int i_in_end, int i_in, int i_in_end,
double d_factor, bool b_factor_old, double d_factor, bool b_factor_old,
...@@ -147,7 +147,6 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf ) ...@@ -147,7 +147,6 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
block_Release( p_in_buf ); block_Release( p_in_buf );
return NULL; return NULL;
} }
float *p_out = (float *)p_out_buf->p_buffer;
if( (p_in_buf->i_flags & BLOCK_FLAG_DISCONTINUITY) || p_sys->b_first ) if( (p_in_buf->i_flags & BLOCK_FLAG_DISCONTINUITY) || p_sys->b_first )
{ {
...@@ -194,7 +193,7 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf ) ...@@ -194,7 +193,7 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
const float *p_in_orig = p_in; const float *p_in_orig = p_in;
/* Make sure the output buffer is reset */ /* Make sure the output buffer is reset */
memset( p_out, 0, p_out_buf->i_buffer ); memset( p_out_buf->p_buffer, 0, p_out_buf->i_buffer );
/* Calculate the new length of the filter wing */ /* Calculate the new length of the filter wing */
d_factor = (double)i_out_rate / p_filter->fmt_in.audio.i_rate; d_factor = (double)i_out_rate / p_filter->fmt_in.audio.i_rate;
...@@ -214,7 +213,7 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf ) ...@@ -214,7 +213,7 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
i_old_in_end = __MIN( i_filter_wing, i_in_nb - p_sys->i_old_wing ); i_old_in_end = __MIN( i_filter_wing, i_in_nb - p_sys->i_old_wing );
ResampleFloat( p_filter, ResampleFloat( p_filter,
p_out_buf, &i_out, &p_in, &p_out_buf, &i_out, &p_in,
i_in, i_old_in_end, i_in, i_old_in_end,
p_sys->d_old_factor, true, p_sys->d_old_factor, true,
i_nb_channels, i_bytes_per_frame ); i_nb_channels, i_bytes_per_frame );
...@@ -226,20 +225,23 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf ) ...@@ -226,20 +225,23 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
p_sys->d_old_factor = d_factor; p_sys->d_old_factor = d_factor;
p_sys->i_old_wing = i_filter_wing; p_sys->i_old_wing = i_filter_wing;
} }
ResampleFloat( p_filter, if( p_out_buf )
p_out_buf, &i_out, &p_in, {
i_in, i_in_nb - i_filter_wing, ResampleFloat( p_filter,
d_factor, false, &p_out_buf, &i_out, &p_in,
i_nb_channels, i_bytes_per_frame ); i_in, i_in_nb - i_filter_wing,
d_factor, false,
/* Finalize aout buffer */ i_nb_channels, i_bytes_per_frame );
p_out_buf->i_nb_samples = i_out;
p_out_buf->i_pts = date_Get( &p_sys->end_date ); /* Finalize aout buffer */
p_out_buf->i_length = date_Increment( &p_sys->end_date, p_out_buf->i_nb_samples = i_out;
p_out_buf->i_nb_samples ) - p_out_buf->i_pts; p_out_buf->i_pts = date_Get( &p_sys->end_date );
p_out_buf->i_length = date_Increment( &p_sys->end_date,
p_out_buf->i_buffer = p_out_buf->i_nb_samples * p_out_buf->i_nb_samples ) - p_out_buf->i_pts;
i_nb_channels * sizeof(int32_t);
p_out_buf->i_buffer = p_out_buf->i_nb_samples *
i_nb_channels * sizeof(int32_t);
}
/* Buffer i_filter_wing * 2 samples for next time */ /* Buffer i_filter_wing * 2 samples for next time */
if( p_sys->i_old_wing ) if( p_sys->i_old_wing )
...@@ -435,8 +437,28 @@ static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing ...@@ -435,8 +437,28 @@ static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing
} }
} }
static int ReallocBuffer( block_t **pp_out_buf,
float **pp_out, size_t i_out,
int i_nb_channels, int i_bytes_per_frame )
{
if( i_out < (*pp_out_buf)->i_buffer/i_bytes_per_frame )
return VLC_SUCCESS;
/* It may happen when the wing size changes */
const unsigned i_extra_frame = 256;
*pp_out_buf = block_Realloc( *pp_out_buf, 0,
(*pp_out_buf)->i_buffer +
i_extra_frame * i_bytes_per_frame );
if( !*pp_out_buf )
return VLC_EGENERIC;
*pp_out = (float*)(*pp_out_buf)->p_buffer + i_out * i_nb_channels;
memset( *pp_out, 0, i_extra_frame * i_bytes_per_frame );
return VLC_SUCCESS;
}
static void ResampleFloat( filter_t *p_filter, static void ResampleFloat( filter_t *p_filter,
block_t *p_out_buf, size_t *pi_out, block_t **pp_out_buf, size_t *pi_out,
float **pp_in, float **pp_in,
int i_in, int i_in_end, int i_in, int i_in_end,
double d_factor, bool b_factor_old, double d_factor, bool b_factor_old,
...@@ -446,12 +468,15 @@ static void ResampleFloat( filter_t *p_filter, ...@@ -446,12 +468,15 @@ static void ResampleFloat( filter_t *p_filter,
float *p_in = *pp_in; float *p_in = *pp_in;
size_t i_out = *pi_out; size_t i_out = *pi_out;
float *p_out = (float*)p_out_buf->p_buffer + i_out * i_nb_channels; float *p_out = (float*)(*pp_out_buf)->p_buffer + i_out * i_nb_channels;
for( ; i_in < i_in_end; i_in++ ) for( ; i_in < i_in_end; i_in++ )
{ {
if( b_factor_old && d_factor == 1 ) if( b_factor_old && d_factor == 1 )
{ {
if( ReallocBuffer( pp_out_buf, &p_out,
i_out, i_nb_channels, i_bytes_per_frame ) )
return;
/* Just copy the samples */ /* Just copy the samples */
memcpy( p_out, p_in, i_bytes_per_frame ); memcpy( p_out, p_in, i_bytes_per_frame );
p_in += i_nb_channels; p_in += i_nb_channels;
...@@ -462,8 +487,9 @@ static void ResampleFloat( filter_t *p_filter, ...@@ -462,8 +487,9 @@ static void ResampleFloat( filter_t *p_filter,
while( p_sys->i_remainder < p_filter->fmt_out.audio.i_rate ) while( p_sys->i_remainder < p_filter->fmt_out.audio.i_rate )
{ {
if( p_out_buf->i_buffer/i_bytes_per_frame <= i_out ) if( ReallocBuffer( pp_out_buf, &p_out,
break; i_out, i_nb_channels, i_bytes_per_frame ) )
return;
if( d_factor >= 1 ) if( d_factor >= 1 )
{ {
......
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