Statistics
| Branch: | Revision:

root / audio / audio.c @ 7372f88d

History | View | Annotate | Download (21 kB)

1
/*
2
 * QEMU Audio subsystem
3
 * 
4
 * Copyright (c) 2003-2004 Vassili Karpov (malc)
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include <assert.h>
25
#include "vl.h"
26

    
27
#define USE_SDL_AUDIO
28
#define USE_WAV_AUDIO
29

    
30
#include "audio/audio_int.h"
31

    
32
#define dolog(...) AUD_log ("audio", __VA_ARGS__)
33
#ifdef DEBUG
34
#define ldebug(...) dolog (__VA_ARGS__)
35
#else
36
#define ldebug(...)
37
#endif
38

    
39
#define QC_AUDIO_DRV    "QEMU_AUDIO_DRV"
40
#define QC_VOICES       "QEMU_VOICES"
41
#define QC_FIXED_FORMAT "QEMU_FIXED_FORMAT"
42
#define QC_FIXED_FREQ   "QEMU_FIXED_FREQ"
43

    
44
static HWVoice *hw_voices;
45

    
46
AudioState audio_state = {
47
    1,                          /* use fixed settings */
48
    44100,                      /* fixed frequency */
49
    2,                          /* fixed channels */
50
    AUD_FMT_S16,                /* fixed format */
51
    1,                          /* number of hw voices */
52
    -1                          /* voice size */
53
};
54

    
55
/* http://www.df.lth.se/~john_e/gems/gem002d.html */
56
/* http://www.multi-platforms.com/Tips/PopCount.htm */
57
uint32_t popcount (uint32_t u)
58
{
59
    u = ((u&0x55555555) + ((u>>1)&0x55555555));
60
    u = ((u&0x33333333) + ((u>>2)&0x33333333));
61
    u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
62
    u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
63
    u = ( u&0x0000ffff) + (u>>16);
64
    return u;
65
}
66

    
67
inline uint32_t lsbindex (uint32_t u)
68
{
69
    return popcount ((u&-u)-1);
70
}
71

    
72
int audio_get_conf_int (const char *key, int defval)
73
{
74
    int val = defval;
75
    char *strval;
76

    
77
    strval = getenv (key);
78
    if (strval) {
79
        val = atoi (strval);
80
    }
81

    
82
    return val;
83
}
84

    
85
const char *audio_get_conf_str (const char *key, const char *defval)
86
{
87
    const char *val = getenv (key);
88
    if (!val)
89
        return defval;
90
    else
91
        return val;
92
}
93

    
94
void AUD_log (const char *cap, const char *fmt, ...)
95
{
96
    va_list ap;
97
    fprintf (stderr, "%s: ", cap);
98
    va_start (ap, fmt);
99
    vfprintf (stderr, fmt, ap);
100
    va_end (ap);
101
}
102

    
103
/*
104
 * Soft Voice
105
 */
106
void pcm_sw_free_resources (SWVoice *sw)
107
{
108
    if (sw->buf) qemu_free (sw->buf);
109
    if (sw->rate) st_rate_stop (sw->rate);
110
    sw->buf = NULL;
111
    sw->rate = NULL;
112
}
113

    
114
int pcm_sw_alloc_resources (SWVoice *sw)
115
{
116
    sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
117
    if (!sw->buf)
118
        return -1;
119

    
120
    sw->rate = st_rate_start (sw->freq, sw->hw->freq);
121
    if (!sw->rate) {
122
        qemu_free (sw->buf);
123
        sw->buf = NULL;
124
        return -1;
125
    }
126
    return 0;
127
}
128

    
129
void pcm_sw_fini (SWVoice *sw)
130
{
131
    pcm_sw_free_resources (sw);
132
}
133

    
134
int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
135
                 int nchannels, audfmt_e fmt)
136
{
137
    int bits = 8, sign = 0;
138

    
139
    switch (fmt) {
140
    case AUD_FMT_S8:
141
        sign = 1;
142
    case AUD_FMT_U8:
143
        break;
144

    
145
    case AUD_FMT_S16:
146
        sign = 1;
147
    case AUD_FMT_U16:
148
        bits = 16;
149
        break;
150
    }
151

    
152
    sw->hw = hw;
153
    sw->freq = freq;
154
    sw->fmt = fmt;
155
    sw->nchannels = nchannels;
156
    sw->shift = (nchannels == 2) + (bits == 16);
157
    sw->align = (1 << sw->shift) - 1;
158
    sw->left = 0;
159
    sw->pos = 0;
160
    sw->wpos = 0;
161
    sw->live = 0;
162
    sw->ratio = (sw->hw->freq * ((int64_t) INT_MAX)) / sw->freq;
163
    sw->bytes_per_second = sw->freq << sw->shift;
164
    sw->conv = mixeng_conv[nchannels == 2][sign][bits == 16];
165

    
166
    pcm_sw_free_resources (sw);
167
    return pcm_sw_alloc_resources (sw);
168
}
169

    
170
/* Hard voice */
171
void pcm_hw_free_resources (HWVoice *hw)
172
{
173
    if (hw->mix_buf)
174
        qemu_free (hw->mix_buf);
175
    hw->mix_buf = NULL;
176
}
177

    
178
int pcm_hw_alloc_resources (HWVoice *hw)
179
{
180
    hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
181
    if (!hw->mix_buf)
182
        return -1;
183
    return 0;
184
}
185

    
186
void pcm_hw_fini (HWVoice *hw)
187
{
188
    if (hw->active) {
189
        ldebug ("pcm_hw_fini: %d %d %d\n", hw->freq, hw->nchannels, hw->fmt);
190
        pcm_hw_free_resources (hw);
191
        hw->pcm_ops->fini (hw);
192
        memset (hw, 0, audio_state.drv->voice_size);
193
    }
194
}
195

    
196
void pcm_hw_gc (HWVoice *hw)
197
{
198
    if (hw->nb_voices)
199
        return;
200

    
201
    pcm_hw_fini (hw);
202
}
203

    
204
int pcm_hw_get_live (HWVoice *hw)
205
{
206
    int i, alive = 0, live = hw->samples;
207

    
208
    for (i = 0; i < hw->nb_voices; i++) {
209
        if (hw->pvoice[i]->live) {
210
            live = audio_MIN (hw->pvoice[i]->live, live);
211
            alive += 1;
212
        }
213
    }
214

    
215
    if (alive)
216
        return live;
217
    else
218
        return -1;
219
}
220

    
221
int pcm_hw_get_live2 (HWVoice *hw, int *nb_active)
222
{
223
    int i, alive = 0, live = hw->samples;
224

    
225
    *nb_active = 0;
226
    for (i = 0; i < hw->nb_voices; i++) {
227
        if (hw->pvoice[i]->live) {
228
            if (hw->pvoice[i]->live < live) {
229
                *nb_active = hw->pvoice[i]->active != 0;
230
                live = hw->pvoice[i]->live;
231
            }
232
            alive += 1;
233
        }
234
    }
235

    
236
    if (alive)
237
        return live;
238
    else
239
        return -1;
240
}
241

    
242
void pcm_hw_dec_live (HWVoice *hw, int decr)
243
{
244
    int i;
245

    
246
    for (i = 0; i < hw->nb_voices; i++) {
247
        if (hw->pvoice[i]->live) {
248
            hw->pvoice[i]->live -= decr;
249
        }
250
    }
251
}
252

    
253
void pcm_hw_clear (HWVoice *hw, void *buf, int len)
254
{
255
    if (!len)
256
        return;
257

    
258
    switch (hw->fmt) {
259
    case AUD_FMT_S16:
260
    case AUD_FMT_S8:
261
        memset (buf, len << hw->shift, 0x00);
262
        break;
263

    
264
    case AUD_FMT_U8:
265
        memset (buf, len << hw->shift, 0x80);
266
        break;
267

    
268
    case AUD_FMT_U16:
269
        {
270
            unsigned int i;
271
            uint16_t *p = buf;
272
            int shift = hw->nchannels - 1;
273

    
274
            for (i = 0; i < len << shift; i++) {
275
                p[i] = INT16_MAX;
276
            }
277
        }
278
        break;
279
    }
280
}
281

    
282
int pcm_hw_write (SWVoice *sw, void *buf, int size)
283
{
284
    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
285
    int ret = 0, pos = 0;
286
    if (!sw)
287
        return size;
288

    
289
    hwsamples = sw->hw->samples;
290
    samples = size >> sw->shift;
291

    
292
    if (!sw->live) {
293
        sw->wpos = sw->hw->rpos;
294
    }
295
    wpos = sw->wpos;
296
    live = sw->live;
297
    dead = hwsamples - live;
298
    swlim = (dead * ((int64_t) INT_MAX)) / sw->ratio;
299
    swlim = audio_MIN (swlim, samples);
300

    
301
    ldebug ("size=%d live=%d dead=%d swlim=%d wpos=%d\n",
302
           size, live, dead, swlim, wpos);
303
    if (swlim)
304
        sw->conv (sw->buf, buf, swlim);
305

    
306
    while (swlim) {
307
        dead = hwsamples - live;
308
        left = hwsamples - wpos;
309
        blck = audio_MIN (dead, left);
310
        if (!blck) {
311
            /* dolog ("swlim=%d\n", swlim); */
312
            break;
313
        }
314
        isamp = swlim;
315
        osamp = blck;
316
        st_rate_flow (sw->rate, sw->buf + pos, sw->hw->mix_buf + wpos, &isamp, &osamp);
317
        ret += isamp;
318
        swlim -= isamp;
319
        pos += isamp;
320
        live += osamp;
321
        wpos = (wpos + osamp) % hwsamples;
322
    }
323

    
324
    sw->wpos = wpos;
325
    sw->live = live;
326
    return ret << sw->shift;
327
}
328

    
329
int pcm_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
330
{
331
    int sign = 0, bits = 8;
332

    
333
    pcm_hw_fini (hw);
334
    ldebug ("pcm_hw_init: %d %d %d\n", freq, nchannels, fmt);
335
    if (hw->pcm_ops->init (hw, freq, nchannels, fmt)) {
336
        memset (hw, 0, audio_state.drv->voice_size);
337
        return -1;
338
    }
339

    
340
    switch (hw->fmt) {
341
    case AUD_FMT_S8:
342
        sign = 1;
343
    case AUD_FMT_U8:
344
        break;
345

    
346
    case AUD_FMT_S16:
347
        sign = 1;
348
    case AUD_FMT_U16:
349
        bits = 16;
350
        break;
351
    }
352

    
353
    hw->nb_voices = 0;
354
    hw->active = 1;
355
    hw->shift = (hw->nchannels == 2) + (bits == 16);
356
    hw->bytes_per_second = hw->freq << hw->shift;
357
    hw->align = (1 << hw->shift) - 1;
358
    hw->samples = hw->bufsize >> hw->shift;
359
    hw->clip = mixeng_clip[hw->nchannels == 2][sign][bits == 16];
360
    if (pcm_hw_alloc_resources (hw)) {
361
        pcm_hw_fini (hw);
362
        return -1;
363
    }
364
    return 0;
365
}
366

    
367
static int dist (void *hw)
368
{
369
    if (hw) {
370
        return (((uint8_t *) hw - (uint8_t *) hw_voices)
371
                / audio_state.voice_size) + 1;
372
    }
373
    else {
374
        return 0;
375
    }
376
}
377

    
378
#define ADVANCE(hw) hw ? advance (hw, audio_state.voice_size) : hw_voices
379

    
380
HWVoice *pcm_hw_find_any (HWVoice *hw)
381
{
382
    int i = dist (hw);
383
    for (; i < audio_state.nb_hw_voices; i++) {
384
        hw = ADVANCE (hw);
385
        return hw;
386
    }
387
    return NULL;
388
}
389

    
390
HWVoice *pcm_hw_find_any_active (HWVoice *hw)
391
{
392
    int i = dist (hw);
393
    for (; i < audio_state.nb_hw_voices; i++) {
394
        hw = ADVANCE (hw);
395
        if (hw->active)
396
            return hw;
397
    }
398
    return NULL;
399
}
400

    
401
HWVoice *pcm_hw_find_any_active_enabled (HWVoice *hw)
402
{
403
    int i = dist (hw);
404
    for (; i < audio_state.nb_hw_voices; i++) {
405
        hw = ADVANCE (hw);
406
        if (hw->active && hw->enabled)
407
            return hw;
408
    }
409
    return NULL;
410
}
411

    
412
HWVoice *pcm_hw_find_any_passive (HWVoice *hw)
413
{
414
    int i = dist (hw);
415
    for (; i < audio_state.nb_hw_voices; i++) {
416
        hw = ADVANCE (hw);
417
        if (!hw->active)
418
            return hw;
419
    }
420
    return NULL;
421
}
422

    
423
HWVoice *pcm_hw_find_specific (HWVoice *hw, int freq,
424
                               int nchannels, audfmt_e fmt)
425
{
426
    while ((hw = pcm_hw_find_any_active (hw))) {
427
        if (hw->freq == freq &&
428
            hw->nchannels == nchannels &&
429
            hw->fmt == fmt)
430
            return hw;
431
    }
432
    return NULL;
433
}
434

    
435
HWVoice *pcm_hw_add (int freq, int nchannels, audfmt_e fmt)
436
{
437
    HWVoice *hw;
438

    
439
    if (audio_state.fixed_format) {
440
        freq = audio_state.fixed_freq;
441
        nchannels = audio_state.fixed_channels;
442
        fmt = audio_state.fixed_fmt;
443
    }
444

    
445
    hw = pcm_hw_find_specific (NULL, freq, nchannels, fmt);
446

    
447
    if (hw)
448
        return hw;
449

    
450
    hw = pcm_hw_find_any_passive (NULL);
451
    if (hw) {
452
        hw->pcm_ops = audio_state.drv->pcm_ops;
453
        if (!hw->pcm_ops)
454
            return NULL;
455

    
456
        if (pcm_hw_init (hw, freq, nchannels, fmt)) {
457
            pcm_hw_gc (hw);
458
            return NULL;
459
        }
460
        else
461
            return hw;
462
    }
463

    
464
    return pcm_hw_find_any (NULL);
465
}
466

    
467
int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw)
468
{
469
    SWVoice **pvoice = qemu_mallocz ((hw->nb_voices + 1) * sizeof (sw));
470
    if (!pvoice)
471
        return -1;
472

    
473
    memcpy (pvoice, hw->pvoice, hw->nb_voices * sizeof (sw));
474
    qemu_free (hw->pvoice);
475
    hw->pvoice = pvoice;
476
    hw->pvoice[hw->nb_voices++] = sw;
477
    return 0;
478
}
479

    
480
int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw)
481
{
482
    int i, j;
483
    if (hw->nb_voices > 1) {
484
        SWVoice **pvoice = qemu_mallocz ((hw->nb_voices - 1) * sizeof (sw));
485

    
486
        if (!pvoice) {
487
            dolog ("Can not maintain consistent state (not enough memory)\n");
488
            return -1;
489
        }
490

    
491
        for (i = 0, j = 0; i < hw->nb_voices; i++) {
492
            if (j >= hw->nb_voices - 1) {
493
                dolog ("Can not maintain consistent state "
494
                       "(invariant violated)\n");
495
                return -1;
496
            }
497
            if (hw->pvoice[i] != sw)
498
                pvoice[j++] = hw->pvoice[i];
499
        }
500
        qemu_free (hw->pvoice);
501
        hw->pvoice = pvoice;
502
        hw->nb_voices -= 1;
503
    }
504
    else {
505
        qemu_free (hw->pvoice);
506
        hw->pvoice = NULL;
507
        hw->nb_voices = 0;
508
    }
509
    return 0;
510
}
511

    
512
SWVoice *pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt)
513
{
514
    SWVoice *sw;
515
    HWVoice *hw;
516

    
517
    sw = qemu_mallocz (sizeof (*sw));
518
    if (!sw)
519
        goto err1;
520

    
521
    hw = pcm_hw_add (freq, nchannels, fmt);
522
    if (!hw)
523
        goto err2;
524

    
525
    if (pcm_hw_add_sw (hw, sw))
526
        goto err3;
527

    
528
    if (pcm_sw_init (sw, hw, freq, nchannels, fmt))
529
        goto err4;
530

    
531
    return sw;
532

    
533
err4:
534
    pcm_hw_del_sw (hw, sw);
535
err3:
536
    pcm_hw_gc (hw);
537
err2:
538
    qemu_free (sw);
539
err1:
540
    return NULL;
541
}
542

    
543
SWVoice *AUD_open (SWVoice *sw, const char *name,
544
                   int freq, int nchannels, audfmt_e fmt)
545
{
546
    if (!audio_state.drv) {
547
        return NULL;
548
    }
549

    
550
    if (sw && freq == sw->freq && sw->nchannels == nchannels && sw->fmt == fmt) {
551
        return sw;
552
    }
553

    
554
    if (sw) {
555
        ldebug ("Different format %s %d %d %d\n",
556
                name,
557
                sw->freq == freq,
558
                sw->nchannels == nchannels,
559
                sw->fmt == fmt);
560
    }
561

    
562
    if (nchannels != 1 && nchannels != 2) {
563
        dolog ("Bogus channel count %d for voice %s\n", nchannels, name);
564
        return NULL;
565
    }
566

    
567
    if (!audio_state.fixed_format && sw) {
568
        pcm_sw_fini (sw);
569
        pcm_hw_del_sw (sw->hw, sw);
570
        pcm_hw_gc (sw->hw);
571
        if (sw->name) {
572
            qemu_free (sw->name);
573
            sw->name = NULL;
574
        }
575
        qemu_free (sw);
576
        sw = NULL;
577
    }
578

    
579
    if (sw) {
580
        HWVoice *hw = sw->hw;
581
        if (!hw) {
582
            dolog ("Internal logic error voice %s has no hardware store\n",
583
                   name);
584
            return sw;
585
        }
586

    
587
        if (pcm_sw_init (sw, hw, freq, nchannels, fmt)) {
588
            pcm_sw_fini (sw);
589
            pcm_hw_del_sw (hw, sw);
590
            pcm_hw_gc (hw);
591
            if (sw->name) {
592
                qemu_free (sw->name);
593
                sw->name = NULL;
594
            }
595
            qemu_free (sw);
596
            return NULL;
597
        }
598
    }
599
    else {
600
        sw = pcm_create_voice_pair (freq, nchannels, fmt);
601
        if (!sw) {
602
            dolog ("Failed to create voice %s\n", name);
603
            return NULL;
604
        }
605
    }
606

    
607
    if (sw->name) {
608
        qemu_free (sw->name);
609
        sw->name = NULL;
610
    }
611
    sw->name = qemu_strdup (name);
612
    return sw;
613
}
614

    
615
void AUD_close (SWVoice *sw)
616
{
617
    if (!sw)
618
        return;
619

    
620
    pcm_sw_fini (sw);
621
    pcm_hw_del_sw (sw->hw, sw);
622
    pcm_hw_gc (sw->hw);
623
    if (sw->name) {
624
        qemu_free (sw->name);
625
        sw->name = NULL;
626
    }
627
    qemu_free (sw);
628
}
629

    
630
int AUD_write (SWVoice *sw, void *buf, int size)
631
{
632
    int bytes;
633

    
634
    if (!sw->hw->enabled)
635
        dolog ("Writing to disabled voice %s\n", sw->name);
636
    bytes = sw->hw->pcm_ops->write (sw, buf, size);
637
    return bytes;
638
}
639

    
640
void AUD_run (void)
641
{
642
    HWVoice *hw = NULL;
643

    
644
    while ((hw = pcm_hw_find_any_active_enabled (hw))) {
645
        int i;
646
        if (hw->pending_disable && pcm_hw_get_live (hw) <= 0) {
647
            hw->enabled = 0;
648
            hw->pcm_ops->ctl (hw, VOICE_DISABLE);
649
            for (i = 0; i < hw->nb_voices; i++) {
650
                hw->pvoice[i]->live = 0;
651
                /* hw->pvoice[i]->old_ticks = 0; */
652
            }
653
            continue;
654
        }
655

    
656
        hw->pcm_ops->run (hw);
657
        assert (hw->rpos < hw->samples);
658
        for (i = 0; i < hw->nb_voices; i++) {
659
            SWVoice *sw = hw->pvoice[i];
660
            if (!sw->active && !sw->live && sw->old_ticks) {
661
                int64_t delta = qemu_get_clock (vm_clock) - sw->old_ticks;
662
                if (delta > audio_state.ticks_threshold) {
663
                    ldebug ("resetting old_ticks for %s\n", sw->name);
664
                    sw->old_ticks = 0;
665
                }
666
            }
667
        }
668
    }
669
}
670

    
671
int AUD_get_free (SWVoice *sw)
672
{
673
    int free;
674

    
675
    if (!sw)
676
        return 4096;
677

    
678
    free = ((sw->hw->samples - sw->live) << sw->hw->shift) * sw->ratio
679
        / INT_MAX;
680

    
681
    free &= ~sw->hw->align;
682
    if (!free) return 0;
683

    
684
    return free;
685
}
686

    
687
int AUD_get_buffer_size (SWVoice *sw)
688
{
689
    return sw->hw->bufsize;
690
}
691

    
692
void AUD_adjust (SWVoice *sw, int bytes)
693
{
694
    if (!sw)
695
        return;
696
    sw->old_ticks += (ticks_per_sec * (int64_t) bytes) / sw->bytes_per_second;
697
}
698

    
699
void AUD_reset (SWVoice *sw)
700
{
701
    sw->active = 0;
702
    sw->old_ticks = 0;
703
}
704

    
705
int AUD_calc_elapsed (SWVoice *sw)
706
{
707
    int64_t now, delta, bytes;
708
    int dead, swlim;
709

    
710
    if (!sw)
711
        return 0;
712

    
713
    now = qemu_get_clock (vm_clock);
714
    delta = now - sw->old_ticks;
715
    bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
716
    if (delta < 0) {
717
        dolog ("whoops delta(<0)=%lld\n", delta);
718
        return 0;
719
    }
720

    
721
    dead = sw->hw->samples - sw->live;
722
    swlim = ((dead * (int64_t) INT_MAX) / sw->ratio);
723

    
724
    if (bytes > swlim) {
725
        return swlim;
726
    }
727
    else {
728
        return bytes;
729
    }
730
}
731

    
732
void AUD_enable (SWVoice *sw, int on)
733
{
734
    int i;
735
    HWVoice *hw;
736

    
737
    if (!sw)
738
        return;
739

    
740
    hw = sw->hw;
741
    if (on) {
742
        if (!sw->live)
743
            sw->wpos = sw->hw->rpos;
744
        if (!sw->old_ticks) {
745
            sw->old_ticks = qemu_get_clock (vm_clock);
746
        }
747
    }
748

    
749
    if (sw->active != on) {
750
        if (on) {
751
            hw->pending_disable = 0;
752
            if (!hw->enabled) {
753
                hw->enabled = 1;
754
                for (i = 0; i < hw->nb_voices; i++) {
755
                    ldebug ("resetting voice\n");
756
                    sw = hw->pvoice[i];
757
                    sw->old_ticks = qemu_get_clock (vm_clock);
758
                }
759
                hw->pcm_ops->ctl (hw, VOICE_ENABLE);
760
            }
761
        }
762
        else {
763
            if (hw->enabled && !hw->pending_disable) {
764
                int nb_active = 0;
765
                for (i = 0; i < hw->nb_voices; i++) {
766
                    nb_active += hw->pvoice[i]->active != 0;
767
                }
768

    
769
                if (nb_active == 1) {
770
                    hw->pending_disable = 1;
771
                }
772
            }
773
        }
774
        sw->active = on;
775
    }
776
}
777

    
778
static struct audio_output_driver *drvtab[] = {
779
#ifdef CONFIG_OSS
780
    &oss_output_driver,
781
#endif
782
#ifdef USE_FMOD_AUDIO
783
    &fmod_output_driver,
784
#endif
785
#ifdef CONFIG_SDL
786
    &sdl_output_driver,
787
#endif
788
    &no_output_driver,
789
#ifdef USE_WAV_AUDIO
790
    &wav_output_driver,
791
#endif
792
};
793

    
794
static int voice_init (struct audio_output_driver *drv)
795
{
796
    audio_state.opaque = drv->init ();
797
    if (audio_state.opaque) {
798
        if (audio_state.nb_hw_voices > drv->max_voices) {
799
            dolog ("`%s' does not support %d multiple hardware channels\n"
800
                   "Resetting to %d\n",
801
                   drv->name, audio_state.nb_hw_voices, drv->max_voices);
802
            audio_state.nb_hw_voices = drv->max_voices;
803
        }
804
        hw_voices = qemu_mallocz (audio_state.nb_hw_voices * drv->voice_size);
805
        if (hw_voices) {
806
            audio_state.drv = drv;
807
            return 1;
808
        }
809
        else {
810
            dolog ("Not enough memory for %d `%s' voices (each %d bytes)\n",
811
                   audio_state.nb_hw_voices, drv->name, drv->voice_size);
812
            drv->fini (audio_state.opaque);
813
            return 0;
814
        }
815
    }
816
    else {
817
        dolog ("Could not init `%s' audio\n", drv->name);
818
        return 0;
819
    }
820
}
821

    
822
static void audio_vm_stop_handler (void *opaque, int reason)
823
{
824
    HWVoice *hw = NULL;
825

    
826
    while ((hw = pcm_hw_find_any (hw))) {
827
        if (!hw->pcm_ops)
828
            continue;
829

    
830
        hw->pcm_ops->ctl (hw, reason ? VOICE_ENABLE : VOICE_DISABLE);
831
    }
832
}
833

    
834
static void audio_atexit (void)
835
{
836
    HWVoice *hw = NULL;
837

    
838
    while ((hw = pcm_hw_find_any (hw))) {
839
        if (!hw->pcm_ops)
840
            continue;
841

    
842
        hw->pcm_ops->ctl (hw, VOICE_DISABLE);
843
        hw->pcm_ops->fini (hw);
844
    }
845
    audio_state.drv->fini (audio_state.opaque);
846
}
847

    
848
static void audio_save (QEMUFile *f, void *opaque)
849
{
850
}
851

    
852
static int audio_load (QEMUFile *f, void *opaque, int version_id)
853
{
854
    if (version_id != 1)
855
        return -EINVAL;
856

    
857
    return 0;
858
}
859

    
860
void AUD_init (void)
861
{
862
    int i;
863
    int done = 0;
864
    const char *drvname;
865

    
866
    audio_state.fixed_format =
867
        !!audio_get_conf_int (QC_FIXED_FORMAT, audio_state.fixed_format);
868
    audio_state.fixed_freq =
869
        audio_get_conf_int (QC_FIXED_FREQ, audio_state.fixed_freq);
870
    audio_state.nb_hw_voices =
871
        audio_get_conf_int (QC_VOICES, audio_state.nb_hw_voices);
872

    
873
    if (audio_state.nb_hw_voices <= 0) {
874
        dolog ("Bogus number of voices %d, resetting to 1\n",
875
               audio_state.nb_hw_voices);
876
    }
877

    
878
    drvname = audio_get_conf_str (QC_AUDIO_DRV, NULL);
879
    if (drvname) {
880
        int found = 0;
881
        for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
882
            if (!strcmp (drvname, drvtab[i]->name)) {
883
                done = voice_init (drvtab[i]);
884
                found = 1;
885
                break;
886
            }
887
        }
888
        if (!found) {
889
            dolog ("Unknown audio driver `%s'\n", drvname);
890
        }
891
    }
892

    
893
    qemu_add_vm_stop_handler (audio_vm_stop_handler, NULL);
894
    atexit (audio_atexit);
895

    
896
    if (!done) {
897
        for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
898
            if (drvtab[i]->can_be_default)
899
                done = voice_init (drvtab[i]);
900
        }
901
    }
902

    
903
    audio_state.ticks_threshold = ticks_per_sec / 50;
904
    audio_state.freq_threshold = 100;
905

    
906
    register_savevm ("audio", 0, 1, audio_save, audio_load, NULL);
907
    if (!done) {
908
        dolog ("Can not initialize audio subsystem\n");
909
        voice_init (&no_output_driver);
910
    }
911
}