Statistics
| Branch: | Revision:

root / audio / audio.c @ 1d6e34fd

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_WAV_AUDIO
28

    
29
#include "audio/audio_int.h"
30

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

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

    
43
static HWVoice *hw_voices;
44

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

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

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

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

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

    
81
    return val;
82
}
83

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
200
    pcm_hw_fini (hw);
201
}
202

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
377
#define ADVANCE(hw) \
378
    ((hw) ? advance (hw, audio_state.drv->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 CONFIG_FMOD
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
}