Skip to content

Latest commit

 

History

History
435 lines (378 loc) · 13.1 KB

SDL_alsa_audio.c

File metadata and controls

435 lines (378 loc) · 13.1 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Jan 4, 2004
Jan 4, 2004
3
Copyright (C) 1997-2004 Sam Lantinga
Apr 26, 2001
Apr 26, 2001
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Apr 26, 2001
Apr 26, 2001
21
22
23
24
25
26
27
*/
/* Allow access to a raw mixing buffer */
#include <sys/types.h>
Feb 7, 2006
Feb 7, 2006
28
#include <signal.h> /* For kill() */
Apr 26, 2001
Apr 26, 2001
29
30
#include "SDL_timer.h"
Feb 16, 2006
Feb 16, 2006
31
32
33
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
Apr 26, 2001
Apr 26, 2001
34
35
#include "SDL_alsa_audio.h"
Feb 16, 2006
Feb 16, 2006
36
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
Mar 2, 2004
Mar 2, 2004
37
38
39
40
41
42
43
44
#include <dlfcn.h>
#include "SDL_name.h"
#include "SDL_loadso.h"
#else
#define SDL_NAME(X) X
#endif
Apr 26, 2001
Apr 26, 2001
45
46
47
/* The tag name used by ALSA audio */
#define DRIVER_NAME "alsa"
Apr 15, 2002
Apr 15, 2002
48
/* The default ALSA audio driver */
Jan 4, 2004
Jan 4, 2004
49
#define DEFAULT_DEVICE "default"
Apr 26, 2001
Apr 26, 2001
50
51
/* Audio driver functions */
Apr 15, 2002
Apr 15, 2002
52
53
54
55
56
57
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec);
static void ALSA_WaitAudio(_THIS);
static void ALSA_PlayAudio(_THIS);
static Uint8 *ALSA_GetAudioBuf(_THIS);
static void ALSA_CloseAudio(_THIS);
Feb 16, 2006
Feb 16, 2006
58
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
Mar 2, 2004
Mar 2, 2004
59
Feb 16, 2006
Feb 16, 2006
60
static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC;
Mar 2, 2004
Mar 2, 2004
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
static void *alsa_handle = NULL;
static int alsa_loaded = 0;
static int (*SDL_snd_pcm_open)(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);
static int (*SDL_NAME(snd_pcm_open))(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);
static int (*SDL_NAME(snd_pcm_close))(snd_pcm_t *pcm);
static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_writei))(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
static int (*SDL_NAME(snd_pcm_resume))(snd_pcm_t *pcm);
static int (*SDL_NAME(snd_pcm_prepare))(snd_pcm_t *pcm);
static int (*SDL_NAME(snd_pcm_drain))(snd_pcm_t *pcm);
static const char *(*SDL_NAME(snd_strerror))(int errnum);
static size_t (*SDL_NAME(snd_pcm_hw_params_sizeof))(void);
static int (*SDL_NAME(snd_pcm_hw_params_any))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
static int (*SDL_NAME(snd_pcm_hw_params_set_access))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access);
static int (*SDL_NAME(snd_pcm_hw_params_set_format))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
static int (*SDL_NAME(snd_pcm_hw_params_set_channels))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
static int (*SDL_NAME(snd_pcm_hw_params_get_channels))(const snd_pcm_hw_params_t *params);
static unsigned int (*SDL_NAME(snd_pcm_hw_params_set_rate_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
static snd_pcm_uframes_t (*SDL_NAME(snd_pcm_hw_params_set_period_size_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir);
static unsigned int (*SDL_NAME(snd_pcm_hw_params_set_periods_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
static int (*SDL_NAME(snd_pcm_hw_params))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
static int (*SDL_NAME(snd_pcm_nonblock))(snd_pcm_t *pcm, int nonblock);
#define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof)
Oct 20, 2005
Oct 20, 2005
85
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
Mar 2, 2004
Mar 2, 2004
86
87
88
89
static struct {
const char *name;
void **func;
} alsa_functions[] = {
Oct 20, 2005
Oct 20, 2005
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
{ "snd_pcm_open", (void**)(char*)&SDL_NAME(snd_pcm_open) },
{ "snd_pcm_close", (void**)(char*)&SDL_NAME(snd_pcm_close) },
{ "snd_pcm_writei", (void**)(char*)&SDL_NAME(snd_pcm_writei) },
{ "snd_pcm_resume", (void**)(char*)&SDL_NAME(snd_pcm_resume) },
{ "snd_pcm_prepare", (void**)(char*)&SDL_NAME(snd_pcm_prepare) },
{ "snd_pcm_drain", (void**)(char*)&SDL_NAME(snd_pcm_drain) },
{ "snd_strerror", (void**)(char*)&SDL_NAME(snd_strerror) },
{ "snd_pcm_hw_params_sizeof", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_sizeof) },
{ "snd_pcm_hw_params_any", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_any) },
{ "snd_pcm_hw_params_set_access", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_access) },
{ "snd_pcm_hw_params_set_format", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_format) },
{ "snd_pcm_hw_params_set_channels", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_channels) },
{ "snd_pcm_hw_params_get_channels", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_channels) },
{ "snd_pcm_hw_params_set_rate_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_rate_near) },
{ "snd_pcm_hw_params_set_period_size_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_period_size_near) },
{ "snd_pcm_hw_params_set_periods_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_periods_near) },
{ "snd_pcm_hw_params", (void**)(char*)&SDL_NAME(snd_pcm_hw_params) },
{ "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) },
Mar 2, 2004
Mar 2, 2004
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
};
static void UnloadALSALibrary(void) {
if (alsa_loaded) {
/* SDL_UnloadObject(alsa_handle);*/
dlclose(alsa_handle);
alsa_handle = NULL;
alsa_loaded = 0;
}
}
static int LoadALSALibrary(void) {
int i, retval = -1;
/* alsa_handle = SDL_LoadObject(alsa_library);*/
alsa_handle = dlopen(alsa_library,RTLD_NOW);
if (alsa_handle) {
alsa_loaded = 1;
retval = 0;
Feb 19, 2006
Feb 19, 2006
127
for (i = 0; i < SDL_arraysize(alsa_functions); i++) {
Mar 2, 2004
Mar 2, 2004
128
/* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/
Feb 16, 2006
Feb 16, 2006
129
#if HAVE_DLVSYM
Mar 2, 2004
Mar 2, 2004
130
*alsa_functions[i].func = dlvsym(alsa_handle,alsa_functions[i].name,"ALSA_0.9");
Aug 21, 2004
Aug 21, 2004
131
132
133
if (!*alsa_functions[i].func)
#endif
*alsa_functions[i].func = dlsym(alsa_handle,alsa_functions[i].name);
Mar 2, 2004
Mar 2, 2004
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
if (!*alsa_functions[i].func) {
retval = -1;
UnloadALSALibrary();
break;
}
}
}
return retval;
}
#else
static void UnloadALSALibrary(void) {
return;
}
static int LoadALSALibrary(void) {
return 0;
}
Feb 16, 2006
Feb 16, 2006
154
#endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */
Mar 2, 2004
Mar 2, 2004
155
Aug 21, 2004
Aug 21, 2004
156
static const char *get_audio_device(int channels)
Apr 26, 2001
Apr 26, 2001
157
{
Apr 15, 2002
Apr 15, 2002
158
159
const char *device;
Feb 7, 2006
Feb 7, 2006
160
device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */
Apr 15, 2002
Apr 15, 2002
161
if ( device == NULL ) {
Aug 21, 2004
Aug 21, 2004
162
163
164
if (channels == 6) device = "surround51";
else if (channels == 4) device = "surround40";
else device = DEFAULT_DEVICE;
Apr 15, 2002
Apr 15, 2002
165
166
}
return device;
Apr 26, 2001
Apr 26, 2001
167
168
169
170
171
172
173
}
/* Audio driver bootstrap functions */
static int Audio_Available(void)
{
int available;
Apr 15, 2002
Apr 15, 2002
174
int status;
Apr 26, 2001
Apr 26, 2001
175
176
177
snd_pcm_t *handle;
available = 0;
Mar 2, 2004
Mar 2, 2004
178
179
180
if (LoadALSALibrary() < 0) {
return available;
}
Aug 21, 2004
Aug 21, 2004
181
status = SDL_NAME(snd_pcm_open)(&handle, get_audio_device(2), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
Apr 15, 2002
Apr 15, 2002
182
183
if ( status >= 0 ) {
available = 1;
Mar 2, 2004
Mar 2, 2004
184
SDL_NAME(snd_pcm_close)(handle);
Apr 26, 2001
Apr 26, 2001
185
}
Mar 2, 2004
Mar 2, 2004
186
UnloadALSALibrary();
Apr 26, 2001
Apr 26, 2001
187
188
189
190
191
return(available);
}
static void Audio_DeleteDevice(SDL_AudioDevice *device)
{
Feb 7, 2006
Feb 7, 2006
192
193
SDL_free(device->hidden);
SDL_free(device);
Mar 2, 2004
Mar 2, 2004
194
UnloadALSALibrary();
Apr 26, 2001
Apr 26, 2001
195
196
197
198
199
200
201
}
static SDL_AudioDevice *Audio_CreateDevice(int devindex)
{
SDL_AudioDevice *this;
/* Initialize all variables that we clean on shutdown */
Mar 2, 2004
Mar 2, 2004
202
LoadALSALibrary();
Feb 7, 2006
Feb 7, 2006
203
this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));
Apr 26, 2001
Apr 26, 2001
204
if ( this ) {
Feb 7, 2006
Feb 7, 2006
205
SDL_memset(this, 0, (sizeof *this));
Apr 26, 2001
Apr 26, 2001
206
this->hidden = (struct SDL_PrivateAudioData *)
Feb 7, 2006
Feb 7, 2006
207
SDL_malloc((sizeof *this->hidden));
Apr 26, 2001
Apr 26, 2001
208
209
210
211
}
if ( (this == NULL) || (this->hidden == NULL) ) {
SDL_OutOfMemory();
if ( this ) {
Feb 7, 2006
Feb 7, 2006
212
SDL_free(this);
Apr 26, 2001
Apr 26, 2001
213
214
215
}
return(0);
}
Feb 7, 2006
Feb 7, 2006
216
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
Apr 26, 2001
Apr 26, 2001
217
218
/* Set the function pointers */
Apr 15, 2002
Apr 15, 2002
219
220
221
222
223
this->OpenAudio = ALSA_OpenAudio;
this->WaitAudio = ALSA_WaitAudio;
this->PlayAudio = ALSA_PlayAudio;
this->GetAudioBuf = ALSA_GetAudioBuf;
this->CloseAudio = ALSA_CloseAudio;
Apr 26, 2001
Apr 26, 2001
224
225
226
227
228
229
230
this->free = Audio_DeleteDevice;
return this;
}
AudioBootStrap ALSA_bootstrap = {
Apr 15, 2002
Apr 15, 2002
231
DRIVER_NAME, "ALSA 0.9 PCM audio",
Apr 26, 2001
Apr 26, 2001
232
233
234
235
Audio_Available, Audio_CreateDevice
};
/* This function waits until it is possible to write a full sound buffer */
Apr 15, 2002
Apr 15, 2002
236
static void ALSA_WaitAudio(_THIS)
Apr 26, 2001
Apr 26, 2001
237
238
239
240
241
242
243
244
245
246
247
248
249
250
{
/* Check to see if the thread-parent process is still alive */
{ static int cnt = 0;
/* Note that this only works with thread implementations
that use a different process id for each thread.
*/
if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */
if ( kill(parent, 0) < 0 ) {
this->enabled = 0;
}
}
}
}
Apr 15, 2002
Apr 15, 2002
251
static void ALSA_PlayAudio(_THIS)
Apr 26, 2001
Apr 26, 2001
252
{
Apr 15, 2002
Apr 15, 2002
253
254
255
int status;
int sample_len;
signed short *sample_buf;
Jan 4, 2004
Jan 4, 2004
256
Apr 15, 2002
Apr 15, 2002
257
258
259
sample_len = this->spec.samples;
sample_buf = (signed short *)mixbuf;
while ( sample_len > 0 ) {
Mar 2, 2004
Mar 2, 2004
260
status = SDL_NAME(snd_pcm_writei)(pcm_handle, sample_buf, sample_len);
Apr 15, 2002
Apr 15, 2002
261
262
if ( status < 0 ) {
if ( status == -EAGAIN ) {
Jan 4, 2004
Jan 4, 2004
263
SDL_Delay(1);
Apr 15, 2002
Apr 15, 2002
264
265
266
267
continue;
}
if ( status == -ESTRPIPE ) {
do {
Jan 4, 2004
Jan 4, 2004
268
SDL_Delay(1);
Mar 2, 2004
Mar 2, 2004
269
status = SDL_NAME(snd_pcm_resume)(pcm_handle);
Apr 15, 2002
Apr 15, 2002
270
271
272
} while ( status == -EAGAIN );
}
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
273
status = SDL_NAME(snd_pcm_prepare)(pcm_handle);
Apr 15, 2002
Apr 15, 2002
274
275
276
277
278
}
if ( status < 0 ) {
/* Hmm, not much we can do - abort */
this->enabled = 0;
return;
Apr 26, 2001
Apr 26, 2001
279
}
Apr 15, 2002
Apr 15, 2002
280
continue;
Apr 26, 2001
Apr 26, 2001
281
}
Apr 15, 2002
Apr 15, 2002
282
283
sample_buf += status * this->spec.channels;
sample_len -= status;
Apr 26, 2001
Apr 26, 2001
284
285
286
}
}
Apr 15, 2002
Apr 15, 2002
287
static Uint8 *ALSA_GetAudioBuf(_THIS)
Apr 26, 2001
Apr 26, 2001
288
{
Apr 15, 2002
Apr 15, 2002
289
return(mixbuf);
Apr 26, 2001
Apr 26, 2001
290
291
}
Apr 15, 2002
Apr 15, 2002
292
static void ALSA_CloseAudio(_THIS)
Apr 26, 2001
Apr 26, 2001
293
{
Apr 15, 2002
Apr 15, 2002
294
295
296
if ( mixbuf != NULL ) {
SDL_FreeAudioMem(mixbuf);
mixbuf = NULL;
Apr 26, 2001
Apr 26, 2001
297
}
Apr 15, 2002
Apr 15, 2002
298
if ( pcm_handle ) {
Mar 2, 2004
Mar 2, 2004
299
300
SDL_NAME(snd_pcm_drain)(pcm_handle);
SDL_NAME(snd_pcm_close)(pcm_handle);
Apr 15, 2002
Apr 15, 2002
301
pcm_handle = NULL;
Apr 26, 2001
Apr 26, 2001
302
303
304
}
}
Apr 15, 2002
Apr 15, 2002
305
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
Apr 26, 2001
Apr 26, 2001
306
{
Apr 15, 2002
Apr 15, 2002
307
308
309
310
311
int status;
snd_pcm_hw_params_t *params;
snd_pcm_format_t format;
snd_pcm_uframes_t frames;
Uint16 test_format;
Apr 26, 2001
Apr 26, 2001
312
313
/* Open the audio device */
Aug 21, 2004
Aug 21, 2004
314
315
316
/* Name of device should depend on # channels in spec */
status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(spec->channels), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
Apr 15, 2002
Apr 15, 2002
317
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
318
SDL_SetError("Couldn't open audio device: %s", SDL_NAME(snd_strerror)(status));
Apr 26, 2001
Apr 26, 2001
319
320
321
return(-1);
}
Apr 15, 2002
Apr 15, 2002
322
323
/* Figure out what the hardware is capable of */
snd_pcm_hw_params_alloca(&params);
Mar 2, 2004
Mar 2, 2004
324
status = SDL_NAME(snd_pcm_hw_params_any)(pcm_handle, params);
Apr 15, 2002
Apr 15, 2002
325
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
326
SDL_SetError("Couldn't get hardware config: %s", SDL_NAME(snd_strerror)(status));
Apr 15, 2002
Apr 15, 2002
327
328
329
ALSA_CloseAudio(this);
return(-1);
}
Apr 26, 2001
Apr 26, 2001
330
Apr 15, 2002
Apr 15, 2002
331
/* SDL only uses interleaved sample output */
Mar 2, 2004
Mar 2, 2004
332
status = SDL_NAME(snd_pcm_hw_params_set_access)(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
Apr 15, 2002
Apr 15, 2002
333
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
334
SDL_SetError("Couldn't set interleaved access: %s", SDL_NAME(snd_strerror)(status));
Apr 15, 2002
Apr 15, 2002
335
336
337
ALSA_CloseAudio(this);
return(-1);
}
Apr 26, 2001
Apr 26, 2001
338
339
/* Try for a closest match on audio format */
Apr 15, 2002
Apr 15, 2002
340
status = -1;
Apr 26, 2001
Apr 26, 2001
341
for ( test_format = SDL_FirstAudioFormat(spec->format);
Apr 15, 2002
Apr 15, 2002
342
343
test_format && (status < 0); ) {
switch ( test_format ) {
Apr 26, 2001
Apr 26, 2001
344
case AUDIO_U8:
Apr 15, 2002
Apr 15, 2002
345
format = SND_PCM_FORMAT_U8;
Apr 26, 2001
Apr 26, 2001
346
347
break;
case AUDIO_S8:
Apr 15, 2002
Apr 15, 2002
348
format = SND_PCM_FORMAT_S8;
Apr 26, 2001
Apr 26, 2001
349
350
break;
case AUDIO_S16LSB:
Apr 15, 2002
Apr 15, 2002
351
format = SND_PCM_FORMAT_S16_LE;
Apr 26, 2001
Apr 26, 2001
352
353
break;
case AUDIO_S16MSB:
Apr 15, 2002
Apr 15, 2002
354
format = SND_PCM_FORMAT_S16_BE;
Apr 26, 2001
Apr 26, 2001
355
356
break;
case AUDIO_U16LSB:
Apr 15, 2002
Apr 15, 2002
357
format = SND_PCM_FORMAT_U16_LE;
Apr 26, 2001
Apr 26, 2001
358
359
break;
case AUDIO_U16MSB:
Apr 15, 2002
Apr 15, 2002
360
format = SND_PCM_FORMAT_U16_BE;
Apr 26, 2001
Apr 26, 2001
361
362
break;
default:
Apr 15, 2002
Apr 15, 2002
363
format = 0;
Apr 26, 2001
Apr 26, 2001
364
365
break;
}
Apr 15, 2002
Apr 15, 2002
366
if ( format != 0 ) {
Mar 2, 2004
Mar 2, 2004
367
status = SDL_NAME(snd_pcm_hw_params_set_format)(pcm_handle, params, format);
Apr 15, 2002
Apr 15, 2002
368
369
}
if ( status < 0 ) {
Apr 26, 2001
Apr 26, 2001
370
371
372
test_format = SDL_NextAudioFormat();
}
}
Apr 15, 2002
Apr 15, 2002
373
if ( status < 0 ) {
Apr 26, 2001
Apr 26, 2001
374
SDL_SetError("Couldn't find any hardware audio formats");
Apr 15, 2002
Apr 15, 2002
375
ALSA_CloseAudio(this);
Apr 26, 2001
Apr 26, 2001
376
377
378
379
return(-1);
}
spec->format = test_format;
Apr 15, 2002
Apr 15, 2002
380
/* Set the number of channels */
Mar 2, 2004
Mar 2, 2004
381
status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, params, spec->channels);
Apr 15, 2002
Apr 15, 2002
382
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
383
status = SDL_NAME(snd_pcm_hw_params_get_channels)(params);
Apr 15, 2002
Apr 15, 2002
384
385
386
387
388
389
390
if ( (status <= 0) || (status > 2) ) {
SDL_SetError("Couldn't set audio channels");
ALSA_CloseAudio(this);
return(-1);
}
spec->channels = status;
}
Apr 26, 2001
Apr 26, 2001
391
Apr 15, 2002
Apr 15, 2002
392
/* Set the audio rate */
Mar 2, 2004
Mar 2, 2004
393
status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, params, spec->freq, NULL);
Apr 15, 2002
Apr 15, 2002
394
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
395
SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status));
Apr 15, 2002
Apr 15, 2002
396
397
398
399
400
401
402
ALSA_CloseAudio(this);
return(-1);
}
spec->freq = status;
/* Set the buffer size, in samples */
frames = spec->samples;
Mar 2, 2004
Mar 2, 2004
403
frames = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, params, frames, NULL);
Apr 15, 2002
Apr 15, 2002
404
spec->samples = frames;
Mar 2, 2004
Mar 2, 2004
405
SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, params, 2, NULL);
Apr 15, 2002
Apr 15, 2002
406
407
/* "set" the hardware with the desired parameters */
Mar 2, 2004
Mar 2, 2004
408
status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, params);
Apr 15, 2002
Apr 15, 2002
409
if ( status < 0 ) {
Mar 2, 2004
Mar 2, 2004
410
SDL_SetError("Couldn't set audio parameters: %s", SDL_NAME(snd_strerror)(status));
Apr 15, 2002
Apr 15, 2002
411
ALSA_CloseAudio(this);
Apr 26, 2001
Apr 26, 2001
412
413
414
return(-1);
}
Apr 15, 2002
Apr 15, 2002
415
416
417
418
419
420
421
422
423
/* Calculate the final parameters for this audio specification */
SDL_CalculateAudioSpec(spec);
/* Allocate mixing buffer */
mixlen = spec->size;
mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
if ( mixbuf == NULL ) {
ALSA_CloseAudio(this);
return(-1);
Apr 26, 2001
Apr 26, 2001
424
}
Feb 7, 2006
Feb 7, 2006
425
SDL_memset(mixbuf, spec->silence, spec->size);
Apr 26, 2001
Apr 26, 2001
426
427
428
429
/* Get the parent process id (we're the parent of the audio thread) */
parent = getpid();
Jan 4, 2004
Jan 4, 2004
430
/* Switch to blocking mode for playback */
Mar 2, 2004
Mar 2, 2004
431
SDL_NAME(snd_pcm_nonblock)(pcm_handle, 0);
Jan 4, 2004
Jan 4, 2004
432
Apr 26, 2001
Apr 26, 2001
433
434
435
/* We're ready to rock and roll. :-) */
return(0);
}