1 /*****************************************************************************
2 * aout_common.h: audio output inner functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
5 * $Id: aout_common.h,v 1.5 2001/11/01 00:29:54 asmax 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 *****************************************************************************/
25 /* Biggest difference allowed between scheduled playing date and actual date
27 #define MAX_DELTA 10000
30 /* Creating as many aout_Thread functions as configurations was one solution,
31 * examining the different cases in the Thread loop of an unique function was
32 * another. I chose the first solution. */
33 void aout_U8MonoThread ( aout_thread_t * p_aout );
34 void aout_U8StereoThread ( aout_thread_t * p_aout );
35 void aout_S8MonoThread ( aout_thread_t * p_aout );
36 void aout_S8StereoThread ( aout_thread_t * p_aout );
37 void aout_U16MonoThread ( aout_thread_t * p_aout );
38 void aout_U16StereoThread ( aout_thread_t * p_aout );
39 void aout_S16MonoThread ( aout_thread_t * p_aout );
40 void aout_S16StereoThread ( aout_thread_t * p_aout );
41 void aout_SpdifThread ( aout_thread_t * p_aout );
43 #define UPDATE_INCREMENT( increment, integer ) \
44 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
46 (integer) += (increment).l_euclidean_integer + 1; \
47 (increment).l_remainder -= (increment).l_euclidean_denominator; \
51 (integer) += (increment).l_euclidean_integer; \
54 /*****************************************************************************
56 *****************************************************************************/
57 static __inline__ void InitializeIncrement( aout_increment_t * p_increment,
61 p_increment->l_remainder = -l_denominator;
63 p_increment->l_euclidean_integer = 0;
64 while ( l_numerator >= l_denominator )
66 p_increment->l_euclidean_integer++;
67 l_numerator -= l_denominator;
70 p_increment->l_euclidean_remainder = l_numerator;
72 p_increment->l_euclidean_denominator = l_denominator;
75 /*****************************************************************************
77 *****************************************************************************/
78 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo,
84 /* We take the lock */
85 vlc_mutex_lock( &p_fifo->data_lock );
87 /* Are we looking for a dated start frame ? */
88 if ( !p_fifo->b_start_frame )
90 while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
92 if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
94 p_fifo->b_start_frame = 1;
95 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
96 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
99 p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
102 if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
104 vlc_mutex_unlock( &p_fifo->data_lock );
109 /* We are looking for the next dated frame */
110 /* FIXME : is the output fifo full ?? */
111 while ( !p_fifo->b_next_frame )
113 while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
115 if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
117 p_fifo->b_next_frame = 1;
120 p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
123 while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
125 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
128 vlc_mutex_unlock( &p_fifo->data_lock );
134 l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
136 l_delta = aout_date - p_fifo->date[p_fifo->l_start_frame];
138 /* Resample if delta is too long */
139 if( abs(l_delta) > MAX_DELTA )
141 l_rate = p_fifo->l_rate + (l_delta / 256);
145 l_rate = p_fifo->l_rate;
148 intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
150 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
152 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
153 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
154 * p_aout->l_rate) / l_rate) + 1;
156 /* We release the lock before leaving */
157 vlc_mutex_unlock( &p_fifo->data_lock );