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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * float32.c : precise float32 audio mixer implementation
  3.  *****************************************************************************
  4.  * Copyright (C) 2002 the VideoLAN team
  5.  * $Id: e3f905464dc6abe0d9c08edeed121d3a7970afec $
  6.  *
  7.  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  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. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <stddef.h>
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_aout.h>
  33. /*****************************************************************************
  34.  * Local prototypes
  35.  *****************************************************************************/
  36. static int  Create    ( vlc_object_t * );
  37. static void DoWork    ( aout_instance_t *, aout_buffer_t * );
  38. /*****************************************************************************
  39.  * Module descriptor
  40.  *****************************************************************************/
  41. vlc_module_begin ()
  42.     set_category( CAT_AUDIO )
  43.     set_subcategory( SUBCAT_AUDIO_MISC )
  44.     set_description( N_("Float32 audio mixer") )
  45.     set_capability( "audio mixer", 10 )
  46.     set_callbacks( Create, NULL )
  47. vlc_module_end ()
  48. /*****************************************************************************
  49.  * Create: allocate mixer
  50.  *****************************************************************************/
  51. static int Create( vlc_object_t *p_this )
  52. {
  53.     aout_instance_t * p_aout = (aout_instance_t *)p_this;
  54.     if ( p_aout->mixer.mixer.i_format != VLC_FOURCC('f','l','3','2') )
  55.     {
  56.         return -1;
  57.     }
  58.     /* Use the trivial mixer when we can */
  59.     if ( p_aout->i_nb_inputs == 1 && p_aout->mixer.f_multiplier == 1.0 )
  60.     {
  61.         int i;
  62.         for( i = 0; i < p_aout->i_nb_inputs; i++ )
  63.         {
  64.             if( p_aout->pp_inputs[i]->f_multiplier != 1.0 )
  65.                 break;
  66.         }
  67.         if( i >= p_aout->i_nb_inputs )
  68.             return -1;
  69.     }
  70.     p_aout->mixer.pf_do_work = DoWork;
  71.     return 0;
  72. }
  73. /*****************************************************************************
  74.  * ScaleWords: prepare input words for averaging
  75.  *****************************************************************************/
  76. static void ScaleWords( float * p_out, const float * p_in, size_t i_nb_words,
  77.                         int i_nb_inputs, float f_multiplier )
  78. {
  79.     int i;
  80.     f_multiplier /= i_nb_inputs;
  81.     for ( i = i_nb_words; i--; )
  82.     {
  83.         *p_out++ = *p_in++ * f_multiplier;
  84.     }
  85. }
  86. /*****************************************************************************
  87.  * MeanWords: average input words
  88.  *****************************************************************************/
  89. static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
  90.                        int i_nb_inputs, float f_multiplier )
  91. {
  92.     int i;
  93.     f_multiplier /= i_nb_inputs;
  94.     for ( i = i_nb_words; i--; )
  95.     {
  96.         *p_out++ += *p_in++ * f_multiplier;
  97.     }
  98. }
  99. /*****************************************************************************
  100.  * DoWork: mix a new output buffer
  101.  *****************************************************************************
  102.  * Terminology : in this function a word designates a single float32, eg.
  103.  * a stereo sample is consituted of two words.
  104.  *****************************************************************************/
  105. static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
  106. {
  107.     const int i_nb_inputs = p_aout->i_nb_inputs;
  108.     const float f_multiplier_global = p_aout->mixer.f_multiplier;
  109.     const int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer );
  110.     int i_input;
  111.     for ( i_input = 0; i_input < i_nb_inputs; i_input++ )
  112.     {
  113.         int i_nb_words = p_buffer->i_nb_samples * i_nb_channels;
  114.         aout_input_t * p_input = p_aout->pp_inputs[i_input];
  115.         float f_multiplier = f_multiplier_global * p_input->f_multiplier;
  116.         float * p_out = (float *)p_buffer->p_buffer;
  117.         float * p_in = (float *)p_input->p_first_byte_to_mix;
  118.         if ( p_input->b_error || p_input->b_paused )
  119.             continue;
  120.         for ( ; ; )
  121.         {
  122.             ptrdiff_t i_available_words = (
  123.                  (float *)p_input->fifo.p_first->p_buffer - p_in)
  124.                                    + p_input->fifo.p_first->i_nb_samples
  125.                                    * i_nb_channels;
  126.             if ( i_available_words < i_nb_words )
  127.             {
  128.                 aout_buffer_t * p_old_buffer;
  129.                 if ( i_available_words > 0 )
  130.                 {
  131.                     if ( !i_input )
  132.                     {
  133.                         ScaleWords( p_out, p_in, i_available_words,
  134.                                     i_nb_inputs, f_multiplier );
  135.                     }
  136.                     else
  137.                     {
  138.                         MeanWords( p_out, p_in, i_available_words,
  139.                                    i_nb_inputs, f_multiplier );
  140.                     }
  141.                 }
  142.                 i_nb_words -= i_available_words;
  143.                 p_out += i_available_words;
  144.                 /* Next buffer */
  145.                 p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
  146.                 aout_BufferFree( p_old_buffer );
  147.                 if ( p_input->fifo.p_first == NULL )
  148.                 {
  149.                     msg_Err( p_aout, "internal amix error" );
  150.                     return;
  151.                 }
  152.                 p_in = (float *)p_input->fifo.p_first->p_buffer;
  153.             }
  154.             else
  155.             {
  156.                 if ( i_nb_words > 0 )
  157.                 {
  158.                     if ( !i_input )
  159.                     {
  160.                         ScaleWords( p_out, p_in, i_nb_words, i_nb_inputs,
  161.                                     f_multiplier );
  162.                     }
  163.                     else
  164.                     {
  165.                         MeanWords( p_out, p_in, i_nb_words, i_nb_inputs,
  166.                                    f_multiplier );
  167.                     }
  168.                 }
  169.                 p_input->p_first_byte_to_mix = (void *)(p_in
  170.                                             + i_nb_words);
  171.                 break;
  172.             }
  173.         }
  174.     }
  175. }