1 /*****************************************************************************
2 * aout_ext-dec.c : exported fifo management functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
5 * $Id: aout_ext-dec.c,v 1.1 2001/05/01 04:18:18 sam Exp $
7 * Authors: Michel Kaempf <maxx@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 *****************************************************************************/
29 #include <stdio.h> /* "intf_msg.h" */
30 #include <stdlib.h> /* calloc(), malloc(), free() */
35 #include "mtime.h" /* mtime_t, mdate(), msleep() */
37 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
39 #include "audio_output.h"
40 #include "aout_common.h"
44 /*****************************************************************************
46 *****************************************************************************/
47 aout_fifo_t * aout_CreateFifo( int i_type, int i_channels, long l_rate,
48 long l_units, long l_frame_size,
51 #define P_AOUT p_main->p_aout
54 /* Spawn an audio output if there is none */
57 P_AOUT = aout_CreateThread( NULL );
65 /* Take the fifos lock */
66 vlc_mutex_lock( &P_AOUT->fifos_lock );
68 /* Looking for a free fifo structure */
69 for( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
71 if( P_AOUT->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO )
73 /* Not very clever, but at least we know which fifo it is */
74 P_AOUT->fifo[i_fifo].i_fifo = i_fifo;
79 if( i_fifo == AOUT_MAX_FIFOS )
81 intf_ErrMsg( "aout error: no fifo available" );
82 vlc_mutex_unlock( &P_AOUT->fifos_lock );
86 /* Initialize the new fifo structure */
87 switch ( P_AOUT->fifo[i_fifo].i_type = i_type )
89 case AOUT_INTF_MONO_FIFO:
90 case AOUT_INTF_STEREO_FIFO:
91 P_AOUT->fifo[i_fifo].b_die = 0;
93 P_AOUT->fifo[i_fifo].i_channels = i_channels;
94 P_AOUT->fifo[i_fifo].b_stereo = ( i_channels == 2 );
95 P_AOUT->fifo[i_fifo].l_rate = l_rate;
97 P_AOUT->fifo[i_fifo].buffer = p_buffer;
99 P_AOUT->fifo[i_fifo].l_unit = 0;
100 InitializeIncrement( &P_AOUT->fifo[i_fifo].unit_increment,
101 l_rate, P_AOUT->l_rate );
102 P_AOUT->fifo[i_fifo].l_units = l_units;
105 case AOUT_ADEC_MONO_FIFO:
106 case AOUT_ADEC_STEREO_FIFO:
107 P_AOUT->fifo[i_fifo].b_die = 0;
109 P_AOUT->fifo[i_fifo].i_channels = i_channels;
110 P_AOUT->fifo[i_fifo].b_stereo = ( i_channels == 2 );
111 P_AOUT->fifo[i_fifo].l_rate = l_rate;
113 P_AOUT->fifo[i_fifo].l_frame_size = l_frame_size;
114 /* Allocate the memory needed to store the audio frames. As the
115 * fifo is a rotative fifo, we must be able to find out whether
116 * the fifo is full or empty, that's why we must in fact allocate
117 * memory for (AOUT_FIFO_SIZE+1) audio frames. */
118 P_AOUT->fifo[i_fifo].buffer = malloc( sizeof(s16) *
119 ( AOUT_FIFO_SIZE + 1 ) * l_frame_size );
120 if ( P_AOUT->fifo[i_fifo].buffer == NULL )
122 intf_ErrMsg( "aout error: cannot create frame buffer" );
123 P_AOUT->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
124 vlc_mutex_unlock( &P_AOUT->fifos_lock );
128 /* Allocate the memory needed to store the dates of the frames */
129 P_AOUT->fifo[i_fifo].date =
130 malloc( sizeof(mtime_t) * ( AOUT_FIFO_SIZE + 1) );
132 if ( P_AOUT->fifo[i_fifo].date == NULL )
134 intf_ErrMsg( "aout error: cannot create date buffer");
135 free( P_AOUT->fifo[i_fifo].buffer );
136 P_AOUT->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
137 vlc_mutex_unlock( &P_AOUT->fifos_lock );
141 /* Set the fifo's buffer as empty (the first frame that is to be
142 * played is also the first frame that is not to be played) */
143 P_AOUT->fifo[i_fifo].l_start_frame = 0;
144 /* P_AOUT->fifo[i_fifo].l_next_frame = 0; */
145 P_AOUT->fifo[i_fifo].l_end_frame = 0;
147 /* Waiting for the audio decoder to compute enough frames to work
148 * out the fifo's current rate (as soon as the decoder has decoded
149 * enough frames, the members of the fifo structure that are not
150 * initialized now will be calculated) */
151 P_AOUT->fifo[i_fifo].b_start_frame = 0;
152 P_AOUT->fifo[i_fifo].b_next_frame = 0;
156 intf_ErrMsg( "aout error: unknown fifo type 0x%x",
157 P_AOUT->fifo[i_fifo].i_type );
158 P_AOUT->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
159 vlc_mutex_unlock( &P_AOUT->fifos_lock );
163 /* Release the fifos lock */
164 vlc_mutex_unlock( &P_AOUT->fifos_lock );
166 intf_WarnMsg( 2, "aout info: fifo #%i allocated, %i channels, rate %li",
167 P_AOUT->fifo[i_fifo].i_fifo, P_AOUT->fifo[i_fifo].i_channels,
168 P_AOUT->fifo[i_fifo].l_rate );
170 /* Return the pointer to the fifo structure */
171 return( &P_AOUT->fifo[i_fifo] );
175 /*****************************************************************************
177 *****************************************************************************/
178 void aout_DestroyFifo( aout_fifo_t * p_fifo )
180 intf_WarnMsg( 2, "aout info: fifo #%i destroyed", p_fifo->i_fifo );
185 /*****************************************************************************
187 *****************************************************************************/
188 void aout_FreeFifo( aout_fifo_t * p_fifo )
190 switch ( p_fifo->i_type )
192 case AOUT_EMPTY_FIFO:
196 case AOUT_INTF_MONO_FIFO:
197 case AOUT_INTF_STEREO_FIFO:
199 free( p_fifo->buffer );
200 p_fifo->i_type = AOUT_EMPTY_FIFO;
204 case AOUT_ADEC_MONO_FIFO:
205 case AOUT_ADEC_STEREO_FIFO:
207 free( p_fifo->buffer );
208 free( p_fifo->date );
209 p_fifo->i_type = AOUT_EMPTY_FIFO;