1 /*****************************************************************************
2 * audio_output.c : audio output instance
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
5 * $Id: audio_output.c,v 1.91 2002/08/09 23:47:23 massiot Exp $
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* calloc(), malloc(), free() */
36 #include "audio_output.h"
37 #include "aout_internal.h"
39 /*****************************************************************************
40 * aout_NewInstance: initialize aout structure
41 *****************************************************************************/
42 aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent )
44 aout_instance_t * p_aout;
46 /* Allocate descriptor. */
47 p_aout = vlc_object_create( p_parent, VLC_OBJECT_AOUT );
53 /* Initialize members. */
54 vlc_mutex_init( p_parent, &p_aout->input_lock );
55 vlc_cond_init( p_parent, &p_aout->input_signal );
56 p_aout->i_inputs_active = 0;
57 p_aout->b_change_requested = 0;
58 p_aout->i_nb_inputs = 0;
60 vlc_mutex_init( p_parent, &p_aout->mixer_lock );
61 vlc_cond_init( p_parent, &p_aout->mixer_signal );
62 p_aout->b_mixer_active = 0;
64 vlc_object_attach( p_aout, p_parent->p_vlc );
69 /*****************************************************************************
70 * aout_DeleteInstance: destroy aout structure
71 *****************************************************************************/
72 void aout_DeleteInstance( aout_instance_t * p_aout )
74 vlc_mutex_destroy( &p_aout->input_lock );
75 vlc_cond_destroy( &p_aout->input_signal );
76 vlc_mutex_destroy( &p_aout->mixer_lock );
77 vlc_cond_destroy( &p_aout->mixer_signal );
80 vlc_object_detach_all( p_aout );
81 vlc_object_destroy( p_aout );
84 /*****************************************************************************
85 * aout_BufferNew : ask for a new empty buffer
86 *****************************************************************************/
87 aout_buffer_t * aout_BufferNew( aout_instance_t * p_aout,
88 aout_input_t * p_input,
91 aout_buffer_t * p_buffer;
93 /* This necessarily allocates in the heap. */
94 aout_BufferAlloc( &p_input->input_alloc, (u64)(1000000 * i_nb_samples)
95 / p_input->input.i_rate,
97 p_buffer->i_nb_samples = i_nb_samples;
99 if ( p_buffer == NULL )
101 msg_Err( p_aout, "NULL buffer !" );
105 p_buffer->start_date = p_buffer->end_date = 0;
111 /*****************************************************************************
112 * aout_BufferDelete : destroy an undecoded buffer
113 *****************************************************************************/
114 void aout_BufferDelete( aout_instance_t * p_aout, aout_input_t * p_input,
115 aout_buffer_t * p_buffer )
117 aout_BufferFree( p_buffer );
120 /*****************************************************************************
121 * aout_BufferPlay : filter & mix the decoded buffer
122 *****************************************************************************/
123 void aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input,
124 aout_buffer_t * p_buffer )
126 vlc_bool_t b_run_mixer = 0;
128 if ( p_buffer->start_date == 0 )
130 msg_Warn( p_aout, "non-dated buffer received" );
131 aout_BufferFree( p_buffer );
135 p_buffer->end_date = p_buffer->start_date
136 + (mtime_t)(p_buffer->i_nb_samples * 1000000)
137 / p_input->input.i_rate;
140 aout_InputPlay( p_aout, p_input, p_buffer );
142 /* Run the mixer if it is able to run. */
143 vlc_mutex_lock( &p_aout->mixer_lock );
144 if ( !p_aout->b_mixer_active )
146 p_aout->b_mixer_active = 1;
149 vlc_mutex_unlock( &p_aout->mixer_lock );
153 aout_MixerRun( p_aout );
154 vlc_mutex_lock( &p_aout->mixer_lock );
155 p_aout->b_mixer_active = 0;
156 vlc_cond_broadcast( &p_aout->mixer_signal );
157 vlc_mutex_unlock( &p_aout->mixer_lock );
161 /*****************************************************************************
162 * aout_FormatTo : compute the number of bytes/sample for format (used for
163 * aout_FormatToByterate and aout_FormatToSize)
164 *****************************************************************************/
165 int aout_FormatTo( audio_sample_format_t * p_format, int i_multiplier )
169 switch ( p_format->i_format )
176 case AOUT_FMT_U16_LE:
177 case AOUT_FMT_U16_BE:
178 case AOUT_FMT_S16_LE:
179 case AOUT_FMT_S16_BE:
183 case AOUT_FMT_FLOAT32:
184 case AOUT_FMT_FIXED32:
189 case AOUT_FMT_A52: /* Actually smaller and variable, but who cares ? */
190 case AOUT_FMT_DTS: /* Unimplemented and untested */
191 /* Please note that we don't multiply by multiplier, because i_rate
192 * and i_nb_samples do not have any sense for S/PDIF (yes, it
193 * _is_ kludgy). --Meuuh */
194 return AOUT_SPDIF_FRAME;
197 return 0; /* will segfault much sooner... */
200 return i_result * p_format->i_channels * i_multiplier;