Commit 75426e20 authored by Gildas Bazin's avatar Gildas Bazin

* modules/audio_filter/resampler/bandlimited.[ch]: new high-quality
   bandlimited interpolation resampler.
   It is not yet enabled by default because it requires a bit more works
   (not fully stable yet because of buffer overflows under certain conditions).

* src/audio_output/input.c: the resamplers are now always active (expcept
   in spdif mode).

* modules/audio_filter/resampler/*: modified the resampler to return the
   input buffer when no resampling is needed.
parent a7c736f0
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output * aout_internal.h : internal defines for audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: aout_internal.h,v 1.38 2003/02/09 01:13:43 massiot Exp $ * $Id: aout_internal.h,v 1.39 2003/03/04 03:27:40 gbazin Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -112,7 +112,7 @@ typedef struct aout_filter_t ...@@ -112,7 +112,7 @@ typedef struct aout_filter_t
struct aout_buffer_t *, struct aout_buffer_t *,
struct aout_buffer_t * ); struct aout_buffer_t * );
vlc_bool_t b_in_place; vlc_bool_t b_in_place;
vlc_bool_t b_reinit; vlc_bool_t b_continuity;
} aout_filter_t; } aout_filter_t;
/***************************************************************************** /*****************************************************************************
......
SOURCES_trivial_resampler = modules/audio_filter/resampler/trivial.c SOURCES_trivial_resampler = modules/audio_filter/resampler/trivial.c
SOURCES_ugly_resampler = modules/audio_filter/resampler/ugly.c SOURCES_ugly_resampler = modules/audio_filter/resampler/ugly.c
SOURCES_linear_resampler = modules/audio_filter/resampler/linear.c SOURCES_linear_resampler = modules/audio_filter/resampler/linear.c
#SOURCES_fast = modules/audio_filter/resampler/fast.c SOURCES_bandlimited_resampler = modules/audio_filter/resampler/bandlimited.c \
modules/audio_filter/resampler/bandlimited.h
This diff is collapsed.
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* linear.c : linear interpolation resampler * linear.c : linear interpolation resampler
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: linear.c,v 1.9 2003/02/17 09:47:16 gbazin Exp $ * $Id: linear.c,v 1.10 2003/03/04 03:27:40 gbazin Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* Sigmund Augdal <sigmunau@idi.ntnu.no> * Sigmund Augdal <sigmunau@idi.ntnu.no>
...@@ -94,7 +94,10 @@ static int Create( vlc_object_t *p_this ) ...@@ -94,7 +94,10 @@ static int Create( vlc_object_t *p_this )
} }
p_filter->pf_do_work = DoWork; p_filter->pf_do_work = DoWork;
p_filter->b_in_place = VLC_FALSE;
/* We don't want a new buffer to be created because we're not sure we'll
* actually need to resample anything. */
p_filter->b_in_place = VLC_TRUE;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -115,18 +118,46 @@ static void Close( vlc_object_t * p_this ) ...@@ -115,18 +118,46 @@ static void Close( vlc_object_t * p_this )
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
{ {
float* p_in = (float*)p_in_buf->p_buffer; float *p_in, *p_out = (float *)p_out_buf->p_buffer;
float* p_out = (float*)p_out_buf->p_buffer; float *p_prev_sample = (float *)p_filter->p_sys->p_prev_sample;
float* p_prev_sample = (float*)p_filter->p_sys->p_prev_sample;
int i_nb_channels = aout_FormatNbChannels( &p_filter->input ); int i_nb_channels = aout_FormatNbChannels( &p_filter->input );
int i_in_nb = p_in_buf->i_nb_samples; int i_in_nb = p_in_buf->i_nb_samples;
int i_chan, i_in, i_out = 0; int i_chan, i_in, i_out = 0;
/* Check if we really need to run the resampler */
if( p_aout->mixer.mixer.i_rate == p_filter->input.i_rate )
{
if( p_filter->b_continuity &&
p_in_buf->i_size >=
p_in_buf->i_nb_bytes + sizeof(float) * i_nb_channels )
{
/* output the whole thing with the last sample from last time */
memmove( ((float *)(p_in_buf->p_buffer)) + i_nb_channels,
p_in_buf->p_buffer, p_in_buf->i_nb_bytes );
memcpy( p_in_buf->p_buffer, p_prev_sample,
i_nb_channels * sizeof(float) );
}
p_filter->b_continuity = VLC_FALSE;
return;
}
#ifdef HAVE_ALLOCA
p_in = (float *)alloca( p_in_buf->i_nb_bytes );
#else
p_in = (float *)malloc( p_in_buf->i_nb_bytes );
#endif
if( p_in == NULL )
{
return;
}
p_aout->p_vlc->pf_memcpy( p_in, p_in_buf->p_buffer, p_in_buf->i_nb_bytes );
/* Take care of the previous input sample (if any) */ /* Take care of the previous input sample (if any) */
if( p_filter->b_reinit ) if( !p_filter->b_continuity )
{ {
p_filter->b_reinit = VLC_FALSE; p_filter->b_continuity = VLC_TRUE;
p_filter->p_sys->i_remainder = 0; p_filter->p_sys->i_remainder = 0;
aout_DateInit( &p_filter->p_sys->end_date, p_filter->output.i_rate ); aout_DateInit( &p_filter->p_sys->end_date, p_filter->output.i_rate );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* trivial.c : trivial resampler (skips samples or pads with zeroes) * trivial.c : trivial resampler (skips samples or pads with zeroes)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: trivial.c,v 1.10 2002/11/20 16:43:32 sam Exp $ * $Id: trivial.c,v 1.11 2003/03/04 03:27:40 gbazin Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -68,7 +68,7 @@ static int Create( vlc_object_t *p_this ) ...@@ -68,7 +68,7 @@ static int Create( vlc_object_t *p_this )
} }
p_filter->pf_do_work = DoWork; p_filter->pf_do_work = DoWork;
p_filter->b_in_place = 1; p_filter->b_in_place = VLC_TRUE;
return 0; return 0;
} }
...@@ -85,6 +85,12 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -85,6 +85,12 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
int i_sample_bytes = aout_FormatNbChannels( &p_filter->input ) int i_sample_bytes = aout_FormatNbChannels( &p_filter->input )
* sizeof(int32_t); * sizeof(int32_t);
/* Check if we really need to run the resampler */
if( p_aout->mixer.mixer.i_rate == p_filter->input.i_rate )
{
return;
}
if ( p_out_buf != p_in_buf ) if ( p_out_buf != p_in_buf )
{ {
/* For whatever reason the buffer allocator decided to allocate /* For whatever reason the buffer allocator decided to allocate
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ugly.c : ugly resampler (changes pitch) * ugly.c : ugly resampler (changes pitch)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: ugly.c,v 1.8 2002/12/06 16:34:04 sam Exp $ * $Id: ugly.c,v 1.9 2003/03/04 03:27:40 gbazin Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -68,7 +68,10 @@ static int Create( vlc_object_t *p_this ) ...@@ -68,7 +68,10 @@ static int Create( vlc_object_t *p_this )
} }
p_filter->pf_do_work = DoWork; p_filter->pf_do_work = DoWork;
p_filter->b_in_place = VLC_FALSE;
/* We don't want a new buffer to be created because we're not sure we'll
* actually need to resample anything. */
p_filter->b_in_place = VLC_TRUE;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -79,8 +82,7 @@ static int Create( vlc_object_t *p_this ) ...@@ -79,8 +82,7 @@ static int Create( vlc_object_t *p_this )
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf ) aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
{ {
int32_t* p_in = (int32_t*)p_in_buf->p_buffer; int32_t *p_in, *p_out = (int32_t*)p_out_buf->p_buffer;
int32_t* p_out = (int32_t*)p_out_buf->p_buffer;
unsigned int i_nb_channels = aout_FormatNbChannels( &p_filter->input ); unsigned int i_nb_channels = aout_FormatNbChannels( &p_filter->input );
unsigned int i_in_nb = p_in_buf->i_nb_samples; unsigned int i_in_nb = p_in_buf->i_nb_samples;
...@@ -89,6 +91,24 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -89,6 +91,24 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
unsigned int i_sample_bytes = i_nb_channels * sizeof(int32_t); unsigned int i_sample_bytes = i_nb_channels * sizeof(int32_t);
unsigned int i_out, i_chan, i_remainder = 0; unsigned int i_out, i_chan, i_remainder = 0;
/* Check if we really need to run the resampler */
if( p_aout->mixer.mixer.i_rate == p_filter->input.i_rate )
{
return;
}
#ifdef HAVE_ALLOCA
p_in = (int32_t *)alloca( p_in_buf->i_nb_bytes );
#else
p_in = (int32_t *)malloc( p_in_buf->i_nb_bytes );
#endif
if( p_in == NULL )
{
return;
}
p_aout->p_vlc->pf_memcpy( p_in, p_in_buf->p_buffer, p_in_buf->i_nb_bytes );
for( i_out = i_out_nb ; i_out-- ; ) for( i_out = i_out_nb ; i_out-- ; )
{ {
for( i_chan = i_nb_channels ; i_chan ; ) for( i_chan = i_nb_channels ; i_chan ; )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* filters.c : audio output filters management * filters.c : audio output filters management
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: filters.c,v 1.17 2003/01/21 10:29:12 massiot Exp $ * $Id: filters.c,v 1.18 2003/03/04 03:27:40 gbazin Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -60,7 +60,7 @@ static aout_filter_t * FindFilter( aout_instance_t * p_aout, ...@@ -60,7 +60,7 @@ static aout_filter_t * FindFilter( aout_instance_t * p_aout,
return NULL; return NULL;
} }
p_filter->b_reinit = VLC_TRUE; p_filter->b_continuity = VLC_FALSE;
return p_filter; return p_filter;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input.c : internal management of input streams for the audio output * input.c : internal management of input streams for the audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: input.c,v 1.32 2003/02/21 22:59:38 gbazin Exp $ * $Id: input.c,v 1.33 2003/03/04 03:27:40 gbazin Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -130,7 +130,7 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) ...@@ -130,7 +130,7 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input )
} }
/* success */ /* success */
p_headphone_filter->b_reinit = VLC_TRUE; p_headphone_filter->b_continuity = VLC_FALSE;
p_input->pp_filters[p_input->i_nb_filters++] = p_headphone_filter; p_input->pp_filters[p_input->i_nb_filters++] = p_headphone_filter;
} }
...@@ -248,7 +248,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -248,7 +248,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
if ( p_input->i_nb_resamplers != 0 ) if ( p_input->i_nb_resamplers != 0 )
{ {
p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate; p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate;
p_input->pp_resamplers[0]->b_reinit = VLC_TRUE; p_input->pp_resamplers[0]->b_continuity = VLC_FALSE;
} }
start_date = 0; start_date = 0;
} }
...@@ -260,7 +260,12 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -260,7 +260,12 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
msg_Warn( p_aout, "PTS is out of range ("I64Fd"), dropping buffer", msg_Warn( p_aout, "PTS is out of range ("I64Fd"), dropping buffer",
mdate() - p_buffer->start_date ); mdate() - p_buffer->start_date );
aout_BufferFree( p_buffer ); aout_BufferFree( p_buffer );
p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
if ( p_input->i_nb_resamplers != 0 )
{
p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate;
p_input->pp_resamplers[0]->b_continuity = VLC_FALSE;
}
return 0; return 0;
} }
...@@ -353,8 +358,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -353,8 +358,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
p_buffer->start_date = start_date; p_buffer->start_date = start_date;
/* Actually run the resampler now. */ /* Actually run the resampler now. */
if ( p_input->i_nb_resamplers > 0 && p_aout->mixer.mixer.i_rate != if ( p_input->i_nb_resamplers > 0 )
p_input->pp_resamplers[0]->input.i_rate )
{ {
aout_FiltersPlay( p_aout, p_input->pp_resamplers, aout_FiltersPlay( p_aout, p_input->pp_resamplers,
p_input->i_nb_resamplers, p_input->i_nb_resamplers,
......
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