Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

trivial.c

00001 /*****************************************************************************
00002  * trivial.c : trivial mixer plug-in (1 input, no downmixing)
00003  *****************************************************************************
00004  * Copyright (C) 2002 the VideoLAN team
00005  * $Id: trivial.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Christophe Massiot <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <stdlib.h>                                      /* malloc(), free() */
00028 #include <string.h>
00029 
00030 #include <vlc/vlc.h>
00031 #include "audio_output.h"
00032 #include "aout_internal.h"
00033 
00034 /*****************************************************************************
00035  * Local prototypes
00036  *****************************************************************************/
00037 static int  Create    ( vlc_object_t * );
00038 
00039 static void DoWork    ( aout_instance_t *, aout_buffer_t * );
00040 
00041 /*****************************************************************************
00042  * Module descriptor
00043  *****************************************************************************/
00044 vlc_module_begin();
00045     set_category( CAT_AUDIO );
00046     set_subcategory( SUBCAT_AUDIO_MISC );
00047     set_description( _("Trivial audio mixer") );
00048     set_capability( "audio mixer", 1 );
00049     set_callbacks( Create, NULL );
00050 vlc_module_end();
00051 
00052 /*****************************************************************************
00053  * Create: allocate trivial mixer
00054  *****************************************************************************/
00055 static int Create( vlc_object_t *p_this )
00056 {
00057     aout_instance_t * p_aout = (aout_instance_t *)p_this;
00058 
00059     if ( p_aout->mixer.mixer.i_format != VLC_FOURCC('f','l','3','2')
00060           && p_aout->mixer.mixer.i_format != VLC_FOURCC('f','i','3','2') )
00061     {
00062         return -1;
00063     }
00064 
00065     p_aout->mixer.pf_do_work = DoWork;
00066 
00067     return 0;
00068 }
00069 
00070 /*****************************************************************************
00071  * DoWork: mix a new output buffer
00072  *****************************************************************************/
00073 static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
00074 {
00075     int i = 0;
00076     aout_input_t * p_input = p_aout->pp_inputs[i];
00077     int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer );
00078     int i_nb_bytes = p_buffer->i_nb_samples * sizeof(int32_t)
00079                       * i_nb_channels;
00080     byte_t * p_in;
00081     byte_t * p_out;
00082 
00083     while ( p_input->b_error )
00084     {
00085         p_input = p_aout->pp_inputs[++i];
00086         /* This can't crash because if no input has b_error == 0, the
00087          * audio mixer cannot run and we can't be here. */
00088     }
00089     p_in = p_input->p_first_byte_to_mix;
00090     p_out = p_buffer->p_buffer;
00091 
00092     for ( ; ; )
00093     {
00094         ptrdiff_t i_available_bytes = (p_input->fifo.p_first->p_buffer
00095                                         - p_in)
00096                                         + p_input->fifo.p_first->i_nb_samples
00097                                            * sizeof(int32_t)
00098                                            * i_nb_channels;
00099 
00100         if ( i_available_bytes < i_nb_bytes )
00101         {
00102             aout_buffer_t * p_old_buffer;
00103 
00104             if ( i_available_bytes > 0 )
00105                 p_aout->p_vlc->pf_memcpy( p_out, p_in, i_available_bytes );
00106             i_nb_bytes -= i_available_bytes;
00107             p_out += i_available_bytes;
00108 
00109             /* Next buffer */
00110             p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
00111             aout_BufferFree( p_old_buffer );
00112             if ( p_input->fifo.p_first == NULL )
00113             {
00114                 msg_Err( p_aout, "internal amix error" );
00115                 return;
00116             }
00117             p_in = p_input->fifo.p_first->p_buffer;
00118         }
00119         else
00120         {
00121             if ( i_nb_bytes > 0 )
00122                 p_aout->p_vlc->pf_memcpy( p_out, p_in, i_nb_bytes );
00123             p_input->p_first_byte_to_mix = p_in + i_nb_bytes;
00124             break;
00125         }
00126     }
00127 
00128     /* Empty other FIFOs to avoid a memory leak. */
00129     for ( i++; i < p_aout->i_nb_inputs; i++ )
00130     {
00131         aout_fifo_t * p_fifo;
00132         aout_buffer_t * p_deleted;
00133 
00134         p_input = p_aout->pp_inputs[i];
00135         if ( p_input->b_error ) continue;
00136         p_fifo = &p_input->fifo;
00137         p_deleted = p_fifo->p_first;
00138         while ( p_deleted != NULL )
00139         {
00140             aout_buffer_t * p_next = p_deleted->p_next;
00141             aout_BufferFree( p_deleted );
00142             p_deleted = p_next;
00143         }
00144         p_fifo->p_first = NULL;
00145         p_fifo->pp_last = &p_fifo->p_first;
00146     }
00147 }
00148 

Generated on Tue Dec 20 10:14:27 2005 for vlc-0.8.4a by  doxygen 1.4.2