audio.c revision f5b97c27b3cfa34df2cbc6dff846972b1605b1ed
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * QEMU Audio subsystem
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * Copyright (c) 2003-2005 Vassili Karpov (malc)
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * of this software and associated documentation files (the "Software"), to deal
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * in the Software without restriction, including without limitation the rights
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * copies of the Software, and to permit persons to whom the Software is
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync * furnished to do so, subject to the following conditions:
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * The above copyright notice and this permission notice shall be included in
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * all copies or substantial portions of the Software.
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync * THE SOFTWARE.
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync#include "../../vl_vbox.h"
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync/* #define DEBUG_PLIVE */
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync/* #define DEBUG_LIVE */
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync/* #define DEBUG_OUT */
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync/* #define DEBUG_CAPTURE */
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsynctypedef struct DRVAUDIO
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync /** The audio interface. */
b34bbc1afcc3a1d2bfbb9814f95a965abd8563e2vboxsync /** Pointer to the driver instance. */
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsyncstatic struct {
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync { /* DAC fixed settings */
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync { /* ADC fixed settings */
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync 0, /* plive */
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync/* http://www.df.lth.se/~john_e/gems/gem002d.html */
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync/* http://www.multi-platforms.com/Tips/PopCount.htm */
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync return s->pDrvIns->pDrvHlp->pfnTMGetVirtualTime (s->pDrvIns);
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync return s->pDrvIns->pDrvHlp->pfnTMGetVirtualFreq (s->pDrvIns);
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync AUD_log (NULL, "Save all your work and restart without audio\n");
9a24efbe4defba67d7fd702128f4afd13efd7b8bvboxsync AUD_log (NULL, "Please send a bug report to InnoTek\n");
abort ();
abort ();
return cond;
int cond;
funcname);
return NULL;
switch (fmt) {
case AUD_FMT_U8:
case AUD_FMT_U16:
case AUD_FMT_S8:
case AUD_FMT_S16:
int *defaultp)
*defaultp = 0;
return AUD_FMT_U8;
*defaultp = 0;
return AUD_FMT_U16;
*defaultp = 0;
return AUD_FMT_S8;
*defaultp = 0;
return AUD_FMT_S16;
return defval;
int *defaultp)
if (!var) {
return defval;
int val;
char *strval;
if (strval) {
*defaultp = 0;
return val;
return defval;
const char *defval,
int *defaultp)
if (!val) {
return defval;
*defaultp = 0;
return val;
if (cap) {
char *optname;
int def;
if (!optname) {
for (i = 0; i <= preflen; ++i) {
case AUD_OPT_BOOL:
case AUD_OPT_INT:
case AUD_OPT_FMT:
case AUD_OPT_STR:
case AUD_FMT_S8:
case AUD_FMT_U8:
case AUD_FMT_S16:
case AUD_FMT_U16:
int invalid;
case AUD_FMT_S8:
case AUD_FMT_U8:
case AUD_FMT_S16:
case AUD_FMT_U16:
case AUD_FMT_S8:
case AUD_FMT_U8:
case AUD_FMT_S16:
case AUD_FMT_U16:
case AUD_FMT_S8:
case AUD_FMT_U8:
case AUD_FMT_S16:
case AUD_FMT_U16:
if (!len) {
short s = INT16_MAX;
s = bswap16 (s);
(void) src;
(void) dst;
(void) samples;
(void) vol;
AudioState *s,
return cap;
return NULL;
#ifdef DEBUG_CAPTURE
int enabled = 0;
while (sc) {
if (was_active) {
if (!sc) {
sizeof (*sc));
#ifdef DEBUG_CAPTURE
return live;
int rpos;
if (rpos >= 0) {
return rpos;
if (!live) {
while (swlim) {
if (isamp <= 0) {
if (!isamp) {
int m = INT_MAX;
int nb_live = 0;
int smin;
if (!*nb_live) {
return live;
int nb_live;
int live;
return live;
if (!sw) {
return size;
#ifdef DEBUG_OUT
if (swlim) {
#ifndef VBOX
while (swlim) {
if (!blck) {
&isamp,
#ifdef DEBUG_OUT
dolog (
ret,
#ifdef DEBUG_AUDIO
#define DAC
#include "audio_template.h"
#include "audio_template.h"
int bytes;
if (!sw) {
return size;
return bytes;
int bytes;
if (!sw) {
return size;
return bytes;
if (!sw) {
if (on) {
int nb_active = 0;
if (!sw) {
if (on) {
int nb_active = 0;
int live;
if (!sw) {
ldebug (
if (!sw) {
#ifdef DEBUG_OUT
n = samples;
int written;
n -= to_write;
int played;
if (!nb_live) {
live = 0;
#ifdef DEBUG_OUT
if (!live) {
if (free > 0) {
#ifdef DEBUG_OUT
if (played) {
cleanup_required = 0;
if (free > 0) {
if (cleanup_required) {
while (sw) {
#ifdef DEBUG_PLIVE
int avail;
if (avail > 0) {
while (live) {
audio_run_out (s);
audio_run_in (s);
audio_run_capture (s);
if (s->drv_opaque) {
static void audio_atexit (void)
if (s->drv) {
audio_timer (s);
size_t i;
int done = 0;
int rc;
return rc;
if (s->nb_hw_voices_out <= 0) {
s->nb_hw_voices_out);
if (s->nb_hw_voices_in <= 0) {
s->nb_hw_voices_in);
s->nb_hw_voices_in = 0;
if (drvname) {
int found = 0;
if (!found) {
if (!done) {
if (!done) {
if (!done) {
if (done) {
return rc;
return VINF_SUCCESS;
AudioState *s,
void *cb_opaque
s = &glob_audio_state;
goto err0;
if (!cb) {
sizeof (*cb));
goto err0;
if (cap) {
return cap;
if (!cap) {
sizeof (*cap));
goto err1;
sizeof (st_sample_t));
goto err2;
goto err3;
return cap;
err3:
err2:
err1:
err0:
return NULL;
while (sw) {
#ifdef DEBUG_CAPTURE
if (sw)
const char *name;
switch (mt)
case AUD_MIXER_VOLUME:
case AUD_MIXER_PCM:
case AUD_MIXER_LINE_IN:
if (vol)
switch (enmInterface)
case PDMINTERFACE_BASE:
return NULL;
audio_vm_change_state_handler (s, 0);
audio_atexit ();
int rc;
char *drvname;
return rc;
return rc;
return VINF_SUCCESS;
audio_vm_change_state_handler (s, 0);
sizeof(DRVAUDIO),
NULL,
NULL,
NULL,
NULL,