bandlimited.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:26k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * bandlimited.c : band-limited interpolation resampler
  3.  *****************************************************************************
  4.  * Copyright (C) 2002, 2006 the VideoLAN team
  5.  * $Id: 9ec0714af3e6f2fc64c4dc07b260b24b216210de $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble:
  25.  *
  26.  * This implementation of the band-limited interpolationis based on the
  27.  * following paper:
  28.  * http://ccrma-www.stanford.edu/~jos/resample/resample.html
  29.  *
  30.  * It uses a Kaiser-windowed sinc-function low-pass filter and the width of the
  31.  * filter is 13 samples.
  32.  *
  33.  *****************************************************************************/
  34. #ifdef HAVE_CONFIG_H
  35. # include "config.h"
  36. #endif
  37. #include <vlc_common.h>
  38. #include <vlc_plugin.h>
  39. #include <vlc_aout.h>
  40. #include <vlc_filter.h>
  41. #include <vlc_block.h>
  42. #include "bandlimited.h"
  43. /*****************************************************************************
  44.  * Local prototypes
  45.  *****************************************************************************/
  46. static int  Create    ( vlc_object_t * );
  47. static void Close     ( vlc_object_t * );
  48. static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
  49.                         aout_buffer_t * );
  50. /* audio filter2 */
  51. static int  OpenFilter ( vlc_object_t * );
  52. static void CloseFilter( vlc_object_t * );
  53. static block_t *Resample( filter_t *, block_t * );
  54. static void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing,
  55.                            float *f_in, float *f_out, uint32_t ui_remainder,
  56.                            uint32_t ui_output_rate, int16_t Inc,
  57.                            int i_nb_channels );
  58. static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing,
  59.                            float *f_in, float *f_out, uint32_t ui_remainder,
  60.                            uint32_t ui_output_rate, uint32_t ui_input_rate,
  61.                            int16_t Inc, int i_nb_channels );
  62. /*****************************************************************************
  63.  * Local structures
  64.  *****************************************************************************/
  65. struct filter_sys_t
  66. {
  67.     int32_t *p_buf;                        /* this filter introduces a delay */
  68.     int i_buf_size;
  69.     int i_old_rate;
  70.     double d_old_factor;
  71.     int i_old_wing;
  72.     unsigned int i_remainder;                /* remainder of previous sample */
  73.     audio_date_t end_date;
  74.     bool b_first;
  75.     bool b_filter2;
  76. };
  77. /*****************************************************************************
  78.  * Module descriptor
  79.  *****************************************************************************/
  80. vlc_module_begin ()
  81.     set_category( CAT_AUDIO )
  82.     set_subcategory( SUBCAT_AUDIO_MISC )
  83.     set_description( N_("Audio filter for band-limited interpolation resampling") )
  84.     set_capability( "audio filter", 20 )
  85.     set_callbacks( Create, Close )
  86.     add_submodule ()
  87.     set_description( N_("Audio filter for band-limited interpolation resampling") )
  88.     set_capability( "audio filter2", 20 )
  89.     set_callbacks( OpenFilter, CloseFilter )
  90. vlc_module_end ()
  91. /*****************************************************************************
  92.  * Create: allocate linear resampler
  93.  *****************************************************************************/
  94. static int Create( vlc_object_t *p_this )
  95. {
  96.     aout_filter_t * p_filter = (aout_filter_t *)p_this;
  97.     struct filter_sys_t * p_sys;
  98.     double d_factor;
  99.     int i_filter_wing;
  100.     if ( p_filter->input.i_rate == p_filter->output.i_rate
  101.           || p_filter->input.i_format != p_filter->output.i_format
  102.           || p_filter->input.i_physical_channels
  103.               != p_filter->output.i_physical_channels
  104.           || p_filter->input.i_original_channels
  105.               != p_filter->output.i_original_channels
  106.           || p_filter->input.i_format != VLC_FOURCC('f','l','3','2') )
  107.     {
  108.         return VLC_EGENERIC;
  109.     }
  110. #if !defined( __APPLE__ )
  111.     if( !config_GetInt( p_this, "hq-resampling" ) )
  112.     {
  113.         return VLC_EGENERIC;
  114.     }
  115. #endif
  116.     /* Allocate the memory needed to store the module's structure */
  117.     p_sys = malloc( sizeof(filter_sys_t) );
  118.     if( p_sys == NULL )
  119.         return VLC_ENOMEM;
  120.     p_filter->p_sys = (struct aout_filter_sys_t *)p_sys;
  121.     /* Calculate worst case for the length of the filter wing */
  122.     d_factor = (double)p_filter->output.i_rate
  123.                         / p_filter->input.i_rate / AOUT_MAX_INPUT_RATE;
  124.     i_filter_wing = ((SMALL_FILTER_NMULT + 1)/2.0)
  125.                       * __MAX(1.0, 1.0/d_factor) + 10;
  126.     p_sys->i_buf_size = aout_FormatNbChannels( &p_filter->input ) *
  127.         sizeof(int32_t) * 2 * i_filter_wing;
  128.     /* Allocate enough memory to buffer previous samples */
  129.     p_sys->p_buf = malloc( p_sys->i_buf_size );
  130.     if( p_sys->p_buf == NULL )
  131.     {
  132.         free( p_sys );
  133.         return VLC_ENOMEM;
  134.     }
  135.     p_sys->i_old_wing = 0;
  136.     p_sys->b_filter2 = false;           /* It seams to be a good valuefor this module */
  137.     p_filter->pf_do_work = DoWork;
  138.     /* We don't want a new buffer to be created because we're not sure we'll
  139.      * actually need to resample anything. */
  140.     p_filter->b_in_place = true;
  141.     return VLC_SUCCESS;
  142. }
  143. /*****************************************************************************
  144.  * Close: free our resources
  145.  *****************************************************************************/
  146. static void Close( vlc_object_t * p_this )
  147. {
  148.     aout_filter_t * p_filter = (aout_filter_t *)p_this;
  149.     filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
  150.     free( p_sys->p_buf );
  151.     free( p_sys );
  152. }
  153. /*****************************************************************************
  154.  * DoWork: convert a buffer
  155.  *****************************************************************************/
  156. static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
  157.                     aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
  158. {
  159.     filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
  160.     float *p_out = (float *)p_out_buf->p_buffer;
  161.     int i_nb_channels = aout_FormatNbChannels( &p_filter->input );
  162.     int i_in_nb = p_in_buf->i_nb_samples;
  163.     int i_in, i_out = 0;
  164.     unsigned int i_out_rate;
  165.     double d_factor, d_scale_factor, d_old_scale_factor;
  166.     int i_filter_wing;
  167.     if( p_sys->b_filter2 )
  168.         i_out_rate = p_filter->output.i_rate;
  169.     else
  170.         i_out_rate = p_aout->mixer.mixer.i_rate;
  171.     /* Check if we really need to run the resampler */
  172.     if( i_out_rate == p_filter->input.i_rate )
  173.     {
  174.         if( /*p_filter->b_continuity && /--* What difference does it make ? :) */
  175.             p_sys->i_old_wing &&
  176.             p_in_buf->i_size >=
  177.               p_in_buf->i_nb_bytes + p_sys->i_old_wing *
  178.               p_filter->input.i_bytes_per_frame )
  179.         {
  180.             /* output the whole thing with the samples from last time */
  181.             memmove( ((float *)(p_in_buf->p_buffer)) +
  182.                      i_nb_channels * p_sys->i_old_wing,
  183.                      p_in_buf->p_buffer, p_in_buf->i_nb_bytes );
  184.             memcpy( p_in_buf->p_buffer, p_sys->p_buf +
  185.                     i_nb_channels * p_sys->i_old_wing,
  186.                     p_sys->i_old_wing *
  187.                     p_filter->input.i_bytes_per_frame );
  188.             p_out_buf->i_nb_samples = p_in_buf->i_nb_samples +
  189.                 p_sys->i_old_wing;
  190.             p_out_buf->start_date = aout_DateGet( &p_sys->end_date );
  191.             p_out_buf->end_date =
  192.                 aout_DateIncrement( &p_sys->end_date,
  193.                                     p_out_buf->i_nb_samples );
  194.             p_out_buf->i_nb_bytes = p_out_buf->i_nb_samples *
  195.                 p_filter->input.i_bytes_per_frame;
  196.         }
  197.         p_filter->b_continuity = false;
  198.         p_sys->i_old_wing = 0;
  199.         return;
  200.     }
  201.     if( !p_filter->b_continuity )
  202.     {
  203.         /* Continuity in sound samples has been broken, we'd better reset
  204.          * everything. */
  205.         p_filter->b_continuity = true;
  206.         p_sys->i_remainder = 0;
  207.         aout_DateInit( &p_sys->end_date, i_out_rate );
  208.         aout_DateSet( &p_sys->end_date, p_in_buf->start_date );
  209.         p_sys->i_old_rate   = p_filter->input.i_rate;
  210.         p_sys->d_old_factor = 1;
  211.         p_sys->i_old_wing   = 0;
  212.     }
  213. #if 0
  214.     msg_Err( p_filter, "old rate: %i, old factor: %f, old wing: %i, i_in: %i",
  215.              p_sys->i_old_rate, p_sys->d_old_factor,
  216.              p_sys->i_old_wing, i_in_nb );
  217. #endif
  218.     /* Prepare the source buffer */
  219.     i_in_nb += (p_sys->i_old_wing * 2);
  220.     float p_in_orig[i_in_nb * p_filter->input.i_bytes_per_frame / 4],
  221.          *p_in = p_in_orig;
  222.     /* Copy all our samples in p_in */
  223.     if( p_sys->i_old_wing )
  224.     {
  225.         vlc_memcpy( p_in, p_sys->p_buf,
  226.                     p_sys->i_old_wing * 2 *
  227.                       p_filter->input.i_bytes_per_frame );
  228.     }
  229.     vlc_memcpy( p_in + p_sys->i_old_wing * 2 * i_nb_channels,
  230.                 p_in_buf->p_buffer,
  231.                 p_in_buf->i_nb_samples * p_filter->input.i_bytes_per_frame );
  232.     /* Make sure the output buffer is reset */
  233.     memset( p_out, 0, p_out_buf->i_size );
  234.     /* Calculate the new length of the filter wing */
  235.     d_factor = (double)i_out_rate / p_filter->input.i_rate;
  236.     i_filter_wing = ((SMALL_FILTER_NMULT+1)/2.0) * __MAX(1.0,1.0/d_factor) + 1;
  237.     /* Account for increased filter gain when using factors less than 1 */
  238.     d_old_scale_factor = SMALL_FILTER_SCALE *
  239.         p_sys->d_old_factor + 0.5;
  240.     d_scale_factor = SMALL_FILTER_SCALE * d_factor + 0.5;
  241.     /* Apply the old rate until we have enough samples for the new one */
  242.     i_in = p_sys->i_old_wing;
  243.     p_in += p_sys->i_old_wing * i_nb_channels;
  244.     for( ; i_in < i_filter_wing &&
  245.            (i_in + p_sys->i_old_wing) < i_in_nb; i_in++ )
  246.     {
  247.         if( p_sys->d_old_factor == 1 )
  248.         {
  249.             /* Just copy the samples */
  250.             memcpy( p_out, p_in,
  251.                     p_filter->input.i_bytes_per_frame );
  252.             p_in += i_nb_channels;
  253.             p_out += i_nb_channels;
  254.             i_out++;
  255.             continue;
  256.         }
  257.         while( p_sys->i_remainder < p_filter->output.i_rate )
  258.         {
  259.             if( p_sys->d_old_factor >= 1 )
  260.             {
  261.                 /* FilterFloatUP() is faster if we can use it */
  262.                 /* Perform left-wing inner product */
  263.                 FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  264.                                SMALL_FILTER_NWING, p_in, p_out,
  265.                                p_sys->i_remainder,
  266.                                p_filter->output.i_rate,
  267.                                -1, i_nb_channels );
  268.                 /* Perform right-wing inner product */
  269.                 FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  270.                                SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
  271.                                p_filter->output.i_rate -
  272.                                p_sys->i_remainder,
  273.                                p_filter->output.i_rate,
  274.                                1, i_nb_channels );
  275. #if 0
  276.                 /* Normalize for unity filter gain */
  277.                 for( i = 0; i < i_nb_channels; i++ )
  278.                 {
  279.                     *(p_out+i) *= d_old_scale_factor;
  280.                 }
  281. #endif
  282.                 /* Sanity check */
  283.                 if( p_out_buf->i_size/p_filter->input.i_bytes_per_frame
  284.                     <= (unsigned int)i_out+1 )
  285.                 {
  286.                     p_out += i_nb_channels;
  287.                     i_out++;
  288.                     p_sys->i_remainder += p_filter->input.i_rate;
  289.                     break;
  290.                 }
  291.             }
  292.             else
  293.             {
  294.                 /* Perform left-wing inner product */
  295.                 FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  296.                                SMALL_FILTER_NWING, p_in, p_out,
  297.                                p_sys->i_remainder,
  298.                                p_filter->output.i_rate, p_filter->input.i_rate,
  299.                                -1, i_nb_channels );
  300.                 /* Perform right-wing inner product */
  301.                 FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  302.                                SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
  303.                                p_filter->output.i_rate -
  304.                                p_sys->i_remainder,
  305.                                p_filter->output.i_rate, p_filter->input.i_rate,
  306.                                1, i_nb_channels );
  307.             }
  308.             p_out += i_nb_channels;
  309.             i_out++;
  310.             p_sys->i_remainder += p_filter->input.i_rate;
  311.         }
  312.         p_in += i_nb_channels;
  313.         p_sys->i_remainder -= p_filter->output.i_rate;
  314.     }
  315.     /* Apply the new rate for the rest of the samples */
  316.     if( i_in < i_in_nb - i_filter_wing )
  317.     {
  318.         p_sys->i_old_rate   = p_filter->input.i_rate;
  319.         p_sys->d_old_factor = d_factor;
  320.         p_sys->i_old_wing   = i_filter_wing;
  321.     }
  322.     for( ; i_in < i_in_nb - i_filter_wing; i_in++ )
  323.     {
  324.         while( p_sys->i_remainder < p_filter->output.i_rate )
  325.         {
  326.             if( d_factor >= 1 )
  327.             {
  328.                 /* FilterFloatUP() is faster if we can use it */
  329.                 /* Perform left-wing inner product */
  330.                 FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  331.                                SMALL_FILTER_NWING, p_in, p_out,
  332.                                p_sys->i_remainder,
  333.                                p_filter->output.i_rate,
  334.                                -1, i_nb_channels );
  335.                 /* Perform right-wing inner product */
  336.                 FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  337.                                SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
  338.                                p_filter->output.i_rate -
  339.                                p_sys->i_remainder,
  340.                                p_filter->output.i_rate,
  341.                                1, i_nb_channels );
  342. #if 0
  343.                 /* Normalize for unity filter gain */
  344.                 for( int i = 0; i < i_nb_channels; i++ )
  345.                 {
  346.                     *(p_out+i) *= d_old_scale_factor;
  347.                 }
  348. #endif
  349.                 /* Sanity check */
  350.                 if( p_out_buf->i_size/p_filter->input.i_bytes_per_frame
  351.                     <= (unsigned int)i_out+1 )
  352.                 {
  353.                     p_out += i_nb_channels;
  354.                     i_out++;
  355.                     p_sys->i_remainder += p_filter->input.i_rate;
  356.                     break;
  357.                 }
  358.             }
  359.             else
  360.             {
  361.                 /* Perform left-wing inner product */
  362.                 FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  363.                                SMALL_FILTER_NWING, p_in, p_out,
  364.                                p_sys->i_remainder,
  365.                                p_filter->output.i_rate, p_filter->input.i_rate,
  366.                                -1, i_nb_channels );
  367.                 /* Perform right-wing inner product */
  368.                 FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
  369.                                SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
  370.                                p_filter->output.i_rate -
  371.                                p_sys->i_remainder,
  372.                                p_filter->output.i_rate, p_filter->input.i_rate,
  373.                                1, i_nb_channels );
  374.             }
  375.             p_out += i_nb_channels;
  376.             i_out++;
  377.             p_sys->i_remainder += p_filter->input.i_rate;
  378.         }
  379.         p_in += i_nb_channels;
  380.         p_sys->i_remainder -= p_filter->output.i_rate;
  381.     }
  382.     /* Buffer i_filter_wing * 2 samples for next time */
  383.     if( p_sys->i_old_wing )
  384.     {
  385.         memcpy( p_sys->p_buf,
  386.                 p_in_orig + (i_in_nb - 2 * p_sys->i_old_wing) *
  387.                 i_nb_channels, (2 * p_sys->i_old_wing) *
  388.                 p_filter->input.i_bytes_per_frame );
  389.     }
  390. #if 0
  391.     msg_Err( p_filter, "p_out size: %i, nb bytes out: %i", p_out_buf->i_size,
  392.              i_out * p_filter->input.i_bytes_per_frame );
  393. #endif
  394.     /* Finalize aout buffer */
  395.     p_out_buf->i_nb_samples = i_out;
  396.     p_out_buf->start_date = aout_DateGet( &p_sys->end_date );
  397.     p_out_buf->end_date = aout_DateIncrement( &p_sys->end_date,
  398.                                               p_out_buf->i_nb_samples );
  399.     p_out_buf->i_nb_bytes = p_out_buf->i_nb_samples *
  400.         i_nb_channels * sizeof(int32_t);
  401. }
  402. /*****************************************************************************
  403.  * OpenFilter:
  404.  *****************************************************************************/
  405. static int OpenFilter( vlc_object_t *p_this )
  406. {
  407.     filter_t *p_filter = (filter_t *)p_this;
  408.     filter_sys_t *p_sys;
  409.     unsigned int i_out_rate  = p_filter->fmt_out.audio.i_rate;
  410.     double d_factor;
  411.     int i_filter_wing;
  412.     if( p_filter->fmt_in.audio.i_rate == p_filter->fmt_out.audio.i_rate ||
  413.         p_filter->fmt_in.i_codec != VLC_FOURCC('f','l','3','2') )
  414.     {
  415.         return VLC_EGENERIC;
  416.     }
  417. #if !defined( SYS_DARWIN )
  418.     if( !config_GetInt( p_this, "hq-resampling" ) )
  419.     {
  420.         return VLC_EGENERIC;
  421.     }
  422. #endif
  423.     /* Allocate the memory needed to store the module's structure */
  424.     p_filter->p_sys = p_sys = malloc( sizeof(struct filter_sys_t) );
  425.     if( p_sys == NULL )
  426.         return VLC_ENOMEM;
  427.     /* Calculate worst case for the length of the filter wing */
  428.     d_factor = (double)i_out_rate / p_filter->fmt_in.audio.i_rate;
  429.     i_filter_wing = ((SMALL_FILTER_NMULT + 1)/2.0)
  430.                       * __MAX(1.0, 1.0/d_factor) + 10;
  431.     p_filter->p_sys->i_buf_size = p_filter->fmt_in.audio.i_channels *
  432.         sizeof(int32_t) * 2 * i_filter_wing;
  433.     /* Allocate enough memory to buffer previous samples */
  434.     p_filter->p_sys->p_buf = malloc( p_filter->p_sys->i_buf_size );
  435.     if( p_filter->p_sys->p_buf == NULL )
  436.     {
  437.         free( p_sys );
  438.         return VLC_ENOMEM;
  439.     }
  440.     p_filter->p_sys->i_old_wing = 0;
  441.     p_sys->b_first = true;
  442.     p_sys->b_filter2 = true;
  443.     p_filter->pf_audio_filter = Resample;
  444.     msg_Dbg( p_this, "%4.4s/%iKHz/%i->%4.4s/%iKHz/%i",
  445.              (char *)&p_filter->fmt_in.i_codec,
  446.              p_filter->fmt_in.audio.i_rate,
  447.              p_filter->fmt_in.audio.i_channels,
  448.              (char *)&p_filter->fmt_out.i_codec,
  449.              p_filter->fmt_out.audio.i_rate,
  450.              p_filter->fmt_out.audio.i_channels);
  451.     p_filter->fmt_out = p_filter->fmt_in;
  452.     p_filter->fmt_out.audio.i_rate = i_out_rate;
  453.     return 0;
  454. }
  455. /*****************************************************************************
  456.  * CloseFilter : deallocate data structures
  457.  *****************************************************************************/
  458. static void CloseFilter( vlc_object_t *p_this )
  459. {
  460.     filter_t *p_filter = (filter_t *)p_this;
  461.     free( p_filter->p_sys->p_buf );
  462.     free( p_filter->p_sys );
  463. }
  464. /*****************************************************************************
  465.  * Resample
  466.  *****************************************************************************/
  467. static block_t *Resample( filter_t *p_filter, block_t *p_block )
  468. {
  469.     aout_filter_t aout_filter;
  470.     aout_buffer_t in_buf, out_buf;
  471.     block_t *p_out;
  472.     int i_out_size;
  473.     int i_bytes_per_frame;
  474.     if( !p_block || !p_block->i_samples )
  475.     {
  476.         if( p_block )
  477.             block_Release( p_block );
  478.         return NULL;
  479.     }
  480.     i_bytes_per_frame = p_filter->fmt_out.audio.i_channels *
  481.                   p_filter->fmt_out.audio.i_bitspersample / 8;
  482.     i_out_size = i_bytes_per_frame * ( 1 + ( p_block->i_samples *
  483.                                              p_filter->fmt_out.audio.i_rate /
  484.                                              p_filter->fmt_in.audio.i_rate) ) +
  485.                  p_filter->p_sys->i_buf_size;
  486.     p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size );
  487.     if( !p_out )
  488.     {
  489.         msg_Warn( p_filter, "can't get output buffer" );
  490.         block_Release( p_block );
  491.         return NULL;
  492.     }
  493.     p_out->i_samples = i_out_size / i_bytes_per_frame;
  494.     p_out->i_dts = p_block->i_dts;
  495.     p_out->i_pts = p_block->i_pts;
  496.     p_out->i_length = p_block->i_length;
  497.     aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys;
  498.     aout_filter.input = p_filter->fmt_in.audio;
  499.     aout_filter.input.i_bytes_per_frame = p_filter->fmt_in.audio.i_channels *
  500.                   p_filter->fmt_in.audio.i_bitspersample / 8;
  501.     aout_filter.output = p_filter->fmt_out.audio;
  502.     aout_filter.output.i_bytes_per_frame = p_filter->fmt_out.audio.i_channels *
  503.                   p_filter->fmt_out.audio.i_bitspersample / 8;
  504.     aout_filter.b_continuity = !p_filter->p_sys->b_first;
  505.     p_filter->p_sys->b_first = false;
  506.     in_buf.p_buffer = p_block->p_buffer;
  507.     in_buf.i_nb_bytes = in_buf.i_size = p_block->i_buffer;
  508.     in_buf.i_nb_samples = p_block->i_samples;
  509.     out_buf.p_buffer = p_out->p_buffer;
  510.     out_buf.i_nb_bytes = out_buf.i_size = p_out->i_buffer;
  511.     out_buf.i_nb_samples = p_out->i_samples;
  512.     DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf );
  513.     block_Release( p_block );
  514.     p_out->i_buffer = out_buf.i_nb_bytes;
  515.     p_out->i_samples = out_buf.i_nb_samples;
  516.     return p_out;
  517. }
  518. void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
  519.                     float *p_out, uint32_t ui_remainder,
  520.                     uint32_t ui_output_rate, int16_t Inc, int i_nb_channels )
  521. {
  522.     const float *Hp, *Hdp, *End;
  523.     float t, temp;
  524.     uint32_t ui_linear_remainder;
  525.     int i;
  526.     Hp = &Imp[(ui_remainder<<Nhc)/ui_output_rate];
  527.     Hdp = &ImpD[(ui_remainder<<Nhc)/ui_output_rate];
  528.     End = &Imp[Nwing];
  529.     ui_linear_remainder = (ui_remainder<<Nhc) -
  530.                             (ui_remainder<<Nhc)/ui_output_rate*ui_output_rate;
  531.     if (Inc == 1)               /* If doing right wing...              */
  532.     {                           /* ...drop extra coeff, so when Ph is  */
  533.         End--;                  /*    0.5, we don't do too many mult's */
  534.         if (ui_remainder == 0)  /* If the phase is zero...           */
  535.         {                       /* ...then we've already skipped the */
  536.             Hp += Npc;          /*    first sample, so we must also  */
  537.             Hdp += Npc;         /*    skip ahead in Imp[] and ImpD[] */
  538.         }
  539.     }
  540.     while (Hp < End) {
  541.         t = *Hp;                /* Get filter coeff */
  542.                                 /* t is now interp'd filter coeff */
  543.         t += *Hdp * ui_linear_remainder / ui_output_rate / Npc;
  544.         for( i = 0; i < i_nb_channels; i++ )
  545.         {
  546.             temp = t;
  547.             temp *= *(p_in+i);  /* Mult coeff by input sample */
  548.             *(p_out+i) += temp; /* The filter output */
  549.         }
  550.         Hdp += Npc;             /* Filter coeff differences step */
  551.         Hp += Npc;              /* Filter coeff step */
  552.         p_in += (Inc * i_nb_channels); /* Input signal step */
  553.     }
  554. }
  555. void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
  556.                     float *p_out, uint32_t ui_remainder,
  557.                     uint32_t ui_output_rate, uint32_t ui_input_rate,
  558.                     int16_t Inc, int i_nb_channels )
  559. {
  560.     const float *Hp, *Hdp, *End;
  561.     float t, temp;
  562.     uint32_t ui_linear_remainder;
  563.     int i, ui_counter = 0;
  564.     Hp = Imp + (ui_remainder<<Nhc) / ui_input_rate;
  565.     Hdp = ImpD  + (ui_remainder<<Nhc) / ui_input_rate;
  566.     End = &Imp[Nwing];
  567.     if (Inc == 1)               /* If doing right wing...              */
  568.     {                           /* ...drop extra coeff, so when Ph is  */
  569.         End--;                  /*    0.5, we don't do too many mult's */
  570.         if (ui_remainder == 0)  /* If the phase is zero...           */
  571.         {                       /* ...then we've already skipped the */
  572.             Hp = Imp +          /* first sample, so we must also  */
  573.                   (ui_output_rate << Nhc) / ui_input_rate;
  574.             Hdp = ImpD +        /* skip ahead in Imp[] and ImpD[] */
  575.                   (ui_output_rate << Nhc) / ui_input_rate;
  576.             ui_counter++;
  577.         }
  578.     }
  579.     while (Hp < End) {
  580.         t = *Hp;                /* Get filter coeff */
  581.                                 /* t is now interp'd filter coeff */
  582.         ui_linear_remainder =
  583.           ((ui_output_rate * ui_counter + ui_remainder)<< Nhc) -
  584.           ((ui_output_rate * ui_counter + ui_remainder)<< Nhc) /
  585.           ui_input_rate * ui_input_rate;
  586.         t += *Hdp * ui_linear_remainder / ui_input_rate / Npc;
  587.         for( i = 0; i < i_nb_channels; i++ )
  588.         {
  589.             temp = t;
  590.             temp *= *(p_in+i);  /* Mult coeff by input sample */
  591.             *(p_out+i) += temp; /* The filter output */
  592.         }
  593.         ui_counter++;
  594.         /* Filter coeff step */
  595.         Hp = Imp + ((ui_output_rate * ui_counter + ui_remainder)<< Nhc)
  596.                     / ui_input_rate;
  597.         /* Filter coeff differences step */
  598.         Hdp = ImpD + ((ui_output_rate * ui_counter + ui_remainder)<< Nhc)
  599.                      / ui_input_rate;
  600.         p_in += (Inc * i_nb_channels); /* Input signal step */
  601.     }
  602. }