1 /*****************************************************************************
2 * aout_fifo.c : exported fifo management functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
6 * Authors: Michel Kaempf <maxx@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
28 #include <stdio.h> /* "intf_msg.h" */
29 #include <stdlib.h> /* calloc(), malloc(), free() */
34 #include "mtime.h" /* mtime_t, mdate(), msleep() */
36 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
38 #include "audio_output.h"
39 #include "aout_common.h"
41 /*****************************************************************************
43 *****************************************************************************/
44 aout_fifo_t
* aout_CreateFifo( aout_thread_t
* p_aout
, aout_fifo_t
* p_fifo
)
48 /* Take the fifos lock */
49 vlc_mutex_lock( &p_aout
->fifos_lock
);
51 /* Looking for a free fifo structure */
52 for ( i_fifo
= 0; i_fifo
< AOUT_MAX_FIFOS
; i_fifo
++ )
54 if ( p_aout
->fifo
[i_fifo
].i_type
== AOUT_EMPTY_FIFO
)
56 /* Not very clever, but at least we know which fifo it is */
57 p_aout
->fifo
[i_fifo
].i_fifo
= i_fifo
;
62 if ( i_fifo
== AOUT_MAX_FIFOS
)
64 intf_ErrMsg( "aout error: no fifo available" );
65 vlc_mutex_unlock( &p_aout
->fifos_lock
);
69 /* Initialize the new fifo structure */
70 switch ( p_aout
->fifo
[i_fifo
].i_type
= p_fifo
->i_type
)
72 case AOUT_INTF_MONO_FIFO
:
73 case AOUT_INTF_STEREO_FIFO
:
74 p_aout
->fifo
[i_fifo
].b_die
= 0;
76 p_aout
->fifo
[i_fifo
].i_channels
= p_fifo
->i_channels
;
77 p_aout
->fifo
[i_fifo
].b_stereo
= p_fifo
->b_stereo
;
78 p_aout
->fifo
[i_fifo
].l_rate
= p_fifo
->l_rate
;
80 p_aout
->fifo
[i_fifo
].buffer
= p_fifo
->buffer
;
82 p_aout
->fifo
[i_fifo
].l_unit
= 0;
83 InitializeIncrement( &p_aout
->fifo
[i_fifo
].unit_increment
,
84 p_fifo
->l_rate
, p_aout
->l_rate
);
85 p_aout
->fifo
[i_fifo
].l_units
= p_fifo
->l_units
;
88 case AOUT_ADEC_MONO_FIFO
:
89 case AOUT_ADEC_STEREO_FIFO
:
90 p_aout
->fifo
[i_fifo
].b_die
= 0;
92 p_aout
->fifo
[i_fifo
].i_channels
= p_fifo
->i_channels
;
93 p_aout
->fifo
[i_fifo
].b_stereo
= p_fifo
->b_stereo
;
94 p_aout
->fifo
[i_fifo
].l_rate
= p_fifo
->l_rate
;
96 p_aout
->fifo
[i_fifo
].l_frame_size
= p_fifo
->l_frame_size
;
97 /* Allocate the memory needed to store the audio frames. As the
98 * fifo is a rotative fifo, we must be able to find out whether the
99 * fifo is full or empty, that's why we must in fact allocate memory
100 * for (AOUT_FIFO_SIZE+1) audio frames. */
101 p_aout
->fifo
[i_fifo
].buffer
= malloc( sizeof(s16
)*(AOUT_FIFO_SIZE
+1)*p_fifo
->l_frame_size
);
102 if ( p_aout
->fifo
[i_fifo
].buffer
== NULL
)
104 intf_ErrMsg( "aout error: cannot create frame buffer" );
105 p_aout
->fifo
[i_fifo
].i_type
= AOUT_EMPTY_FIFO
;
106 vlc_mutex_unlock( &p_aout
->fifos_lock
);
110 /* Allocate the memory needed to store the dates of the frames */
111 p_aout
->fifo
[i_fifo
].date
= (mtime_t
*)malloc( sizeof(mtime_t
)*(AOUT_FIFO_SIZE
+1) );
112 if ( p_aout
->fifo
[i_fifo
].date
== NULL
)
114 intf_ErrMsg( "aout error: cannot create date buffer");
115 free( p_aout
->fifo
[i_fifo
].buffer
);
116 p_aout
->fifo
[i_fifo
].i_type
= AOUT_EMPTY_FIFO
;
117 vlc_mutex_unlock( &p_aout
->fifos_lock
);
121 /* Set the fifo's buffer as empty (the first frame that is to be
122 * played is also the first frame that is not to be played) */
123 p_aout
->fifo
[i_fifo
].l_start_frame
= 0;
124 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
125 p_aout
->fifo
[i_fifo
].l_end_frame
= 0;
127 /* Waiting for the audio decoder to compute enough frames to work
128 * out the fifo's current rate (as soon as the decoder has decoded
129 * enough frames, the members of the fifo structure that are not
130 * initialized now will be calculated) */
131 p_aout
->fifo
[i_fifo
].b_start_frame
= 0;
132 p_aout
->fifo
[i_fifo
].b_next_frame
= 0;
136 intf_ErrMsg( "aout error: unknown fifo type 0x%x", p_aout
->fifo
[i_fifo
].i_type
);
137 p_aout
->fifo
[i_fifo
].i_type
= AOUT_EMPTY_FIFO
;
138 vlc_mutex_unlock( &p_aout
->fifos_lock
);
142 /* Release the fifos lock */
143 vlc_mutex_unlock( &p_aout
->fifos_lock
);
145 intf_WarnMsg( 2, "aout info: fifo #%i allocated, %i channels, rate %li",
146 p_aout
->fifo
[i_fifo
].i_fifo
, p_aout
->fifo
[i_fifo
].i_channels
, p_aout
->fifo
[i_fifo
].l_rate
);
148 /* Return the pointer to the fifo structure */
152 /*****************************************************************************
154 *****************************************************************************/
155 void aout_DestroyFifo( aout_fifo_t
* p_fifo
)
157 intf_WarnMsg( 2, "aout info: fifo #%i destroyed", p_fifo
->i_fifo
);
162 /*****************************************************************************
164 *****************************************************************************/
165 void aout_FreeFifo( aout_fifo_t
* p_fifo
)
167 switch ( p_fifo
->i_type
)
169 case AOUT_EMPTY_FIFO
:
173 case AOUT_INTF_MONO_FIFO
:
174 case AOUT_INTF_STEREO_FIFO
:
176 free( p_fifo
->buffer
);
177 p_fifo
->i_type
= AOUT_EMPTY_FIFO
;
181 case AOUT_ADEC_MONO_FIFO
:
182 case AOUT_ADEC_STEREO_FIFO
:
184 free( p_fifo
->buffer
);
185 free( p_fifo
->date
);
186 p_fifo
->i_type
= AOUT_EMPTY_FIFO
;