X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_filter%2Fscaletempo.c;h=4600ec33b5ffcb1b0836c4e4d3623b4af6268ab8;hb=6d5336200143e6d1ad70ef653c72265d25f67640;hp=3137bf1cd7468ce1233d7aba5f947aff4207b57a;hpb=14f37b2101842fa6e427f962f689db74eff6faba;p=vlc diff --git a/modules/audio_filter/scaletempo.c b/modules/audio_filter/scaletempo.c index 3137bf1cd7..4600ec33b5 100644 --- a/modules/audio_filter/scaletempo.c +++ b/modules/audio_filter/scaletempo.c @@ -1,24 +1,24 @@ /***************************************************************************** * scaletempo.c: Scale audio tempo while maintaining pitch ***************************************************************************** - * Copyright © 2008 the VideoLAN team + * Copyright © 2008 VLC authors and VideoLAN * $Id$ * * Authors: Rov Juvano * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -31,6 +31,7 @@ #include #include #include +#include #include /* for memset */ #include /* form INT_MIN */ @@ -40,8 +41,7 @@ *****************************************************************************/ static int Open( vlc_object_t * ); static void Close( vlc_object_t * ); -static void DoWork( aout_instance_t *, aout_filter_t *, - aout_buffer_t *, aout_buffer_t * ); +static block_t *DoWork( filter_t *, block_t * ); vlc_module_begin () set_description( N_("Audio tempo scaler synched with rate") ) @@ -50,11 +50,11 @@ vlc_module_begin () set_category( CAT_AUDIO ) set_subcategory( SUBCAT_AUDIO_AFILTER ) - add_integer_with_range( "scaletempo-stride", 30, 1, 2000, NULL, + add_integer_with_range( "scaletempo-stride", 30, 1, 2000, N_("Stride Length"), N_("Length in milliseconds to output each stride"), true ) - add_float_with_range( "scaletempo-overlap", .20, 0.0, 1.0, NULL, + add_float_with_range( "scaletempo-overlap", .20, 0.0, 1.0, N_("Overlap Length"), N_("Percentage of stride to overlap"), true ) - add_integer_with_range( "scaletempo-search", 14, 0, 200, NULL, + add_integer_with_range( "scaletempo-search", 14, 0, 200, N_("Search Length"), N_("Length in milliseconds to search for best overlap position"), true ) set_callbacks( Open, Close ) @@ -76,7 +76,7 @@ vlc_module_end () * frame: a single set of samples, one for each channel * VLC uses these terms differently */ -struct aout_filter_sys_t +struct filter_sys_t { /* Filter static config */ double scale; @@ -105,23 +105,20 @@ struct aout_filter_sys_t unsigned bytes_standing; void *buf_overlap; void *table_blend; - void (*output_overlap)( aout_filter_t *p_filter, void *p_out_buf, unsigned bytes_off ); + void (*output_overlap)( filter_t *p_filter, void *p_out_buf, unsigned bytes_off ); /* best overlap */ unsigned frames_search; void *buf_pre_corr; void *table_window; - unsigned(*best_overlap_offset)( aout_filter_t *p_filter ); - /* for "audio filter" only, manage own buffers */ - int i_buf; - uint8_t *p_buffers[2]; + unsigned(*best_overlap_offset)( filter_t *p_filter ); }; /***************************************************************************** * best_overlap_offset: calculate best offset for overlap *****************************************************************************/ -static unsigned best_overlap_offset_float( aout_filter_t *p_filter ) +static unsigned best_overlap_offset_float( filter_t *p_filter ) { - aout_filter_sys_t *p = p_filter->p_sys; + filter_sys_t *p = p_filter->p_sys; float *pw, *po, *ppc, *search_start; float best_corr = INT_MIN; unsigned best_off = 0; @@ -156,11 +153,11 @@ static unsigned best_overlap_offset_float( aout_filter_t *p_filter ) /***************************************************************************** * output_overlap: blend end of previous stride with beginning of current stride *****************************************************************************/ -static void output_overlap_float( aout_filter_t *p_filter, +static void output_overlap_float( filter_t *p_filter, void *buf_out, unsigned bytes_off ) { - aout_filter_sys_t *p = p_filter->p_sys; + filter_sys_t *p = p_filter->p_sys; float *pout = buf_out; float *pb = p->table_blend; float *po = p->buf_overlap; @@ -174,12 +171,12 @@ static void output_overlap_float( aout_filter_t *p_filter, /***************************************************************************** * fill_queue: fill p_sys->buf_queue as much possible, skipping samples as needed *****************************************************************************/ -static size_t fill_queue( aout_filter_t *p_filter, +static size_t fill_queue( filter_t *p_filter, uint8_t *p_buffer, size_t i_buffer, size_t offset ) { - aout_filter_sys_t *p = p_filter->p_sys; + filter_sys_t *p = p_filter->p_sys; unsigned bytes_in = i_buffer - offset; size_t offset_unchanged = offset; @@ -217,12 +214,12 @@ static size_t fill_queue( aout_filter_t *p_filter, /***************************************************************************** * transform_buffer: main filter loop *****************************************************************************/ -static size_t transform_buffer( aout_filter_t *p_filter, +static size_t transform_buffer( filter_t *p_filter, uint8_t *p_buffer, size_t i_buffer, uint8_t *pout ) { - aout_filter_sys_t *p = p_filter->p_sys; + filter_sys_t *p = p_filter->p_sys; size_t offset_in = fill_queue( p_filter, p_buffer, i_buffer, 0 ); unsigned bytes_out = 0; @@ -260,10 +257,10 @@ static size_t transform_buffer( aout_filter_t *p_filter, /***************************************************************************** * calculate_output_buffer_size *****************************************************************************/ -static size_t calculate_output_buffer_size( aout_filter_t *p_filter, +static size_t calculate_output_buffer_size( filter_t *p_filter, size_t bytes_in ) { - aout_filter_sys_t *p = p_filter->p_sys; + filter_sys_t *p = p_filter->p_sys; size_t bytes_out = 0; int bytes_to_out = bytes_in + p->bytes_queued - p->bytes_to_slide; if( bytes_to_out >= (int)p->bytes_queue_max ) { @@ -278,9 +275,9 @@ static size_t calculate_output_buffer_size( aout_filter_t *p_filter, /***************************************************************************** * reinit_buffers: reinitializes buffers in p_filter->p_sys *****************************************************************************/ -static int reinit_buffers( aout_filter_t *p_filter ) +static int reinit_buffers( filter_t *p_filter ) { - aout_filter_sys_t *p = p_filter->p_sys; + filter_sys_t *p = p_filter->p_sys; unsigned i,j; unsigned frames_stride = p->ms_stride * p->sample_rate / 1000.0; @@ -388,38 +385,16 @@ static int reinit_buffers( aout_filter_t *p_filter ) *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - aout_filter_t *p_filter = (aout_filter_t *)p_this; - aout_filter_sys_t *p_sys; - bool b_fit = true; - - if( p_filter->input.i_format != VLC_CODEC_FL32 || - p_filter->output.i_format != VLC_CODEC_FL32 ) - { - b_fit = false; - p_filter->input.i_format = p_filter->output.i_format = VLC_CODEC_FL32; - msg_Warn( p_filter, "bad input or output format" ); - } - if( ! AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) - { - b_fit = false; - memcpy( &p_filter->output, &p_filter->input, sizeof(audio_sample_format_t) ); - msg_Warn( p_filter, "input and output formats are not similar" ); - } - - if( ! b_fit ) - return VLC_EGENERIC; - - p_filter->pf_do_work = DoWork; - p_filter->b_in_place = false; + filter_t *p_filter = (filter_t *)p_this; /* Allocate structure */ - p_sys = p_filter->p_sys = malloc( sizeof(aout_filter_sys_t) ); + filter_sys_t *p_sys = p_filter->p_sys = malloc( sizeof(*p_sys) ); if( ! p_sys ) return VLC_ENOMEM; p_sys->scale = 1.0; - p_sys->sample_rate = p_filter->input.i_rate; - p_sys->samples_per_frame = aout_FormatNbChannels( &p_filter->input ); + p_sys->sample_rate = p_filter->fmt_in.audio.i_rate; + p_sys->samples_per_frame = aout_FormatNbChannels( &p_filter->fmt_in.audio ); p_sys->bytes_per_sample = 4; p_sys->bytes_per_frame = p_sys->samples_per_frame * p_sys->bytes_per_sample; @@ -429,17 +404,13 @@ static int Open( vlc_object_t *p_this ) p_sys->bytes_per_sample, "fl32" ); - p_sys->ms_stride = config_GetInt( p_this, "scaletempo-stride" ); - p_sys->percent_overlap = config_GetFloat( p_this, "scaletempo-overlap" ); - p_sys->ms_search = config_GetInt( p_this, "scaletempo-search" ); + p_sys->ms_stride = var_InheritInteger( p_this, "scaletempo-stride" ); + p_sys->percent_overlap = var_InheritFloat( p_this, "scaletempo-overlap" ); + p_sys->ms_search = var_InheritInteger( p_this, "scaletempo-search" ); msg_Dbg( p_this, "params: %i stride, %.3f overlap, %i search", p_sys->ms_stride, p_sys->percent_overlap, p_sys->ms_search ); - p_sys->i_buf = 0; - p_sys->p_buffers[0] = NULL; - p_sys->p_buffers[1] = NULL; - p_sys->buf_queue = NULL; p_sys->buf_overlap = NULL; p_sys->table_blend = NULL; @@ -455,40 +426,36 @@ static int Open( vlc_object_t *p_this ) Close( p_this ); return VLC_EGENERIC; } + + p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32; + p_filter->fmt_out.audio = p_filter->fmt_in.audio; + p_filter->pf_audio_filter = DoWork; return VLC_SUCCESS; } static void Close( vlc_object_t *p_this ) { - aout_filter_t *p_filter = (aout_filter_t *)p_this; - aout_filter_sys_t *p_sys = p_filter->p_sys; + filter_t *p_filter = (filter_t *)p_this; + filter_sys_t *p_sys = p_filter->p_sys; free( p_sys->buf_queue ); free( p_sys->buf_overlap ); free( p_sys->table_blend ); free( p_sys->buf_pre_corr ); free( p_sys->table_window ); - free( p_sys->p_buffers[0] ); - free( p_sys->p_buffers[1] ); - free( p_filter->p_sys ); + free( p_sys ); } /***************************************************************************** - * DoWork: aout_filter wrapper for transform_buffer + * DoWork: filter wrapper for transform_buffer *****************************************************************************/ -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 ) +static block_t *DoWork( filter_t * p_filter, block_t * p_in_buf ) { - VLC_UNUSED(p_aout); - aout_filter_sys_t *p = p_filter->p_sys; - - if( p_filter->input.i_rate == p->sample_rate ) { - memcpy( p_out_buf->p_buffer, p_in_buf->p_buffer, p_in_buf->i_nb_bytes ); - p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes; - p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; - return; - } + filter_sys_t *p = p_filter->p_sys; + + if( p_filter->fmt_in.audio.i_rate == p->sample_rate ) + return p_in_buf; - double scale = p_filter->input.i_rate / (double)p->sample_rate; + double scale = p_filter->fmt_in.audio.i_rate / (double)p->sample_rate; if( scale != p->scale ) { p->scale = scale; p->bytes_stride_scaled = p->bytes_stride * p->scale; @@ -500,22 +467,21 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, (int)( p->bytes_stride / p->bytes_per_frame ) ); } - size_t i_outsize = calculate_output_buffer_size ( p_filter, p_in_buf->i_nb_bytes ); - if( i_outsize > p_out_buf->i_size ) { - void *temp = realloc( p->p_buffers[ p->i_buf ], i_outsize ); - if( temp == NULL ) - { - return; - } - p->p_buffers[ p->i_buf ] = temp; - p_out_buf->p_buffer = p->p_buffers[ p->i_buf ]; - p->i_buf = ! p->i_buf; - } + size_t i_outsize = calculate_output_buffer_size ( p_filter, p_in_buf->i_buffer ); + block_t *p_out_buf = block_Alloc( i_outsize ); + if( p_out_buf == NULL ) + return NULL; size_t bytes_out = transform_buffer( p_filter, - p_in_buf->p_buffer, p_in_buf->i_nb_bytes, + p_in_buf->p_buffer, p_in_buf->i_buffer, p_out_buf->p_buffer ); - p_out_buf->i_nb_bytes = bytes_out; + p_out_buf->i_buffer = bytes_out; p_out_buf->i_nb_samples = bytes_out / p->bytes_per_frame; + p_out_buf->i_dts = p_in_buf->i_dts; + p_out_buf->i_pts = p_in_buf->i_pts; + p_out_buf->i_length = p_in_buf->i_length; + + block_Release( p_in_buf ); + return p_out_buf; }