Hacker Guide/Audio Filters

From VideoLAN Wiki
Revision as of 15:04, 21 December 2008 by Geal (talk | contribs) (→‎Module descriptor: fix macros)
Jump to navigation Jump to search

Overview

Writing an audio filter

Module descriptor

static int  Open     ( vlc_object_t *p_this );
static void Close    ( vlc_object_t *p_this );
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 );

vlc_module_begin()
    set_description( N_("audio filter x") )
    set_shortname( N_("audio filter x") )
    set_category( CAT_AUDIO )
    set_subcategory( SUBCAT_AUDIO_AFILTER )
    add_shortcut( "afx" )
    set_capability( "audio filter", 0 )
    set_callbacks( Open, Close )
vlc_module_end()

Mandatory structures

  • aout_filter_sys_t

I/O Buffers

Data comes in and out the plugin in an aout_buffer_t, one sample at a time, and in each sample, one block by channel.

data stream ch 1 ch 2 ch 1 ch 2 ch 1 ch 2 ...
Sample 1 Sample 2 Sample 3 ...


An audio filter module is constituted of a constructor, a destructor, and a p_filter->pf_do_work function. The constructor is passed a p_filter structure, and it returns 0 if it is able to do the whole transformation between p_filter->input and p_filter->output. If you can do only part of the transformation, say you can't do it (if the aout core doesn't find a fitting filter, it will split the transformation and ask you again).

Note

Audio filters can be of three types :

  • Converters : change i_format (for instance from float32 to s16).
  • Resamplers : change i_rate (for instance from 48 kHz to 44.1 kHz).
  • Channel mixers : change i_physical_channels/i_original_channels (for instance from 5.1 to stereo).

Audio filters can also combine any of these types. For instance you can have an audio filter which transforms A/52 5.1 to float32 stereo.

The constructor must also set p_filter->b_in_place. If it's 0, the aout core will allocate a new buffer for the output. If it's 1, when you write a byte in the output buffer, it destroys the same byte in the input buffer (they share the same memory area). Some filters can work in place because they just do a linear transformation (like float32->s16), but most filters will want b_in_place = 0. The filter can allocate private data in p_filter->p_sys. Do not forget to deallocate it in the destructor.

The p_filter->pf_do_work gets an input and an output buffer as arguments, and process them. At the end of the processing, do not forget to set p_out_buf->i_nb_samples and p_out_buf->i_nb_bytes, since they aren't inited by the aout core (their values can change between input and output and it's not quite predictible).