]> git.sesse.net Git - vlc/blob - src/audio_output/aout_common.h
1980ba8b61d5fcd268341edf659b2a7cae2f29d4
[vlc] / src / audio_output / aout_common.h
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 $
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *
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.
13  * 
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.
18  *
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  *****************************************************************************/
23
24
25 /* Biggest difference allowed between scheduled playing date and actual date 
26    (in microseconds) */
27 #define MAX_DELTA 10000
28
29
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 );
42
43 #define UPDATE_INCREMENT( increment, integer ) \
44     if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
45     { \
46         (integer) += (increment).l_euclidean_integer + 1; \
47         (increment).l_remainder -= (increment).l_euclidean_denominator; \
48     } \
49     else \
50     { \
51         (integer) += (increment).l_euclidean_integer; \
52     }
53
54 /*****************************************************************************
55  * InitializeIncrement
56  *****************************************************************************/
57 static __inline__ void InitializeIncrement( aout_increment_t * p_increment,
58                                             long l_numerator,
59                                             long l_denominator )
60 {
61     p_increment->l_remainder = -l_denominator;
62
63     p_increment->l_euclidean_integer = 0;
64     while ( l_numerator >= l_denominator )
65     {
66         p_increment->l_euclidean_integer++;
67         l_numerator -= l_denominator;
68     }
69
70     p_increment->l_euclidean_remainder = l_numerator;
71
72     p_increment->l_euclidean_denominator = l_denominator;
73 }
74
75 /*****************************************************************************
76  * NextFrame
77  *****************************************************************************/
78 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo,
79                                  mtime_t aout_date )
80 {
81     long l_units, l_rate;
82     long long l_delta;    
83
84     /* We take the lock */
85     vlc_mutex_lock( &p_fifo->data_lock );
86
87     /* Are we looking for a dated start frame ? */
88     if ( !p_fifo->b_start_frame )
89     {
90         while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
91         {
92             if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
93             {
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));
97                 break;
98             }
99             p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
100         }
101
102         if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
103         {
104             vlc_mutex_unlock( &p_fifo->data_lock );
105             return( -1 );
106         }
107     }
108
109     /* We are looking for the next dated frame */
110     /* FIXME : is the output fifo full ?? */
111     while ( !p_fifo->b_next_frame )
112     {
113         while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
114         {
115             if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
116             {
117                 p_fifo->b_next_frame = 1;
118                 break;
119             }
120             p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
121         }
122
123         while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
124         {
125             vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
126             if ( p_fifo->b_die )
127             {
128                 vlc_mutex_unlock( &p_fifo->data_lock );
129                 return( -1 );
130             }
131         }
132     }
133
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));
135
136     l_delta = aout_date - p_fifo->date[p_fifo->l_start_frame];
137
138 /* Resample if delta is too long */
139     if( abs(l_delta) > MAX_DELTA )
140     {
141         l_rate = p_fifo->l_rate + (l_delta / 256);
142     }
143     else
144     {
145         l_rate = p_fifo->l_rate;
146     }
147
148     intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
149
150     InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
151
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;
155
156     /* We release the lock before leaving */
157     vlc_mutex_unlock( &p_fifo->data_lock );
158     return( 0 );
159 }
160