]> git.sesse.net Git - vlc/blob - modules/video_output/sdl/aout.c
Audio output 3. Expect major breakages.
[vlc] / modules / video_output / sdl / aout.c
1 /*****************************************************************************
2  * aout_sdl.c : audio sdl functions library
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: aout.c,v 1.2 2002/08/07 21:36:56 massiot Exp $
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *          Samuel Hocevar <sam@zoy.org>
9  *          Pierre Baillet <oct@zoy.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <errno.h>                                                 /* ENOMEM */
30 #include <fcntl.h>                                       /* open(), O_WRONLY */
31 #include <string.h>                                            /* strerror() */
32 #include <unistd.h>                                      /* write(), close() */
33 #include <stdlib.h>                            /* calloc(), malloc(), free() */
34
35 #include <vlc/vlc.h>
36 #include <vlc/aout.h>
37 #include "aout_internal.h"
38
39 #include SDL_INCLUDE_FILE
40
41 #define DEFAULT_FRAME_SIZE 2048
42
43 /*****************************************************************************
44  * Local prototypes
45  *****************************************************************************/
46 static int     SetFormat   ( aout_instance_t * );
47 static void    Play        ( aout_instance_t *, aout_buffer_t * );
48
49 static void    SDLCallback ( void *, Uint8 *, int );
50
51 /*****************************************************************************
52  * OpenAudio: open the audio device
53  *****************************************************************************/
54 int E_(OpenAudio) ( aout_instance_t *p_aout )
55 {
56     if( SDL_WasInit( SDL_INIT_AUDIO ) != 0 )
57     {
58         return( 1 );
59     }
60
61     p_aout->output.pf_setformat = SetFormat;
62     p_aout->output.pf_play = Play;
63
64     /* Initialize library */
65     if( SDL_Init( SDL_INIT_AUDIO
66 #ifndef WIN32
67     /* Win32 SDL implementation doesn't support SDL_INIT_EVENTTHREAD yet*/
68                 | SDL_INIT_EVENTTHREAD
69 #endif
70 #ifdef DEBUG
71     /* In debug mode you may want vlc to dump a core instead of staying
72      * stuck */
73                 | SDL_INIT_NOPARACHUTE
74 #endif
75                 ) < 0 )
76     {
77         msg_Err( p_aout, "cannot initialize SDL (%s)", SDL_GetError() );
78         return( 1 );
79     }
80
81     return( 0 );
82 }
83
84 /*****************************************************************************
85  * SetFormat: reset the audio device and sets its format
86  *****************************************************************************/
87 static int SetFormat( aout_instance_t *p_aout )
88 {
89     /* TODO: finish and clean this */
90     SDL_AudioSpec desired;
91
92     desired.freq       = p_aout->output.output.i_rate;
93     desired.format     = AUDIO_S16SYS;
94     desired.channels   = p_aout->output.output.i_channels;
95     desired.callback   = SDLCallback;
96     desired.userdata   = p_aout;
97     desired.samples    = DEFAULT_FRAME_SIZE;
98
99     /* Open the sound device - FIXME : get the "natural" paramaters */
100     if( SDL_OpenAudio( &desired, NULL ) < 0 )
101     {
102         return -1;
103     }
104
105     p_aout->output.output.i_format = AOUT_FMT_S16_NE;
106     p_aout->output.i_nb_samples = DEFAULT_FRAME_SIZE;
107
108     SDL_PauseAudio( 0 );
109
110     return 0;
111 }
112
113 /*****************************************************************************
114  * Play: play a sound samples buffer
115  *****************************************************************************/
116 static void Play( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
117 {
118     SDL_LockAudio();                                     /* Stop callbacking */
119
120     aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
121
122     SDL_UnlockAudio();                                  /* go on callbacking */
123 }
124
125 /*****************************************************************************
126  * CloseAudio: close the audio device
127  *****************************************************************************/
128 void E_(CloseAudio) ( aout_instance_t *p_aout )
129 {
130     SDL_PauseAudio( 1 );
131
132     SDL_CloseAudio();
133
134     SDL_QuitSubSystem( SDL_INIT_AUDIO );
135 }
136
137 /*****************************************************************************
138  * SDLCallback: what to do once SDL has played sound samples
139  *****************************************************************************/
140 static void SDLCallback( void * _p_aout, byte_t * p_stream, int i_len )
141 {
142     aout_instance_t * p_aout = (aout_instance_t *)_p_aout;
143     /* FIXME : take into account SDL latency instead of mdate() */
144     aout_buffer_t * p_buffer = aout_OutputNextBuffer( p_aout, mdate() );
145
146     if ( i_len != DEFAULT_FRAME_SIZE * sizeof(s16)
147                     * p_aout->output.output.i_channels )
148     {
149         msg_Err( p_aout, "SDL doesn't know its buffer size (%d)", i_len );
150     }
151
152     if ( p_buffer != NULL )
153     {
154         p_aout->p_vlc->pf_memcpy( p_stream, p_buffer->p_buffer, i_len );
155         aout_BufferFree( p_buffer );
156     }
157     else
158     {
159         memset( p_stream, 0, i_len );
160     }
161 }
162