audio.c 48.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 26 27 28
#include "hw/hw.h"
#include "audio.h"
#include "console.h"
#include "qemu-timer.h"
#include "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 */
bellard's avatar
bellard committed
37

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

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
static struct audio_driver *drvtab[] = {
#ifdef CONFIG_OSS
    &oss_audio_driver,
#endif
#ifdef CONFIG_ALSA
    &alsa_audio_driver,
#endif
#ifdef CONFIG_COREAUDIO
    &coreaudio_audio_driver,
#endif
#ifdef CONFIG_DSOUND
    &dsound_audio_driver,
#endif
#ifdef CONFIG_FMOD
    &fmod_audio_driver,
#endif
#ifdef CONFIG_SDL
    &sdl_audio_driver,
58 59 60
#endif
#ifdef CONFIG_ESD
    &esd_audio_driver,
61 62 63 64
#endif
    &no_audio_driver,
    &wav_audio_driver
};
bellard's avatar
bellard committed
65

bellard's avatar
bellard committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
struct fixed_settings {
    int enabled;
    int nb_voices;
    int greedy;
    audsettings_t settings;
};

static struct {
    struct fixed_settings fixed_out;
    struct fixed_settings fixed_in;
    union {
        int hz;
        int64_t ticks;
    } period;
    int plive;
bellard's avatar
bellard committed
81
    int log_to_monitor;
bellard's avatar
bellard committed
82 83 84 85 86 87 88 89
} conf = {
    {                           /* DAC fixed settings */
        1,                      /* enabled */
        1,                      /* nb_voices */
        1,                      /* greedy */
        {
            44100,              /* freq */
            2,                  /* nchannels */
90 91
            AUD_FMT_S16,        /* fmt */
            AUDIO_HOST_ENDIANNESS
bellard's avatar
bellard committed
92 93 94 95 96 97 98 99 100 101
        }
    },

    {                           /* ADC fixed settings */
        1,                      /* enabled */
        1,                      /* nb_voices */
        1,                      /* greedy */
        {
            44100,              /* freq */
            2,                  /* nchannels */
102 103
            AUD_FMT_S16,        /* fmt */
            AUDIO_HOST_ENDIANNESS
bellard's avatar
bellard committed
104 105 106
        }
    },

107
    { 0 },                      /* period */
bellard's avatar
bellard committed
108
    0,                          /* plive */
bellard's avatar
bellard committed
109
    0                           /* log_to_monitor */
110 111
};

bellard's avatar
bellard committed
112 113
static AudioState glob_audio_state;

114 115 116 117 118 119
volume_t nominal_volume = {
    0,
#ifdef FLOAT_MIXENG
    1.0,
    1.0
#else
120 121
    1ULL << 32,
    1ULL << 32
122
#endif
bellard's avatar
bellard committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
};

/* http://www.df.lth.se/~john_e/gems/gem002d.html */
/* http://www.multi-platforms.com/Tips/PopCount.htm */
uint32_t popcount (uint32_t u)
{
    u = ((u&0x55555555) + ((u>>1)&0x55555555));
    u = ((u&0x33333333) + ((u>>2)&0x33333333));
    u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
    u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
    u = ( u&0x0000ffff) + (u>>16);
    return u;
}

inline uint32_t lsbindex (uint32_t u)
{
    return popcount ((u&-u)-1);
}

142 143 144 145
#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
#error No its not
#else
int audio_bug (const char *funcname, int cond)
bellard's avatar
bellard committed
146
{
147 148 149
    if (cond) {
        static int shown;

150
        AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
        if (!shown) {
            shown = 1;
            AUD_log (NULL, "Save all your work and restart without audio\n");
            AUD_log (NULL, "Please send bug report to malc@pulsesoft.com\n");
            AUD_log (NULL, "I am sorry\n");
        }
        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
172 173
    }

174
    return cond;
bellard's avatar
bellard committed
175
}
176
#endif
bellard's avatar
bellard committed
177

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
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
197 198 199 200 201 202 203 204 205 206 207 208 209
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
210
        AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
bellard's avatar
bellard committed
211 212 213 214 215 216
        return NULL;
    }

    return qemu_mallocz (len);
}

217
static char *audio_alloc_prefix (const char *s)
bellard's avatar
bellard committed
218
{
219 220 221
    const char qemu_prefix[] = "QEMU_";
    size_t len;
    char *r;
bellard's avatar
bellard committed
222

223 224 225
    if (!s) {
        return NULL;
    }
bellard's avatar
bellard committed
226

227 228
    len = strlen (s);
    r = qemu_malloc (len + sizeof (qemu_prefix));
bellard's avatar
bellard committed
229

230 231 232
    if (r) {
        size_t i;
        char *u = r + sizeof (qemu_prefix) - 1;
bellard's avatar
bellard committed
233

234 235 236 237 238 239
        strcpy (r, qemu_prefix);
        strcat (r, s);

        for (i = 0; i < len; ++i) {
            u[i] = toupper (u[i]);
        }
bellard's avatar
bellard committed
240
    }
241
    return r;
bellard's avatar
bellard committed
242 243
}

244
static const char *audio_audfmt_to_string (audfmt_e fmt)
bellard's avatar
bellard committed
245
{
246 247 248
    switch (fmt) {
    case AUD_FMT_U8:
        return "U8";
bellard's avatar
bellard committed
249

250 251
    case AUD_FMT_U16:
        return "U16";
bellard's avatar
bellard committed
252 253

    case AUD_FMT_S8:
254
        return "S8";
bellard's avatar
bellard committed
255 256

    case AUD_FMT_S16:
257
        return "S16";
258 259 260 261 262 263

    case AUD_FMT_U32:
        return "U32";

    case AUD_FMT_S32:
        return "S32";
bellard's avatar
bellard committed
264 265
    }

266 267
    dolog ("Bogus audfmt %d returning S16\n", fmt);
    return "S16";
bellard's avatar
bellard committed
268 269
}

270 271
static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
                                        int *defaultp)
bellard's avatar
bellard committed
272
{
273 274 275 276 277 278 279 280
    if (!strcasecmp (s, "u8")) {
        *defaultp = 0;
        return AUD_FMT_U8;
    }
    else if (!strcasecmp (s, "u16")) {
        *defaultp = 0;
        return AUD_FMT_U16;
    }
281 282 283 284
    else if (!strcasecmp (s, "u32")) {
        *defaultp = 0;
        return AUD_FMT_U32;
    }
285 286 287 288 289 290 291 292
    else if (!strcasecmp (s, "s8")) {
        *defaultp = 0;
        return AUD_FMT_S8;
    }
    else if (!strcasecmp (s, "s16")) {
        *defaultp = 0;
        return AUD_FMT_S16;
    }
293 294 295 296
    else if (!strcasecmp (s, "s32")) {
        *defaultp = 0;
        return AUD_FMT_S32;
    }
297 298 299 300 301 302
    else {
        dolog ("Bogus audio format `%s' using %s\n",
               s, audio_audfmt_to_string (defval));
        *defaultp = 1;
        return defval;
    }
bellard's avatar
bellard committed
303 304
}

305 306 307
static audfmt_e audio_get_conf_fmt (const char *envname,
                                    audfmt_e defval,
                                    int *defaultp)
bellard's avatar
bellard committed
308
{
309 310 311 312
    const char *var = getenv (envname);
    if (!var) {
        *defaultp = 1;
        return defval;
bellard's avatar
bellard committed
313
    }
314
    return audio_string_to_audfmt (var, defval, defaultp);
bellard's avatar
bellard committed
315 316
}

317
static int audio_get_conf_int (const char *key, int defval, int *defaultp)
bellard's avatar
bellard committed
318
{
319 320
    int val;
    char *strval;
bellard's avatar
bellard committed
321

322 323 324 325 326 327 328 329 330 331
    strval = getenv (key);
    if (strval) {
        *defaultp = 0;
        val = atoi (strval);
        return val;
    }
    else {
        *defaultp = 1;
        return defval;
    }
bellard's avatar
bellard committed
332 333
}

334 335 336
static const char *audio_get_conf_str (const char *key,
                                       const char *defval,
                                       int *defaultp)
bellard's avatar
bellard committed
337
{
338 339 340 341 342 343 344 345
    const char *val = getenv (key);
    if (!val) {
        *defaultp = 1;
        return defval;
    }
    else {
        *defaultp = 0;
        return val;
bellard's avatar
bellard committed
346 347 348
    }
}

bellard's avatar
bellard committed
349
void AUD_vlog (const char *cap, const char *fmt, va_list ap)
bellard's avatar
bellard committed
350
{
bellard's avatar
bellard committed
351 352 353 354 355 356 357 358 359 360 361 362 363
    if (conf.log_to_monitor) {
        if (cap) {
            term_printf ("%s: ", cap);
        }

        term_vprintf (fmt, ap);
    }
    else {
        if (cap) {
            fprintf (stderr, "%s: ", cap);
        }

        vfprintf (stderr, fmt, ap);
bellard's avatar
bellard committed
364 365 366
    }
}

bellard's avatar
bellard committed
367
void AUD_log (const char *cap, const char *fmt, ...)
bellard's avatar
bellard committed
368
{
bellard's avatar
bellard committed
369 370 371 372 373
    va_list ap;

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

376 377
static void audio_print_options (const char *prefix,
                                 struct audio_option *opt)
bellard's avatar
bellard committed
378
{
379 380 381 382 383 384 385 386 387
    char *uprefix;

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

    if (!opt) {
        dolog ("No options\n");
bellard's avatar
bellard committed
388
        return;
389
    }
bellard's avatar
bellard committed
390

391
    uprefix = audio_alloc_prefix (prefix);
bellard's avatar
bellard committed
392

393 394 395
    for (; opt->name; opt++) {
        const char *state = "default";
        printf ("  %s_%s: ", uprefix, opt->name);
bellard's avatar
bellard committed
396

ths's avatar
ths committed
397
        if (opt->overriddenp && *opt->overriddenp) {
398 399
            state = "current";
        }
bellard's avatar
bellard committed
400

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
        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 (
420
                    "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
421 422 423 424 425 426 427 428 429 430 431 432
                    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
433
            }
434 435 436 437 438 439 440
            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
441
        }
442
        printf ("    %s\n", opt->descr);
bellard's avatar
bellard committed
443
    }
444 445

    qemu_free (uprefix);
bellard's avatar
bellard committed
446 447
}

448 449
static void audio_process_options (const char *prefix,
                                   struct audio_option *opt)
bellard's avatar
bellard committed
450
{
451 452 453
    char *optname;
    const char qemu_prefix[] = "QEMU_";
    size_t preflen;
bellard's avatar
bellard committed
454

455 456 457 458
    if (audio_bug (AUDIO_FUNC, !prefix)) {
        dolog ("prefix = NULL\n");
        return;
    }
bellard's avatar
bellard committed
459

460 461 462
    if (audio_bug (AUDIO_FUNC, !opt)) {
        dolog ("opt = NULL\n");
        return;
bellard's avatar
bellard committed
463 464
    }

465
    preflen = strlen (prefix);
bellard's avatar
bellard committed
466

467 468 469 470 471 472 473 474 475 476 477
    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
478 479 480
        /* len of opt->name + len of prefix + size of qemu_prefix
         * (includes trailing zero) + zero + underscore (on behalf of
         * sizeof) */
481 482
        optname = qemu_malloc (len + preflen + sizeof (qemu_prefix) + 1);
        if (!optname) {
bellard's avatar
bellard committed
483
            dolog ("Could not allocate memory for option name `%s'\n",
484 485 486 487 488
                   opt->name);
            continue;
        }

        strcpy (optname, qemu_prefix);
bellard's avatar
bellard committed
489 490

        /* copy while upper-casing, including trailing zero */
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
        for (i = 0; i <= preflen; ++i) {
            optname[i + sizeof (qemu_prefix) - 1] = toupper (prefix[i]);
        }
        strcat (optname, "_");
        strcat (optname, opt->name);

        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
524 525 526
            break;
        }

ths's avatar
ths committed
527 528
        if (!opt->overriddenp) {
            opt->overriddenp = &opt->overridden;
529
        }
ths's avatar
ths committed
530
        *opt->overriddenp = !def;
531 532
        qemu_free (optname);
    }
bellard's avatar
bellard committed
533 534
}

bellard's avatar
bellard committed
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
static void audio_print_settings (audsettings_t *as)
{
    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;
    default:
        AUD_log (NULL, "invalid(%d)", as->fmt);
        break;
    }
bellard's avatar
bellard committed
556 557

    AUD_log (NULL, " endianness=");
558 559 560 561 562 563 564 565 566 567 568
    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
569 570 571
    AUD_log (NULL, "\n");
}

bellard's avatar
bellard committed
572
static int audio_validate_settings (audsettings_t *as)
bellard's avatar
bellard committed
573 574 575 576
{
    int invalid;

    invalid = as->nchannels != 1 && as->nchannels != 2;
577
    invalid |= as->endianness != 0 && as->endianness != 1;
bellard's avatar
bellard committed
578 579 580 581 582 583

    switch (as->fmt) {
    case AUD_FMT_S8:
    case AUD_FMT_U8:
    case AUD_FMT_S16:
    case AUD_FMT_U16:
584 585
    case AUD_FMT_S32:
    case AUD_FMT_U32:
bellard's avatar
bellard committed
586 587 588 589 590 591 592
        break;
    default:
        invalid = 1;
        break;
    }

    invalid |= as->freq <= 0;
593
    return invalid ? -1 : 0;
bellard's avatar
bellard committed
594 595 596
}

static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
bellard's avatar
bellard committed
597
{
598
    int bits = 8, sign = 0;
bellard's avatar
bellard committed
599

bellard's avatar
bellard committed
600
    switch (as->fmt) {
601 602 603 604 605 606 607 608 609 610
    case AUD_FMT_S8:
        sign = 1;
    case AUD_FMT_U8:
        break;

    case AUD_FMT_S16:
        sign = 1;
    case AUD_FMT_U16:
        bits = 16;
        break;
611 612 613 614 615 616

    case AUD_FMT_S32:
        sign = 1;
    case AUD_FMT_U32:
        bits = 32;
        break;
bellard's avatar
bellard committed
617
    }
bellard's avatar
bellard committed
618 619
    return info->freq == as->freq
        && info->nchannels == as->nchannels
620
        && info->sign == sign
621 622
        && info->bits == bits
        && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
623
}
bellard's avatar
bellard committed
624

625
void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)
626
{
627
    int bits = 8, sign = 0, shift = 0;
628

bellard's avatar
bellard committed
629
    switch (as->fmt) {
bellard's avatar
bellard committed
630 631 632 633 634 635 636 637 638
    case AUD_FMT_S8:
        sign = 1;
    case AUD_FMT_U8:
        break;

    case AUD_FMT_S16:
        sign = 1;
    case AUD_FMT_U16:
        bits = 16;
639 640 641 642 643 644 645 646
        shift = 1;
        break;

    case AUD_FMT_S32:
        sign = 1;
    case AUD_FMT_U32:
        bits = 32;
        shift = 2;
bellard's avatar
bellard committed
647 648 649
        break;
    }

bellard's avatar
bellard committed
650
    info->freq = as->freq;
651 652
    info->bits = bits;
    info->sign = sign;
bellard's avatar
bellard committed
653
    info->nchannels = as->nchannels;
654
    info->shift = (as->nchannels == 2) + shift;
655 656
    info->align = (1 << info->shift) - 1;
    info->bytes_per_second = info->freq << info->shift;
657
    info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
bellard's avatar
bellard committed
658 659
}

660
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
bellard's avatar
bellard committed
661
{
662 663 664 665 666
    if (!len) {
        return;
    }

    if (info->sign) {
667
        memset (buf, 0x00, len << info->shift);
bellard's avatar
bellard committed
668 669
    }
    else {
670 671
        switch (info->bits) {
        case 8:
672
            memset (buf, 0x80, len << info->shift);
673
            break;
674

675 676 677 678 679 680 681 682 683 684 685 686 687 688
        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;
                }
689
            }
690 691 692 693 694 695 696 697 698 699 700 701
            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);
                }
702

703 704 705
                for (i = 0; i < len << shift; i++) {
                    p[i] = s;
                }
706
            }
707 708 709 710 711 712
            break;

        default:
            AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
                     info->bits);
            break;
713
        }
bellard's avatar
bellard committed
714 715 716
    }
}

717 718 719 720 721 722 723 724 725 726 727 728 729 730
/*
 * Capture
 */
static void noop_conv (st_sample_t *dst, const void *src,
                       int samples, volume_t *vol)
{
    (void) src;
    (void) dst;
    (void) samples;
    (void) vol;
}

static CaptureVoiceOut *audio_pcm_capture_find_specific (
    AudioState *s,
731
    audsettings_t *as
732 733 734 735 736
    )
{
    CaptureVoiceOut *cap;

    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
737
        if (audio_pcm_info_eq (&cap->hw.info, as)) {
738 739 740 741 742 743
            return cap;
        }
    }
    return NULL;
}

bellard's avatar
bellard committed
744
static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
745
{
bellard's avatar
bellard committed
746 747 748 749 750 751 752 753 754
    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);
    }
}
755

bellard's avatar
bellard committed
756 757 758 759
static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
{
    if (cap->hw.enabled != enabled) {
        audcnotification_e cmd;
760
        cap->hw.enabled = enabled;
bellard's avatar
bellard committed
761 762
        cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
        audio_notify_capture (cap, cmd);
763 764 765 766 767 768 769 770 771
    }
}

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

bellard's avatar
bellard committed
772
    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
773 774 775 776 777
        if (sw->active) {
            enabled = 1;
            break;
        }
    }
bellard's avatar
bellard committed
778
    audio_capture_maybe_changed (cap, enabled);
779 780 781 782
}

static void audio_detach_capture (HWVoiceOut *hw)
{
bellard's avatar
bellard committed
783 784 785 786 787 788 789
    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;
790 791 792 793 794 795 796

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

        LIST_REMOVE (sw, entries);
bellard's avatar
bellard committed
797 798 799 800 801 802 803 804 805
        LIST_REMOVE (sc, entries);
        qemu_free (sc);
        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;
806 807 808 809 810 811 812 813 814
    }
}

static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
{
    CaptureVoiceOut *cap;

    audio_detach_capture (hw);
    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
bellard's avatar
bellard committed
815
        SWVoiceCap *sc;
816
        SWVoiceOut *sw;
bellard's avatar
bellard committed
817
        HWVoiceOut *hw_cap = &cap->hw;
818

bellard's avatar
bellard committed
819 820
        sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
        if (!sc) {
821
            dolog ("Could not allocate soft capture voice (%zu bytes)\n",
bellard's avatar
bellard committed
822
                   sizeof (*sc));
823 824 825
            return -1;
        }

bellard's avatar
bellard committed
826 827
        sc->cap = cap;
        sw = &sc->sw;
828
        sw->hw = hw_cap;
bellard's avatar
bellard committed
829
        sw->info = hw->info;
830 831 832 833 834 835 836 837 838 839 840
        sw->empty = 1;
        sw->active = hw->enabled;
        sw->conv = noop_conv;
        sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
        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));
            qemu_free (sw);
            return -1;
        }
        LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
bellard's avatar
bellard committed
841 842 843 844 845 846
        LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
#ifdef DEBUG_CAPTURE
        asprintf (&sw->name, "for %p %d,%d,%d",
                  hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
        dolog ("Added %s active = %d\n", sw->name, sw->active);
#endif
847
        if (sw->active) {
bellard's avatar
bellard committed
848
            audio_capture_maybe_changed (cap, 1);
849 850 851 852 853
        }
    }
    return 0;
}

854 855 856
/*
 * Hard voice (capture)
 */
bellard's avatar
bellard committed
857
static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
bellard's avatar
bellard committed
858
{
859 860 861 862 863 864 865
    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
866
    }
867
    return m;
bellard's avatar
bellard committed
868 869
}

870
int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
bellard's avatar
bellard committed
871
{
872 873 874 875
    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
876
    }
877
    return live;
bellard's avatar
bellard committed
878 879
}

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
/*
 * 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
897 898
    }
    else {
899
        return hw->samples + rpos;
bellard's avatar
bellard committed
900 901 902
    }
}

903
int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
bellard's avatar
bellard committed
904
{
905 906
    HWVoiceIn *hw = sw->hw;
    int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
bellard's avatar
bellard committed
907
    st_sample_t *src, *dst = sw->buf;
908 909 910 911 912 913 914 915 916 917 918 919 920

    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
921

922 923
    swlim = (live * sw->ratio) >> 32;
    swlim = audio_MIN (swlim, samples);
bellard's avatar
bellard committed
924

925 926 927 928 929 930 931
    while (swlim) {
        src = hw->conv_buf + rpos;
        isamp = hw->wpos - rpos;
        /* XXX: <= ? */
        if (isamp <= 0) {
            isamp = hw->samples - rpos;
        }
bellard's avatar
bellard committed
932

933 934 935 936
        if (!isamp) {
            break;
        }
        osamp = swlim;
bellard's avatar
bellard committed
937

938 939
        if (audio_bug (AUDIO_FUNC, osamp < 0)) {
            dolog ("osamp=%d\n", osamp);
bellard's avatar
bellard committed
940
            return 0;
941
        }
bellard's avatar
bellard committed
942

943 944 945 946 947 948 949
        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
950

bellard's avatar
bellard committed
951
    sw->clip (buf, sw->buf, ret);
952 953
    sw->total_hw_samples_acquired += total;
    return ret << sw->info.shift;
bellard's avatar
bellard committed
954 955
}

956 957 958
/*
 * Hard voice (playback)
 */
bellard's avatar
bellard committed
959
static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
960
{
bellard's avatar
bellard committed
961 962 963
    SWVoiceOut *sw;
    int m = INT_MAX;
    int nb_live = 0;
bellard's avatar
bellard committed
964

bellard's avatar
bellard committed
965 966 967 968 969
    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
970
    }
bellard's avatar
bellard committed
971 972 973

    *nb_livep = nb_live;
    return m;
974
}
bellard's avatar
bellard committed
975

976 977 978
int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live)
{
    int smin;
bellard's avatar
bellard committed
979

980 981 982 983
    smin = audio_pcm_hw_find_min_out (hw, nb_live);

    if (!*nb_live) {
        return 0;
bellard's avatar
bellard committed
984 985
    }
    else {
986 987 988 989 990
        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
991
        }
992
        return live;
bellard's avatar
bellard committed
993
    }
994 995 996 997 998 999
}

int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
{
    int nb_live;
    int live;
bellard's avatar
bellard committed
1000

1001 1002 1003 1004
    live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
    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
1005
    }
1006
    return live;
bellard's avatar
bellard committed
1007 1008
}

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

1017 1018 1019
    if (!sw) {
        return size;
    }
bellard's avatar
bellard committed
1020

1021
    hwsamples = sw->hw->samples;
bellard's avatar
bellard committed
1022

1023 1024 1025 1026 1027
    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
1028

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

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

1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
    dead = hwsamples - live;
    swlim = ((int64_t) dead << 32) / sw->ratio;
    swlim = audio_MIN (swlim, samples);
    if (swlim) {
        sw->conv (sw->buf, buf, swlim, &sw->vol);
    }

    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
1075 1076
        "%s: write size %d ret %d total sw %d\n",
        SW_NAME (sw),
1077 1078
        size >> sw->info.shift,
        ret,
bellard's avatar
bellard committed
1079
        sw->total_hw_samples_mixed
1080 1081 1082 1083
        );
#endif

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

1086 1087
#ifdef DEBUG_AUDIO
static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
bellard's avatar
bellard committed
1088
{
1089 1090
    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
1091
}
1092
#endif
bellard's avatar
bellard committed
1093

1094 1095 1096 1097 1098 1099
#define DAC
#include "audio_template.h"
#undef DAC
#include "audio_template.h"

int AUD_write (SWVoiceOut *sw, void *buf, int size)
bellard's avatar
bellard committed
1100
{
1101
    int bytes;
bellard's avatar
bellard committed
1102

1103 1104 1105 1106
    if (!sw) {
        /* XXX: Consider options */
        return size;
    }
bellard's avatar
bellard committed
1107

1108
    if (!sw->hw->enabled) {
bellard's avatar
bellard committed
1109
        dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
bellard's avatar
bellard committed
1110 1111 1112
        return 0;
    }

1113 1114 1115 1116 1117 1118 1119
    bytes = sw->hw->pcm_ops->write (sw, buf, size);
    return bytes;
}

int AUD_read (SWVoiceIn *sw, void *buf, int size)
{
    int bytes;
bellard's avatar
bellard committed
1120

1121 1122 1123
    if (!sw) {
        /* XXX: Consider options */
        return size;
bellard's avatar
bellard committed
1124
    }
1125 1126

    if (!sw->hw->enabled) {
bellard's avatar
bellard committed
1127
        dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
1128
        return 0;
bellard's avatar
bellard committed
1129
    }
1130 1131 1132

    bytes = sw->hw->pcm_ops->read (sw, buf, size);
    return bytes;
bellard's avatar
bellard committed
1133 1134
}

1135
int AUD_get_buffer_size_out (SWVoiceOut *sw)
bellard's avatar
bellard committed
1136
{
bellard's avatar
bellard committed
1137
    return sw->hw->samples << sw->hw->info.shift;
1138 1139 1140 1141 1142
}

void AUD_set_active_out (SWVoiceOut *sw, int on)
{
    HWVoiceOut *hw;
bellard's avatar
bellard committed
1143

1144
    if (!sw) {
bellard's avatar
bellard committed
1145
        return;
1146
    }
bellard's avatar
bellard committed
1147 1148

    hw = sw->hw;
1149 1150
    if (sw->active != on) {
        SWVoiceOut *temp_sw;
bellard's avatar
bellard committed
1151
        SWVoiceCap *sc;
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170

        if (on) {
            hw->pending_disable = 0;
            if (!hw->enabled) {
                hw->enabled = 1;
                hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
            }
        }
        else {
            if (hw->enabled) {
                int nb_active = 0;

                for (temp_sw = hw->sw_head.lh_first; temp_sw;
                     temp_sw = temp_sw->entries.le_next) {
                    nb_active += temp_sw->active != 0;
                }

                hw->pending_disable = nb_active == 1;
            }
bellard's avatar
bellard committed
1171
        }
bellard's avatar
bellard committed
1172 1173 1174

        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
            sc->sw.active = hw->enabled;
1175
            if (hw->enabled) {
bellard's avatar
bellard committed
1176
                audio_capture_maybe_changed (sc->cap, 1);
1177 1178
            }
        }
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
        sw->active = on;
    }
}

void AUD_set_active_in (SWVoiceIn *sw, int on)
{
    HWVoiceIn *hw;

    if (!sw) {
        return;
bellard's avatar
bellard committed
1189 1190
    }

1191
    hw = sw->hw;
bellard's avatar
bellard committed
1192
    if (sw->active != on) {
1193 1194
        SWVoiceIn *temp_sw;

bellard's avatar
bellard committed
1195 1196 1197
        if (on) {
            if (!hw->enabled) {
                hw->enabled = 1;
1198
                hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);
bellard's avatar
bellard committed
1199
            }
1200
            sw->total_hw_samples_acquired = hw->total_samples_captured;
bellard's avatar
bellard committed
1201 1202
        }
        else {
1203
            if (hw->enabled) {
bellard's avatar
bellard committed
1204
                int nb_active = 0;
1205 1206 1207 1208

                for (temp_sw = hw->sw_head.lh_first; temp_sw;
                     temp_sw = temp_sw->entries.le_next) {
                    nb_active += temp_sw->active != 0;
bellard's avatar
bellard committed
1209 1210 1211
                }

                if (nb_active == 1) {
1212 1213
                    hw->enabled = 0;
                    hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
bellard's avatar
bellard committed
1214 1215 1216 1217 1218 1219 1220
                }
            }
        }
        sw->active = on;
    }
}

1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
static int audio_get_avail (SWVoiceIn *sw)
{
    int live;

    if (!sw) {
        return 0;
    }

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

    ldebug (
bellard's avatar
bellard committed
1236
        "%s: get_avail live %d ret %" PRId64 "\n",
bellard's avatar
bellard committed
1237
        SW_NAME (sw),
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
        live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
        );

    return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
}

static int audio_get_free (SWVoiceOut *sw)
{
    int live, dead;

    if (!sw) {
        return 0;
    }

    live = sw->total_hw_samples_mixed;

    if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
        dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
bellard's avatar
bellard committed
1256
        return 0;
1257 1258 1259 1260 1261
    }

    dead = sw->hw->samples - live;

#ifdef DEBUG_OUT
bellard's avatar
bellard committed
1262
    dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
bellard's avatar
bellard committed
1263
           SW_NAME (sw),
1264
           live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
bellard's avatar
bellard committed
1265
#endif
1266 1267 1268 1269

    return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
}

1270 1271 1272 1273 1274
static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
{
    int n;

    if (hw->enabled) {
bellard's avatar
bellard committed
1275
        SWVoiceCap *sc;
1276

bellard's avatar
bellard committed
1277 1278
        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
            SWVoiceOut *sw = &sc->sw;
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
            int rpos2 = rpos;

            n = samples;
            while (n) {
                int till_end_of_hw = hw->samples - rpos2;
                int to_write = audio_MIN (till_end_of_hw, n);
                int bytes = to_write << hw->info.shift;
                int written;

                sw->buf = hw->mix_buf + rpos2;
                written = audio_pcm_sw_write (sw, NULL, bytes);
                if (written - bytes) {
bellard's avatar
bellard committed
1291 1292 1293
                    dolog ("Could not mix %d bytes into a capture "
                           "buffer, mixed %d\n",
                           bytes, written);
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
                    break;
                }
                n -= to_write;
                rpos2 = (rpos2 + to_write) % hw->samples;
            }
        }
    }

    n = audio_MIN (samples, hw->samples - rpos);
    mixeng_clear (hw->mix_buf + rpos, n);
    mixeng_clear (hw->mix_buf, samples - n);
}

bellard's avatar
bellard committed
1307
static void audio_run_out (AudioState *s)
1308 1309 1310 1311
{
    HWVoiceOut *hw = NULL;
    SWVoiceOut *sw;

bellard's avatar
bellard committed
1312
    while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
1313
        int played;
1314
        int live, free, nb_live, cleanup_required, prev_rpos;
1315 1316 1317 1318 1319

        live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
        if (!nb_live) {
            live = 0;
        }
bellard's avatar
bellard committed
1320

1321 1322
        if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
            dolog ("live=%d hw->samples=%d\n", live, hw->samples);
bellard's avatar
bellard committed
1323
            continue;
1324 1325 1326
        }

        if (hw->pending_disable && !nb_live) {