1bc69c96aa5183cda2aa524fcc5b10f3967505c4
[vlc.git] / src / audio_output / aout_s16.c
1 /*****************************************************************************
2  * aout_s16.c: 16 bit signed audio output functions
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *          Cyril Deguet <asmax@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdio.h>                                           /* "intf_msg.h" */
29 #include <stdlib.h>                            /* calloc(), malloc(), free() */
30 #include <string.h>
31
32 #include <videolan/vlc.h>
33
34 #include "audio_output.h"
35 #include "aout_common.h"
36
37 /*****************************************************************************
38  * Functions
39  *****************************************************************************/
40
41 void aout_S16Thread( aout_thread_t * p_aout )
42 {
43     int  i_fifo;
44     long l_buffer, l_buffer_limit, l_bytes;
45
46     /* As the s32_buffer was created with calloc(), we don't have to set this
47      * memory to zero and we can immediately jump into the thread's loop */
48     while ( ! p_aout->b_die )
49     {
50         vlc_mutex_lock( &p_aout->fifos_lock );
51
52         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
53         {
54             if( p_aout->fifo[i_fifo].b_die )
55             {
56                 aout_FreeFifo( &p_aout->fifo[i_fifo] );
57             }
58             else
59             {
60                 aout_FillBuffer( p_aout, &p_aout->fifo[i_fifo] );
61             }
62         }
63
64         vlc_mutex_unlock( &p_aout->fifos_lock );
65
66         l_buffer_limit = p_aout->l_units <<  p_aout->b_stereo;
67
68         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
69         {
70             ((s16 *)p_aout->buffer)[l_buffer] =
71                      (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS )
72                             * p_aout->i_volume / 256 ) ;
73             p_aout->s32_buffer[l_buffer] = 0;
74         }
75
76         l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
77
78         p_aout->date = mdate() + ((((mtime_t)((l_bytes + 4 * p_aout->i_latency) / 
79                 (sizeof(s16) << p_aout->b_stereo))) * 1000000) / 
80                 ((mtime_t)p_aout->l_rate)) + p_main->i_desync;
81                 
82         p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer,
83                          l_buffer_limit * sizeof(s16) );
84
85         if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
86         {
87             msleep( p_aout->l_msleep );
88         }
89     }
90
91     vlc_mutex_lock( &p_aout->fifos_lock );
92
93     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
94     {
95         aout_FreeFifo( &p_aout->fifo[i_fifo] );
96     }
97
98     vlc_mutex_unlock( &p_aout->fifos_lock );
99 }
100