~ubuntu-branches/ubuntu/trusty/mpeg4ip/trusty

« back to all changes in this revision

Viewing changes to lib/SDLAudio/src/audio/SDL_audio.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Limonciello
  • Date: 2008-01-12 15:59:56 UTC
  • Revision ID: james.westby@ubuntu.com-20080112155956-1vznw5njidvrh649
Tags: upstream-1.6dfsg
ImportĀ upstreamĀ versionĀ 1.6dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    SDL - Simple DirectMedia Layer
 
3
    Copyright (C) 1997-2004 Sam Lantinga
 
4
 
 
5
    This library is free software; you can redistribute it and/or
 
6
    modify it under the terms of the GNU Library General Public
 
7
    License as published by the Free Software Foundation; either
 
8
    version 2 of the License, or (at your option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
    Library General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Library General Public
 
16
    License along with this library; if not, write to the Free
 
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
    Sam Lantinga
 
20
    slouken@libsdl.org
 
21
*/
 
22
 
 
23
#ifdef SAVE_RCSID
 
24
static char rcsid =
 
25
 "@(#) $Id$";
 
26
#endif
 
27
 
 
28
/* Allow access to a raw mixing buffer */
 
29
#include <stdlib.h>
 
30
#include <stdio.h>
 
31
#include <string.h>
 
32
#include "Our_SDL_audio.h"
 
33
#include "SDL_audio_c.h"
 
34
#include "SDL_audiomem.h"
 
35
#include "SDL_sysaudio.h"
 
36
 
 
37
/* Available audio drivers */
 
38
static AudioBootStrap *bootstrap[] = {
 
39
#ifdef OPENBSD_AUDIO_SUPPORT
 
40
        &OPENBSD_AUDIO_bootstrap_ours,
 
41
#endif
 
42
#ifdef OSS_SUPPORT
 
43
        &DSP_bootstrap_ours,
 
44
        &DMA_bootstrap_ours,
 
45
#endif
 
46
#ifdef ALSA_SUPPORT
 
47
        &ALSA_bootstrap_ours,
 
48
#endif
 
49
#ifdef QNXNTOAUDIO_SUPPORT
 
50
        &QNXNTOAUDIO_bootstrap_ours,
 
51
#endif
 
52
#ifdef SUNAUDIO_SUPPORT
 
53
        &SUNAUDIO_bootstrap_ours,
 
54
#endif
 
55
#ifdef DMEDIA_SUPPORT
 
56
        &DMEDIA_bootstrap_ours,
 
57
#endif
 
58
#ifdef ARTSC_SUPPORT
 
59
        &ARTSC_bootstrap_ours,
 
60
#endif
 
61
#ifdef ESD_SUPPORT
 
62
        &ESD_bootstrap_ours,
 
63
#endif
 
64
#ifdef NAS_SUPPORT
 
65
        &NAS_bootstrap_ours,
 
66
#endif
 
67
#ifdef ENABLE_DIRECTX
 
68
        &DSOUND_bootstrap_ours,
 
69
#endif
 
70
#ifdef ENABLE_WINDIB
 
71
        &WAVEOUT_bootstrap_ours,
 
72
#endif
 
73
#ifdef __BEOS__
 
74
        &BAUDIO_bootstrap_ours,
 
75
#endif
 
76
#ifdef MACOSX
 
77
        &COREAUDIO_bootstrap,
 
78
#endif
 
79
#if defined(macintosh) || TARGET_API_MAC_CARBON
 
80
        &SNDMGR_bootstrap_ours,
 
81
#endif
 
82
#ifdef _AIX
 
83
        &Paud_bootstrap_ours,
 
84
#endif
 
85
#ifdef ENABLE_AHI
 
86
        &AHI_bootstrap_ours,
 
87
#endif
 
88
#ifdef MMEAUDIO_SUPPORT
 
89
        &MMEAUDIO_bootstrap_ours,
 
90
#endif
 
91
#ifdef MINTAUDIO_SUPPORT
 
92
        &MINTAUDIO_GSXB_bootstrap_ours,
 
93
        &MINTAUDIO_MCSN_bootstrap_ours,
 
94
        &MINTAUDIO_STFA_bootstrap_ours,
 
95
        &MINTAUDIO_XBIOS_bootstrap_ours,
 
96
        &MINTAUDIO_DMA8_bootstrap_ours,
 
97
#endif
 
98
#ifdef DISKAUD_SUPPORT
 
99
        &DISKAUD_bootstrap_ours,
 
100
#endif
 
101
#ifdef ENABLE_DC
 
102
        &DCAUD_bootstrap_ours,
 
103
#endif
 
104
#ifdef DRENDERER_SUPPORT
 
105
        &DRENDERER_bootstrap_ours,
 
106
#endif
 
107
        NULL
 
108
};
 
109
SDL_AudioDevice *current_audio = NULL;
 
110
 
 
111
/* Various local functions */
 
112
 
 
113
#ifdef ENABLE_AHI
 
114
static int audio_configured = 0;
 
115
#endif
 
116
 
 
117
/* The general mixing thread function */
 
118
static int SDL_RunAudio(void *audiop)
 
119
{
 
120
        SDL_AudioDevice *audio = (SDL_AudioDevice *)audiop;
 
121
        Uint8 *stream;
 
122
        int    stream_len;
 
123
        void  *udata;
 
124
        void (*fill)(void *userdata,Uint8 *stream, int len);
 
125
        int    silence;
 
126
#ifdef ENABLE_AHI
 
127
        int started = 0;
 
128
 
 
129
/* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
 
130
 
 
131
        D(bug("Task audio started audio struct:<%lx>...\n",audiop));
 
132
 
 
133
        D(bug("Before Openaudio..."));
 
134
        if(audio->OpenAudio(audio, &audio->spec)==-1)
 
135
        {
 
136
                D(bug("Open audio failed...\n"));
 
137
                return(-1);
 
138
        }
 
139
        D(bug("OpenAudio...OK\n"));
 
140
#endif 
 
141
 
 
142
        /* Perform any thread setup */
 
143
        if ( audio->ThreadInit ) {
 
144
                audio->ThreadInit(audio);
 
145
        }
 
146
        audio->threadid = SDL_ThreadID();
 
147
 
 
148
        /* Set up the mixing function */
 
149
        fill  = audio->spec.callback;
 
150
        udata = audio->spec.userdata;
 
151
 
 
152
#ifdef ENABLE_AHI
 
153
        audio_configured = 1;
 
154
 
 
155
        D(bug("Audio configured... Checking for conversion\n"));
 
156
        SDL_mutexP(audio->mixer_lock);
 
157
        D(bug("Semaphore obtained...\n"));
 
158
#endif
 
159
 
 
160
        if ( audio->convert.needed ) {
 
161
                if ( audio->convert.src_format == AUDIO_U8 ) {
 
162
                        silence = 0x80;
 
163
                } else {
 
164
                        silence = 0;
 
165
                }
 
166
                stream_len = audio->convert.len;
 
167
        } else {
 
168
                silence = audio->spec.silence;
 
169
                stream_len = audio->spec.size;
 
170
        }
 
171
#ifndef _WINDOWS
 
172
        stream = audio->GetAudioBuf(audio);
 
173
        if (stream == NULL) 
 
174
#endif
 
175
          stream = audio->fake_stream;
 
176
 
 
177
#ifdef ENABLE_AHI
 
178
        SDL_mutexV(audio->mixer_lock);
 
179
        D(bug("Entering audio loop...\n"));
 
180
#endif
 
181
 
 
182
 
 
183
        /* Loop, filling the audio buffers */
 
184
        while ( audio->enabled ) {
 
185
 
 
186
                /* Wait for new current buffer to finish playing */
 
187
                if ( stream == audio->fake_stream ) {
 
188
                        SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
 
189
                } else {
 
190
#ifdef ENABLE_AHI
 
191
                        if ( started > 1 )
 
192
#endif
 
193
                        audio->WaitAudio(audio);
 
194
                }
 
195
 
 
196
                /* Fill the current buffer with sound */
 
197
                if ( audio->convert.needed ) {
 
198
                        if ( audio->convert.buf ) {
 
199
                                stream = audio->convert.buf;
 
200
                        } else {
 
201
                                continue;
 
202
                        }
 
203
                } else {
 
204
                        stream = audio->GetAudioBuf(audio);
 
205
                        if ( stream == NULL ) {
 
206
                                stream = audio->fake_stream;
 
207
                        }
 
208
                }
 
209
                memset(stream, silence, stream_len);
 
210
 
 
211
                if ( ! audio->paused ) {
 
212
                        SDL_mutexP(audio->mixer_lock);
 
213
                        (*fill)(udata, stream, stream_len);
 
214
                        SDL_mutexV(audio->mixer_lock);
 
215
                }
 
216
 
 
217
                /* Convert the audio if necessary */
 
218
                if ( audio->convert.needed ) {
 
219
                        Our_SDL_ConvertAudio(&audio->convert);
 
220
                        stream = audio->GetAudioBuf(audio);
 
221
                        if ( stream == NULL ) {
 
222
                                stream = audio->fake_stream;
 
223
                        }
 
224
                        memcpy(stream, audio->convert.buf,
 
225
                                       audio->convert.len_cvt);
 
226
                }
 
227
 
 
228
                /* Ready current buffer for play and change current buffer */
 
229
                if ( stream != audio->fake_stream ) {
 
230
                        audio->PlayAudio(audio);
 
231
#ifdef ENABLE_AHI
 
232
/* AmigaOS don't have to wait the first time audio is played! */
 
233
                        started++;
 
234
#endif
 
235
                }
 
236
        }
 
237
        /* Wait for the audio to drain.. */
 
238
        if ( audio->WaitDone ) {
 
239
                audio->WaitDone(audio);
 
240
        }
 
241
 
 
242
#ifdef ENABLE_AHI
 
243
        D(bug("WaitAudio...Done\n"));
 
244
 
 
245
        audio->CloseAudio(audio);
 
246
 
 
247
        D(bug("CloseAudio..Done, subtask exiting...\n"));
 
248
        audio_configured = 0;
 
249
#endif
 
250
        return(0);
 
251
}
 
252
 
 
253
static void SDL_LockAudio_Default(SDL_AudioDevice *audio)
 
254
{
 
255
        if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
 
256
                return;
 
257
        }
 
258
        SDL_mutexP(audio->mixer_lock);
 
259
}
 
260
 
 
261
static void SDL_UnlockAudio_Default(SDL_AudioDevice *audio)
 
262
{
 
263
        if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
 
264
                return;
 
265
        }
 
266
        SDL_mutexV(audio->mixer_lock);
 
267
}
 
268
 
 
269
int Our_SDL_AudioInit(const char *driver_name)
 
270
{
 
271
        SDL_AudioDevice *audio;
 
272
        int i = 0, idx;
 
273
 
 
274
        /* Check to make sure we don't overwrite 'current_audio' */
 
275
        if ( current_audio != NULL ) {
 
276
                Our_SDL_AudioQuit();
 
277
        }
 
278
 
 
279
        /* Select the proper audio driver */
 
280
        audio = NULL;
 
281
        idx = 0;
 
282
#ifdef unix
 
283
        if ( (driver_name == NULL) && (getenv("ESPEAKER") != NULL) ) {
 
284
                /* Ahem, we know that if ESPEAKER is set, user probably wants
 
285
                   to use ESD, but don't start it if it's not already running.
 
286
                   This probably isn't the place to do this, but... Shh! :)
 
287
                 */
 
288
                for ( i=0; bootstrap[i]; ++i ) {
 
289
                        if ( strcmp(bootstrap[i]->name, "esd") == 0 ) {
 
290
                                const char *esd_no_spawn;
 
291
 
 
292
                                /* Don't start ESD if it's not running */
 
293
                                esd_no_spawn = getenv("ESD_NO_SPAWN");
 
294
                                if ( esd_no_spawn == NULL ) {
 
295
                                        putenv("ESD_NO_SPAWN=1");
 
296
                                }
 
297
                                if ( bootstrap[i]->available() ) {
 
298
                                        audio = bootstrap[i]->create(0);
 
299
                                        break;
 
300
                                }
 
301
#ifdef linux    /* No unsetenv() on most platforms */
 
302
                                if ( esd_no_spawn == NULL ) {
 
303
                                        unsetenv("ESD_NO_SPAWN");
 
304
                                }
 
305
#endif
 
306
                        }
 
307
                }
 
308
        }
 
309
#endif /* unix */
 
310
        if ( audio == NULL ) {
 
311
                if ( driver_name != NULL ) {
 
312
#if 0   /* This will be replaced with a better driver selection API */
 
313
                        if ( strrchr(driver_name, ':') != NULL ) {
 
314
                                idx = atoi(strrchr(driver_name, ':')+1);
 
315
                        }
 
316
#endif
 
317
                        for ( i=0; bootstrap[i]; ++i ) {
 
318
                                if (strncmp(bootstrap[i]->name, driver_name,
 
319
                                            strlen(bootstrap[i]->name)) == 0) {
 
320
                                        if ( bootstrap[i]->available() ) {
 
321
                                                audio=bootstrap[i]->create(idx);
 
322
                                                break;
 
323
                                        }
 
324
                                }
 
325
                        }
 
326
                } else {
 
327
                        for ( i=0; bootstrap[i]; ++i ) {
 
328
                                if ( bootstrap[i]->available() ) {
 
329
                                        audio = bootstrap[i]->create(idx);
 
330
                                        if ( audio != NULL ) {
 
331
                                                break;
 
332
                                        }
 
333
                                }
 
334
                        }
 
335
                }
 
336
                if ( audio == NULL ) {
 
337
                        SDL_SetError("No available audio device");
 
338
#if 0 /* Don't fail SDL_Init() if audio isn't available.
 
339
         SDL_OpenAudio() will handle it at that point.  *sigh*
 
340
       */
 
341
                        return(-1);
 
342
#endif
 
343
                }
 
344
        }
 
345
        current_audio = audio;
 
346
        if ( current_audio ) {
 
347
                current_audio->name = bootstrap[i]->name;
 
348
                if ( !current_audio->LockAudio && !current_audio->UnlockAudio ) {
 
349
                        current_audio->LockAudio = SDL_LockAudio_Default;
 
350
                        current_audio->UnlockAudio = SDL_UnlockAudio_Default;
 
351
                }
 
352
        }
 
353
        return(0);
 
354
}
 
355
 
 
356
char *Our_SDL_AudioDriverName(char *namebuf, int maxlen)
 
357
{
 
358
        if ( current_audio != NULL ) {
 
359
                strncpy(namebuf, current_audio->name, maxlen-1);
 
360
                namebuf[maxlen-1] = '\0';
 
361
                return(namebuf);
 
362
        }
 
363
        return(NULL);
 
364
}
 
365
 
 
366
int Our_SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
 
367
{
 
368
        SDL_AudioDevice *audio;
 
369
 
 
370
        /* Start up the audio driver, if necessary */
 
371
        if ( ! current_audio ) {
 
372
          if ((Our_SDL_AudioInit(getenv("SDL_AUDIODRIVER")) < 0) ||
 
373
                     (current_audio == NULL) ) {
 
374
                        return(-1);
 
375
                }
 
376
        }
 
377
        audio = current_audio;
 
378
 
 
379
        if (audio->opened) {
 
380
                SDL_SetError("Audio device is already opened");
 
381
                return(-1);
 
382
        }
 
383
 
 
384
        /* Verify some parameters */
 
385
        if ( desired->callback == NULL ) {
 
386
                SDL_SetError("SDL_OpenAudio() passed a NULL callback");
 
387
                return(-1);
 
388
        }
 
389
        switch ( desired->channels ) {
 
390
            case 1:     /* Mono */
 
391
            case 2:     /* Stereo */
 
392
            case 4:     /* surround */
 
393
            case 6:     /* surround */
 
394
                break;
 
395
            default:
 
396
                SDL_SetError("1 (mono) and 2 (stereo) channels supported");
 
397
                return(-1);
 
398
        }
 
399
 
 
400
#if defined(macintosh) || (defined(__riscos__) && !defined(DISABLE_THREADS))
 
401
        /* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
 
402
#else
 
403
#if defined(__MINT__) && !defined(ENABLE_THREADS)
 
404
        /* Uses interrupt driven audio, without thread */
 
405
#else
 
406
        /* Create a semaphore for locking the sound buffers */
 
407
        audio->mixer_lock = SDL_CreateMutex();
 
408
        if ( audio->mixer_lock == NULL ) {
 
409
                SDL_SetError("Couldn't create mixer lock");
 
410
                Our_SDL_CloseAudio();
 
411
                return(-1);
 
412
        }
 
413
#endif /* __MINT__ */
 
414
#endif /* macintosh */
 
415
 
 
416
        /* Calculate the silence and size of the audio specification */
 
417
        SDL_CalculateAudioSpec(desired);
 
418
 
 
419
        /* Open the audio subsystem */
 
420
        memcpy(&audio->spec, desired, sizeof(audio->spec));
 
421
        audio->convert.needed = 0;
 
422
        audio->enabled = 1;
 
423
        audio->paused  = 1;
 
424
 
 
425
#ifndef ENABLE_AHI
 
426
 
 
427
/* AmigaOS opens audio inside the main loop */
 
428
        audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
 
429
 
 
430
        if ( ! audio->opened ) {
 
431
                SDL_CloseAudio();
 
432
                return(-1);
 
433
        }
 
434
#else
 
435
        D(bug("Locking semaphore..."));
 
436
        SDL_mutexP(audio->mixer_lock);
 
437
 
 
438
        audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
 
439
        D(bug("Created thread...\n"));
 
440
 
 
441
        if ( audio->thread == NULL ) {
 
442
                SDL_mutexV(audio->mixer_lock);
 
443
                Our_SDL_CloseAudio();
 
444
                SDL_SetError("Couldn't create audio thread");
 
445
                return(-1);
 
446
        }
 
447
 
 
448
        while(!audio_configured) 
 
449
                SDL_Delay(100);
 
450
#endif
 
451
 
 
452
        /* If the audio driver changes the buffer size, accept it */
 
453
        if ( audio->spec.samples != desired->samples ) {
 
454
                desired->samples = audio->spec.samples;
 
455
                SDL_CalculateAudioSpec(desired);
 
456
        }
 
457
 
 
458
        /* Allocate a fake audio memory buffer */
 
459
        audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
 
460
        if ( audio->fake_stream == NULL ) {
 
461
                Our_SDL_CloseAudio();
 
462
                SDL_OutOfMemory();
 
463
                return(-1);
 
464
        }
 
465
 
 
466
        /* See if we need to do any conversion */
 
467
        if ( obtained != NULL ) {
 
468
                memcpy(obtained, &audio->spec, sizeof(audio->spec));
 
469
        } else if ( desired->freq != audio->spec.freq ||
 
470
                    desired->format != audio->spec.format ||
 
471
                    desired->channels != audio->spec.channels ) {
 
472
          // wmay
 
473
          if (desired->format == AUDIO_FORMAT_HW_AC3) {
 
474
            return -1;
 
475
          }
 
476
                /* Build an audio conversion block */
 
477
                if ( SDL_BuildAudioCVT(&audio->convert,
 
478
                        desired->format, desired->channels,
 
479
                                        desired->freq,
 
480
                        audio->spec.format, audio->spec.channels,
 
481
                                        audio->spec.freq) < 0 ) {
 
482
                        Our_SDL_CloseAudio();
 
483
                        return(-1);
 
484
                }
 
485
                if ( audio->convert.needed ) {
 
486
                        audio->convert.len = desired->size;
 
487
                        audio->convert.buf =(Uint8 *)SDL_AllocAudioMem(
 
488
                           audio->convert.len*audio->convert.len_mult);
 
489
                        if ( audio->convert.buf == NULL ) {
 
490
                                Our_SDL_CloseAudio();
 
491
                                SDL_OutOfMemory();
 
492
                                return(-1);
 
493
                        }
 
494
                }
 
495
        }
 
496
 
 
497
#ifndef ENABLE_AHI
 
498
        /* Start the audio thread if necessary */
 
499
        switch (audio->opened) {
 
500
                case  1:
 
501
                        /* Start the audio thread */
 
502
                        audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
 
503
                        if ( audio->thread == NULL ) {
 
504
                                Our_SDL_CloseAudio();
 
505
                                SDL_SetError("Couldn't create audio thread");
 
506
                                return(-1);
 
507
                        }
 
508
                        break;
 
509
 
 
510
                default:
 
511
                        /* The audio is now playing */
 
512
                        break;
 
513
        }
 
514
#else
 
515
        SDL_mutexV(audio->mixer_lock);
 
516
        D(bug("SDL_OpenAudio USCITA...\n"));
 
517
 
 
518
#endif
 
519
 
 
520
        return(0);
 
521
}
 
522
 
 
523
SDL_audiostatus Our_SDL_GetAudioStatus(void)
 
524
{
 
525
        SDL_AudioDevice *audio = current_audio;
 
526
        SDL_audiostatus status;
 
527
 
 
528
        status = SDL_AUDIO_STOPPED;
 
529
        if ( audio && audio->enabled ) {
 
530
                if ( audio->paused ) {
 
531
                        status = SDL_AUDIO_PAUSED;
 
532
                } else {
 
533
                        status = SDL_AUDIO_PLAYING;
 
534
                }
 
535
        }
 
536
        return(status);
 
537
}
 
538
 
 
539
void Our_SDL_PauseAudio (int pause_on)
 
540
{
 
541
        SDL_AudioDevice *audio = current_audio;
 
542
 
 
543
        if ( audio ) {
 
544
                audio->paused = pause_on;
 
545
        }
 
546
}
 
547
 
 
548
void Our_SDL_LockAudio (void)
 
549
{
 
550
        SDL_AudioDevice *audio = current_audio;
 
551
 
 
552
        /* Obtain a lock on the mixing buffers */
 
553
        if ( audio && audio->LockAudio ) {
 
554
                audio->LockAudio(audio);
 
555
        }
 
556
}
 
557
 
 
558
void Our_SDL_UnlockAudio (void)
 
559
{
 
560
        SDL_AudioDevice *audio = current_audio;
 
561
 
 
562
        /* Release lock on the mixing buffers */
 
563
        if ( audio && audio->UnlockAudio ) {
 
564
                audio->UnlockAudio(audio);
 
565
        }
 
566
}
 
567
 
 
568
void Our_SDL_CloseAudio (void)
 
569
{
 
570
  Our_SDL_AudioQuit();
 
571
}
 
572
int Our_SDL_HasAudioDelay (void)
 
573
{
 
574
  SDL_AudioDevice *audio = current_audio;
 
575
 
 
576
  if (audio && audio->AudioDelay != NULL) {
 
577
    return 1;
 
578
  }
 
579
  return 0;
 
580
}
 
581
 
 
582
int Our_SDL_AudioDelay (void)
 
583
{
 
584
  SDL_AudioDevice *audio = current_audio;
 
585
  if (audio && audio->AudioDelay != NULL) {
 
586
    return (audio->AudioDelay(audio));
 
587
  } else {
 
588
    return (-1);
 
589
  }
 
590
 
 
591
}
 
592
 
 
593
void Our_SDL_AudioQuit(void)
 
594
{
 
595
        SDL_AudioDevice *audio = current_audio;
 
596
 
 
597
        if ( audio ) {
 
598
                audio->enabled = 0;
 
599
                if ( audio->thread != NULL ) {
 
600
                        SDL_WaitThread(audio->thread, NULL);
 
601
                }
 
602
                if ( audio->mixer_lock != NULL ) {
 
603
                        SDL_DestroyMutex(audio->mixer_lock);
 
604
                }
 
605
                if ( audio->fake_stream != NULL ) {
 
606
                        SDL_FreeAudioMem(audio->fake_stream);
 
607
                }
 
608
                if ( audio->convert.needed ) {
 
609
                        SDL_FreeAudioMem(audio->convert.buf);
 
610
 
 
611
                }
 
612
#ifndef ENABLE_AHI
 
613
                if ( audio->opened ) {
 
614
                        audio->CloseAudio(audio);
 
615
                        audio->opened = 0;
 
616
                }
 
617
#endif
 
618
                /* Free the driver data */
 
619
                if (audio->free) audio->free(audio);
 
620
                current_audio = NULL;
 
621
        }
 
622
}
 
623
 
 
624
#define NUM_FORMATS     6
 
625
static int format_idx;
 
626
static int format_idx_sub;
 
627
static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = {
 
628
 { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
 
629
 { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
 
630
 { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 },
 
631
 { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 },
 
632
 { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 },
 
633
 { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 },
 
634
};
 
635
 
 
636
Uint16 SDL_FirstAudioFormat(Uint16 format)
 
637
{
 
638
        for ( format_idx=0; format_idx < NUM_FORMATS; ++format_idx ) {
 
639
                if ( format_list[format_idx][0] == format ) {
 
640
                        break;
 
641
                }
 
642
        }
 
643
        format_idx_sub = 0;
 
644
        return(SDL_NextAudioFormat());
 
645
}
 
646
 
 
647
Uint16 SDL_NextAudioFormat(void)
 
648
{
 
649
        if ( (format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS) ) {
 
650
                return(0);
 
651
        }
 
652
        return(format_list[format_idx][format_idx_sub++]);
 
653
}
 
654
 
 
655
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
 
656
{
 
657
        switch (spec->format) {
 
658
                case AUDIO_U8:
 
659
                        spec->silence = 0x80;
 
660
                        break;
 
661
                default:
 
662
                        spec->silence = 0x00;
 
663
                        break;
 
664
        }
 
665
        if (spec->format == AUDIO_FORMAT_HW_AC3) {
 
666
          spec->size = 256 * 6 * 2 * 2;
 
667
        } else {
 
668
        spec->size = (spec->format&0xFF)/8;
 
669
        spec->size *= spec->channels;
 
670
        spec->size *= spec->samples;
 
671
        }
 
672
}