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

30
31
#define AUDIO_CAP "audio"
#include "audio_int.h"
bellard's avatar
bellard committed
32

33
34
35
/* #define DEBUG_PLIVE */
/* #define DEBUG_LIVE */
/* #define DEBUG_OUT */
36
/* #define DEBUG_CAPTURE */
malc's avatar
malc committed
37
/* #define DEBUG_POLL */
bellard's avatar
bellard committed
38

bellard's avatar
bellard committed
39
40
#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"

41
42
43
44
45

/* Order of CONFIG_AUDIO_DRIVERS is import.
   The 1st one is the one used by default, that is the reason
    that we generate the list.
*/
46
static struct audio_driver *drvtab[] = {
Gerd Hoffmann's avatar
Gerd Hoffmann committed
47
48
49
#ifdef CONFIG_SPICE
    &spice_audio_driver,
#endif
50
    CONFIG_AUDIO_DRIVERS
51
52
53
    &no_audio_driver,
    &wav_audio_driver
};
bellard's avatar
bellard committed
54

bellard's avatar
bellard committed
55
56
57
58
struct fixed_settings {
    int enabled;
    int nb_voices;
    int greedy;
malc's avatar
malc committed
59
    struct audsettings settings;
bellard's avatar
bellard committed
60
61
62
63
64
65
};

static struct {
    struct fixed_settings fixed_out;
    struct fixed_settings fixed_in;
    union {
malc's avatar
malc committed
66
        int hertz;
bellard's avatar
bellard committed
67
68
69
        int64_t ticks;
    } period;
    int plive;
bellard's avatar
bellard committed
70
    int log_to_monitor;
malc's avatar
malc committed
71
72
    int try_poll_in;
    int try_poll_out;
bellard's avatar
bellard committed
73
} conf = {
74
75
76
77
78
79
80
81
82
    .fixed_out = { /* DAC fixed settings */
        .enabled = 1,
        .nb_voices = 1,
        .greedy = 1,
        .settings = {
            .freq = 44100,
            .nchannels = 2,
            .fmt = AUD_FMT_S16,
            .endianness =  AUDIO_HOST_ENDIANNESS,
bellard's avatar
bellard committed
83
84
85
        }
    },

86
87
88
89
90
91
92
93
94
    .fixed_in = { /* ADC fixed settings */
        .enabled = 1,
        .nb_voices = 1,
        .greedy = 1,
        .settings = {
            .freq = 44100,
            .nchannels = 2,
            .fmt = AUD_FMT_S16,
            .endianness = AUDIO_HOST_ENDIANNESS,
bellard's avatar
bellard committed
95
96
97
        }
    },

malc's avatar
malc committed
98
    .period = { .hertz = 250 },
99
100
    .plive = 0,
    .log_to_monitor = 0,
malc's avatar
malc committed
101
102
    .try_poll_in = 1,
    .try_poll_out = 1,
103
104
};

bellard's avatar
bellard committed
105
106
static AudioState glob_audio_state;

107
const struct mixeng_volume nominal_volume = {
108
    .mute = 0,
109
#ifdef FLOAT_MIXENG
110
111
    .r = 1.0,
    .l = 1.0,
112
#else
113
114
    .r = 1ULL << 32,
    .l = 1ULL << 32,
115
#endif
bellard's avatar
bellard committed
116
117
};

118
119
120
#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
#error No its not
#else
121
122
123
static void audio_print_options (const char *prefix,
                                 struct audio_option *opt);

124
int audio_bug (const char *funcname, int cond)
bellard's avatar
bellard committed
125
{
126
127
128
    if (cond) {
        static int shown;

129
        AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
130
        if (!shown) {
131
132
            struct audio_driver *d;

133
134
            shown = 1;
            AUD_log (NULL, "Save all your work and restart without audio\n");
malc's avatar
malc committed
135
            AUD_log (NULL, "Please send bug report to av1474@comtv.ru\n");
136
            AUD_log (NULL, "I am sorry\n");
137
138
139
140
            d = glob_audio_state.drv;
            if (d) {
                audio_print_options (d->name, d->options);
            }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
        }
        AUD_log (NULL, "Context:\n");

#if defined AUDIO_BREAKPOINT_ON_BUG
#  if defined HOST_I386
#    if defined __GNUC__
        __asm__ ("int3");
#    elif defined _MSC_VER
        _asm _emit 0xcc;
#    else
        abort ();
#    endif
#  else
        abort ();
#  endif
#endif
bellard's avatar
bellard committed
157
158
    }

159
    return cond;
bellard's avatar
bellard committed
160
}
161
#endif
bellard's avatar
bellard committed
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
static inline int audio_bits_to_index (int bits)
{
    switch (bits) {
    case 8:
        return 0;

    case 16:
        return 1;

    case 32:
        return 2;

    default:
        audio_bug ("bits_to_index", 1);
        AUD_log (NULL, "invalid bits %d\n", bits);
        return 0;
    }
}

bellard's avatar
bellard committed
182
183
184
185
186
187
188
189
190
191
192
193
194
void *audio_calloc (const char *funcname, int nmemb, size_t size)
{
    int cond;
    size_t len;

    len = nmemb * size;
    cond = !nmemb || !size;
    cond |= nmemb < 0;
    cond |= len < size;

    if (audio_bug ("audio_calloc", cond)) {
        AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
                 funcname);
bellard's avatar
bellard committed
195
        AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
bellard's avatar
bellard committed
196
197
198
        return NULL;
    }

199
    return g_malloc0 (len);
bellard's avatar
bellard committed
200
201
}

202
static char *audio_alloc_prefix (const char *s)
bellard's avatar
bellard committed
203
{
204
    const char qemu_prefix[] = "QEMU_";
205
206
    size_t len, i;
    char *r, *u;
bellard's avatar
bellard committed
207

208
209
210
    if (!s) {
        return NULL;
    }
bellard's avatar
bellard committed
211

212
    len = strlen (s);
213
    r = g_malloc (len + sizeof (qemu_prefix));
bellard's avatar
bellard committed
214

215
    u = r + sizeof (qemu_prefix) - 1;
bellard's avatar
bellard committed
216

217
218
    pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix);
    pstrcat (r, len + sizeof (qemu_prefix), s);
219

220
221
    for (i = 0; i < len; ++i) {
        u[i] = qemu_toupper(u[i]);
bellard's avatar
bellard committed
222
    }
223

224
    return r;
bellard's avatar
bellard committed
225
226
}

227
static const char *audio_audfmt_to_string (audfmt_e fmt)
bellard's avatar
bellard committed
228
{
229
230
231
    switch (fmt) {
    case AUD_FMT_U8:
        return "U8";
bellard's avatar
bellard committed
232

233
234
    case AUD_FMT_U16:
        return "U16";
bellard's avatar
bellard committed
235
236

    case AUD_FMT_S8:
237
        return "S8";
bellard's avatar
bellard committed
238
239

    case AUD_FMT_S16:
240
        return "S16";
241
242
243
244
245
246

    case AUD_FMT_U32:
        return "U32";

    case AUD_FMT_S32:
        return "S32";
bellard's avatar
bellard committed
247
248
    }

249
250
    dolog ("Bogus audfmt %d returning S16\n", fmt);
    return "S16";
bellard's avatar
bellard committed
251
252
}

253
254
static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
                                        int *defaultp)
bellard's avatar
bellard committed
255
{
256
257
258
259
260
261
262
263
    if (!strcasecmp (s, "u8")) {
        *defaultp = 0;
        return AUD_FMT_U8;
    }
    else if (!strcasecmp (s, "u16")) {
        *defaultp = 0;
        return AUD_FMT_U16;
    }
264
265
266
267
    else if (!strcasecmp (s, "u32")) {
        *defaultp = 0;
        return AUD_FMT_U32;
    }
268
269
270
271
272
273
274
275
    else if (!strcasecmp (s, "s8")) {
        *defaultp = 0;
        return AUD_FMT_S8;
    }
    else if (!strcasecmp (s, "s16")) {
        *defaultp = 0;
        return AUD_FMT_S16;
    }
276
277
278
279
    else if (!strcasecmp (s, "s32")) {
        *defaultp = 0;
        return AUD_FMT_S32;
    }
280
281
282
283
284
285
    else {
        dolog ("Bogus audio format `%s' using %s\n",
               s, audio_audfmt_to_string (defval));
        *defaultp = 1;
        return defval;
    }
bellard's avatar
bellard committed
286
287
}

288
289
290
static audfmt_e audio_get_conf_fmt (const char *envname,
                                    audfmt_e defval,
                                    int *defaultp)
bellard's avatar
bellard committed
291
{
292
293
294
295
    const char *var = getenv (envname);
    if (!var) {
        *defaultp = 1;
        return defval;
bellard's avatar
bellard committed
296
    }
297
    return audio_string_to_audfmt (var, defval, defaultp);
bellard's avatar
bellard committed
298
299
}

300
static int audio_get_conf_int (const char *key, int defval, int *defaultp)
bellard's avatar
bellard committed
301
{
302
303
    int val;
    char *strval;
bellard's avatar
bellard committed
304

305
306
307
308
309
310
311
312
313
314
    strval = getenv (key);
    if (strval) {
        *defaultp = 0;
        val = atoi (strval);
        return val;
    }
    else {
        *defaultp = 1;
        return defval;
    }
bellard's avatar
bellard committed
315
316
}

317
318
319
static const char *audio_get_conf_str (const char *key,
                                       const char *defval,
                                       int *defaultp)
bellard's avatar
bellard committed
320
{
321
322
323
324
325
326
327
328
    const char *val = getenv (key);
    if (!val) {
        *defaultp = 1;
        return defval;
    }
    else {
        *defaultp = 0;
        return val;
bellard's avatar
bellard committed
329
330
331
    }
}

bellard's avatar
bellard committed
332
void AUD_vlog (const char *cap, const char *fmt, va_list ap)
bellard's avatar
bellard committed
333
{
bellard's avatar
bellard committed
334
335
    if (conf.log_to_monitor) {
        if (cap) {
336
            monitor_printf(default_mon, "%s: ", cap);
bellard's avatar
bellard committed
337
338
        }

339
        monitor_vprintf(default_mon, fmt, ap);
bellard's avatar
bellard committed
340
341
342
343
344
345
346
    }
    else {
        if (cap) {
            fprintf (stderr, "%s: ", cap);
        }

        vfprintf (stderr, fmt, ap);
bellard's avatar
bellard committed
347
348
349
    }
}

bellard's avatar
bellard committed
350
void AUD_log (const char *cap, const char *fmt, ...)
bellard's avatar
bellard committed
351
{
bellard's avatar
bellard committed
352
353
354
355
356
    va_list ap;

    va_start (ap, fmt);
    AUD_vlog (cap, fmt, ap);
    va_end (ap);
bellard's avatar
bellard committed
357
358
}

359
360
static void audio_print_options (const char *prefix,
                                 struct audio_option *opt)
bellard's avatar
bellard committed
361
{
362
363
364
365
366
367
368
369
370
    char *uprefix;

    if (!prefix) {
        dolog ("No prefix specified\n");
        return;
    }

    if (!opt) {
        dolog ("No options\n");
bellard's avatar
bellard committed
371
        return;
372
    }
bellard's avatar
bellard committed
373

374
    uprefix = audio_alloc_prefix (prefix);
bellard's avatar
bellard committed
375

376
377
378
    for (; opt->name; opt++) {
        const char *state = "default";
        printf ("  %s_%s: ", uprefix, opt->name);
bellard's avatar
bellard committed
379

ths's avatar
ths committed
380
        if (opt->overriddenp && *opt->overriddenp) {
381
382
            state = "current";
        }
bellard's avatar
bellard committed
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
        switch (opt->tag) {
        case AUD_OPT_BOOL:
            {
                int *intp = opt->valp;
                printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
            }
            break;

        case AUD_OPT_INT:
            {
                int *intp = opt->valp;
                printf ("integer, %s = %d\n", state, *intp);
            }
            break;

        case AUD_OPT_FMT:
            {
                audfmt_e *fmtp = opt->valp;
                printf (
403
                    "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
404
405
406
407
408
409
410
411
412
413
414
415
                    state,
                    audio_audfmt_to_string (*fmtp)
                    );
            }
            break;

        case AUD_OPT_STR:
            {
                const char **strp = opt->valp;
                printf ("string, %s = %s\n",
                        state,
                        *strp ? *strp : "(not set)");
bellard's avatar
bellard committed
416
            }
417
418
419
420
421
422
423
            break;

        default:
            printf ("???\n");
            dolog ("Bad value tag for option %s_%s %d\n",
                   uprefix, opt->name, opt->tag);
            break;
bellard's avatar
bellard committed
424
        }
425
        printf ("    %s\n", opt->descr);
bellard's avatar
bellard committed
426
    }
427

428
    g_free (uprefix);
bellard's avatar
bellard committed
429
430
}

431
432
static void audio_process_options (const char *prefix,
                                   struct audio_option *opt)
bellard's avatar
bellard committed
433
{
434
435
    char *optname;
    const char qemu_prefix[] = "QEMU_";
blueswir1's avatar
blueswir1 committed
436
    size_t preflen, optlen;
bellard's avatar
bellard committed
437

438
439
440
441
    if (audio_bug (AUDIO_FUNC, !prefix)) {
        dolog ("prefix = NULL\n");
        return;
    }
bellard's avatar
bellard committed
442

443
444
445
    if (audio_bug (AUDIO_FUNC, !opt)) {
        dolog ("opt = NULL\n");
        return;
bellard's avatar
bellard committed
446
447
    }

448
    preflen = strlen (prefix);
bellard's avatar
bellard committed
449

450
451
452
453
454
455
456
457
458
459
460
    for (; opt->name; opt++) {
        size_t len, i;
        int def;

        if (!opt->valp) {
            dolog ("Option value pointer for `%s' is not set\n",
                   opt->name);
            continue;
        }

        len = strlen (opt->name);
bellard's avatar
bellard committed
461
462
463
        /* len of opt->name + len of prefix + size of qemu_prefix
         * (includes trailing zero) + zero + underscore (on behalf of
         * sizeof) */
blueswir1's avatar
blueswir1 committed
464
        optlen = len + preflen + sizeof (qemu_prefix) + 1;
465
        optname = g_malloc (optlen);
466

blueswir1's avatar
blueswir1 committed
467
        pstrcpy (optname, optlen, qemu_prefix);
bellard's avatar
bellard committed
468
469

        /* copy while upper-casing, including trailing zero */
470
        for (i = 0; i <= preflen; ++i) {
471
            optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]);
472
        }
blueswir1's avatar
blueswir1 committed
473
474
        pstrcat (optname, optlen, "_");
        pstrcat (optname, optlen, opt->name);
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

        def = 1;
        switch (opt->tag) {
        case AUD_OPT_BOOL:
        case AUD_OPT_INT:
            {
                int *intp = opt->valp;
                *intp = audio_get_conf_int (optname, *intp, &def);
            }
            break;

        case AUD_OPT_FMT:
            {
                audfmt_e *fmtp = opt->valp;
                *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
            }
            break;

        case AUD_OPT_STR:
            {
                const char **strp = opt->valp;
                *strp = audio_get_conf_str (optname, *strp, &def);
            }
            break;

        default:
            dolog ("Bad value tag for option `%s' - %d\n",
                   optname, opt->tag);
bellard's avatar
bellard committed
503
504
505
            break;
        }

ths's avatar
ths committed
506
507
        if (!opt->overriddenp) {
            opt->overriddenp = &opt->overridden;
508
        }
ths's avatar
ths committed
509
        *opt->overriddenp = !def;
510
        g_free (optname);
511
    }
bellard's avatar
bellard committed
512
513
}

malc's avatar
malc committed
514
static void audio_print_settings (struct audsettings *as)
bellard's avatar
bellard committed
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
{
    dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);

    switch (as->fmt) {
    case AUD_FMT_S8:
        AUD_log (NULL, "S8");
        break;
    case AUD_FMT_U8:
        AUD_log (NULL, "U8");
        break;
    case AUD_FMT_S16:
        AUD_log (NULL, "S16");
        break;
    case AUD_FMT_U16:
        AUD_log (NULL, "U16");
        break;
malc's avatar
malc committed
531
532
533
534
535
536
    case AUD_FMT_S32:
        AUD_log (NULL, "S32");
        break;
    case AUD_FMT_U32:
        AUD_log (NULL, "U32");
        break;
bellard's avatar
bellard committed
537
538
539
540
    default:
        AUD_log (NULL, "invalid(%d)", as->fmt);
        break;
    }
bellard's avatar
bellard committed
541
542

    AUD_log (NULL, " endianness=");
bellard's avatar
bellard committed
543
544
545
546
547
548
549
550
551
552
553
    switch (as->endianness) {
    case 0:
        AUD_log (NULL, "little");
        break;
    case 1:
        AUD_log (NULL, "big");
        break;
    default:
        AUD_log (NULL, "invalid");
        break;
    }
bellard's avatar
bellard committed
554
555
556
    AUD_log (NULL, "\n");
}

malc's avatar
malc committed
557
static int audio_validate_settings (struct audsettings *as)
bellard's avatar
bellard committed
558
559
560
561
{
    int invalid;

    invalid = as->nchannels != 1 && as->nchannels != 2;
bellard's avatar
bellard committed
562
    invalid |= as->endianness != 0 && as->endianness != 1;
bellard's avatar
bellard committed
563
564
565
566
567
568

    switch (as->fmt) {
    case AUD_FMT_S8:
    case AUD_FMT_U8:
    case AUD_FMT_S16:
    case AUD_FMT_U16:
569
570
    case AUD_FMT_S32:
    case AUD_FMT_U32:
bellard's avatar
bellard committed
571
572
573
574
575
576
577
        break;
    default:
        invalid = 1;
        break;
    }

    invalid |= as->freq <= 0;
bellard's avatar
bellard committed
578
    return invalid ? -1 : 0;
bellard's avatar
bellard committed
579
580
}

malc's avatar
malc committed
581
static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *as)
bellard's avatar
bellard committed
582
{
583
    int bits = 8, sign = 0;
bellard's avatar
bellard committed
584

bellard's avatar
bellard committed
585
    switch (as->fmt) {
586
587
    case AUD_FMT_S8:
        sign = 1;
588
        /* fall through */
589
590
591
592
593
    case AUD_FMT_U8:
        break;

    case AUD_FMT_S16:
        sign = 1;
594
        /* fall through */
595
596
597
    case AUD_FMT_U16:
        bits = 16;
        break;
598
599
600

    case AUD_FMT_S32:
        sign = 1;
601
        /* fall through */
602
603
604
    case AUD_FMT_U32:
        bits = 32;
        break;
bellard's avatar
bellard committed
605
    }
bellard's avatar
bellard committed
606
607
    return info->freq == as->freq
        && info->nchannels == as->nchannels
608
        && info->sign == sign
bellard's avatar
bellard committed
609
610
        && info->bits == bits
        && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
611
}
bellard's avatar
bellard committed
612

malc's avatar
malc committed
613
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
614
{
615
    int bits = 8, sign = 0, shift = 0;
616

bellard's avatar
bellard committed
617
    switch (as->fmt) {
bellard's avatar
bellard committed
618
619
620
621
622
623
624
625
626
    case AUD_FMT_S8:
        sign = 1;
    case AUD_FMT_U8:
        break;

    case AUD_FMT_S16:
        sign = 1;
    case AUD_FMT_U16:
        bits = 16;
627
628
629
630
631
632
633
634
        shift = 1;
        break;

    case AUD_FMT_S32:
        sign = 1;
    case AUD_FMT_U32:
        bits = 32;
        shift = 2;
bellard's avatar
bellard committed
635
636
637
        break;
    }

bellard's avatar
bellard committed
638
    info->freq = as->freq;
639
640
    info->bits = bits;
    info->sign = sign;
bellard's avatar
bellard committed
641
    info->nchannels = as->nchannels;
642
    info->shift = (as->nchannels == 2) + shift;
643
644
    info->align = (1 << info->shift) - 1;
    info->bytes_per_second = info->freq << info->shift;
bellard's avatar
bellard committed
645
    info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
bellard's avatar
bellard committed
646
647
}

648
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
bellard's avatar
bellard committed
649
{
650
651
652
653
654
    if (!len) {
        return;
    }

    if (info->sign) {
655
        memset (buf, 0x00, len << info->shift);
bellard's avatar
bellard committed
656
657
    }
    else {
658
659
        switch (info->bits) {
        case 8:
660
            memset (buf, 0x80, len << info->shift);
661
            break;
662

663
664
665
666
667
668
669
670
671
672
673
674
675
676
        case 16:
            {
                int i;
                uint16_t *p = buf;
                int shift = info->nchannels - 1;
                short s = INT16_MAX;

                if (info->swap_endianness) {
                    s = bswap16 (s);
                }

                for (i = 0; i < len << shift; i++) {
                    p[i] = s;
                }
677
            }
678
679
680
681
682
683
684
685
686
687
688
689
            break;

        case 32:
            {
                int i;
                uint32_t *p = buf;
                int shift = info->nchannels - 1;
                int32_t s = INT32_MAX;

                if (info->swap_endianness) {
                    s = bswap32 (s);
                }
690

691
692
693
                for (i = 0; i < len << shift; i++) {
                    p[i] = s;
                }
694
            }
695
696
697
698
699
700
            break;

        default:
            AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
                     info->bits);
            break;
701
        }
bellard's avatar
bellard committed
702
703
704
    }
}

705
706
707
/*
 * Capture
 */
708
static void noop_conv (struct st_sample *dst, const void *src, int samples)
709
710
711
712
713
714
715
{
    (void) src;
    (void) dst;
    (void) samples;
}

static CaptureVoiceOut *audio_pcm_capture_find_specific (
malc's avatar
malc committed
716
    struct audsettings *as
717
718
719
    )
{
    CaptureVoiceOut *cap;
720
    AudioState *s = &glob_audio_state;
721
722

    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
bellard's avatar
bellard committed
723
        if (audio_pcm_info_eq (&cap->hw.info, as)) {
724
725
726
727
728
729
            return cap;
        }
    }
    return NULL;
}

bellard's avatar
bellard committed
730
static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
731
{
bellard's avatar
bellard committed
732
733
734
735
736
737
738
739
740
    struct capture_callback *cb;

#ifdef DEBUG_CAPTURE
    dolog ("notification %d sent\n", cmd);
#endif
    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
        cb->ops.notify (cb->opaque, cmd);
    }
}
741

bellard's avatar
bellard committed
742
743
744
745
static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
{
    if (cap->hw.enabled != enabled) {
        audcnotification_e cmd;
746
        cap->hw.enabled = enabled;
bellard's avatar
bellard committed
747
748
        cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
        audio_notify_capture (cap, cmd);
749
750
751
752
753
754
755
756
757
    }
}

static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
{
    HWVoiceOut *hw = &cap->hw;
    SWVoiceOut *sw;
    int enabled = 0;

bellard's avatar
bellard committed
758
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
759
760
761
762
763
        if (sw->active) {
            enabled = 1;
            break;
        }
    }
bellard's avatar
bellard committed
764
    audio_capture_maybe_changed (cap, enabled);
765
766
767
768
}

static void audio_detach_capture (HWVoiceOut *hw)
{
bellard's avatar
bellard committed
769
770
771
772
773
774
775
    SWVoiceCap *sc = hw->cap_head.lh_first;

    while (sc) {
        SWVoiceCap *sc1 = sc->entries.le_next;
        SWVoiceOut *sw = &sc->sw;
        CaptureVoiceOut *cap = sc->cap;
        int was_active = sw->active;
776
777
778
779
780
781

        if (sw->rate) {
            st_rate_stop (sw->rate);
            sw->rate = NULL;
        }

Blue Swirl's avatar
Blue Swirl committed
782
783
        QLIST_REMOVE (sw, entries);
        QLIST_REMOVE (sc, entries);
784
        g_free (sc);
bellard's avatar
bellard committed
785
786
787
788
789
790
791
        if (was_active) {
            /* We have removed soft voice from the capture:
               this might have changed the overall status of the capture
               since this might have been the only active voice */
            audio_recalc_and_notify_capture (cap);
        }
        sc = sc1;
792
793
794
    }
}

795
static int audio_attach_capture (HWVoiceOut *hw)
796
{
797
    AudioState *s = &glob_audio_state;
798
799
800
801
    CaptureVoiceOut *cap;

    audio_detach_capture (hw);
    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
bellard's avatar
bellard committed
802
        SWVoiceCap *sc;
803
        SWVoiceOut *sw;
bellard's avatar
bellard committed
804
        HWVoiceOut *hw_cap = &cap->hw;
805

bellard's avatar
bellard committed
806
807
        sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
        if (!sc) {
808
            dolog ("Could not allocate soft capture voice (%zu bytes)\n",
bellard's avatar
bellard committed
809
                   sizeof (*sc));
810
811
812
            return -1;
        }

bellard's avatar
bellard committed
813
814
        sc->cap = cap;
        sw = &sc->sw;
815
        sw->hw = hw_cap;
bellard's avatar
bellard committed
816
        sw->info = hw->info;
817
818
819
820
        sw->empty = 1;
        sw->active = hw->enabled;
        sw->conv = noop_conv;
        sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
malc's avatar
malc committed
821
        sw->vol = nominal_volume;
822
823
824
        sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
        if (!sw->rate) {
            dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
825
            g_free (sw);
826
827
            return -1;
        }
Blue Swirl's avatar
Blue Swirl committed
828
829
        QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
        QLIST_INSERT_HEAD (&hw->cap_head, sc, entries);
bellard's avatar
bellard committed
830
#ifdef DEBUG_CAPTURE
831
832
833
        sw->name = g_strdup_printf ("for %p %d,%d,%d",
                                    hw, sw->info.freq, sw->info.bits,
                                    sw->info.nchannels);
bellard's avatar
bellard committed
834
835
        dolog ("Added %s active = %d\n", sw->name, sw->active);
#endif
836
        if (sw->active) {
bellard's avatar
bellard committed
837
            audio_capture_maybe_changed (cap, 1);
838
839
840
841
842
        }
    }
    return 0;
}

843
844
845
/*
 * Hard voice (capture)
 */
bellard's avatar
bellard committed
846
static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
bellard's avatar
bellard committed
847
{
848
849
850
851
852
853
854
    SWVoiceIn *sw;
    int m = hw->total_samples_captured;

    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
        if (sw->active) {
            m = audio_MIN (m, sw->total_hw_samples_acquired);
        }
bellard's avatar
bellard committed
855
    }
856
    return m;
bellard's avatar
bellard committed
857
858
}

859
int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
bellard's avatar
bellard committed
860
{
861
862
863
864
    int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
        return 0;
bellard's avatar
bellard committed
865
    }
866
    return live;
bellard's avatar
bellard committed
867
868
}

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
                           int live, int pending)
{
    int left = hw->samples - pending;
    int len = audio_MIN (left, live);
    int clipped = 0;

    while (len) {
        struct st_sample *src = hw->mix_buf + hw->rpos;
        uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift);
        int samples_till_end_of_buf = hw->samples - hw->rpos;
        int samples_to_clip = audio_MIN (len, samples_till_end_of_buf);

        hw->clip (dst, src, samples_to_clip);

        hw->rpos = (hw->rpos + samples_to_clip) % hw->samples;
        len -= samples_to_clip;
        clipped += samples_to_clip;
    }
    return clipped;
}

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
/*
 * Soft voice (capture)
 */
static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
{
    HWVoiceIn *hw = sw->hw;
    int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
    int rpos;

    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
        dolog ("live=%d hw->samples=%d\n", live, hw->samples);
        return 0;
    }

    rpos = hw->wpos - live;
    if (rpos >= 0) {
        return rpos;
bellard's avatar
bellard committed
908
909
    }
    else {
910
        return hw->samples + rpos;
bellard's avatar
bellard committed
911
912
913
    }
}

914
int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
bellard's avatar
bellard committed
915
{
916
917
    HWVoiceIn *hw = sw->hw;
    int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
malc's avatar
malc committed
918
    struct st_sample *src, *dst = sw->buf;
919
920
921
922
923
924
925
926
927
928
929
930
931

    rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;

    live = hw->total_samples_captured - sw->total_hw_samples_acquired;
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
        dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
        return 0;
    }

    samples = size >> sw->info.shift;
    if (!live) {
        return 0;
    }
bellard's avatar
bellard committed
932

933
934
    swlim = (live * sw->ratio) >> 32;
    swlim = audio_MIN (swlim, samples);
bellard's avatar
bellard committed
935

936
937
938
939
940
941
942
    while (swlim) {
        src = hw->conv_buf + rpos;
        isamp = hw->wpos - rpos;
        /* XXX: <= ? */
        if (isamp <= 0) {
            isamp = hw->samples - rpos;
        }
bellard's avatar
bellard committed
943

944
945
946
947
        if (!isamp) {
            break;
        }
        osamp = swlim;
bellard's avatar
bellard committed
948

949
950
        if (audio_bug (AUDIO_FUNC, osamp < 0)) {
            dolog ("osamp=%d\n", osamp);
bellard's avatar
bellard committed
951
            return 0;
952
        }
bellard's avatar
bellard committed
953

954
955
956
957
958
959
960
        st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
        swlim -= osamp;
        rpos = (rpos + isamp) % hw->samples;
        dst += osamp;
        ret += osamp;
        total += isamp;
    }
bellard's avatar
bellard committed
961

962
963
964
    if (!(hw->ctl_caps & VOICE_VOLUME_CAP)) {
        mixeng_volume (sw->buf, ret, &sw->vol);
    }
965

bellard's avatar
bellard committed
966
    sw->clip (buf, sw->buf, ret);
967
968
    sw->total_hw_samples_acquired += total;
    return ret << sw->info.shift;
bellard's avatar
bellard committed
969
970
}

971
972
973
/*
 * Hard voice (playback)
 */
bellard's avatar
bellard committed
974
static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
975
{
bellard's avatar
bellard committed
976
977
978
    SWVoiceOut *sw;
    int m = INT_MAX;
    int nb_live = 0;
bellard's avatar
bellard committed
979

bellard's avatar
bellard committed
980
981
982
983
984
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
        if (sw->active || !sw->empty) {
            m = audio_MIN (m, sw->total_hw_samples_mixed);
            nb_live += 1;
        }
bellard's avatar
bellard committed
985
    }
bellard's avatar
bellard committed
986
987
988

    *nb_livep = nb_live;
    return m;
989
}
bellard's avatar
bellard committed
990

malc's avatar
malc committed
991
static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
992
993
{
    int smin;
malc's avatar
malc committed
994
    int nb_live1;
bellard's avatar
bellard committed
995

malc's avatar
malc committed
996
997
998
    smin = audio_pcm_hw_find_min_out (hw, &nb_live1);
    if (nb_live) {
        *nb_live = nb_live1;
bellard's avatar
bellard committed
999
    }
malc's avatar
malc committed
1000
1001

    if (nb_live1) {
1002
1003
1004
1005
1006
        int live = smin;

        if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
            dolog ("live=%d hw->samples=%d\n", live, hw->samples);
            return 0;
bellard's avatar
bellard committed
1007
        }
1008
        return live;
bellard's avatar
bellard committed
1009
    }
malc's avatar
malc committed
1010
    return 0;
bellard's avatar
bellard committed
1011
1012
}

1013
1014
1015
1016
/*
 * Soft voice (playback)
 */
int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
bellard's avatar
bellard committed
1017
{
1018
1019
    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
    int ret = 0, pos = 0, total = 0;
bellard's avatar
bellard committed
1020

1021
1022
1023
    if (!sw) {
        return size;
    }
bellard's avatar
bellard committed
1024

1025
    hwsamples = sw->hw->samples;
bellard's avatar
bellard committed
1026

1027
1028
1029
1030
1031
    live = sw->total_hw_samples_mixed;
    if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
        dolog ("live=%d hw->samples=%d\n", live, hwsamples);
        return 0;
    }
bellard's avatar
bellard committed
1032

1033
    if (live == hwsamples) {
bellard's avatar
bellard committed
1034
1035
1036
#ifdef DEBUG_OUT
        dolog ("%s is full %d\n", sw->name, live);
#endif
1037
1038
        return 0;
    }
bellard's avatar
bellard committed
1039

1040
1041
    wpos = (sw->hw->rpos + live) % hwsamples;
    samples = size >> sw->info.shift;
bellard's avatar
bellard committed
1042

1043
1044
1045
1046
    dead = hwsamples - live;
    swlim = ((int64_t) dead << 32) / sw->ratio;
    swlim = audio_MIN (swlim, samples);
    if (swlim) {
1047
        sw->conv (sw->buf, buf, swlim);
1048
1049
1050
1051

        if (!(sw->hw->ctl_caps & VOICE_VOLUME_CAP)) {
            mixeng_volume (sw->buf, swlim, &sw->vol);
        }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
    }

    while (swlim) {
        dead = hwsamples - live;
        left = hwsamples - wpos;
        blck = audio_MIN (dead, left);
        if (!blck) {
            break;
        }
        isamp = swlim;
        osamp = blck;
        st_rate_flow_mix (
            sw->rate,
            sw->buf + pos,
            sw->hw->mix_buf + wpos,
            &isamp,
            &osamp
            );
        ret += isamp;
        swlim -= isamp;
        pos += isamp;
        live += osamp;
        wpos = (wpos + osamp) % hwsamples;
        total += osamp;
    }

    sw->total_hw_samples_mixed += total;
    sw->empty = sw->total_hw_samples_mixed == 0;

#ifdef DEBUG_OUT
    dolog (
bellard's avatar
bellard committed
1083
1084
        "%s: write size %d ret %d total sw %d\n",
        SW_NAME (sw),
1085
1086
        size >> sw->info.shift,
        ret,
bellard's avatar
bellard committed
1087
        sw->total_hw_samples_mixed
1088
1089
1090
1091
        );
#endif

    return ret << sw->info.shift;
bellard's avatar
bellard committed
1092
1093
}

1094
1095
#ifdef DEBUG_AUDIO
static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
bellard's avatar
bellard committed
1096
{
1097
1098
    dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
           cap, info->bits, info->sign, info->freq, info->nchannels);
bellard's avatar
bellard committed
1099
}
1100
#endif
bellard's avatar
bellard committed
1101

1102
1103
1104
1105
1106
#define DAC
#include "audio_template.h"
#undef DAC
#include "audio_template.h"

malc's avatar
malc committed
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
/*
 * Timer
 */
static int audio_is_timer_needed (void)
{
    HWVoiceIn *hwi = NULL;
    HWVoiceOut *hwo = NULL;

    while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
        if (!hwo->poll_mode) return 1;
    }
    while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
        if (!hwi->poll_mode) return 1;
    }
    return 0;
}

1124
static void audio_reset_timer (AudioState *s)
malc's avatar
malc committed
1125
1126
{
    if (audio_is_timer_needed ()) {
1127
        timer_mod (s->ts, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1);
malc's avatar
malc committed
1128
1129
    }
    else {
1130
        timer_del (s->ts);
malc's avatar
malc committed
1131
1132
1133
    }
}

1134
1135
1136
1137
1138
1139
static void audio_timer (void *opaque)
{
    audio_run ("timer");
    audio_reset_timer (opaque);
}

malc's avatar
malc committed
1140
1141
1142
/*
 * Public API
 */
1143
int AUD_write (SWVoiceOut *sw, void *buf, int size)
bellard's avatar
bellard committed
1144
{
1145
    int bytes;
bellard's avatar
bellard committed
1146

1147
1148
1149
1150
    if (!sw) {
        /* XXX: Consider options */
        return size;
    }
bellard's avatar
bellard committed
1151

1152
    if (!sw->hw->enabled) {
bellard's avatar
bellard committed
1153
        dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
bellard's avatar
bellard committed
1154
1155
1156
        return 0;
    }

1157
1158
1159
1160