float32.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:7k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * float32.c : precise float32 audio mixer implementation
  3.  *****************************************************************************
  4.  * Copyright (C) 2002 VideoLAN
  5.  * $Id: float32.c 6961 2004-03-05 17:34:23Z sam $
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <string.h>
  28. #include <vlc/vlc.h>
  29. #include "audio_output.h"
  30. #include "aout_internal.h"
  31. /*****************************************************************************
  32.  * Local prototypes
  33.  *****************************************************************************/
  34. static int  Create    ( vlc_object_t * );
  35. static void DoWork    ( aout_instance_t *, aout_buffer_t * );
  36. /*****************************************************************************
  37.  * Module descriptor
  38.  *****************************************************************************/
  39. vlc_module_begin();
  40.     set_description( _("Float32 audio mixer") );
  41.     set_capability( "audio mixer", 10 );
  42.     set_callbacks( Create, NULL );
  43. vlc_module_end();
  44. /*****************************************************************************
  45.  * Create: allocate mixer
  46.  *****************************************************************************/
  47. static int Create( vlc_object_t *p_this )
  48. {
  49.     aout_instance_t * p_aout = (aout_instance_t *)p_this;
  50.     if ( p_aout->mixer.mixer.i_format != VLC_FOURCC('f','l','3','2') )
  51.     {
  52.         return -1;
  53.     }
  54.     if ( p_aout->i_nb_inputs == 1 && p_aout->mixer.f_multiplier == 1.0 )
  55.     {
  56.         /* Tell the trivial mixer to go for it. */
  57.         return -1;
  58.     }
  59.     p_aout->mixer.pf_do_work = DoWork;
  60.     return 0;
  61. }
  62. /*****************************************************************************
  63.  * ScaleWords: prepare input words for averaging
  64.  *****************************************************************************/
  65. static void ScaleWords( float * p_out, const float * p_in, size_t i_nb_words,
  66.                         int i_nb_inputs, float f_multiplier )
  67. {
  68.     int i;
  69.     f_multiplier /= i_nb_inputs;
  70.     for ( i = i_nb_words; i--; )
  71.     {
  72.         *p_out++ = *p_in++ * f_multiplier;
  73.     }
  74. }
  75. /*****************************************************************************
  76.  * MeanWords: average input words
  77.  *****************************************************************************/
  78. static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
  79.                        int i_nb_inputs, float f_multiplier )
  80. {
  81.     int i;
  82.     f_multiplier /= i_nb_inputs;
  83.     for ( i = i_nb_words; i--; )
  84.     {
  85.         *p_out++ += *p_in++ * f_multiplier;
  86.     }
  87. }
  88. /*****************************************************************************
  89.  * DoWork: mix a new output buffer
  90.  *****************************************************************************
  91.  * Terminology : in this function a word designates a single float32, eg.
  92.  * a stereo sample is consituted of two words.
  93.  *****************************************************************************/
  94. static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
  95. {
  96.     int i_nb_inputs = p_aout->i_nb_inputs;
  97.     float f_multiplier = p_aout->mixer.f_multiplier;
  98.     int i_input;
  99.     int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer );
  100.     for ( i_input = 0; i_input < i_nb_inputs; i_input++ )
  101.     {
  102.         int i_nb_words = p_buffer->i_nb_samples * i_nb_channels;
  103.         aout_input_t * p_input = p_aout->pp_inputs[i_input];
  104.         float * p_out = (float *)p_buffer->p_buffer;
  105.         float * p_in = (float *)p_input->p_first_byte_to_mix;
  106.         if ( p_input->b_error ) continue;
  107.         for ( ; ; )
  108.         {
  109.             ptrdiff_t i_available_words = (
  110.                  (float *)p_input->fifo.p_first->p_buffer - p_in)
  111.                                    + p_input->fifo.p_first->i_nb_samples
  112.                                    * i_nb_channels;
  113.             if ( i_available_words < i_nb_words )
  114.             {
  115.                 aout_buffer_t * p_old_buffer;
  116.                 if ( i_available_words > 0 )
  117.                 {
  118.                     if ( !i_input )
  119.                     {
  120.                         ScaleWords( p_out, p_in, i_available_words,
  121.                                     i_nb_inputs, f_multiplier );
  122.                     }
  123.                     else
  124.                     {
  125.                         MeanWords( p_out, p_in, i_available_words,
  126.                                    i_nb_inputs, f_multiplier );
  127.                     }
  128.                 }
  129.                 i_nb_words -= i_available_words;
  130.                 p_out += i_available_words;
  131.                 /* Next buffer */
  132.                 p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
  133.                 aout_BufferFree( p_old_buffer );
  134.                 if ( p_input->fifo.p_first == NULL )
  135.                 {
  136.                     msg_Err( p_aout, "internal amix error" );
  137.                     return;
  138.                 }
  139.                 p_in = (float *)p_input->fifo.p_first->p_buffer;
  140.             }
  141.             else
  142.             {
  143.                 if ( i_nb_words > 0 )
  144.                 {
  145.                     if ( !i_input )
  146.                     {
  147.                         ScaleWords( p_out, p_in, i_nb_words, i_nb_inputs,
  148.                                     f_multiplier );
  149.                     }
  150.                     else
  151.                     {
  152.                         MeanWords( p_out, p_in, i_nb_words, i_nb_inputs,
  153.                                    f_multiplier );
  154.                     }
  155.                 }
  156.                 p_input->p_first_byte_to_mix = (void *)(p_in
  157.                                             + i_nb_words);
  158.                 break;
  159.             }
  160.         }
  161.     }
  162. }