Mercurial > sdl-ios-xcode
comparison src/audio/nto/SDL_nto_audio.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | d910939febfa |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
55 #define QSA_NO_WORKAROUNDS 0x00000000 | 55 #define QSA_NO_WORKAROUNDS 0x00000000 |
56 #define QSA_MMAP_WORKAROUND 0x00000001 | 56 #define QSA_MMAP_WORKAROUND 0x00000001 |
57 | 57 |
58 struct BuggyCards | 58 struct BuggyCards |
59 { | 59 { |
60 char* cardname; | 60 char *cardname; |
61 unsigned long bugtype; | 61 unsigned long bugtype; |
62 }; | 62 }; |
63 | 63 |
64 #define QSA_WA_CARDS 3 | 64 #define QSA_WA_CARDS 3 |
65 | 65 |
66 struct BuggyCards buggycards[QSA_WA_CARDS]= | 66 struct BuggyCards buggycards[QSA_WA_CARDS] = { |
67 { | 67 {"Sound Blaster Live!", QSA_MMAP_WORKAROUND}, |
68 {"Sound Blaster Live!", QSA_MMAP_WORKAROUND}, | 68 {"Vortex 8820", QSA_MMAP_WORKAROUND}, |
69 {"Vortex 8820", QSA_MMAP_WORKAROUND}, | 69 {"Vortex 8830", QSA_MMAP_WORKAROUND}, |
70 {"Vortex 8830", QSA_MMAP_WORKAROUND}, | |
71 }; | 70 }; |
72 | 71 |
73 /* Audio driver functions */ | 72 /* Audio driver functions */ |
74 static void NTO_ThreadInit(_THIS); | 73 static void NTO_ThreadInit (_THIS); |
75 static int NTO_OpenAudio(_THIS, SDL_AudioSpec* spec); | 74 static int NTO_OpenAudio (_THIS, SDL_AudioSpec * spec); |
76 static void NTO_WaitAudio(_THIS); | 75 static void NTO_WaitAudio (_THIS); |
77 static void NTO_PlayAudio(_THIS); | 76 static void NTO_PlayAudio (_THIS); |
78 static Uint8* NTO_GetAudioBuf(_THIS); | 77 static Uint8 *NTO_GetAudioBuf (_THIS); |
79 static void NTO_CloseAudio(_THIS); | 78 static void NTO_CloseAudio (_THIS); |
80 | 79 |
81 /* card names check to apply the workarounds */ | 80 /* card names check to apply the workarounds */ |
82 static int NTO_CheckBuggyCards(_THIS, unsigned long checkfor) | 81 static int |
82 NTO_CheckBuggyCards (_THIS, unsigned long checkfor) | |
83 { | 83 { |
84 char scardname[33]; | 84 char scardname[33]; |
85 int it; | 85 int it; |
86 | 86 |
87 if (snd_card_get_name(cardno, scardname, 32)<0) | 87 if (snd_card_get_name (cardno, scardname, 32) < 0) { |
88 { | |
89 return 0; | 88 return 0; |
90 } | 89 } |
91 | 90 |
92 for (it=0; it<QSA_WA_CARDS; it++) | 91 for (it = 0; it < QSA_WA_CARDS; it++) { |
93 { | 92 if (SDL_strcmp (buggycards[it].cardname, scardname) == 0) { |
94 if (SDL_strcmp(buggycards[it].cardname, scardname)==0) | 93 if (buggycards[it].bugtype == checkfor) { |
95 { | 94 return 1; |
96 if (buggycards[it].bugtype==checkfor) | 95 } |
97 { | 96 } |
98 return 1; | |
99 } | |
100 } | |
101 } | 97 } |
102 | 98 |
103 return 0; | 99 return 0; |
104 } | 100 } |
105 | 101 |
106 static void NTO_ThreadInit(_THIS) | 102 static void |
107 { | 103 NTO_ThreadInit (_THIS) |
108 int status; | 104 { |
109 struct sched_param param; | 105 int status; |
110 | 106 struct sched_param param; |
111 /* increasing default 10 priority to 25 to avoid jerky sound */ | 107 |
112 status=SchedGet(0, 0, ¶m); | 108 /* increasing default 10 priority to 25 to avoid jerky sound */ |
113 param.sched_priority=param.sched_curpriority+15; | 109 status = SchedGet (0, 0, ¶m); |
114 status=SchedSet(0, 0, SCHED_NOCHANGE, ¶m); | 110 param.sched_priority = param.sched_curpriority + 15; |
111 status = SchedSet (0, 0, SCHED_NOCHANGE, ¶m); | |
115 } | 112 } |
116 | 113 |
117 /* PCM transfer channel parameters initialize function */ | 114 /* PCM transfer channel parameters initialize function */ |
118 static void NTO_InitAudioParams(snd_pcm_channel_params_t* cpars) | 115 static void |
119 { | 116 NTO_InitAudioParams (snd_pcm_channel_params_t * cpars) |
120 SDL_memset(cpars, 0, sizeof(snd_pcm_channel_params_t)); | 117 { |
118 SDL_memset (cpars, 0, sizeof (snd_pcm_channel_params_t)); | |
121 | 119 |
122 cpars->channel = SND_PCM_CHANNEL_PLAYBACK; | 120 cpars->channel = SND_PCM_CHANNEL_PLAYBACK; |
123 cpars->mode = SND_PCM_MODE_BLOCK; | 121 cpars->mode = SND_PCM_MODE_BLOCK; |
124 cpars->start_mode = SND_PCM_START_DATA; | 122 cpars->start_mode = SND_PCM_START_DATA; |
125 cpars->stop_mode = SND_PCM_STOP_STOP; | 123 cpars->stop_mode = SND_PCM_STOP_STOP; |
126 cpars->format.format = SND_PCM_SFMT_S16_LE; | 124 cpars->format.format = SND_PCM_SFMT_S16_LE; |
127 cpars->format.interleave = 1; | 125 cpars->format.interleave = 1; |
128 cpars->format.rate = DEFAULT_CPARAMS_RATE; | 126 cpars->format.rate = DEFAULT_CPARAMS_RATE; |
129 cpars->format.voices = DEFAULT_CPARAMS_VOICES; | 127 cpars->format.voices = DEFAULT_CPARAMS_VOICES; |
130 cpars->buf.block.frag_size = DEFAULT_CPARAMS_FRAG_SIZE; | 128 cpars->buf.block.frag_size = DEFAULT_CPARAMS_FRAG_SIZE; |
131 cpars->buf.block.frags_min = DEFAULT_CPARAMS_FRAGS_MIN; | 129 cpars->buf.block.frags_min = DEFAULT_CPARAMS_FRAGS_MIN; |
132 cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; | 130 cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; |
133 } | 131 } |
134 | 132 |
135 static int NTO_AudioAvailable(void) | 133 static int |
134 NTO_AudioAvailable (void) | |
136 { | 135 { |
137 /* See if we can open a nonblocking channel. | 136 /* See if we can open a nonblocking channel. |
138 Return value '1' means we can. | 137 Return value '1' means we can. |
139 Return value '0' means we cannot. */ | 138 Return value '0' means we cannot. */ |
140 | 139 |
141 int available; | 140 int available; |
142 int rval; | 141 int rval; |
143 snd_pcm_t* handle; | 142 snd_pcm_t *handle; |
144 | 143 |
145 available = 0; | 144 available = 0; |
146 handle = NULL; | 145 handle = NULL; |
147 | 146 |
148 rval = snd_pcm_open_preferred(&handle, NULL, NULL, OPEN_FLAGS); | 147 rval = snd_pcm_open_preferred (&handle, NULL, NULL, OPEN_FLAGS); |
149 | 148 |
150 if (rval >= 0) | 149 if (rval >= 0) { |
151 { | |
152 available = 1; | 150 available = 1; |
153 | 151 |
154 if ((rval = snd_pcm_close(handle)) < 0) | 152 if ((rval = snd_pcm_close (handle)) < 0) { |
155 { | 153 SDL_SetError |
156 SDL_SetError("NTO_AudioAvailable(): snd_pcm_close failed: %s\n", snd_strerror(rval)); | 154 ("NTO_AudioAvailable(): snd_pcm_close failed: %s\n", |
155 snd_strerror (rval)); | |
157 available = 0; | 156 available = 0; |
158 } | 157 } |
159 } | 158 } else { |
160 else | 159 SDL_SetError |
161 { | 160 ("NTO_AudioAvailable(): there are no available audio devices.\n"); |
162 SDL_SetError("NTO_AudioAvailable(): there are no available audio devices.\n"); | |
163 } | 161 } |
164 | 162 |
165 return (available); | 163 return (available); |
166 } | 164 } |
167 | 165 |
168 static void NTO_DeleteAudioDevice(SDL_AudioDevice *device) | 166 static void |
169 { | 167 NTO_DeleteAudioDevice (SDL_AudioDevice * device) |
170 if ((device)&&(device->hidden)) | 168 { |
171 { | 169 if ((device) && (device->hidden)) { |
172 SDL_free(device->hidden); | 170 SDL_free (device->hidden); |
173 } | 171 } |
174 if (device) | 172 if (device) { |
175 { | 173 SDL_free (device); |
176 SDL_free(device); | 174 } |
177 } | 175 } |
178 } | 176 |
179 | 177 static SDL_AudioDevice * |
180 static SDL_AudioDevice* NTO_CreateAudioDevice(int devindex) | 178 NTO_CreateAudioDevice (int devindex) |
181 { | 179 { |
182 SDL_AudioDevice *this; | 180 SDL_AudioDevice *this; |
183 | 181 |
184 /* Initialize all variables that we clean on shutdown */ | 182 /* Initialize all variables that we clean on shutdown */ |
185 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | 183 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); |
186 if (this) | 184 if (this) { |
187 { | 185 SDL_memset (this, 0, sizeof (SDL_AudioDevice)); |
188 SDL_memset(this, 0, sizeof(SDL_AudioDevice)); | 186 this->hidden = (struct SDL_PrivateAudioData *) |
189 this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(struct SDL_PrivateAudioData)); | 187 SDL_malloc (sizeof (struct SDL_PrivateAudioData)); |
190 } | 188 } |
191 if ((this == NULL) || (this->hidden == NULL)) | 189 if ((this == NULL) || (this->hidden == NULL)) { |
192 { | 190 SDL_OutOfMemory (); |
193 SDL_OutOfMemory(); | 191 if (this) { |
194 if (this) | 192 SDL_free (this); |
195 { | 193 } |
196 SDL_free(this); | |
197 } | |
198 return (0); | 194 return (0); |
199 } | 195 } |
200 SDL_memset(this->hidden, 0, sizeof(struct SDL_PrivateAudioData)); | 196 SDL_memset (this->hidden, 0, sizeof (struct SDL_PrivateAudioData)); |
201 audio_handle = NULL; | 197 audio_handle = NULL; |
202 | 198 |
203 /* Set the function pointers */ | 199 /* Set the function pointers */ |
204 this->ThreadInit = NTO_ThreadInit; | 200 this->ThreadInit = NTO_ThreadInit; |
205 this->OpenAudio = NTO_OpenAudio; | 201 this->OpenAudio = NTO_OpenAudio; |
211 this->free = NTO_DeleteAudioDevice; | 207 this->free = NTO_DeleteAudioDevice; |
212 | 208 |
213 return this; | 209 return this; |
214 } | 210 } |
215 | 211 |
216 AudioBootStrap QNXNTOAUDIO_bootstrap = | 212 AudioBootStrap QNXNTOAUDIO_bootstrap = { |
217 { | |
218 DRIVER_NAME, "QNX6 QSA-NTO Audio", | 213 DRIVER_NAME, "QNX6 QSA-NTO Audio", |
219 NTO_AudioAvailable, | 214 NTO_AudioAvailable, |
220 NTO_CreateAudioDevice | 215 NTO_CreateAudioDevice |
221 }; | 216 }; |
222 | 217 |
223 /* This function waits until it is possible to write a full sound buffer */ | 218 /* This function waits until it is possible to write a full sound buffer */ |
224 static void NTO_WaitAudio(_THIS) | 219 static void |
220 NTO_WaitAudio (_THIS) | |
225 { | 221 { |
226 fd_set wfds; | 222 fd_set wfds; |
227 int selectret; | 223 int selectret; |
228 | 224 |
229 FD_ZERO(&wfds); | 225 FD_ZERO (&wfds); |
230 FD_SET(audio_fd, &wfds); | 226 FD_SET (audio_fd, &wfds); |
231 | 227 |
232 do { | 228 do { |
233 selectret=select(audio_fd + 1, NULL, &wfds, NULL, NULL); | 229 selectret = select (audio_fd + 1, NULL, &wfds, NULL, NULL); |
234 switch (selectret) | 230 switch (selectret) { |
235 { | 231 case -1: |
236 case -1: | 232 case 0: |
237 case 0: SDL_SetError("NTO_WaitAudio(): select() failed: %s\n", strerror(errno)); | 233 SDL_SetError ("NTO_WaitAudio(): select() failed: %s\n", |
238 return; | 234 strerror (errno)); |
239 default: if (FD_ISSET(audio_fd, &wfds)) | 235 return; |
240 { | 236 default: |
241 return; | 237 if (FD_ISSET (audio_fd, &wfds)) { |
242 } | 238 return; |
243 break; | 239 } |
244 } | 240 break; |
245 } while(1); | 241 } |
246 } | 242 } |
247 | 243 while (1); |
248 static void NTO_PlayAudio(_THIS) | 244 } |
245 | |
246 static void | |
247 NTO_PlayAudio (_THIS) | |
249 { | 248 { |
250 int written, rval; | 249 int written, rval; |
251 int towrite; | 250 int towrite; |
252 void* pcmbuffer; | 251 void *pcmbuffer; |
253 | 252 |
254 if (!this->enabled) | 253 if (!this->enabled) { |
255 { | |
256 return; | 254 return; |
257 } | 255 } |
258 | 256 |
259 towrite = this->spec.size; | 257 towrite = this->spec.size; |
260 pcmbuffer = pcm_buf; | 258 pcmbuffer = pcm_buf; |
261 | 259 |
262 /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ | 260 /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ |
263 do { | 261 do { |
264 written = snd_pcm_plugin_write(audio_handle, pcm_buf, towrite); | 262 written = snd_pcm_plugin_write (audio_handle, pcm_buf, towrite); |
265 if (written != towrite) | 263 if (written != towrite) { |
266 { | 264 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { |
267 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) | |
268 { | |
269 /* Let a little CPU time go by and try to write again */ | 265 /* Let a little CPU time go by and try to write again */ |
270 SDL_Delay(1); | 266 SDL_Delay (1); |
271 /* if we wrote some data */ | 267 /* if we wrote some data */ |
272 towrite -= written; | 268 towrite -= written; |
273 pcmbuffer += written * this->spec.channels; | 269 pcmbuffer += written * this->spec.channels; |
274 continue; | 270 continue; |
275 } | 271 } else { |
276 else | 272 if ((errno == EINVAL) || (errno == EIO)) { |
277 { | 273 SDL_memset (&cstatus, 0, sizeof (cstatus)); |
278 if ((errno == EINVAL) || (errno == EIO)) | |
279 { | |
280 SDL_memset(&cstatus, 0, sizeof(cstatus)); | |
281 cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; | 274 cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; |
282 if ((rval = snd_pcm_plugin_status(audio_handle, &cstatus)) < 0) | 275 if ((rval = |
283 { | 276 snd_pcm_plugin_status (audio_handle, |
284 SDL_SetError("NTO_PlayAudio(): snd_pcm_plugin_status failed: %s\n", snd_strerror(rval)); | 277 &cstatus)) < 0) { |
278 SDL_SetError | |
279 ("NTO_PlayAudio(): snd_pcm_plugin_status failed: %s\n", | |
280 snd_strerror (rval)); | |
285 return; | 281 return; |
286 } | 282 } |
287 if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || (cstatus.status == SND_PCM_STATUS_READY)) | 283 if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) |
288 { | 284 || (cstatus.status == SND_PCM_STATUS_READY)) { |
289 if ((rval = snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) | 285 if ((rval = |
290 { | 286 snd_pcm_plugin_prepare (audio_handle, |
291 SDL_SetError("NTO_PlayAudio(): snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rval)); | 287 SND_PCM_CHANNEL_PLAYBACK)) |
288 < 0) { | |
289 SDL_SetError | |
290 ("NTO_PlayAudio(): snd_pcm_plugin_prepare failed: %s\n", | |
291 snd_strerror (rval)); | |
292 return; | 292 return; |
293 } | 293 } |
294 } | 294 } |
295 continue; | 295 continue; |
296 } | 296 } else { |
297 else | |
298 { | |
299 return; | 297 return; |
300 } | 298 } |
301 } | 299 } |
302 } | 300 } else { |
303 else | |
304 { | |
305 /* we wrote all remaining data */ | 301 /* we wrote all remaining data */ |
306 towrite -= written; | 302 towrite -= written; |
307 pcmbuffer += written * this->spec.channels; | 303 pcmbuffer += written * this->spec.channels; |
308 } | 304 } |
309 } while ((towrite > 0) && (this->enabled)); | 305 } |
306 while ((towrite > 0) && (this->enabled)); | |
310 | 307 |
311 /* If we couldn't write, assume fatal error for now */ | 308 /* If we couldn't write, assume fatal error for now */ |
312 if (towrite != 0) | 309 if (towrite != 0) { |
313 { | |
314 this->enabled = 0; | 310 this->enabled = 0; |
315 } | 311 } |
316 | 312 |
317 return; | 313 return; |
318 } | 314 } |
319 | 315 |
320 static Uint8* NTO_GetAudioBuf(_THIS) | 316 static Uint8 * |
317 NTO_GetAudioBuf (_THIS) | |
321 { | 318 { |
322 return pcm_buf; | 319 return pcm_buf; |
323 } | 320 } |
324 | 321 |
325 static void NTO_CloseAudio(_THIS) | 322 static void |
323 NTO_CloseAudio (_THIS) | |
326 { | 324 { |
327 int rval; | 325 int rval; |
328 | 326 |
329 this->enabled = 0; | 327 this->enabled = 0; |
330 | 328 |
331 if (audio_handle != NULL) | 329 if (audio_handle != NULL) { |
332 { | 330 if ((rval = |
333 if ((rval = snd_pcm_plugin_flush(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) | 331 snd_pcm_plugin_flush (audio_handle, |
334 { | 332 SND_PCM_CHANNEL_PLAYBACK)) < 0) { |
335 SDL_SetError("NTO_CloseAudio(): snd_pcm_plugin_flush failed: %s\n", snd_strerror(rval)); | 333 SDL_SetError |
334 ("NTO_CloseAudio(): snd_pcm_plugin_flush failed: %s\n", | |
335 snd_strerror (rval)); | |
336 return; | 336 return; |
337 } | 337 } |
338 if ((rval = snd_pcm_close(audio_handle)) < 0) | 338 if ((rval = snd_pcm_close (audio_handle)) < 0) { |
339 { | 339 SDL_SetError ("NTO_CloseAudio(): snd_pcm_close failed: %s\n", |
340 SDL_SetError("NTO_CloseAudio(): snd_pcm_close failed: %s\n",snd_strerror(rval)); | 340 snd_strerror (rval)); |
341 return; | 341 return; |
342 } | 342 } |
343 audio_handle = NULL; | 343 audio_handle = NULL; |
344 } | 344 } |
345 } | 345 } |
346 | 346 |
347 static int NTO_OpenAudio(_THIS, SDL_AudioSpec* spec) | 347 static int |
348 NTO_OpenAudio (_THIS, SDL_AudioSpec * spec) | |
348 { | 349 { |
349 int rval; | 350 int rval; |
350 int format; | 351 int format; |
351 Uint16 test_format; | 352 Uint16 test_format; |
352 int found; | 353 int found; |
353 | 354 |
354 audio_handle = NULL; | 355 audio_handle = NULL; |
355 this->enabled = 0; | 356 this->enabled = 0; |
356 | 357 |
357 if (pcm_buf != NULL) | 358 if (pcm_buf != NULL) { |
358 { | 359 SDL_FreeAudioMem (pcm_buf); |
359 SDL_FreeAudioMem(pcm_buf); | |
360 pcm_buf = NULL; | 360 pcm_buf = NULL; |
361 } | 361 } |
362 | 362 |
363 /* initialize channel transfer parameters to default */ | 363 /* initialize channel transfer parameters to default */ |
364 NTO_InitAudioParams(&cparams); | 364 NTO_InitAudioParams (&cparams); |
365 | 365 |
366 /* Open the audio device */ | 366 /* Open the audio device */ |
367 rval = snd_pcm_open_preferred(&audio_handle, &cardno, &deviceno, OPEN_FLAGS); | 367 rval = |
368 if (rval < 0) | 368 snd_pcm_open_preferred (&audio_handle, &cardno, &deviceno, |
369 { | 369 OPEN_FLAGS); |
370 SDL_SetError("NTO_OpenAudio(): snd_pcm_open failed: %s\n", snd_strerror(rval)); | 370 if (rval < 0) { |
371 SDL_SetError ("NTO_OpenAudio(): snd_pcm_open failed: %s\n", | |
372 snd_strerror (rval)); | |
371 return (-1); | 373 return (-1); |
372 } | 374 } |
373 | 375 |
374 if (!NTO_CheckBuggyCards(this, QSA_MMAP_WORKAROUND)) | 376 if (!NTO_CheckBuggyCards (this, QSA_MMAP_WORKAROUND)) { |
375 { | |
376 /* enable count status parameter */ | 377 /* enable count status parameter */ |
377 if ((rval = snd_pcm_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP)) < 0) | 378 if ((rval = |
378 { | 379 snd_pcm_plugin_set_disable (audio_handle, |
379 SDL_SetError("snd_pcm_plugin_set_disable failed: %s\n", snd_strerror(rval)); | 380 PLUGIN_DISABLE_MMAP)) < 0) { |
381 SDL_SetError ("snd_pcm_plugin_set_disable failed: %s\n", | |
382 snd_strerror (rval)); | |
380 return (-1); | 383 return (-1); |
381 } | 384 } |
382 } | 385 } |
383 | 386 |
384 /* Try for a closest match on audio format */ | 387 /* Try for a closest match on audio format */ |
385 format = 0; | 388 format = 0; |
386 /* can't use format as SND_PCM_SFMT_U8 = 0 in nto */ | 389 /* can't use format as SND_PCM_SFMT_U8 = 0 in nto */ |
387 found = 0; | 390 found = 0; |
388 | 391 |
389 for (test_format=SDL_FirstAudioFormat(spec->format); !found ;) | 392 for (test_format = SDL_FirstAudioFormat (spec->format); !found;) { |
390 { | |
391 /* if match found set format to equivalent ALSA format */ | 393 /* if match found set format to equivalent ALSA format */ |
392 switch (test_format) | 394 switch (test_format) { |
393 { | 395 case AUDIO_U8: |
394 case AUDIO_U8: | 396 format = SND_PCM_SFMT_U8; |
395 format = SND_PCM_SFMT_U8; | 397 found = 1; |
396 found = 1; | 398 break; |
397 break; | 399 case AUDIO_S8: |
398 case AUDIO_S8: | 400 format = SND_PCM_SFMT_S8; |
399 format = SND_PCM_SFMT_S8; | 401 found = 1; |
400 found = 1; | 402 break; |
401 break; | 403 case AUDIO_S16LSB: |
402 case AUDIO_S16LSB: | 404 format = SND_PCM_SFMT_S16_LE; |
403 format = SND_PCM_SFMT_S16_LE; | 405 found = 1; |
404 found = 1; | 406 break; |
405 break; | 407 case AUDIO_S16MSB: |
406 case AUDIO_S16MSB: | 408 format = SND_PCM_SFMT_S16_BE; |
407 format = SND_PCM_SFMT_S16_BE; | 409 found = 1; |
408 found = 1; | 410 break; |
409 break; | 411 case AUDIO_U16LSB: |
410 case AUDIO_U16LSB: | 412 format = SND_PCM_SFMT_U16_LE; |
411 format = SND_PCM_SFMT_U16_LE; | 413 found = 1; |
412 found = 1; | 414 break; |
413 break; | 415 case AUDIO_U16MSB: |
414 case AUDIO_U16MSB: | 416 format = SND_PCM_SFMT_U16_BE; |
415 format = SND_PCM_SFMT_U16_BE; | 417 found = 1; |
416 found = 1; | 418 break; |
417 break; | 419 default: |
418 default: | 420 break; |
419 break; | 421 } |
420 } | 422 |
421 | 423 if (!found) { |
422 if (!found) | 424 test_format = SDL_NextAudioFormat (); |
423 { | |
424 test_format = SDL_NextAudioFormat(); | |
425 } | 425 } |
426 } | 426 } |
427 | 427 |
428 /* assumes test_format not 0 on success */ | 428 /* assumes test_format not 0 on success */ |
429 if (test_format == 0) | 429 if (test_format == 0) { |
430 { | 430 SDL_SetError |
431 SDL_SetError("NTO_OpenAudio(): Couldn't find any hardware audio formats"); | 431 ("NTO_OpenAudio(): Couldn't find any hardware audio formats"); |
432 return (-1); | 432 return (-1); |
433 } | 433 } |
434 | 434 |
435 spec->format = test_format; | 435 spec->format = test_format; |
436 | 436 |
437 /* Set the audio format */ | 437 /* Set the audio format */ |
438 cparams.format.format = format; | 438 cparams.format.format = format; |
439 | 439 |
440 /* Set mono or stereo audio (currently only two channels supported) */ | 440 /* Set mono or stereo audio (currently only two channels supported) */ |
441 cparams.format.voices = spec->channels; | 441 cparams.format.voices = spec->channels; |
442 | 442 |
443 /* Set rate */ | 443 /* Set rate */ |
444 cparams.format.rate = spec->freq; | 444 cparams.format.rate = spec->freq; |
445 | 445 |
446 /* Setup the transfer parameters according to cparams */ | 446 /* Setup the transfer parameters according to cparams */ |
447 rval = snd_pcm_plugin_params(audio_handle, &cparams); | 447 rval = snd_pcm_plugin_params (audio_handle, &cparams); |
448 if (rval < 0) | 448 if (rval < 0) { |
449 { | 449 SDL_SetError |
450 SDL_SetError("NTO_OpenAudio(): snd_pcm_channel_params failed: %s\n", snd_strerror(rval)); | 450 ("NTO_OpenAudio(): snd_pcm_channel_params failed: %s\n", |
451 snd_strerror (rval)); | |
451 return (-1); | 452 return (-1); |
452 } | 453 } |
453 | 454 |
454 /* Make sure channel is setup right one last time */ | 455 /* Make sure channel is setup right one last time */ |
455 SDL_memset(&csetup, 0x00, sizeof(csetup)); | 456 SDL_memset (&csetup, 0x00, sizeof (csetup)); |
456 csetup.channel = SND_PCM_CHANNEL_PLAYBACK; | 457 csetup.channel = SND_PCM_CHANNEL_PLAYBACK; |
457 if (snd_pcm_plugin_setup(audio_handle, &csetup) < 0) | 458 if (snd_pcm_plugin_setup (audio_handle, &csetup) < 0) { |
458 { | 459 SDL_SetError ("NTO_OpenAudio(): Unable to setup playback channel\n"); |
459 SDL_SetError("NTO_OpenAudio(): Unable to setup playback channel\n"); | |
460 return -1; | 460 return -1; |
461 } | 461 } |
462 | 462 |
463 | 463 |
464 /* Calculate the final parameters for this audio specification */ | 464 /* Calculate the final parameters for this audio specification */ |
465 SDL_CalculateAudioSpec(spec); | 465 SDL_CalculateAudioSpec (spec); |
466 | 466 |
467 pcm_len = spec->size; | 467 pcm_len = spec->size; |
468 | 468 |
469 if (pcm_len==0) | 469 if (pcm_len == 0) { |
470 { | 470 pcm_len = |
471 pcm_len = csetup.buf.block.frag_size * spec->channels * (snd_pcm_format_width(format)/8); | 471 csetup.buf.block.frag_size * spec->channels * |
472 (snd_pcm_format_width (format) / 8); | |
472 } | 473 } |
473 | 474 |
474 /* Allocate memory to the audio buffer and initialize with silence (Note that | 475 /* Allocate memory to the audio buffer and initialize with silence (Note that |
475 buffer size must be a multiple of fragment size, so find closest multiple) | 476 buffer size must be a multiple of fragment size, so find closest multiple) |
476 */ | 477 */ |
477 pcm_buf = (Uint8*)SDL_AllocAudioMem(pcm_len); | 478 pcm_buf = (Uint8 *) SDL_AllocAudioMem (pcm_len); |
478 if (pcm_buf == NULL) | 479 if (pcm_buf == NULL) { |
479 { | 480 SDL_SetError ("NTO_OpenAudio(): pcm buffer allocation failed\n"); |
480 SDL_SetError("NTO_OpenAudio(): pcm buffer allocation failed\n"); | |
481 return (-1); | 481 return (-1); |
482 } | 482 } |
483 SDL_memset(pcm_buf, spec->silence, pcm_len); | 483 SDL_memset (pcm_buf, spec->silence, pcm_len); |
484 | 484 |
485 /* get the file descriptor */ | 485 /* get the file descriptor */ |
486 if ((audio_fd = snd_pcm_file_descriptor(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) | 486 if ((audio_fd = |
487 { | 487 snd_pcm_file_descriptor (audio_handle, |
488 SDL_SetError("NTO_OpenAudio(): snd_pcm_file_descriptor failed with error code: %s\n", snd_strerror(rval)); | 488 SND_PCM_CHANNEL_PLAYBACK)) < 0) { |
489 SDL_SetError | |
490 ("NTO_OpenAudio(): snd_pcm_file_descriptor failed with error code: %s\n", | |
491 snd_strerror (rval)); | |
489 return (-1); | 492 return (-1); |
490 } | 493 } |
491 | 494 |
492 /* Trigger audio playback */ | 495 /* Trigger audio playback */ |
493 rval = snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK); | 496 rval = snd_pcm_plugin_prepare (audio_handle, SND_PCM_CHANNEL_PLAYBACK); |
494 if (rval < 0) | 497 if (rval < 0) { |
495 { | 498 SDL_SetError ("snd_pcm_plugin_prepare failed: %s\n", |
496 SDL_SetError("snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rval)); | 499 snd_strerror (rval)); |
497 return (-1); | 500 return (-1); |
498 } | 501 } |
499 | 502 |
500 this->enabled = 1; | 503 this->enabled = 1; |
501 | 504 |
502 /* Get the parent process id (we're the parent of the audio thread) */ | 505 /* Get the parent process id (we're the parent of the audio thread) */ |
503 parent = getpid(); | 506 parent = getpid (); |
504 | 507 |
505 /* We're really ready to rock and roll. :-) */ | 508 /* We're really ready to rock and roll. :-) */ |
506 return (0); | 509 return (0); |
507 } | 510 } |
511 | |
512 /* vi: set ts=4 sw=4 expandtab: */ |