summaryrefslogtreecommitdiffstats
path: root/qemu/audio
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/audio')
-rw-r--r--qemu/audio/Makefile.objs13
-rw-r--r--qemu/audio/alsaaudio.c1228
-rw-r--r--qemu/audio/audio.c2057
-rw-r--r--qemu/audio/audio.h165
-rw-r--r--qemu/audio/audio_int.h260
-rw-r--r--qemu/audio/audio_pt_int.c174
-rw-r--r--qemu/audio/audio_pt_int.h22
-rw-r--r--qemu/audio/audio_template.h514
-rw-r--r--qemu/audio/audio_win_int.c108
-rw-r--r--qemu/audio/audio_win_int.h10
-rw-r--r--qemu/audio/coreaudio.c745
-rw-r--r--qemu/audio/dsound_template.h278
-rw-r--r--qemu/audio/dsoundaudio.c905
-rw-r--r--qemu/audio/mixeng.c367
-rw-r--r--qemu/audio/mixeng.h51
-rw-r--r--qemu/audio/mixeng_template.h154
-rw-r--r--qemu/audio/noaudio.c174
-rw-r--r--qemu/audio/ossaudio.c940
-rw-r--r--qemu/audio/paaudio.c954
-rw-r--r--qemu/audio/rate_template.h111
-rw-r--r--qemu/audio/sdlaudio.c467
-rw-r--r--qemu/audio/spiceaudio.c412
-rw-r--r--qemu/audio/wavaudio.c293
-rw-r--r--qemu/audio/wavcapture.c195
24 files changed, 0 insertions, 10597 deletions
diff --git a/qemu/audio/Makefile.objs b/qemu/audio/Makefile.objs
deleted file mode 100644
index 481d1aa30..000000000
--- a/qemu/audio/Makefile.objs
+++ /dev/null
@@ -1,13 +0,0 @@
-common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
-common-obj-$(CONFIG_SDL) += sdlaudio.o
-common-obj-$(CONFIG_OSS) += ossaudio.o
-common-obj-$(CONFIG_SPICE) += spiceaudio.o
-common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
-common-obj-$(CONFIG_ALSA) += alsaaudio.o
-common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-common-obj-$(CONFIG_PA) += paaudio.o
-common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
-common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
-common-obj-y += wavcapture.o
-
-sdlaudio.o-cflags := $(SDL_CFLAGS)
diff --git a/qemu/audio/alsaaudio.c b/qemu/audio/alsaaudio.c
deleted file mode 100644
index 3652a7b5f..000000000
--- a/qemu/audio/alsaaudio.c
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- * QEMU ALSA audio driver
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include <alsa/asoundlib.h>
-#include "qemu-common.h"
-#include "qemu/main-loop.h"
-#include "audio.h"
-#include "trace.h"
-
-#if QEMU_GNUC_PREREQ(4, 3)
-#pragma GCC diagnostic ignored "-Waddress"
-#endif
-
-#define AUDIO_CAP "alsa"
-#include "audio_int.h"
-
-typedef struct ALSAConf {
- int size_in_usec_in;
- int size_in_usec_out;
- const char *pcm_name_in;
- const char *pcm_name_out;
- unsigned int buffer_size_in;
- unsigned int period_size_in;
- unsigned int buffer_size_out;
- unsigned int period_size_out;
- unsigned int threshold;
-
- int buffer_size_in_overridden;
- int period_size_in_overridden;
-
- int buffer_size_out_overridden;
- int period_size_out_overridden;
-} ALSAConf;
-
-struct pollhlp {
- snd_pcm_t *handle;
- struct pollfd *pfds;
- ALSAConf *conf;
- int count;
- int mask;
-};
-
-typedef struct ALSAVoiceOut {
- HWVoiceOut hw;
- int wpos;
- int pending;
- void *pcm_buf;
- snd_pcm_t *handle;
- struct pollhlp pollhlp;
-} ALSAVoiceOut;
-
-typedef struct ALSAVoiceIn {
- HWVoiceIn hw;
- snd_pcm_t *handle;
- void *pcm_buf;
- struct pollhlp pollhlp;
-} ALSAVoiceIn;
-
-struct alsa_params_req {
- int freq;
- snd_pcm_format_t fmt;
- int nchannels;
- int size_in_usec;
- int override_mask;
- unsigned int buffer_size;
- unsigned int period_size;
-};
-
-struct alsa_params_obt {
- int freq;
- audfmt_e fmt;
- int endianness;
- int nchannels;
- snd_pcm_uframes_t samples;
-};
-
-static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
-}
-
-static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
- int err,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
-}
-
-static void alsa_fini_poll (struct pollhlp *hlp)
-{
- int i;
- struct pollfd *pfds = hlp->pfds;
-
- if (pfds) {
- for (i = 0; i < hlp->count; ++i) {
- qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
- }
- g_free (pfds);
- }
- hlp->pfds = NULL;
- hlp->count = 0;
- hlp->handle = NULL;
-}
-
-static void alsa_anal_close1 (snd_pcm_t **handlep)
-{
- int err = snd_pcm_close (*handlep);
- if (err) {
- alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
- }
- *handlep = NULL;
-}
-
-static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
-{
- alsa_fini_poll (hlp);
- alsa_anal_close1 (handlep);
-}
-
-static int alsa_recover (snd_pcm_t *handle)
-{
- int err = snd_pcm_prepare (handle);
- if (err < 0) {
- alsa_logerr (err, "Failed to prepare handle %p\n", handle);
- return -1;
- }
- return 0;
-}
-
-static int alsa_resume (snd_pcm_t *handle)
-{
- int err = snd_pcm_resume (handle);
- if (err < 0) {
- alsa_logerr (err, "Failed to resume handle %p\n", handle);
- return -1;
- }
- return 0;
-}
-
-static void alsa_poll_handler (void *opaque)
-{
- int err, count;
- snd_pcm_state_t state;
- struct pollhlp *hlp = opaque;
- unsigned short revents;
-
- count = poll (hlp->pfds, hlp->count, 0);
- if (count < 0) {
- dolog ("alsa_poll_handler: poll %s\n", strerror (errno));
- return;
- }
-
- if (!count) {
- return;
- }
-
- /* XXX: ALSA example uses initial count, not the one returned by
- poll, correct? */
- err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds,
- hlp->count, &revents);
- if (err < 0) {
- alsa_logerr (err, "snd_pcm_poll_descriptors_revents");
- return;
- }
-
- if (!(revents & hlp->mask)) {
- trace_alsa_revents(revents);
- return;
- }
-
- state = snd_pcm_state (hlp->handle);
- switch (state) {
- case SND_PCM_STATE_SETUP:
- alsa_recover (hlp->handle);
- break;
-
- case SND_PCM_STATE_XRUN:
- alsa_recover (hlp->handle);
- break;
-
- case SND_PCM_STATE_SUSPENDED:
- alsa_resume (hlp->handle);
- break;
-
- case SND_PCM_STATE_PREPARED:
- audio_run ("alsa run (prepared)");
- break;
-
- case SND_PCM_STATE_RUNNING:
- audio_run ("alsa run (running)");
- break;
-
- default:
- dolog ("Unexpected state %d\n", state);
- }
-}
-
-static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
-{
- int i, count, err;
- struct pollfd *pfds;
-
- count = snd_pcm_poll_descriptors_count (handle);
- if (count <= 0) {
- dolog ("Could not initialize poll mode\n"
- "Invalid number of poll descriptors %d\n", count);
- return -1;
- }
-
- pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));
- if (!pfds) {
- dolog ("Could not initialize poll mode\n");
- return -1;
- }
-
- err = snd_pcm_poll_descriptors (handle, pfds, count);
- if (err < 0) {
- alsa_logerr (err, "Could not initialize poll mode\n"
- "Could not obtain poll descriptors\n");
- g_free (pfds);
- return -1;
- }
-
- for (i = 0; i < count; ++i) {
- if (pfds[i].events & POLLIN) {
- qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, NULL, hlp);
- }
- if (pfds[i].events & POLLOUT) {
- trace_alsa_pollout(i, pfds[i].fd);
- qemu_set_fd_handler (pfds[i].fd, NULL, alsa_poll_handler, hlp);
- }
- trace_alsa_set_handler(pfds[i].events, i, pfds[i].fd, err);
-
- }
- hlp->pfds = pfds;
- hlp->count = count;
- hlp->handle = handle;
- hlp->mask = mask;
- return 0;
-}
-
-static int alsa_poll_out (HWVoiceOut *hw)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT);
-}
-
-static int alsa_poll_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
-}
-
-static int alsa_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- return SND_PCM_FORMAT_S8;
-
- case AUD_FMT_U8:
- return SND_PCM_FORMAT_U8;
-
- case AUD_FMT_S16:
- if (endianness) {
- return SND_PCM_FORMAT_S16_BE;
- }
- else {
- return SND_PCM_FORMAT_S16_LE;
- }
-
- case AUD_FMT_U16:
- if (endianness) {
- return SND_PCM_FORMAT_U16_BE;
- }
- else {
- return SND_PCM_FORMAT_U16_LE;
- }
-
- case AUD_FMT_S32:
- if (endianness) {
- return SND_PCM_FORMAT_S32_BE;
- }
- else {
- return SND_PCM_FORMAT_S32_LE;
- }
-
- case AUD_FMT_U32:
- if (endianness) {
- return SND_PCM_FORMAT_U32_BE;
- }
- else {
- return SND_PCM_FORMAT_U32_LE;
- }
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return SND_PCM_FORMAT_U8;
- }
-}
-
-static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
- int *endianness)
-{
- switch (alsafmt) {
- case SND_PCM_FORMAT_S8:
- *endianness = 0;
- *fmt = AUD_FMT_S8;
- break;
-
- case SND_PCM_FORMAT_U8:
- *endianness = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case SND_PCM_FORMAT_S16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case SND_PCM_FORMAT_U16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case SND_PCM_FORMAT_S16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case SND_PCM_FORMAT_U16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- case SND_PCM_FORMAT_S32_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S32;
- break;
-
- case SND_PCM_FORMAT_U32_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U32;
- break;
-
- case SND_PCM_FORMAT_S32_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S32;
- break;
-
- case SND_PCM_FORMAT_U32_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U32;
- break;
-
- default:
- dolog ("Unrecognized audio format %d\n", alsafmt);
- return -1;
- }
-
- return 0;
-}
-
-static void alsa_dump_info (struct alsa_params_req *req,
- struct alsa_params_obt *obt,
- snd_pcm_format_t obtfmt)
-{
- dolog ("parameter | requested value | obtained value\n");
- dolog ("format | %10d | %10d\n", req->fmt, obtfmt);
- dolog ("channels | %10d | %10d\n",
- req->nchannels, obt->nchannels);
- dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
- dolog ("============================================\n");
- dolog ("requested: buffer size %d period size %d\n",
- req->buffer_size, req->period_size);
- dolog ("obtained: samples %ld\n", obt->samples);
-}
-
-static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
-{
- int err;
- snd_pcm_sw_params_t *sw_params;
-
- snd_pcm_sw_params_alloca (&sw_params);
-
- err = snd_pcm_sw_params_current (handle, sw_params);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to get current software parameters\n");
- return;
- }
-
- err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to set software threshold to %ld\n",
- threshold);
- return;
- }
-
- err = snd_pcm_sw_params (handle, sw_params);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to set software parameters\n");
- return;
- }
-}
-
-static int alsa_open (int in, struct alsa_params_req *req,
- struct alsa_params_obt *obt, snd_pcm_t **handlep,
- ALSAConf *conf)
-{
- snd_pcm_t *handle;
- snd_pcm_hw_params_t *hw_params;
- int err;
- int size_in_usec;
- unsigned int freq, nchannels;
- const char *pcm_name = in ? conf->pcm_name_in : conf->pcm_name_out;
- snd_pcm_uframes_t obt_buffer_size;
- const char *typ = in ? "ADC" : "DAC";
- snd_pcm_format_t obtfmt;
-
- freq = req->freq;
- nchannels = req->nchannels;
- size_in_usec = req->size_in_usec;
-
- snd_pcm_hw_params_alloca (&hw_params);
-
- err = snd_pcm_open (
- &handle,
- pcm_name,
- in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
- SND_PCM_NONBLOCK
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
- return -1;
- }
-
- err = snd_pcm_hw_params_any (handle, hw_params);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_set_access (
- handle,
- hw_params,
- SND_PCM_ACCESS_RW_INTERLEAVED
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set access type\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
- }
-
- err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
- goto err;
- }
-
- err = snd_pcm_hw_params_set_channels_near (
- handle,
- hw_params,
- &nchannels
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
- req->nchannels);
- goto err;
- }
-
- if (nchannels != 1 && nchannels != 2) {
- alsa_logerr2 (err, typ,
- "Can not handle obtained number of channels %d\n",
- nchannels);
- goto err;
- }
-
- if (req->buffer_size) {
- unsigned long obt;
-
- if (size_in_usec) {
- int dir = 0;
- unsigned int btime = req->buffer_size;
-
- err = snd_pcm_hw_params_set_buffer_time_near (
- handle,
- hw_params,
- &btime,
- &dir
- );
- obt = btime;
- }
- else {
- snd_pcm_uframes_t bsize = req->buffer_size;
-
- err = snd_pcm_hw_params_set_buffer_size_near (
- handle,
- hw_params,
- &bsize
- );
- obt = bsize;
- }
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
- size_in_usec ? "time" : "size", req->buffer_size);
- goto err;
- }
-
- if ((req->override_mask & 2) && (obt - req->buffer_size))
- dolog ("Requested buffer %s %u was rejected, using %lu\n",
- size_in_usec ? "time" : "size", req->buffer_size, obt);
- }
-
- if (req->period_size) {
- unsigned long obt;
-
- if (size_in_usec) {
- int dir = 0;
- unsigned int ptime = req->period_size;
-
- err = snd_pcm_hw_params_set_period_time_near (
- handle,
- hw_params,
- &ptime,
- &dir
- );
- obt = ptime;
- }
- else {
- int dir = 0;
- snd_pcm_uframes_t psize = req->period_size;
-
- err = snd_pcm_hw_params_set_period_size_near (
- handle,
- hw_params,
- &psize,
- &dir
- );
- obt = psize;
- }
-
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
- size_in_usec ? "time" : "size", req->period_size);
- goto err;
- }
-
- if (((req->override_mask & 1) && (obt - req->period_size)))
- dolog ("Requested period %s %u was rejected, using %lu\n",
- size_in_usec ? "time" : "size", req->period_size, obt);
- }
-
- err = snd_pcm_hw_params (handle, hw_params);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to get buffer size\n");
- goto err;
- }
-
- err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to get format\n");
- goto err;
- }
-
- if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
- dolog ("Invalid format was returned %d\n", obtfmt);
- goto err;
- }
-
- err = snd_pcm_prepare (handle);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
- goto err;
- }
-
- if (!in && conf->threshold) {
- snd_pcm_uframes_t threshold;
- int bytes_per_sec;
-
- bytes_per_sec = freq << (nchannels == 2);
-
- switch (obt->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- bytes_per_sec <<= 1;
- break;
-
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- bytes_per_sec <<= 2;
- break;
- }
-
- threshold = (conf->threshold * bytes_per_sec) / 1000;
- alsa_set_threshold (handle, threshold);
- }
-
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->samples = obt_buffer_size;
-
- *handlep = handle;
-
- if (obtfmt != req->fmt ||
- obt->nchannels != req->nchannels ||
- obt->freq != req->freq) {
- dolog ("Audio parameters for %s\n", typ);
- alsa_dump_info (req, obt, obtfmt);
- }
-
-#ifdef DEBUG
- alsa_dump_info (req, obt, obtfmt);
-#endif
- return 0;
-
- err:
- alsa_anal_close1 (&handle);
- return -1;
-}
-
-static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
-{
- snd_pcm_sframes_t avail;
-
- avail = snd_pcm_avail_update (handle);
- if (avail < 0) {
- if (avail == -EPIPE) {
- if (!alsa_recover (handle)) {
- avail = snd_pcm_avail_update (handle);
- }
- }
-
- if (avail < 0) {
- alsa_logerr (avail,
- "Could not obtain number of available frames\n");
- return -1;
- }
- }
-
- return avail;
-}
-
-static void alsa_write_pending (ALSAVoiceOut *alsa)
-{
- HWVoiceOut *hw = &alsa->hw;
-
- while (alsa->pending) {
- int left_till_end_samples = hw->samples - alsa->wpos;
- int len = audio_MIN (alsa->pending, left_till_end_samples);
- char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
-
- while (len) {
- snd_pcm_sframes_t written;
-
- written = snd_pcm_writei (alsa->handle, src, len);
-
- if (written <= 0) {
- switch (written) {
- case 0:
- trace_alsa_wrote_zero(len);
- return;
-
- case -EPIPE:
- if (alsa_recover (alsa->handle)) {
- alsa_logerr (written, "Failed to write %d frames\n",
- len);
- return;
- }
- trace_alsa_xrun_out();
- continue;
-
- case -ESTRPIPE:
- /* stream is suspended and waiting for an
- application recovery */
- if (alsa_resume (alsa->handle)) {
- alsa_logerr (written, "Failed to write %d frames\n",
- len);
- return;
- }
- trace_alsa_resume_out();
- continue;
-
- case -EAGAIN:
- return;
-
- default:
- alsa_logerr (written, "Failed to write %d frames from %p\n",
- len, src);
- return;
- }
- }
-
- alsa->wpos = (alsa->wpos + written) % hw->samples;
- alsa->pending -= written;
- len -= written;
- }
- }
-}
-
-static int alsa_run_out (HWVoiceOut *hw, int live)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
- int decr;
- snd_pcm_sframes_t avail;
-
- avail = alsa_get_avail (alsa->handle);
- if (avail < 0) {
- dolog ("Could not get number of available playback frames\n");
- return 0;
- }
-
- decr = audio_MIN (live, avail);
- decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
- alsa->pending += decr;
- alsa_write_pending (alsa);
- return decr;
-}
-
-static void alsa_fini_out (HWVoiceOut *hw)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- ldebug ("alsa_fini\n");
- alsa_anal_close (&alsa->handle, &alsa->pollhlp);
-
- g_free(alsa->pcm_buf);
- alsa->pcm_buf = NULL;
-}
-
-static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
- struct alsa_params_req req;
- struct alsa_params_obt obt;
- snd_pcm_t *handle;
- struct audsettings obt_as;
- ALSAConf *conf = drv_opaque;
-
- req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.period_size = conf->period_size_out;
- req.buffer_size = conf->buffer_size_out;
- req.size_in_usec = conf->size_in_usec_out;
- req.override_mask =
- (conf->period_size_out_overridden ? 1 : 0) |
- (conf->buffer_size_out_overridden ? 2 : 0);
-
- if (alsa_open (0, &req, &obt, &handle, conf)) {
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = obt.fmt;
- obt_as.endianness = obt.endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
- if (!alsa->pcm_buf) {
- dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- alsa_anal_close1 (&handle);
- return -1;
- }
-
- alsa->handle = handle;
- alsa->pollhlp.conf = conf;
- return 0;
-}
-
-#define VOICE_CTL_PAUSE 0
-#define VOICE_CTL_PREPARE 1
-#define VOICE_CTL_START 2
-
-static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)
-{
- int err;
-
- if (ctl == VOICE_CTL_PAUSE) {
- err = snd_pcm_drop (handle);
- if (err < 0) {
- alsa_logerr (err, "Could not stop %s\n", typ);
- return -1;
- }
- }
- else {
- err = snd_pcm_prepare (handle);
- if (err < 0) {
- alsa_logerr (err, "Could not prepare handle for %s\n", typ);
- return -1;
- }
- if (ctl == VOICE_CTL_START) {
- err = snd_pcm_start(handle);
- if (err < 0) {
- alsa_logerr (err, "Could not start handle for %s\n", typ);
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- {
- va_list ap;
- int poll_mode;
-
- va_start (ap, cmd);
- poll_mode = va_arg (ap, int);
- va_end (ap);
-
- ldebug ("enabling voice\n");
- if (poll_mode && alsa_poll_out (hw)) {
- poll_mode = 0;
- }
- hw->poll_mode = poll_mode;
- return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE);
- }
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- if (hw->poll_mode) {
- hw->poll_mode = 0;
- alsa_fini_poll (&alsa->pollhlp);
- }
- return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE);
- }
-
- return -1;
-}
-
-static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
- struct alsa_params_req req;
- struct alsa_params_obt obt;
- snd_pcm_t *handle;
- struct audsettings obt_as;
- ALSAConf *conf = drv_opaque;
-
- req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.period_size = conf->period_size_in;
- req.buffer_size = conf->buffer_size_in;
- req.size_in_usec = conf->size_in_usec_in;
- req.override_mask =
- (conf->period_size_in_overridden ? 1 : 0) |
- (conf->buffer_size_in_overridden ? 2 : 0);
-
- if (alsa_open (1, &req, &obt, &handle, conf)) {
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = obt.fmt;
- obt_as.endianness = obt.endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!alsa->pcm_buf) {
- dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- alsa_anal_close1 (&handle);
- return -1;
- }
-
- alsa->handle = handle;
- alsa->pollhlp.conf = conf;
- return 0;
-}
-
-static void alsa_fini_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- alsa_anal_close (&alsa->handle, &alsa->pollhlp);
-
- g_free(alsa->pcm_buf);
- alsa->pcm_buf = NULL;
-}
-
-static int alsa_run_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int i;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- int decr;
- struct {
- int add;
- int len;
- } bufs[2] = {
- { .add = hw->wpos, .len = 0 },
- { .add = 0, .len = 0 }
- };
- snd_pcm_sframes_t avail;
- snd_pcm_uframes_t read_samples = 0;
-
- if (!dead) {
- return 0;
- }
-
- avail = alsa_get_avail (alsa->handle);
- if (avail < 0) {
- dolog ("Could not get number of captured frames\n");
- return 0;
- }
-
- if (!avail) {
- snd_pcm_state_t state;
-
- state = snd_pcm_state (alsa->handle);
- switch (state) {
- case SND_PCM_STATE_PREPARED:
- avail = hw->samples;
- break;
- case SND_PCM_STATE_SUSPENDED:
- /* stream is suspended and waiting for an application recovery */
- if (alsa_resume (alsa->handle)) {
- dolog ("Failed to resume suspended input stream\n");
- return 0;
- }
- trace_alsa_resume_in();
- break;
- default:
- trace_alsa_no_frames(state);
- return 0;
- }
- }
-
- decr = audio_MIN (dead, avail);
- if (!decr) {
- return 0;
- }
-
- if (hw->wpos + decr > hw->samples) {
- bufs[0].len = (hw->samples - hw->wpos);
- bufs[1].len = (decr - (hw->samples - hw->wpos));
- }
- else {
- bufs[0].len = decr;
- }
-
- for (i = 0; i < 2; ++i) {
- void *src;
- struct st_sample *dst;
- snd_pcm_sframes_t nread;
- snd_pcm_uframes_t len;
-
- len = bufs[i].len;
-
- src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
- dst = hw->conv_buf + bufs[i].add;
-
- while (len) {
- nread = snd_pcm_readi (alsa->handle, src, len);
-
- if (nread <= 0) {
- switch (nread) {
- case 0:
- trace_alsa_read_zero(len);
- goto exit;
-
- case -EPIPE:
- if (alsa_recover (alsa->handle)) {
- alsa_logerr (nread, "Failed to read %ld frames\n", len);
- goto exit;
- }
- trace_alsa_xrun_in();
- continue;
-
- case -EAGAIN:
- goto exit;
-
- default:
- alsa_logerr (
- nread,
- "Failed to read %ld frames from %p\n",
- len,
- src
- );
- goto exit;
- }
- }
-
- hw->conv (dst, src, nread);
-
- src = advance (src, nread << hwshift);
- dst += nread;
-
- read_samples += nread;
- len -= nread;
- }
- }
-
- exit:
- hw->wpos = (hw->wpos + read_samples) % hw->samples;
- return read_samples;
-}
-
-static int alsa_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- {
- va_list ap;
- int poll_mode;
-
- va_start (ap, cmd);
- poll_mode = va_arg (ap, int);
- va_end (ap);
-
- ldebug ("enabling voice\n");
- if (poll_mode && alsa_poll_in (hw)) {
- poll_mode = 0;
- }
- hw->poll_mode = poll_mode;
-
- return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START);
- }
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- if (hw->poll_mode) {
- hw->poll_mode = 0;
- alsa_fini_poll (&alsa->pollhlp);
- }
- return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE);
- }
-
- return -1;
-}
-
-static ALSAConf glob_conf = {
- .buffer_size_out = 4096,
- .period_size_out = 1024,
- .pcm_name_out = "default",
- .pcm_name_in = "default",
-};
-
-static void *alsa_audio_init (void)
-{
- ALSAConf *conf = g_malloc(sizeof(ALSAConf));
- *conf = glob_conf;
- return conf;
-}
-
-static void alsa_audio_fini (void *opaque)
-{
- g_free(opaque);
-}
-
-static struct audio_option alsa_options[] = {
- {
- .name = "DAC_SIZE_IN_USEC",
- .tag = AUD_OPT_BOOL,
- .valp = &glob_conf.size_in_usec_out,
- .descr = "DAC period/buffer size in microseconds (otherwise in frames)"
- },
- {
- .name = "DAC_PERIOD_SIZE",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.period_size_out,
- .descr = "DAC period size (0 to go with system default)",
- .overriddenp = &glob_conf.period_size_out_overridden
- },
- {
- .name = "DAC_BUFFER_SIZE",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.buffer_size_out,
- .descr = "DAC buffer size (0 to go with system default)",
- .overriddenp = &glob_conf.buffer_size_out_overridden
- },
- {
- .name = "ADC_SIZE_IN_USEC",
- .tag = AUD_OPT_BOOL,
- .valp = &glob_conf.size_in_usec_in,
- .descr =
- "ADC period/buffer size in microseconds (otherwise in frames)"
- },
- {
- .name = "ADC_PERIOD_SIZE",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.period_size_in,
- .descr = "ADC period size (0 to go with system default)",
- .overriddenp = &glob_conf.period_size_in_overridden
- },
- {
- .name = "ADC_BUFFER_SIZE",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.buffer_size_in,
- .descr = "ADC buffer size (0 to go with system default)",
- .overriddenp = &glob_conf.buffer_size_in_overridden
- },
- {
- .name = "THRESHOLD",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.threshold,
- .descr = "(undocumented)"
- },
- {
- .name = "DAC_DEV",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.pcm_name_out,
- .descr = "DAC device name (for instance dmix)"
- },
- {
- .name = "ADC_DEV",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.pcm_name_in,
- .descr = "ADC device name"
- },
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops alsa_pcm_ops = {
- .init_out = alsa_init_out,
- .fini_out = alsa_fini_out,
- .run_out = alsa_run_out,
- .write = alsa_write,
- .ctl_out = alsa_ctl_out,
-
- .init_in = alsa_init_in,
- .fini_in = alsa_fini_in,
- .run_in = alsa_run_in,
- .read = alsa_read,
- .ctl_in = alsa_ctl_in,
-};
-
-struct audio_driver alsa_audio_driver = {
- .name = "alsa",
- .descr = "ALSA http://www.alsa-project.org",
- .options = alsa_options,
- .init = alsa_audio_init,
- .fini = alsa_audio_fini,
- .pcm_ops = &alsa_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = INT_MAX,
- .max_voices_in = INT_MAX,
- .voice_size_out = sizeof (ALSAVoiceOut),
- .voice_size_in = sizeof (ALSAVoiceIn)
-};
diff --git a/qemu/audio/audio.c b/qemu/audio/audio.c
deleted file mode 100644
index e60c124de..000000000
--- a/qemu/audio/audio.c
+++ /dev/null
@@ -1,2057 +0,0 @@
-/*
- * QEMU Audio subsystem
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "audio.h"
-#include "monitor/monitor.h"
-#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "qemu/cutils.h"
-
-#define AUDIO_CAP "audio"
-#include "audio_int.h"
-
-/* #define DEBUG_LIVE */
-/* #define DEBUG_OUT */
-/* #define DEBUG_CAPTURE */
-/* #define DEBUG_POLL */
-
-#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
-
-
-/* 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.
-*/
-static struct audio_driver *drvtab[] = {
-#ifdef CONFIG_SPICE
- &spice_audio_driver,
-#endif
- CONFIG_AUDIO_DRIVERS
- &no_audio_driver,
- &wav_audio_driver
-};
-
-struct fixed_settings {
- int enabled;
- int nb_voices;
- int greedy;
- struct audsettings settings;
-};
-
-static struct {
- struct fixed_settings fixed_out;
- struct fixed_settings fixed_in;
- union {
- int hertz;
- int64_t ticks;
- } period;
- int try_poll_in;
- int try_poll_out;
-} conf = {
- .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,
- }
- },
-
- .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,
- }
- },
-
- .period = { .hertz = 100 },
- .try_poll_in = 1,
- .try_poll_out = 1,
-};
-
-static AudioState glob_audio_state;
-
-const struct mixeng_volume nominal_volume = {
- .mute = 0,
-#ifdef FLOAT_MIXENG
- .r = 1.0,
- .l = 1.0,
-#else
- .r = 1ULL << 32,
- .l = 1ULL << 32,
-#endif
-};
-
-#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
-#error No its not
-#else
-static void audio_print_options (const char *prefix,
- struct audio_option *opt);
-
-int audio_bug (const char *funcname, int cond)
-{
- if (cond) {
- static int shown;
-
- AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
- if (!shown) {
- struct audio_driver *d;
-
- shown = 1;
- AUD_log (NULL, "Save all your work and restart without audio\n");
- AUD_log (NULL, "Please send bug report to av1474@comtv.ru\n");
- AUD_log (NULL, "I am sorry\n");
- d = glob_audio_state.drv;
- if (d) {
- audio_print_options (d->name, d->options);
- }
- }
- 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
- }
-
- return cond;
-}
-#endif
-
-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;
- }
-}
-
-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);
- AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
- return NULL;
- }
-
- return g_malloc0 (len);
-}
-
-static char *audio_alloc_prefix (const char *s)
-{
- const char qemu_prefix[] = "QEMU_";
- size_t len, i;
- char *r, *u;
-
- if (!s) {
- return NULL;
- }
-
- len = strlen (s);
- r = g_malloc (len + sizeof (qemu_prefix));
-
- u = r + sizeof (qemu_prefix) - 1;
-
- pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix);
- pstrcat (r, len + sizeof (qemu_prefix), s);
-
- for (i = 0; i < len; ++i) {
- u[i] = qemu_toupper(u[i]);
- }
-
- return r;
-}
-
-static const char *audio_audfmt_to_string (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_U8:
- return "U8";
-
- case AUD_FMT_U16:
- return "U16";
-
- case AUD_FMT_S8:
- return "S8";
-
- case AUD_FMT_S16:
- return "S16";
-
- case AUD_FMT_U32:
- return "U32";
-
- case AUD_FMT_S32:
- return "S32";
- }
-
- dolog ("Bogus audfmt %d returning S16\n", fmt);
- return "S16";
-}
-
-static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
- int *defaultp)
-{
- if (!strcasecmp (s, "u8")) {
- *defaultp = 0;
- return AUD_FMT_U8;
- }
- else if (!strcasecmp (s, "u16")) {
- *defaultp = 0;
- return AUD_FMT_U16;
- }
- else if (!strcasecmp (s, "u32")) {
- *defaultp = 0;
- return AUD_FMT_U32;
- }
- else if (!strcasecmp (s, "s8")) {
- *defaultp = 0;
- return AUD_FMT_S8;
- }
- else if (!strcasecmp (s, "s16")) {
- *defaultp = 0;
- return AUD_FMT_S16;
- }
- else if (!strcasecmp (s, "s32")) {
- *defaultp = 0;
- return AUD_FMT_S32;
- }
- else {
- dolog ("Bogus audio format `%s' using %s\n",
- s, audio_audfmt_to_string (defval));
- *defaultp = 1;
- return defval;
- }
-}
-
-static audfmt_e audio_get_conf_fmt (const char *envname,
- audfmt_e defval,
- int *defaultp)
-{
- const char *var = getenv (envname);
- if (!var) {
- *defaultp = 1;
- return defval;
- }
- return audio_string_to_audfmt (var, defval, defaultp);
-}
-
-static int audio_get_conf_int (const char *key, int defval, int *defaultp)
-{
- int val;
- char *strval;
-
- strval = getenv (key);
- if (strval) {
- *defaultp = 0;
- val = atoi (strval);
- return val;
- }
- else {
- *defaultp = 1;
- return defval;
- }
-}
-
-static const char *audio_get_conf_str (const char *key,
- const char *defval,
- int *defaultp)
-{
- const char *val = getenv (key);
- if (!val) {
- *defaultp = 1;
- return defval;
- }
- else {
- *defaultp = 0;
- return val;
- }
-}
-
-void AUD_vlog (const char *cap, const char *fmt, va_list ap)
-{
- if (cap) {
- fprintf(stderr, "%s: ", cap);
- }
-
- vfprintf(stderr, fmt, ap);
-}
-
-void AUD_log (const char *cap, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (cap, fmt, ap);
- va_end (ap);
-}
-
-static void audio_print_options (const char *prefix,
- struct audio_option *opt)
-{
- char *uprefix;
-
- if (!prefix) {
- dolog ("No prefix specified\n");
- return;
- }
-
- if (!opt) {
- dolog ("No options\n");
- return;
- }
-
- uprefix = audio_alloc_prefix (prefix);
-
- for (; opt->name; opt++) {
- const char *state = "default";
- printf (" %s_%s: ", uprefix, opt->name);
-
- if (opt->overriddenp && *opt->overriddenp) {
- state = "current";
- }
-
- 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 (
- "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
- 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)");
- }
- break;
-
- default:
- printf ("???\n");
- dolog ("Bad value tag for option %s_%s %d\n",
- uprefix, opt->name, opt->tag);
- break;
- }
- printf (" %s\n", opt->descr);
- }
-
- g_free (uprefix);
-}
-
-static void audio_process_options (const char *prefix,
- struct audio_option *opt)
-{
- char *optname;
- const char qemu_prefix[] = "QEMU_";
- size_t preflen, optlen;
-
- if (audio_bug (AUDIO_FUNC, !prefix)) {
- dolog ("prefix = NULL\n");
- return;
- }
-
- if (audio_bug (AUDIO_FUNC, !opt)) {
- dolog ("opt = NULL\n");
- return;
- }
-
- preflen = strlen (prefix);
-
- 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);
- /* len of opt->name + len of prefix + size of qemu_prefix
- * (includes trailing zero) + zero + underscore (on behalf of
- * sizeof) */
- optlen = len + preflen + sizeof (qemu_prefix) + 1;
- optname = g_malloc (optlen);
-
- pstrcpy (optname, optlen, qemu_prefix);
-
- /* copy while upper-casing, including trailing zero */
- for (i = 0; i <= preflen; ++i) {
- optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]);
- }
- pstrcat (optname, optlen, "_");
- pstrcat (optname, optlen, 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);
- break;
- }
-
- if (!opt->overriddenp) {
- opt->overriddenp = &opt->overridden;
- }
- *opt->overriddenp = !def;
- g_free (optname);
- }
-}
-
-static void audio_print_settings (struct audsettings *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;
- case AUD_FMT_S32:
- AUD_log (NULL, "S32");
- break;
- case AUD_FMT_U32:
- AUD_log (NULL, "U32");
- break;
- default:
- AUD_log (NULL, "invalid(%d)", as->fmt);
- break;
- }
-
- AUD_log (NULL, " endianness=");
- switch (as->endianness) {
- case 0:
- AUD_log (NULL, "little");
- break;
- case 1:
- AUD_log (NULL, "big");
- break;
- default:
- AUD_log (NULL, "invalid");
- break;
- }
- AUD_log (NULL, "\n");
-}
-
-static int audio_validate_settings (struct audsettings *as)
-{
- int invalid;
-
- invalid = as->nchannels != 1 && as->nchannels != 2;
- invalid |= as->endianness != 0 && as->endianness != 1;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- break;
- default:
- invalid = 1;
- break;
- }
-
- invalid |= as->freq <= 0;
- return invalid ? -1 : 0;
-}
-
-static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *as)
-{
- int bits = 8, sign = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- sign = 1;
- /* fall through */
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- /* fall through */
- case AUD_FMT_U16:
- bits = 16;
- break;
-
- case AUD_FMT_S32:
- sign = 1;
- /* fall through */
- case AUD_FMT_U32:
- bits = 32;
- break;
- }
- return info->freq == as->freq
- && info->nchannels == as->nchannels
- && info->sign == sign
- && info->bits == bits
- && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
-}
-
-void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
-{
- int bits = 8, sign = 0, shift = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- sign = 1;
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- case AUD_FMT_U16:
- bits = 16;
- shift = 1;
- break;
-
- case AUD_FMT_S32:
- sign = 1;
- case AUD_FMT_U32:
- bits = 32;
- shift = 2;
- break;
- }
-
- info->freq = as->freq;
- info->bits = bits;
- info->sign = sign;
- info->nchannels = as->nchannels;
- info->shift = (as->nchannels == 2) + shift;
- info->align = (1 << info->shift) - 1;
- info->bytes_per_second = info->freq << info->shift;
- info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
-}
-
-void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
-{
- if (!len) {
- return;
- }
-
- if (info->sign) {
- memset (buf, 0x00, len << info->shift);
- }
- else {
- switch (info->bits) {
- case 8:
- memset (buf, 0x80, len << info->shift);
- break;
-
- 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;
- }
- }
- 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);
- }
-
- for (i = 0; i < len << shift; i++) {
- p[i] = s;
- }
- }
- break;
-
- default:
- AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
- info->bits);
- break;
- }
- }
-}
-
-/*
- * Capture
- */
-static void noop_conv (struct st_sample *dst, const void *src, int samples)
-{
- (void) src;
- (void) dst;
- (void) samples;
-}
-
-static CaptureVoiceOut *audio_pcm_capture_find_specific (
- struct audsettings *as
- )
-{
- CaptureVoiceOut *cap;
- AudioState *s = &glob_audio_state;
-
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- if (audio_pcm_info_eq (&cap->hw.info, as)) {
- return cap;
- }
- }
- return NULL;
-}
-
-static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
-{
- 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);
- }
-}
-
-static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
-{
- if (cap->hw.enabled != enabled) {
- audcnotification_e cmd;
- cap->hw.enabled = enabled;
- cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
- audio_notify_capture (cap, cmd);
- }
-}
-
-static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
-{
- HWVoiceOut *hw = &cap->hw;
- SWVoiceOut *sw;
- int enabled = 0;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- enabled = 1;
- break;
- }
- }
- audio_capture_maybe_changed (cap, enabled);
-}
-
-static void audio_detach_capture (HWVoiceOut *hw)
-{
- 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;
-
- if (sw->rate) {
- st_rate_stop (sw->rate);
- sw->rate = NULL;
- }
-
- QLIST_REMOVE (sw, entries);
- QLIST_REMOVE (sc, entries);
- g_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;
- }
-}
-
-static int audio_attach_capture (HWVoiceOut *hw)
-{
- AudioState *s = &glob_audio_state;
- CaptureVoiceOut *cap;
-
- audio_detach_capture (hw);
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- SWVoiceCap *sc;
- SWVoiceOut *sw;
- HWVoiceOut *hw_cap = &cap->hw;
-
- sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
- if (!sc) {
- dolog ("Could not allocate soft capture voice (%zu bytes)\n",
- sizeof (*sc));
- return -1;
- }
-
- sc->cap = cap;
- sw = &sc->sw;
- sw->hw = hw_cap;
- sw->info = hw->info;
- sw->empty = 1;
- sw->active = hw->enabled;
- sw->conv = noop_conv;
- sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
- sw->vol = nominal_volume;
- 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));
- g_free (sw);
- return -1;
- }
- QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
- QLIST_INSERT_HEAD (&hw->cap_head, sc, entries);
-#ifdef DEBUG_CAPTURE
- sw->name = g_strdup_printf ("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
- if (sw->active) {
- audio_capture_maybe_changed (cap, 1);
- }
- }
- return 0;
-}
-
-/*
- * Hard voice (capture)
- */
-static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
-{
- 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);
- }
- }
- return m;
-}
-
-int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
-{
- 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;
- }
- return live;
-}
-
-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;
-}
-
-/*
- * 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;
- }
- else {
- return hw->samples + rpos;
- }
-}
-
-int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
-{
- HWVoiceIn *hw = sw->hw;
- int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
- struct st_sample *src, *dst = sw->buf;
-
- 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;
- }
-
- swlim = (live * sw->ratio) >> 32;
- swlim = audio_MIN (swlim, samples);
-
- while (swlim) {
- src = hw->conv_buf + rpos;
- isamp = hw->wpos - rpos;
- /* XXX: <= ? */
- if (isamp <= 0) {
- isamp = hw->samples - rpos;
- }
-
- if (!isamp) {
- break;
- }
- osamp = swlim;
-
- if (audio_bug (AUDIO_FUNC, osamp < 0)) {
- dolog ("osamp=%d\n", osamp);
- return 0;
- }
-
- st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
- swlim -= osamp;
- rpos = (rpos + isamp) % hw->samples;
- dst += osamp;
- ret += osamp;
- total += isamp;
- }
-
- if (!(hw->ctl_caps & VOICE_VOLUME_CAP)) {
- mixeng_volume (sw->buf, ret, &sw->vol);
- }
-
- sw->clip (buf, sw->buf, ret);
- sw->total_hw_samples_acquired += total;
- return ret << sw->info.shift;
-}
-
-/*
- * Hard voice (playback)
- */
-static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
-{
- SWVoiceOut *sw;
- int m = INT_MAX;
- int nb_live = 0;
-
- 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;
- }
- }
-
- *nb_livep = nb_live;
- return m;
-}
-
-static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
-{
- int smin;
- int nb_live1;
-
- smin = audio_pcm_hw_find_min_out (hw, &nb_live1);
- if (nb_live) {
- *nb_live = nb_live1;
- }
-
- if (nb_live1) {
- 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;
- }
- return live;
- }
- return 0;
-}
-
-/*
- * Soft voice (playback)
- */
-int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
-{
- int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
- int ret = 0, pos = 0, total = 0;
-
- if (!sw) {
- return size;
- }
-
- hwsamples = sw->hw->samples;
-
- 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;
- }
-
- if (live == hwsamples) {
-#ifdef DEBUG_OUT
- dolog ("%s is full %d\n", sw->name, live);
-#endif
- return 0;
- }
-
- wpos = (sw->hw->rpos + live) % hwsamples;
- samples = size >> sw->info.shift;
-
- dead = hwsamples - live;
- swlim = ((int64_t) dead << 32) / sw->ratio;
- swlim = audio_MIN (swlim, samples);
- if (swlim) {
- sw->conv (sw->buf, buf, swlim);
-
- if (!(sw->hw->ctl_caps & VOICE_VOLUME_CAP)) {
- mixeng_volume (sw->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 (
- "%s: write size %d ret %d total sw %d\n",
- SW_NAME (sw),
- size >> sw->info.shift,
- ret,
- sw->total_hw_samples_mixed
- );
-#endif
-
- return ret << sw->info.shift;
-}
-
-#ifdef DEBUG_AUDIO
-static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
-{
- dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
- cap, info->bits, info->sign, info->freq, info->nchannels);
-}
-#endif
-
-#define DAC
-#include "audio_template.h"
-#undef DAC
-#include "audio_template.h"
-
-/*
- * 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;
-}
-
-static void audio_reset_timer (AudioState *s)
-{
- if (audio_is_timer_needed ()) {
- timer_mod (s->ts,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + conf.period.ticks);
- }
- else {
- timer_del (s->ts);
- }
-}
-
-static void audio_timer (void *opaque)
-{
- audio_run ("timer");
- audio_reset_timer (opaque);
-}
-
-/*
- * Public API
- */
-int AUD_write (SWVoiceOut *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw) {
- /* XXX: Consider options */
- return size;
- }
-
- if (!sw->hw->enabled) {
- dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
- return 0;
- }
-
- bytes = sw->hw->pcm_ops->write (sw, buf, size);
- return bytes;
-}
-
-int AUD_read (SWVoiceIn *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw) {
- /* XXX: Consider options */
- return size;
- }
-
- if (!sw->hw->enabled) {
- dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
- return 0;
- }
-
- bytes = sw->hw->pcm_ops->read (sw, buf, size);
- return bytes;
-}
-
-int AUD_get_buffer_size_out (SWVoiceOut *sw)
-{
- return sw->hw->samples << sw->hw->info.shift;
-}
-
-void AUD_set_active_out (SWVoiceOut *sw, int on)
-{
- HWVoiceOut *hw;
-
- if (!sw) {
- return;
- }
-
- hw = sw->hw;
- if (sw->active != on) {
- AudioState *s = &glob_audio_state;
- SWVoiceOut *temp_sw;
- SWVoiceCap *sc;
-
- if (on) {
- hw->pending_disable = 0;
- if (!hw->enabled) {
- hw->enabled = 1;
- if (s->vm_running) {
- hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
- audio_reset_timer (s);
- }
- }
- }
- 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;
- }
- }
-
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- sc->sw.active = hw->enabled;
- if (hw->enabled) {
- audio_capture_maybe_changed (sc->cap, 1);
- }
- }
- sw->active = on;
- }
-}
-
-void AUD_set_active_in (SWVoiceIn *sw, int on)
-{
- HWVoiceIn *hw;
-
- if (!sw) {
- return;
- }
-
- hw = sw->hw;
- if (sw->active != on) {
- AudioState *s = &glob_audio_state;
- SWVoiceIn *temp_sw;
-
- if (on) {
- if (!hw->enabled) {
- hw->enabled = 1;
- if (s->vm_running) {
- hw->pcm_ops->ctl_in (hw, VOICE_ENABLE, conf.try_poll_in);
- audio_reset_timer (s);
- }
- }
- sw->total_hw_samples_acquired = hw->total_samples_captured;
- }
- 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;
- }
-
- if (nb_active == 1) {
- hw->enabled = 0;
- hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
- }
- }
- }
- sw->active = on;
- }
-}
-
-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 (
- "%s: get_avail live %d ret %" PRId64 "\n",
- SW_NAME (sw),
- 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);
- return 0;
- }
-
- dead = sw->hw->samples - live;
-
-#ifdef DEBUG_OUT
- dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
- SW_NAME (sw),
- live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
-#endif
-
- return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
-}
-
-static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
-{
- int n;
-
- if (hw->enabled) {
- SWVoiceCap *sc;
-
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- SWVoiceOut *sw = &sc->sw;
- 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) {
- dolog ("Could not mix %d bytes into a capture "
- "buffer, mixed %d\n",
- bytes, written);
- 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);
-}
-
-static void audio_run_out (AudioState *s)
-{
- HWVoiceOut *hw = NULL;
- SWVoiceOut *sw;
-
- while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) {
- int played;
- int live, free, nb_live, cleanup_required, prev_rpos;
-
- live = audio_pcm_hw_get_live_out (hw, &nb_live);
- if (!nb_live) {
- live = 0;
- }
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- continue;
- }
-
- if (hw->pending_disable && !nb_live) {
- SWVoiceCap *sc;
-#ifdef DEBUG_OUT
- dolog ("Disabling voice\n");
-#endif
- hw->enabled = 0;
- hw->pending_disable = 0;
- hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- sc->sw.active = 0;
- audio_recalc_and_notify_capture (sc->cap);
- }
- continue;
- }
-
- if (!live) {
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- free = audio_get_free (sw);
- if (free > 0) {
- sw->callback.fn (sw->callback.opaque, free);
- }
- }
- }
- continue;
- }
-
- prev_rpos = hw->rpos;
- played = hw->pcm_ops->run_out (hw, live);
- if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
- dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
- hw->rpos, hw->samples, played);
- hw->rpos = 0;
- }
-
-#ifdef DEBUG_OUT
- dolog ("played=%d\n", played);
-#endif
-
- if (played) {
- hw->ts_helper += played;
- audio_capture_mix_and_clear (hw, prev_rpos, played);
- }
-
- cleanup_required = 0;
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (!sw->active && sw->empty) {
- continue;
- }
-
- if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
- dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
- played, sw->total_hw_samples_mixed);
- played = sw->total_hw_samples_mixed;
- }
-
- sw->total_hw_samples_mixed -= played;
-
- if (!sw->total_hw_samples_mixed) {
- sw->empty = 1;
- cleanup_required |= !sw->active && !sw->callback.fn;
- }
-
- if (sw->active) {
- free = audio_get_free (sw);
- if (free > 0) {
- sw->callback.fn (sw->callback.opaque, free);
- }
- }
- }
-
- if (cleanup_required) {
- SWVoiceOut *sw1;
-
- sw = hw->sw_head.lh_first;
- while (sw) {
- sw1 = sw->entries.le_next;
- if (!sw->active && !sw->callback.fn) {
- audio_close_out (sw);
- }
- sw = sw1;
- }
- }
- }
-}
-
-static void audio_run_in (AudioState *s)
-{
- HWVoiceIn *hw = NULL;
-
- while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
- SWVoiceIn *sw;
- int captured, min;
-
- captured = hw->pcm_ops->run_in (hw);
-
- min = audio_pcm_hw_find_min_in (hw);
- hw->total_samples_captured += captured - min;
- hw->ts_helper += captured;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- sw->total_hw_samples_acquired -= min;
-
- if (sw->active) {
- int avail;
-
- avail = audio_get_avail (sw);
- if (avail > 0) {
- sw->callback.fn (sw->callback.opaque, avail);
- }
- }
- }
- }
-}
-
-static void audio_run_capture (AudioState *s)
-{
- CaptureVoiceOut *cap;
-
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- int live, rpos, captured;
- HWVoiceOut *hw = &cap->hw;
- SWVoiceOut *sw;
-
- captured = live = audio_pcm_hw_get_live_out (hw, NULL);
- rpos = hw->rpos;
- while (live) {
- int left = hw->samples - rpos;
- int to_capture = audio_MIN (live, left);
- struct st_sample *src;
- struct capture_callback *cb;
-
- src = hw->mix_buf + rpos;
- hw->clip (cap->buf, src, to_capture);
- mixeng_clear (src, to_capture);
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.capture (cb->opaque, cap->buf,
- to_capture << hw->info.shift);
- }
- rpos = (rpos + to_capture) % hw->samples;
- live -= to_capture;
- }
- hw->rpos = rpos;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (!sw->active && sw->empty) {
- continue;
- }
-
- if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
- dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
- captured, sw->total_hw_samples_mixed);
- captured = sw->total_hw_samples_mixed;
- }
-
- sw->total_hw_samples_mixed -= captured;
- sw->empty = sw->total_hw_samples_mixed == 0;
- }
- }
-}
-
-void audio_run (const char *msg)
-{
- AudioState *s = &glob_audio_state;
-
- audio_run_out (s);
- audio_run_in (s);
- audio_run_capture (s);
-#ifdef DEBUG_POLL
- {
- static double prevtime;
- double currtime;
- struct timeval tv;
-
- if (gettimeofday (&tv, NULL)) {
- perror ("audio_run: gettimeofday");
- return;
- }
-
- currtime = tv.tv_sec + tv.tv_usec * 1e-6;
- dolog ("Elapsed since last %s: %f\n", msg, currtime - prevtime);
- prevtime = currtime;
- }
-#endif
-}
-
-static struct audio_option audio_options[] = {
- /* DAC */
- {
- .name = "DAC_FIXED_SETTINGS",
- .tag = AUD_OPT_BOOL,
- .valp = &conf.fixed_out.enabled,
- .descr = "Use fixed settings for host DAC"
- },
- {
- .name = "DAC_FIXED_FREQ",
- .tag = AUD_OPT_INT,
- .valp = &conf.fixed_out.settings.freq,
- .descr = "Frequency for fixed host DAC"
- },
- {
- .name = "DAC_FIXED_FMT",
- .tag = AUD_OPT_FMT,
- .valp = &conf.fixed_out.settings.fmt,
- .descr = "Format for fixed host DAC"
- },
- {
- .name = "DAC_FIXED_CHANNELS",
- .tag = AUD_OPT_INT,
- .valp = &conf.fixed_out.settings.nchannels,
- .descr = "Number of channels for fixed DAC (1 - mono, 2 - stereo)"
- },
- {
- .name = "DAC_VOICES",
- .tag = AUD_OPT_INT,
- .valp = &conf.fixed_out.nb_voices,
- .descr = "Number of voices for DAC"
- },
- {
- .name = "DAC_TRY_POLL",
- .tag = AUD_OPT_BOOL,
- .valp = &conf.try_poll_out,
- .descr = "Attempt using poll mode for DAC"
- },
- /* ADC */
- {
- .name = "ADC_FIXED_SETTINGS",
- .tag = AUD_OPT_BOOL,
- .valp = &conf.fixed_in.enabled,
- .descr = "Use fixed settings for host ADC"
- },
- {
- .name = "ADC_FIXED_FREQ",
- .tag = AUD_OPT_INT,
- .valp = &conf.fixed_in.settings.freq,
- .descr = "Frequency for fixed host ADC"
- },
- {
- .name = "ADC_FIXED_FMT",
- .tag = AUD_OPT_FMT,
- .valp = &conf.fixed_in.settings.fmt,
- .descr = "Format for fixed host ADC"
- },
- {
- .name = "ADC_FIXED_CHANNELS",
- .tag = AUD_OPT_INT,
- .valp = &conf.fixed_in.settings.nchannels,
- .descr = "Number of channels for fixed ADC (1 - mono, 2 - stereo)"
- },
- {
- .name = "ADC_VOICES",
- .tag = AUD_OPT_INT,
- .valp = &conf.fixed_in.nb_voices,
- .descr = "Number of voices for ADC"
- },
- {
- .name = "ADC_TRY_POLL",
- .tag = AUD_OPT_BOOL,
- .valp = &conf.try_poll_in,
- .descr = "Attempt using poll mode for ADC"
- },
- /* Misc */
- {
- .name = "TIMER_PERIOD",
- .tag = AUD_OPT_INT,
- .valp = &conf.period.hertz,
- .descr = "Timer period in HZ (0 - use lowest possible)"
- },
- { /* End of list */ }
-};
-
-static void audio_pp_nb_voices (const char *typ, int nb)
-{
- switch (nb) {
- case 0:
- printf ("Does not support %s\n", typ);
- break;
- case 1:
- printf ("One %s voice\n", typ);
- break;
- case INT_MAX:
- printf ("Theoretically supports many %s voices\n", typ);
- break;
- default:
- printf ("Theoretically supports up to %d %s voices\n", nb, typ);
- break;
- }
-
-}
-
-void AUD_help (void)
-{
- size_t i;
-
- audio_process_options ("AUDIO", audio_options);
- for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
- struct audio_driver *d = drvtab[i];
- if (d->options) {
- audio_process_options (d->name, d->options);
- }
- }
-
- printf ("Audio options:\n");
- audio_print_options ("AUDIO", audio_options);
- printf ("\n");
-
- printf ("Available drivers:\n");
-
- for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
- struct audio_driver *d = drvtab[i];
-
- printf ("Name: %s\n", d->name);
- printf ("Description: %s\n", d->descr);
-
- audio_pp_nb_voices ("playback", d->max_voices_out);
- audio_pp_nb_voices ("capture", d->max_voices_in);
-
- if (d->options) {
- printf ("Options:\n");
- audio_print_options (d->name, d->options);
- }
- else {
- printf ("No options\n");
- }
- printf ("\n");
- }
-
- printf (
- "Options are settable through environment variables.\n"
- "Example:\n"
-#ifdef _WIN32
- " set QEMU_AUDIO_DRV=wav\n"
- " set QEMU_WAV_PATH=c:\\tune.wav\n"
-#else
- " export QEMU_AUDIO_DRV=wav\n"
- " export QEMU_WAV_PATH=$HOME/tune.wav\n"
- "(for csh replace export with setenv in the above)\n"
-#endif
- " qemu ...\n\n"
- );
-}
-
-static int audio_driver_init (AudioState *s, struct audio_driver *drv)
-{
- if (drv->options) {
- audio_process_options (drv->name, drv->options);
- }
- s->drv_opaque = drv->init ();
-
- if (s->drv_opaque) {
- audio_init_nb_voices_out (drv);
- audio_init_nb_voices_in (drv);
- s->drv = drv;
- return 0;
- }
- else {
- dolog ("Could not init `%s' audio driver\n", drv->name);
- return -1;
- }
-}
-
-static void audio_vm_change_state_handler (void *opaque, int running,
- RunState state)
-{
- AudioState *s = opaque;
- HWVoiceOut *hwo = NULL;
- HWVoiceIn *hwi = NULL;
- int op = running ? VOICE_ENABLE : VOICE_DISABLE;
-
- s->vm_running = running;
- while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
- hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out);
- }
-
- while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
- hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
- }
- audio_reset_timer (s);
-}
-
-static void audio_atexit (void)
-{
- AudioState *s = &glob_audio_state;
- HWVoiceOut *hwo = NULL;
- HWVoiceIn *hwi = NULL;
-
- while ((hwo = audio_pcm_hw_find_any_out (hwo))) {
- SWVoiceCap *sc;
-
- if (hwo->enabled) {
- hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
- }
- hwo->pcm_ops->fini_out (hwo);
-
- for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- CaptureVoiceOut *cap = sc->cap;
- struct capture_callback *cb;
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.destroy (cb->opaque);
- }
- }
- }
-
- while ((hwi = audio_pcm_hw_find_any_in (hwi))) {
- if (hwi->enabled) {
- hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
- }
- hwi->pcm_ops->fini_in (hwi);
- }
-
- if (s->drv) {
- s->drv->fini (s->drv_opaque);
- }
-}
-
-static const VMStateDescription vmstate_audio = {
- .name = "audio",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void audio_init (void)
-{
- size_t i;
- int done = 0;
- const char *drvname;
- VMChangeStateEntry *e;
- AudioState *s = &glob_audio_state;
-
- if (s->drv) {
- return;
- }
-
- QLIST_INIT (&s->hw_head_out);
- QLIST_INIT (&s->hw_head_in);
- QLIST_INIT (&s->cap_head);
- atexit (audio_atexit);
-
- s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
-
- audio_process_options ("AUDIO", audio_options);
-
- s->nb_hw_voices_out = conf.fixed_out.nb_voices;
- s->nb_hw_voices_in = conf.fixed_in.nb_voices;
-
- if (s->nb_hw_voices_out <= 0) {
- dolog ("Bogus number of playback voices %d, setting to 1\n",
- s->nb_hw_voices_out);
- s->nb_hw_voices_out = 1;
- }
-
- if (s->nb_hw_voices_in <= 0) {
- dolog ("Bogus number of capture voices %d, setting to 0\n",
- s->nb_hw_voices_in);
- s->nb_hw_voices_in = 0;
- }
-
- {
- int def;
- drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
- }
-
- if (drvname) {
- int found = 0;
-
- for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
- if (!strcmp (drvname, drvtab[i]->name)) {
- done = !audio_driver_init (s, drvtab[i]);
- found = 1;
- break;
- }
- }
-
- if (!found) {
- dolog ("Unknown audio driver `%s'\n", drvname);
- dolog ("Run with -audio-help to list available drivers\n");
- }
- }
-
- if (!done) {
- for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {
- if (drvtab[i]->can_be_default) {
- done = !audio_driver_init (s, drvtab[i]);
- }
- }
- }
-
- if (!done) {
- done = !audio_driver_init (s, &no_audio_driver);
- assert(done);
- dolog("warning: Using timer based audio emulation\n");
- }
-
- if (conf.period.hertz <= 0) {
- if (conf.period.hertz < 0) {
- dolog ("warning: Timer period is negative - %d "
- "treating as zero\n",
- conf.period.hertz);
- }
- conf.period.ticks = 1;
- } else {
- conf.period.ticks = NANOSECONDS_PER_SECOND / conf.period.hertz;
- }
-
- e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
- if (!e) {
- dolog ("warning: Could not register change state handler\n"
- "(Audio can continue looping even after stopping the VM)\n");
- }
-
- QLIST_INIT (&s->card_head);
- vmstate_register (NULL, 0, &vmstate_audio, s);
-}
-
-void AUD_register_card (const char *name, QEMUSoundCard *card)
-{
- audio_init ();
- card->name = g_strdup (name);
- memset (&card->entries, 0, sizeof (card->entries));
- QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries);
-}
-
-void AUD_remove_card (QEMUSoundCard *card)
-{
- QLIST_REMOVE (card, entries);
- g_free (card->name);
-}
-
-
-CaptureVoiceOut *AUD_add_capture (
- struct audsettings *as,
- struct audio_capture_ops *ops,
- void *cb_opaque
- )
-{
- AudioState *s = &glob_audio_state;
- CaptureVoiceOut *cap;
- struct capture_callback *cb;
-
- if (audio_validate_settings (as)) {
- dolog ("Invalid settings were passed when trying to add capture\n");
- audio_print_settings (as);
- goto err0;
- }
-
- cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
- if (!cb) {
- dolog ("Could not allocate capture callback information, size %zu\n",
- sizeof (*cb));
- goto err0;
- }
- cb->ops = *ops;
- cb->opaque = cb_opaque;
-
- cap = audio_pcm_capture_find_specific (as);
- if (cap) {
- QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
- return cap;
- }
- else {
- HWVoiceOut *hw;
- CaptureVoiceOut *cap;
-
- cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
- if (!cap) {
- dolog ("Could not allocate capture voice, size %zu\n",
- sizeof (*cap));
- goto err1;
- }
-
- hw = &cap->hw;
- QLIST_INIT (&hw->sw_head);
- QLIST_INIT (&cap->cb_head);
-
- /* XXX find a more elegant way */
- hw->samples = 4096 * 4;
- hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
- sizeof (struct st_sample));
- if (!hw->mix_buf) {
- dolog ("Could not allocate capture mix buffer (%d samples)\n",
- hw->samples);
- goto err2;
- }
-
- audio_pcm_init_info (&hw->info, as);
-
- cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!cap->buf) {
- dolog ("Could not allocate capture buffer "
- "(%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- goto err3;
- }
-
- hw->clip = mixeng_clip
- [hw->info.nchannels == 2]
- [hw->info.sign]
- [hw->info.swap_endianness]
- [audio_bits_to_index (hw->info.bits)];
-
- QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
- QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
-
- hw = NULL;
- while ((hw = audio_pcm_hw_find_any_out (hw))) {
- audio_attach_capture (hw);
- }
- return cap;
-
- err3:
- g_free (cap->hw.mix_buf);
- err2:
- g_free (cap);
- err1:
- g_free (cb);
- err0:
- return NULL;
- }
-}
-
-void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
-{
- struct capture_callback *cb;
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- if (cb->opaque == cb_opaque) {
- cb->ops.destroy (cb_opaque);
- QLIST_REMOVE (cb, entries);
- g_free (cb);
-
- if (!cap->cb_head.lh_first) {
- SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
-
- while (sw) {
- SWVoiceCap *sc = (SWVoiceCap *) sw;
-#ifdef DEBUG_CAPTURE
- dolog ("freeing %s\n", sw->name);
-#endif
-
- sw1 = sw->entries.le_next;
- if (sw->rate) {
- st_rate_stop (sw->rate);
- sw->rate = NULL;
- }
- QLIST_REMOVE (sw, entries);
- QLIST_REMOVE (sc, entries);
- g_free (sc);
- sw = sw1;
- }
- QLIST_REMOVE (cap, entries);
- g_free (cap);
- }
- return;
- }
- }
-}
-
-void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
-{
- if (sw) {
- HWVoiceOut *hw = sw->hw;
-
- sw->vol.mute = mute;
- sw->vol.l = nominal_volume.l * lvol / 255;
- sw->vol.r = nominal_volume.r * rvol / 255;
-
- if (hw->pcm_ops->ctl_out) {
- hw->pcm_ops->ctl_out (hw, VOICE_VOLUME, sw);
- }
- }
-}
-
-void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
-{
- if (sw) {
- HWVoiceIn *hw = sw->hw;
-
- sw->vol.mute = mute;
- sw->vol.l = nominal_volume.l * lvol / 255;
- sw->vol.r = nominal_volume.r * rvol / 255;
-
- if (hw->pcm_ops->ctl_in) {
- hw->pcm_ops->ctl_in (hw, VOICE_VOLUME, sw);
- }
- }
-}
diff --git a/qemu/audio/audio.h b/qemu/audio/audio.h
deleted file mode 100644
index b41a97053..000000000
--- a/qemu/audio/audio.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#ifndef QEMU_AUDIO_H
-#define QEMU_AUDIO_H
-
-#include "qemu/queue.h"
-
-typedef void (*audio_callback_fn) (void *opaque, int avail);
-
-typedef enum {
- AUD_FMT_U8,
- AUD_FMT_S8,
- AUD_FMT_U16,
- AUD_FMT_S16,
- AUD_FMT_U32,
- AUD_FMT_S32
-} audfmt_e;
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define AUDIO_HOST_ENDIANNESS 1
-#else
-#define AUDIO_HOST_ENDIANNESS 0
-#endif
-
-struct audsettings {
- int freq;
- int nchannels;
- audfmt_e fmt;
- int endianness;
-};
-
-typedef enum {
- AUD_CNOTIFY_ENABLE,
- AUD_CNOTIFY_DISABLE
-} audcnotification_e;
-
-struct audio_capture_ops {
- void (*notify) (void *opaque, audcnotification_e cmd);
- void (*capture) (void *opaque, void *buf, int size);
- void (*destroy) (void *opaque);
-};
-
-struct capture_ops {
- void (*info) (void *opaque);
- void (*destroy) (void *opaque);
-};
-
-typedef struct CaptureState {
- void *opaque;
- struct capture_ops ops;
- QLIST_ENTRY (CaptureState) entries;
-} CaptureState;
-
-typedef struct SWVoiceOut SWVoiceOut;
-typedef struct CaptureVoiceOut CaptureVoiceOut;
-typedef struct SWVoiceIn SWVoiceIn;
-
-typedef struct QEMUSoundCard {
- char *name;
- QLIST_ENTRY (QEMUSoundCard) entries;
-} QEMUSoundCard;
-
-typedef struct QEMUAudioTimeStamp {
- uint64_t old_ts;
-} QEMUAudioTimeStamp;
-
-void AUD_vlog (const char *cap, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
-void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
-
-void AUD_help (void);
-void AUD_register_card (const char *name, QEMUSoundCard *card);
-void AUD_remove_card (QEMUSoundCard *card);
-CaptureVoiceOut *AUD_add_capture (
- struct audsettings *as,
- struct audio_capture_ops *ops,
- void *opaque
- );
-void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque);
-
-SWVoiceOut *AUD_open_out (
- QEMUSoundCard *card,
- SWVoiceOut *sw,
- const char *name,
- void *callback_opaque,
- audio_callback_fn callback_fn,
- struct audsettings *settings
- );
-
-void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
-int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
-int AUD_get_buffer_size_out (SWVoiceOut *sw);
-void AUD_set_active_out (SWVoiceOut *sw, int on);
-int AUD_is_active_out (SWVoiceOut *sw);
-
-void AUD_init_time_stamp_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
-uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
-
-void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol);
-void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol);
-
-SWVoiceIn *AUD_open_in (
- QEMUSoundCard *card,
- SWVoiceIn *sw,
- const char *name,
- void *callback_opaque,
- audio_callback_fn callback_fn,
- struct audsettings *settings
- );
-
-void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
-int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
-void AUD_set_active_in (SWVoiceIn *sw, int on);
-int AUD_is_active_in (SWVoiceIn *sw);
-
-void AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
-uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
-
-static inline void *advance (void *p, int incr)
-{
- uint8_t *d = p;
- return (d + incr);
-}
-
-#ifdef __GNUC__
-#define audio_MIN(a, b) ( __extension__ ({ \
- __typeof (a) ta = a; \
- __typeof (b) tb = b; \
- ((ta)>(tb)?(tb):(ta)); \
-}))
-
-#define audio_MAX(a, b) ( __extension__ ({ \
- __typeof (a) ta = a; \
- __typeof (b) tb = b; \
- ((ta)<(tb)?(tb):(ta)); \
-}))
-#else
-#define audio_MIN(a, b) ((a)>(b)?(b):(a))
-#define audio_MAX(a, b) ((a)<(b)?(b):(a))
-#endif
-
-int wav_start_capture (CaptureState *s, const char *path, int freq,
- int bits, int nchannels);
-
-#endif /* audio.h */
diff --git a/qemu/audio/audio_int.h b/qemu/audio/audio_int.h
deleted file mode 100644
index 566df5edf..000000000
--- a/qemu/audio/audio_int.h
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#ifndef QEMU_AUDIO_INT_H
-#define QEMU_AUDIO_INT_H
-
-#ifdef CONFIG_COREAUDIO
-#define FLOAT_MIXENG
-/* #define RECIPROCAL */
-#endif
-#include "mixeng.h"
-
-struct audio_pcm_ops;
-
-typedef enum {
- AUD_OPT_INT,
- AUD_OPT_FMT,
- AUD_OPT_STR,
- AUD_OPT_BOOL
-} audio_option_tag_e;
-
-struct audio_option {
- const char *name;
- audio_option_tag_e tag;
- void *valp;
- const char *descr;
- int *overriddenp;
- int overridden;
-};
-
-struct audio_callback {
- void *opaque;
- audio_callback_fn fn;
-};
-
-struct audio_pcm_info {
- int bits;
- int sign;
- int freq;
- int nchannels;
- int align;
- int shift;
- int bytes_per_second;
- int swap_endianness;
-};
-
-typedef struct SWVoiceCap SWVoiceCap;
-
-typedef struct HWVoiceOut {
- int enabled;
- int poll_mode;
- int pending_disable;
- struct audio_pcm_info info;
-
- f_sample *clip;
-
- int rpos;
- uint64_t ts_helper;
-
- struct st_sample *mix_buf;
-
- int samples;
- QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
- QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
- int ctl_caps;
- struct audio_pcm_ops *pcm_ops;
- QLIST_ENTRY (HWVoiceOut) entries;
-} HWVoiceOut;
-
-typedef struct HWVoiceIn {
- int enabled;
- int poll_mode;
- struct audio_pcm_info info;
-
- t_sample *conv;
-
- int wpos;
- int total_samples_captured;
- uint64_t ts_helper;
-
- struct st_sample *conv_buf;
-
- int samples;
- QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
- int ctl_caps;
- struct audio_pcm_ops *pcm_ops;
- QLIST_ENTRY (HWVoiceIn) entries;
-} HWVoiceIn;
-
-struct SWVoiceOut {
- QEMUSoundCard *card;
- struct audio_pcm_info info;
- t_sample *conv;
- int64_t ratio;
- struct st_sample *buf;
- void *rate;
- int total_hw_samples_mixed;
- int active;
- int empty;
- HWVoiceOut *hw;
- char *name;
- struct mixeng_volume vol;
- struct audio_callback callback;
- QLIST_ENTRY (SWVoiceOut) entries;
-};
-
-struct SWVoiceIn {
- QEMUSoundCard *card;
- int active;
- struct audio_pcm_info info;
- int64_t ratio;
- void *rate;
- int total_hw_samples_acquired;
- struct st_sample *buf;
- f_sample *clip;
- HWVoiceIn *hw;
- char *name;
- struct mixeng_volume vol;
- struct audio_callback callback;
- QLIST_ENTRY (SWVoiceIn) entries;
-};
-
-struct audio_driver {
- const char *name;
- const char *descr;
- struct audio_option *options;
- void *(*init) (void);
- void (*fini) (void *);
- struct audio_pcm_ops *pcm_ops;
- int can_be_default;
- int max_voices_out;
- int max_voices_in;
- int voice_size_out;
- int voice_size_in;
- int ctl_caps;
-};
-
-struct audio_pcm_ops {
- int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
- void (*fini_out)(HWVoiceOut *hw);
- int (*run_out) (HWVoiceOut *hw, int live);
- int (*write) (SWVoiceOut *sw, void *buf, int size);
- int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
-
- int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
- void (*fini_in) (HWVoiceIn *hw);
- int (*run_in) (HWVoiceIn *hw);
- int (*read) (SWVoiceIn *sw, void *buf, int size);
- int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
-};
-
-struct capture_callback {
- struct audio_capture_ops ops;
- void *opaque;
- QLIST_ENTRY (capture_callback) entries;
-};
-
-struct CaptureVoiceOut {
- HWVoiceOut hw;
- void *buf;
- QLIST_HEAD (cb_listhead, capture_callback) cb_head;
- QLIST_ENTRY (CaptureVoiceOut) entries;
-};
-
-struct SWVoiceCap {
- SWVoiceOut sw;
- CaptureVoiceOut *cap;
- QLIST_ENTRY (SWVoiceCap) entries;
-};
-
-struct AudioState {
- struct audio_driver *drv;
- void *drv_opaque;
-
- QEMUTimer *ts;
- QLIST_HEAD (card_listhead, QEMUSoundCard) card_head;
- QLIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
- QLIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
- QLIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
- int nb_hw_voices_out;
- int nb_hw_voices_in;
- int vm_running;
-};
-
-extern struct audio_driver no_audio_driver;
-extern struct audio_driver oss_audio_driver;
-extern struct audio_driver sdl_audio_driver;
-extern struct audio_driver wav_audio_driver;
-extern struct audio_driver alsa_audio_driver;
-extern struct audio_driver coreaudio_audio_driver;
-extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver pa_audio_driver;
-extern struct audio_driver spice_audio_driver;
-extern const struct mixeng_volume nominal_volume;
-
-void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
-void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
-
-int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
-int audio_pcm_hw_get_live_in (HWVoiceIn *hw);
-
-int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
-
-int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
- int live, int pending);
-
-int audio_bug (const char *funcname, int cond);
-void *audio_calloc (const char *funcname, int nmemb, size_t size);
-
-void audio_run (const char *msg);
-
-#define VOICE_ENABLE 1
-#define VOICE_DISABLE 2
-#define VOICE_VOLUME 3
-
-#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME)
-
-static inline int audio_ring_dist (int dst, int src, int len)
-{
- return (dst >= src) ? (dst - src) : (len - src + dst);
-}
-
-#define dolog(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
-
-#ifdef DEBUG
-#define ldebug(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
-#else
-#define ldebug(fmt, ...) (void)0
-#endif
-
-#define AUDIO_STRINGIFY_(n) #n
-#define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n)
-
-#if defined _MSC_VER || defined __GNUC__
-#define AUDIO_FUNC __FUNCTION__
-#else
-#define AUDIO_FUNC __FILE__ ":" AUDIO_STRINGIFY (__LINE__)
-#endif
-
-#endif /* audio_int.h */
diff --git a/qemu/audio/audio_pt_int.c b/qemu/audio/audio_pt_int.c
deleted file mode 100644
index 21ff9c580..000000000
--- a/qemu/audio/audio_pt_int.c
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "audio.h"
-
-#define AUDIO_CAP "audio-pt"
-
-#include "audio_int.h"
-#include "audio_pt_int.h"
-
-static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
- const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (pt->drv, fmt, ap);
- va_end (ap);
-
- AUD_log (NULL, "\n");
- AUD_log (pt->drv, "Reason: %s\n", strerror (err));
-}
-
-int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
- void *opaque, const char *drv, const char *cap)
-{
- int err, err2;
- const char *efunc;
- sigset_t set, old_set;
-
- p->drv = drv;
-
- err = sigfillset (&set);
- if (err) {
- logerr (p, errno, "%s(%s): sigfillset failed", cap, AUDIO_FUNC);
- return -1;
- }
-
- err = pthread_mutex_init (&p->mutex, NULL);
- if (err) {
- efunc = "pthread_mutex_init";
- goto err0;
- }
-
- err = pthread_cond_init (&p->cond, NULL);
- if (err) {
- efunc = "pthread_cond_init";
- goto err1;
- }
-
- err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
- if (err) {
- efunc = "pthread_sigmask";
- goto err2;
- }
-
- err = pthread_create (&p->thread, NULL, func, opaque);
-
- err2 = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_sigmask (restore) failed",
- cap, AUDIO_FUNC);
- /* We have failed to restore original signal mask, all bets are off,
- so terminate the process */
- exit (EXIT_FAILURE);
- }
-
- if (err) {
- efunc = "pthread_create";
- goto err2;
- }
-
- return 0;
-
- err2:
- err2 = pthread_cond_destroy (&p->cond);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
- }
-
- err1:
- err2 = pthread_mutex_destroy (&p->mutex);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
- }
-
- err0:
- logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
- return -1;
-}
-
-int audio_pt_fini (struct audio_pt *p, const char *cap)
-{
- int err, ret = 0;
-
- err = pthread_cond_destroy (&p->cond);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
- ret = -1;
- }
-
- err = pthread_mutex_destroy (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
- ret = -1;
- }
- return ret;
-}
-
-int audio_pt_lock (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_lock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_unlock (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_unlock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_wait (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_cond_wait (&p->cond, &p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_unlock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
- return -1;
- }
- err = pthread_cond_signal (&p->cond);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
-{
- int err;
- void *ret;
-
- err = pthread_join (p->thread, &ret);
- if (err) {
- logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
- return -1;
- }
- *arg = ret;
- return 0;
-}
diff --git a/qemu/audio/audio_pt_int.h b/qemu/audio/audio_pt_int.h
deleted file mode 100644
index 0dfff76aa..000000000
--- a/qemu/audio/audio_pt_int.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef QEMU_AUDIO_PT_INT_H
-#define QEMU_AUDIO_PT_INT_H
-
-#include <pthread.h>
-
-struct audio_pt {
- const char *drv;
- pthread_t thread;
- pthread_cond_t cond;
- pthread_mutex_t mutex;
-};
-
-int audio_pt_init (struct audio_pt *, void *(*) (void *), void *,
- const char *, const char *);
-int audio_pt_fini (struct audio_pt *, const char *);
-int audio_pt_lock (struct audio_pt *, const char *);
-int audio_pt_unlock (struct audio_pt *, const char *);
-int audio_pt_wait (struct audio_pt *, const char *);
-int audio_pt_unlock_and_signal (struct audio_pt *, const char *);
-int audio_pt_join (struct audio_pt *, void **, const char *);
-
-#endif /* audio_pt_int.h */
diff --git a/qemu/audio/audio_template.h b/qemu/audio/audio_template.h
deleted file mode 100644
index 99b27b285..000000000
--- a/qemu/audio/audio_template.h
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * 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.
- */
-
-#ifdef DAC
-#define NAME "playback"
-#define HWBUF hw->mix_buf
-#define TYPE out
-#define HW HWVoiceOut
-#define SW SWVoiceOut
-#else
-#define NAME "capture"
-#define TYPE in
-#define HW HWVoiceIn
-#define SW SWVoiceIn
-#define HWBUF hw->conv_buf
-#endif
-
-static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
-{
- AudioState *s = &glob_audio_state;
- int max_voices = glue (drv->max_voices_, TYPE);
- int voice_size = glue (drv->voice_size_, TYPE);
-
- if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
- if (!max_voices) {
-#ifdef DAC
- dolog ("Driver `%s' does not support " NAME "\n", drv->name);
-#endif
- }
- else {
- dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
- drv->name,
- glue (s->nb_hw_voices_, TYPE),
- max_voices);
- }
- glue (s->nb_hw_voices_, TYPE) = max_voices;
- }
-
- if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
- dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
- drv->name, max_voices);
- glue (s->nb_hw_voices_, TYPE) = 0;
- }
-
- if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
- dolog ("drv=`%s' voice_size=%d max_voices=0\n",
- drv->name, voice_size);
- }
-}
-
-static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
-{
- g_free (HWBUF);
- HWBUF = NULL;
-}
-
-static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
-{
- HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (struct st_sample));
- if (!HWBUF) {
- dolog ("Could not allocate " NAME " buffer (%d samples)\n",
- hw->samples);
- return -1;
- }
-
- return 0;
-}
-
-static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
-{
- g_free (sw->buf);
-
- if (sw->rate) {
- st_rate_stop (sw->rate);
- }
-
- sw->buf = NULL;
- sw->rate = NULL;
-}
-
-static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
-{
- int samples;
-
- samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
-
- sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample));
- if (!sw->buf) {
- dolog ("Could not allocate buffer for `%s' (%d samples)\n",
- SW_NAME (sw), samples);
- return -1;
- }
-
-#ifdef DAC
- sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
-#else
- sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
-#endif
- if (!sw->rate) {
- g_free (sw->buf);
- sw->buf = NULL;
- return -1;
- }
- return 0;
-}
-
-static int glue (audio_pcm_sw_init_, TYPE) (
- SW *sw,
- HW *hw,
- const char *name,
- struct audsettings *as
- )
-{
- int err;
-
- audio_pcm_init_info (&sw->info, as);
- sw->hw = hw;
- sw->active = 0;
-#ifdef DAC
- sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
- sw->total_hw_samples_mixed = 0;
- sw->empty = 1;
-#else
- sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
-#endif
-
-#ifdef DAC
- sw->conv = mixeng_conv
-#else
- sw->clip = mixeng_clip
-#endif
- [sw->info.nchannels == 2]
- [sw->info.sign]
- [sw->info.swap_endianness]
- [audio_bits_to_index (sw->info.bits)];
-
- sw->name = g_strdup (name);
- err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
- if (err) {
- g_free (sw->name);
- sw->name = NULL;
- }
- return err;
-}
-
-static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
-{
- glue (audio_pcm_sw_free_resources_, TYPE) (sw);
- g_free (sw->name);
- sw->name = NULL;
-}
-
-static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
-{
- QLIST_INSERT_HEAD (&hw->sw_head, sw, entries);
-}
-
-static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
-{
- QLIST_REMOVE (sw, entries);
-}
-
-static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
-{
- AudioState *s = &glob_audio_state;
- HW *hw = *hwp;
-
- if (!hw->sw_head.lh_first) {
-#ifdef DAC
- audio_detach_capture (hw);
-#endif
- QLIST_REMOVE (hw, entries);
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- glue (s->nb_hw_voices_, TYPE) += 1;
- glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
- g_free (hw);
- *hwp = NULL;
- }
-}
-
-static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw)
-{
- AudioState *s = &glob_audio_state;
- return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
-}
-
-static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw)
-{
- while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
- if (hw->enabled) {
- return hw;
- }
- }
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
- HW *hw,
- struct audsettings *as
- )
-{
- while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
- if (audio_pcm_info_eq (&hw->info, as)) {
- return hw;
- }
- }
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
-{
- HW *hw;
- AudioState *s = &glob_audio_state;
- struct audio_driver *drv = s->drv;
-
- if (!glue (s->nb_hw_voices_, TYPE)) {
- return NULL;
- }
-
- if (audio_bug (AUDIO_FUNC, !drv)) {
- dolog ("No host audio driver\n");
- return NULL;
- }
-
- if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
- dolog ("Host audio driver without pcm_ops\n");
- return NULL;
- }
-
- hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
- if (!hw) {
- dolog ("Can not allocate voice `%s' size %d\n",
- drv->name, glue (drv->voice_size_, TYPE));
- return NULL;
- }
-
- hw->pcm_ops = drv->pcm_ops;
- hw->ctl_caps = drv->ctl_caps;
-
- QLIST_INIT (&hw->sw_head);
-#ifdef DAC
- QLIST_INIT (&hw->cap_head);
-#endif
- if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
- goto err0;
- }
-
- if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
- dolog ("hw->samples=%d\n", hw->samples);
- goto err1;
- }
-
-#ifdef DAC
- hw->clip = mixeng_clip
-#else
- hw->conv = mixeng_conv
-#endif
- [hw->info.nchannels == 2]
- [hw->info.sign]
- [hw->info.swap_endianness]
- [audio_bits_to_index (hw->info.bits)];
-
- if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
- goto err1;
- }
-
- QLIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
- glue (s->nb_hw_voices_, TYPE) -= 1;
-#ifdef DAC
- audio_attach_capture (hw);
-#endif
- return hw;
-
- err1:
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- err0:
- g_free (hw);
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as)
-{
- HW *hw;
-
- if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
- hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
- if (hw) {
- return hw;
- }
- }
-
- hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as);
- if (hw) {
- return hw;
- }
-
- hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
- if (hw) {
- return hw;
- }
-
- return glue (audio_pcm_hw_find_any_, TYPE) (NULL);
-}
-
-static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
- const char *sw_name,
- struct audsettings *as
- )
-{
- SW *sw;
- HW *hw;
- struct audsettings hw_as;
-
- if (glue (conf.fixed_, TYPE).enabled) {
- hw_as = glue (conf.fixed_, TYPE).settings;
- }
- else {
- hw_as = *as;
- }
-
- sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
- if (!sw) {
- dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
- sw_name ? sw_name : "unknown", sizeof (*sw));
- goto err1;
- }
-
- hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as);
- if (!hw) {
- goto err2;
- }
-
- glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
-
- if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
- goto err3;
- }
-
- return sw;
-
-err3:
- glue (audio_pcm_hw_del_sw_, TYPE) (sw);
- glue (audio_pcm_hw_gc_, TYPE) (&hw);
-err2:
- g_free (sw);
-err1:
- return NULL;
-}
-
-static void glue (audio_close_, TYPE) (SW *sw)
-{
- glue (audio_pcm_sw_fini_, TYPE) (sw);
- glue (audio_pcm_hw_del_sw_, TYPE) (sw);
- glue (audio_pcm_hw_gc_, TYPE) (&sw->hw);
- g_free (sw);
-}
-
-void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
-{
- if (sw) {
- if (audio_bug (AUDIO_FUNC, !card)) {
- dolog ("card=%p\n", card);
- return;
- }
-
- glue (audio_close_, TYPE) (sw);
- }
-}
-
-SW *glue (AUD_open_, TYPE) (
- QEMUSoundCard *card,
- SW *sw,
- const char *name,
- void *callback_opaque ,
- audio_callback_fn callback_fn,
- struct audsettings *as
- )
-{
- AudioState *s = &glob_audio_state;
-
- if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
- dolog ("card=%p name=%p callback_fn=%p as=%p\n",
- card, name, callback_fn, as);
- goto fail;
- }
-
- ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
- name, as->freq, as->nchannels, as->fmt);
-
- if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
- audio_print_settings (as);
- goto fail;
- }
-
- if (audio_bug (AUDIO_FUNC, !s->drv)) {
- dolog ("Can not open `%s' (no host audio driver)\n", name);
- goto fail;
- }
-
- if (sw && audio_pcm_info_eq (&sw->info, as)) {
- return sw;
- }
-
- if (!glue (conf.fixed_, TYPE).enabled && sw) {
- glue (AUD_close_, TYPE) (card, sw);
- sw = NULL;
- }
-
- if (sw) {
- HW *hw = sw->hw;
-
- if (!hw) {
- dolog ("Internal logic error voice `%s' has no hardware store\n",
- SW_NAME (sw));
- goto fail;
- }
-
- glue (audio_pcm_sw_fini_, TYPE) (sw);
- if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
- goto fail;
- }
- }
- else {
- sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as);
- if (!sw) {
- dolog ("Failed to create voice `%s'\n", name);
- return NULL;
- }
- }
-
- sw->card = card;
- sw->vol = nominal_volume;
- sw->callback.fn = callback_fn;
- sw->callback.opaque = callback_opaque;
-
-#ifdef DEBUG_AUDIO
- dolog ("%s\n", name);
- audio_pcm_print_info ("hw", &sw->hw->info);
- audio_pcm_print_info ("sw", &sw->info);
-#endif
-
- return sw;
-
- fail:
- glue (AUD_close_, TYPE) (card, sw);
- return NULL;
-}
-
-int glue (AUD_is_active_, TYPE) (SW *sw)
-{
- return sw ? sw->active : 0;
-}
-
-void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
-{
- if (!sw) {
- return;
- }
-
- ts->old_ts = sw->hw->ts_helper;
-}
-
-uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
-{
- uint64_t delta, cur_ts, old_ts;
-
- if (!sw) {
- return 0;
- }
-
- cur_ts = sw->hw->ts_helper;
- old_ts = ts->old_ts;
- /* dolog ("cur %" PRId64 " old %" PRId64 "\n", cur_ts, old_ts); */
-
- if (cur_ts >= old_ts) {
- delta = cur_ts - old_ts;
- }
- else {
- delta = UINT64_MAX - old_ts + cur_ts;
- }
-
- if (!delta) {
- return 0;
- }
-
- return muldiv64 (delta, sw->hw->info.freq, 1000000);
-}
-
-#undef TYPE
-#undef HW
-#undef SW
-#undef HWBUF
-#undef NAME
diff --git a/qemu/audio/audio_win_int.c b/qemu/audio/audio_win_int.c
deleted file mode 100644
index 6900008d0..000000000
--- a/qemu/audio/audio_win_int.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* public domain */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-
-#define AUDIO_CAP "win-int"
-#include <windows.h>
-#include <mmsystem.h>
-
-#include "audio.h"
-#include "audio_int.h"
-#include "audio_win_int.h"
-
-int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
- struct audsettings *as)
-{
- memset (wfx, 0, sizeof (*wfx));
-
- wfx->wFormatTag = WAVE_FORMAT_PCM;
- wfx->nChannels = as->nchannels;
- wfx->nSamplesPerSec = as->freq;
- wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
- wfx->nBlockAlign = 1 << (as->nchannels == 2);
- wfx->cbSize = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- wfx->wBitsPerSample = 8;
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- wfx->wBitsPerSample = 16;
- wfx->nAvgBytesPerSec <<= 1;
- wfx->nBlockAlign <<= 1;
- break;
-
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- wfx->wBitsPerSample = 32;
- wfx->nAvgBytesPerSec <<= 2;
- wfx->nBlockAlign <<= 2;
- break;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", as->freq);
- return -1;
- }
-
- return 0;
-}
-
-int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
- struct audsettings *as)
-{
- if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
- dolog ("Invalid wave format, tag is not PCM, but %d\n",
- wfx->wFormatTag);
- return -1;
- }
-
- if (!wfx->nSamplesPerSec) {
- dolog ("Invalid wave format, frequency is zero\n");
- return -1;
- }
- as->freq = wfx->nSamplesPerSec;
-
- switch (wfx->nChannels) {
- case 1:
- as->nchannels = 1;
- break;
-
- case 2:
- as->nchannels = 2;
- break;
-
- default:
- dolog (
- "Invalid wave format, number of channels is not 1 or 2, but %d\n",
- wfx->nChannels
- );
- return -1;
- }
-
- switch (wfx->wBitsPerSample) {
- case 8:
- as->fmt = AUD_FMT_U8;
- break;
-
- case 16:
- as->fmt = AUD_FMT_S16;
- break;
-
- case 32:
- as->fmt = AUD_FMT_S32;
- break;
-
- default:
- dolog ("Invalid wave format, bits per sample is not "
- "8, 16 or 32, but %d\n",
- wfx->wBitsPerSample);
- return -1;
- }
-
- return 0;
-}
-
diff --git a/qemu/audio/audio_win_int.h b/qemu/audio/audio_win_int.h
deleted file mode 100644
index fa5b3cb80..000000000
--- a/qemu/audio/audio_win_int.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef AUDIO_WIN_INT_H
-#define AUDIO_WIN_INT_H
-
-int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
- struct audsettings *as);
-
-int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
- struct audsettings *as);
-
-#endif /* AUDIO_WIN_INT_H */
diff --git a/qemu/audio/coreaudio.c b/qemu/audio/coreaudio.c
deleted file mode 100644
index d4ad22459..000000000
--- a/qemu/audio/coreaudio.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * QEMU OS X CoreAudio audio driver
- *
- * Copyright (c) 2005 Mike Kronenberg
- *
- * 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.
- */
-
-#include "qemu/osdep.h"
-#include <CoreAudio/CoreAudio.h>
-#include <pthread.h> /* pthread_X */
-
-#include "qemu-common.h"
-#include "audio.h"
-
-#define AUDIO_CAP "coreaudio"
-#include "audio_int.h"
-
-#ifndef MAC_OS_X_VERSION_10_6
-#define MAC_OS_X_VERSION_10_6 1060
-#endif
-
-static int isAtexit;
-
-typedef struct {
- int buffer_frames;
- int nbuffers;
-} CoreaudioConf;
-
-typedef struct coreaudioVoiceOut {
- HWVoiceOut hw;
- pthread_mutex_t mutex;
- AudioDeviceID outputDeviceID;
- UInt32 audioDevicePropertyBufferFrameSize;
- AudioStreamBasicDescription outputStreamBasicDescription;
- AudioDeviceIOProcID ioprocid;
- int live;
- int decr;
- int rpos;
-} coreaudioVoiceOut;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-/* The APIs used here only become available from 10.6 */
-
-static OSStatus coreaudio_get_voice(AudioDeviceID *id)
-{
- UInt32 size = sizeof(*id);
- AudioObjectPropertyAddress addr = {
- kAudioHardwarePropertyDefaultOutputDevice,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &addr,
- 0,
- NULL,
- &size,
- id);
-}
-
-static OSStatus coreaudio_get_framesizerange(AudioDeviceID id,
- AudioValueRange *framerange)
-{
- UInt32 size = sizeof(*framerange);
- AudioObjectPropertyAddress addr = {
- kAudioDevicePropertyBufferFrameSizeRange,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectGetPropertyData(id,
- &addr,
- 0,
- NULL,
- &size,
- framerange);
-}
-
-static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize)
-{
- UInt32 size = sizeof(*framesize);
- AudioObjectPropertyAddress addr = {
- kAudioDevicePropertyBufferFrameSize,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectGetPropertyData(id,
- &addr,
- 0,
- NULL,
- &size,
- framesize);
-}
-
-static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize)
-{
- UInt32 size = sizeof(*framesize);
- AudioObjectPropertyAddress addr = {
- kAudioDevicePropertyBufferFrameSize,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectSetPropertyData(id,
- &addr,
- 0,
- NULL,
- size,
- framesize);
-}
-
-static OSStatus coreaudio_get_streamformat(AudioDeviceID id,
- AudioStreamBasicDescription *d)
-{
- UInt32 size = sizeof(*d);
- AudioObjectPropertyAddress addr = {
- kAudioDevicePropertyStreamFormat,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectGetPropertyData(id,
- &addr,
- 0,
- NULL,
- &size,
- d);
-}
-
-static OSStatus coreaudio_set_streamformat(AudioDeviceID id,
- AudioStreamBasicDescription *d)
-{
- UInt32 size = sizeof(*d);
- AudioObjectPropertyAddress addr = {
- kAudioDevicePropertyStreamFormat,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectSetPropertyData(id,
- &addr,
- 0,
- NULL,
- size,
- d);
-}
-
-static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result)
-{
- UInt32 size = sizeof(*result);
- AudioObjectPropertyAddress addr = {
- kAudioDevicePropertyDeviceIsRunning,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster
- };
-
- return AudioObjectGetPropertyData(id,
- &addr,
- 0,
- NULL,
- &size,
- result);
-}
-#else
-/* Legacy versions of functions using deprecated APIs */
-
-static OSStatus coreaudio_get_voice(AudioDeviceID *id)
-{
- UInt32 size = sizeof(*id);
-
- return AudioHardwareGetProperty(
- kAudioHardwarePropertyDefaultOutputDevice,
- &size,
- id);
-}
-
-static OSStatus coreaudio_get_framesizerange(AudioDeviceID id,
- AudioValueRange *framerange)
-{
- UInt32 size = sizeof(*framerange);
-
- return AudioDeviceGetProperty(
- id,
- 0,
- 0,
- kAudioDevicePropertyBufferFrameSizeRange,
- &size,
- framerange);
-}
-
-static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize)
-{
- UInt32 size = sizeof(*framesize);
-
- return AudioDeviceGetProperty(
- id,
- 0,
- false,
- kAudioDevicePropertyBufferFrameSize,
- &size,
- framesize);
-}
-
-static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize)
-{
- UInt32 size = sizeof(*framesize);
-
- return AudioDeviceSetProperty(
- id,
- NULL,
- 0,
- false,
- kAudioDevicePropertyBufferFrameSize,
- size,
- framesize);
-}
-
-static OSStatus coreaudio_get_streamformat(AudioDeviceID id,
- AudioStreamBasicDescription *d)
-{
- UInt32 size = sizeof(*d);
-
- return AudioDeviceGetProperty(
- id,
- 0,
- false,
- kAudioDevicePropertyStreamFormat,
- &size,
- d);
-}
-
-static OSStatus coreaudio_set_streamformat(AudioDeviceID id,
- AudioStreamBasicDescription *d)
-{
- UInt32 size = sizeof(*d);
-
- return AudioDeviceSetProperty(
- id,
- 0,
- 0,
- 0,
- kAudioDevicePropertyStreamFormat,
- size,
- d);
-}
-
-static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result)
-{
- UInt32 size = sizeof(*result);
-
- return AudioDeviceGetProperty(
- id,
- 0,
- 0,
- kAudioDevicePropertyDeviceIsRunning,
- &size,
- result);
-}
-#endif
-
-static void coreaudio_logstatus (OSStatus status)
-{
- const char *str = "BUG";
-
- switch(status) {
- case kAudioHardwareNoError:
- str = "kAudioHardwareNoError";
- break;
-
- case kAudioHardwareNotRunningError:
- str = "kAudioHardwareNotRunningError";
- break;
-
- case kAudioHardwareUnspecifiedError:
- str = "kAudioHardwareUnspecifiedError";
- break;
-
- case kAudioHardwareUnknownPropertyError:
- str = "kAudioHardwareUnknownPropertyError";
- break;
-
- case kAudioHardwareBadPropertySizeError:
- str = "kAudioHardwareBadPropertySizeError";
- break;
-
- case kAudioHardwareIllegalOperationError:
- str = "kAudioHardwareIllegalOperationError";
- break;
-
- case kAudioHardwareBadDeviceError:
- str = "kAudioHardwareBadDeviceError";
- break;
-
- case kAudioHardwareBadStreamError:
- str = "kAudioHardwareBadStreamError";
- break;
-
- case kAudioHardwareUnsupportedOperationError:
- str = "kAudioHardwareUnsupportedOperationError";
- break;
-
- case kAudioDeviceUnsupportedFormatError:
- str = "kAudioDeviceUnsupportedFormatError";
- break;
-
- case kAudioDevicePermissionsError:
- str = "kAudioDevicePermissionsError";
- break;
-
- default:
- AUD_log (AUDIO_CAP, "Reason: status code %" PRId32 "\n", (int32_t)status);
- return;
- }
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
- OSStatus status,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_log (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- coreaudio_logstatus (status);
-}
-
-static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
- OSStatus status,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- coreaudio_logstatus (status);
-}
-
-static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
-{
- OSStatus status;
- UInt32 result = 0;
- status = coreaudio_get_isrunning(outputDeviceID, &result);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr(status,
- "Could not determine whether Device is playing\n");
- }
- return result;
-}
-
-static void coreaudio_atexit (void)
-{
- isAtexit = 1;
-}
-
-static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
-{
- int err;
-
- err = pthread_mutex_lock (&core->mutex);
- if (err) {
- dolog ("Could not lock voice for %s\nReason: %s\n",
- fn_name, strerror (err));
- return -1;
- }
- return 0;
-}
-
-static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
-{
- int err;
-
- err = pthread_mutex_unlock (&core->mutex);
- if (err) {
- dolog ("Could not unlock voice for %s\nReason: %s\n",
- fn_name, strerror (err));
- return -1;
- }
- return 0;
-}
-
-static int coreaudio_run_out (HWVoiceOut *hw, int live)
-{
- int decr;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
-
- if (coreaudio_lock (core, "coreaudio_run_out")) {
- return 0;
- }
-
- if (core->decr > live) {
- ldebug ("core->decr %d live %d core->live %d\n",
- core->decr,
- live,
- core->live);
- }
-
- decr = audio_MIN (core->decr, live);
- core->decr -= decr;
-
- core->live = live - decr;
- hw->rpos = core->rpos;
-
- coreaudio_unlock (core, "coreaudio_run_out");
- return decr;
-}
-
-/* callback to feed audiooutput buffer */
-static OSStatus audioDeviceIOProc(
- AudioDeviceID inDevice,
- const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData,
- const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData,
- const AudioTimeStamp* inOutputTime,
- void* hwptr)
-{
- UInt32 frame, frameCount;
- float *out = outOutputData->mBuffers[0].mData;
- HWVoiceOut *hw = hwptr;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
- int rpos, live;
- struct st_sample *src;
-#ifndef FLOAT_MIXENG
-#ifdef RECIPROCAL
- const float scale = 1.f / UINT_MAX;
-#else
- const float scale = UINT_MAX;
-#endif
-#endif
-
- if (coreaudio_lock (core, "audioDeviceIOProc")) {
- inInputTime = 0;
- return 0;
- }
-
- frameCount = core->audioDevicePropertyBufferFrameSize;
- live = core->live;
-
- /* if there are not enough samples, set signal and return */
- if (live < frameCount) {
- inInputTime = 0;
- coreaudio_unlock (core, "audioDeviceIOProc(empty)");
- return 0;
- }
-
- rpos = core->rpos;
- src = hw->mix_buf + rpos;
-
- /* fill buffer */
- for (frame = 0; frame < frameCount; frame++) {
-#ifdef FLOAT_MIXENG
- *out++ = src[frame].l; /* left channel */
- *out++ = src[frame].r; /* right channel */
-#else
-#ifdef RECIPROCAL
- *out++ = src[frame].l * scale; /* left channel */
- *out++ = src[frame].r * scale; /* right channel */
-#else
- *out++ = src[frame].l / scale; /* left channel */
- *out++ = src[frame].r / scale; /* right channel */
-#endif
-#endif
- }
-
- rpos = (rpos + frameCount) % hw->samples;
- core->decr += frameCount;
- core->rpos = rpos;
-
- coreaudio_unlock (core, "audioDeviceIOProc");
- return 0;
-}
-
-static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- OSStatus status;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
- int err;
- const char *typ = "playback";
- AudioValueRange frameRange;
- CoreaudioConf *conf = drv_opaque;
-
- /* create mutex */
- err = pthread_mutex_init(&core->mutex, NULL);
- if (err) {
- dolog("Could not create mutex\nReason: %s\n", strerror (err));
- return -1;
- }
-
- audio_pcm_init_info (&hw->info, as);
-
- status = coreaudio_get_voice(&core->outputDeviceID);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get default output Device\n");
- return -1;
- }
- if (core->outputDeviceID == kAudioDeviceUnknown) {
- dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
- return -1;
- }
-
- /* get minimum and maximum buffer frame sizes */
- status = coreaudio_get_framesizerange(core->outputDeviceID,
- &frameRange);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame range\n");
- return -1;
- }
-
- if (frameRange.mMinimum > conf->buffer_frames) {
- core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
- dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
- }
- else if (frameRange.mMaximum < conf->buffer_frames) {
- core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
- dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum);
- }
- else {
- core->audioDevicePropertyBufferFrameSize = conf->buffer_frames;
- }
-
- /* set Buffer Frame Size */
- status = coreaudio_set_framesize(core->outputDeviceID,
- &core->audioDevicePropertyBufferFrameSize);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not set device buffer frame size %" PRIu32 "\n",
- (uint32_t)core->audioDevicePropertyBufferFrameSize);
- return -1;
- }
-
- /* get Buffer Frame Size */
- status = coreaudio_get_framesize(core->outputDeviceID,
- &core->audioDevicePropertyBufferFrameSize);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame size\n");
- return -1;
- }
- hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize;
-
- /* get StreamFormat */
- status = coreaudio_get_streamformat(core->outputDeviceID,
- &core->outputStreamBasicDescription);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get Device Stream properties\n");
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* set Samplerate */
- core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
- status = coreaudio_set_streamformat(core->outputDeviceID,
- &core->outputStreamBasicDescription);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
- as->freq);
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* set Callback */
- core->ioprocid = NULL;
- status = AudioDeviceCreateIOProcID(core->outputDeviceID,
- audioDeviceIOProc,
- hw,
- &core->ioprocid);
- if (status != kAudioHardwareNoError || core->ioprocid == NULL) {
- coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* start Playback */
- if (!isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not start playback\n");
- AudioDeviceDestroyIOProcID(core->outputDeviceID, core->ioprocid);
- core->outputDeviceID = kAudioDeviceUnknown;
- return -1;
- }
- }
-
- return 0;
-}
-
-static void coreaudio_fini_out (HWVoiceOut *hw)
-{
- OSStatus status;
- int err;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
-
- if (!isAtexit) {
- /* stop playback */
- if (isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not stop playback\n");
- }
- }
-
- /* remove callback */
- status = AudioDeviceDestroyIOProcID(core->outputDeviceID,
- core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not remove IOProc\n");
- }
- }
- core->outputDeviceID = kAudioDeviceUnknown;
-
- /* destroy mutex */
- err = pthread_mutex_destroy(&core->mutex);
- if (err) {
- dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
- }
-}
-
-static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- OSStatus status;
- coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- /* start playback */
- if (!isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStart(core->outputDeviceID, core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not resume playback\n");
- }
- }
- break;
-
- case VOICE_DISABLE:
- /* stop playback */
- if (!isAtexit) {
- if (isPlaying(core->outputDeviceID)) {
- status = AudioDeviceStop(core->outputDeviceID,
- core->ioprocid);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not pause playback\n");
- }
- }
- }
- break;
- }
- return 0;
-}
-
-static CoreaudioConf glob_conf = {
- .buffer_frames = 512,
- .nbuffers = 4,
-};
-
-static void *coreaudio_audio_init (void)
-{
- CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
- *conf = glob_conf;
-
- atexit(coreaudio_atexit);
- return conf;
-}
-
-static void coreaudio_audio_fini (void *opaque)
-{
- g_free(opaque);
-}
-
-static struct audio_option coreaudio_options[] = {
- {
- .name = "BUFFER_SIZE",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.buffer_frames,
- .descr = "Size of the buffer in frames"
- },
- {
- .name = "BUFFER_COUNT",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.nbuffers,
- .descr = "Number of buffers"
- },
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops coreaudio_pcm_ops = {
- .init_out = coreaudio_init_out,
- .fini_out = coreaudio_fini_out,
- .run_out = coreaudio_run_out,
- .write = coreaudio_write,
- .ctl_out = coreaudio_ctl_out
-};
-
-struct audio_driver coreaudio_audio_driver = {
- .name = "coreaudio",
- .descr = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
- .options = coreaudio_options,
- .init = coreaudio_audio_init,
- .fini = coreaudio_audio_fini,
- .pcm_ops = &coreaudio_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = 1,
- .max_voices_in = 0,
- .voice_size_out = sizeof (coreaudioVoiceOut),
- .voice_size_in = 0
-};
diff --git a/qemu/audio/dsound_template.h b/qemu/audio/dsound_template.h
deleted file mode 100644
index b439f33f5..000000000
--- a/qemu/audio/dsound_template.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * QEMU DirectSound audio driver header
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#ifdef DSBTYPE_IN
-#define NAME "capture buffer"
-#define NAME2 "DirectSoundCapture"
-#define TYPE in
-#define IFACE IDirectSoundCaptureBuffer
-#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
-#define FIELD dsound_capture_buffer
-#define FIELD2 dsound_capture
-#else
-#define NAME "playback buffer"
-#define NAME2 "DirectSound"
-#define TYPE out
-#define IFACE IDirectSoundBuffer
-#define BUFPTR LPDIRECTSOUNDBUFFER
-#define FIELD dsound_buffer
-#define FIELD2 dsound
-#endif
-
-static int glue (dsound_unlock_, TYPE) (
- BUFPTR buf,
- LPVOID p1,
- LPVOID p2,
- DWORD blen1,
- DWORD blen2
- )
-{
- HRESULT hr;
-
- hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not unlock " NAME "\n");
- return -1;
- }
-
- return 0;
-}
-
-static int glue (dsound_lock_, TYPE) (
- BUFPTR buf,
- struct audio_pcm_info *info,
- DWORD pos,
- DWORD len,
- LPVOID *p1p,
- LPVOID *p2p,
- DWORD *blen1p,
- DWORD *blen2p,
- int entire,
- dsound *s
- )
-{
- HRESULT hr;
- LPVOID p1 = NULL, p2 = NULL;
- DWORD blen1 = 0, blen2 = 0;
- DWORD flag;
-
-#ifdef DSBTYPE_IN
- flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
-#else
- flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
-#endif
- hr = glue(IFACE, _Lock)(buf, pos, len, &p1, &blen1, &p2, &blen2, flag);
-
- if (FAILED (hr)) {
-#ifndef DSBTYPE_IN
- if (hr == DSERR_BUFFERLOST) {
- if (glue (dsound_restore_, TYPE) (buf, s)) {
- dsound_logerr (hr, "Could not lock " NAME "\n");
- }
- goto fail;
- }
-#endif
- dsound_logerr (hr, "Could not lock " NAME "\n");
- goto fail;
- }
-
- if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
- dolog ("DirectSound returned misaligned buffer %ld %ld\n",
- blen1, blen2);
- glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
- goto fail;
- }
-
- if (!p1 && blen1) {
- dolog ("warning: !p1 && blen1=%ld\n", blen1);
- blen1 = 0;
- }
-
- if (!p2 && blen2) {
- dolog ("warning: !p2 && blen2=%ld\n", blen2);
- blen2 = 0;
- }
-
- *p1p = p1;
- *p2p = p2;
- *blen1p = blen1;
- *blen2p = blen2;
- return 0;
-
- fail:
- *p1p = NULL - 1;
- *p2p = NULL - 1;
- *blen1p = -1;
- *blen2p = -1;
- return -1;
-}
-
-#ifdef DSBTYPE_IN
-static void dsound_fini_in (HWVoiceIn *hw)
-#else
-static void dsound_fini_out (HWVoiceOut *hw)
-#endif
-{
- HRESULT hr;
-#ifdef DSBTYPE_IN
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
-#else
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
-#endif
-
- if (ds->FIELD) {
- hr = glue (IFACE, _Stop) (ds->FIELD);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop " NAME "\n");
- }
-
- hr = glue (IFACE, _Release) (ds->FIELD);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release " NAME "\n");
- }
- ds->FIELD = NULL;
- }
-}
-
-#ifdef DSBTYPE_IN
-static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
- void *drv_opaque)
-#else
-static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-#endif
-{
- int err;
- HRESULT hr;
- dsound *s = drv_opaque;
- WAVEFORMATEX wfx;
- struct audsettings obt_as;
- DSoundConf *conf = &s->conf;
-#ifdef DSBTYPE_IN
- const char *typ = "ADC";
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- DSCBUFFERDESC bd;
- DSCBCAPS bc;
-#else
- const char *typ = "DAC";
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- DSBUFFERDESC bd;
- DSBCAPS bc;
-#endif
-
- if (!s->FIELD2) {
- dolog ("Attempt to initialize voice without " NAME2 " object\n");
- return -1;
- }
-
- err = waveformat_from_audio_settings (&wfx, as);
- if (err) {
- return -1;
- }
-
- memset (&bd, 0, sizeof (bd));
- bd.dwSize = sizeof (bd);
- bd.lpwfxFormat = &wfx;
-#ifdef DSBTYPE_IN
- bd.dwBufferBytes = conf->bufsize_in;
- hr = IDirectSoundCapture_CreateCaptureBuffer (
- s->dsound_capture,
- &bd,
- &ds->dsound_capture_buffer,
- NULL
- );
-#else
- bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
- bd.dwBufferBytes = conf->bufsize_out;
- hr = IDirectSound_CreateSoundBuffer (
- s->dsound,
- &bd,
- &ds->dsound_buffer,
- NULL
- );
-#endif
-
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
- return -1;
- }
-
- hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
- goto fail0;
- }
-
-#ifdef DEBUG_DSOUND
- dolog (NAME "\n");
- print_wave_format (&wfx);
-#endif
-
- memset (&bc, 0, sizeof (bc));
- bc.dwSize = sizeof (bc);
-
- hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
- goto fail0;
- }
-
- err = waveformat_to_audio_settings (&wfx, &obt_as);
- if (err) {
- goto fail0;
- }
-
- ds->first_time = 1;
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
-
- if (bc.dwBufferBytes & hw->info.align) {
- dolog (
- "GetCaps returned misaligned buffer size %ld, alignment %d\n",
- bc.dwBufferBytes, hw->info.align + 1
- );
- }
- hw->samples = bc.dwBufferBytes >> hw->info.shift;
- ds->s = s;
-
-#ifdef DEBUG_DSOUND
- dolog ("caps %ld, desc %ld\n",
- bc.dwBufferBytes, bd.dwBufferBytes);
-
- dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
- hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
-#endif
- return 0;
-
- fail0:
- glue (dsound_fini_, TYPE) (hw);
- return -1;
-}
-
-#undef NAME
-#undef NAME2
-#undef TYPE
-#undef IFACE
-#undef BUFPTR
-#undef FIELD
-#undef FIELD2
diff --git a/qemu/audio/dsoundaudio.c b/qemu/audio/dsoundaudio.c
deleted file mode 100644
index 516846eb8..000000000
--- a/qemu/audio/dsoundaudio.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/*
- * QEMU DirectSound audio driver
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * 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.
- */
-
-/*
- * SEAL 1.07 by Carlos 'pel' Hasan was used as documentation
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "audio.h"
-
-#define AUDIO_CAP "dsound"
-#include "audio_int.h"
-
-#include <windows.h>
-#include <mmsystem.h>
-#include <objbase.h>
-#include <dsound.h>
-
-#include "audio_win_int.h"
-
-/* #define DEBUG_DSOUND */
-
-typedef struct {
- int bufsize_in;
- int bufsize_out;
- int latency_millis;
-} DSoundConf;
-
-typedef struct {
- LPDIRECTSOUND dsound;
- LPDIRECTSOUNDCAPTURE dsound_capture;
- struct audsettings settings;
- DSoundConf conf;
-} dsound;
-
-typedef struct {
- HWVoiceOut hw;
- LPDIRECTSOUNDBUFFER dsound_buffer;
- DWORD old_pos;
- int first_time;
- dsound *s;
-#ifdef DEBUG_DSOUND
- DWORD old_ppos;
- DWORD played;
- DWORD mixed;
-#endif
-} DSoundVoiceOut;
-
-typedef struct {
- HWVoiceIn hw;
- int first_time;
- LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
- dsound *s;
-} DSoundVoiceIn;
-
-static void dsound_log_hresult (HRESULT hr)
-{
- const char *str = "BUG";
-
- switch (hr) {
- case DS_OK:
- str = "The method succeeded";
- break;
-#ifdef DS_NO_VIRTUALIZATION
- case DS_NO_VIRTUALIZATION:
- str = "The buffer was created, but another 3D algorithm was substituted";
- break;
-#endif
-#ifdef DS_INCOMPLETE
- case DS_INCOMPLETE:
- str = "The method succeeded, but not all the optional effects were obtained";
- break;
-#endif
-#ifdef DSERR_ACCESSDENIED
- case DSERR_ACCESSDENIED:
- str = "The request failed because access was denied";
- break;
-#endif
-#ifdef DSERR_ALLOCATED
- case DSERR_ALLOCATED:
- str = "The request failed because resources, such as a priority level, were already in use by another caller";
- break;
-#endif
-#ifdef DSERR_ALREADYINITIALIZED
- case DSERR_ALREADYINITIALIZED:
- str = "The object is already initialized";
- break;
-#endif
-#ifdef DSERR_BADFORMAT
- case DSERR_BADFORMAT:
- str = "The specified wave format is not supported";
- break;
-#endif
-#ifdef DSERR_BADSENDBUFFERGUID
- case DSERR_BADSENDBUFFERGUID:
- str = "The GUID specified in an audiopath file does not match a valid mix-in buffer";
- break;
-#endif
-#ifdef DSERR_BUFFERLOST
- case DSERR_BUFFERLOST:
- str = "The buffer memory has been lost and must be restored";
- break;
-#endif
-#ifdef DSERR_BUFFERTOOSMALL
- case DSERR_BUFFERTOOSMALL:
- str = "The buffer size is not great enough to enable effects processing";
- break;
-#endif
-#ifdef DSERR_CONTROLUNAVAIL
- case DSERR_CONTROLUNAVAIL:
- str = "The buffer control (volume, pan, and so on) requested by the caller is not available. Controls must be specified when the buffer is created, using the dwFlags member of DSBUFFERDESC";
- break;
-#endif
-#ifdef DSERR_DS8_REQUIRED
- case DSERR_DS8_REQUIRED:
- str = "A DirectSound object of class CLSID_DirectSound8 or later is required for the requested functionality. For more information, see IDirectSound8 Interface";
- break;
-#endif
-#ifdef DSERR_FXUNAVAILABLE
- case DSERR_FXUNAVAILABLE:
- str = "The effects requested could not be found on the system, or they are in the wrong order or in the wrong location; for example, an effect expected in hardware was found in software";
- break;
-#endif
-#ifdef DSERR_GENERIC
- case DSERR_GENERIC :
- str = "An undetermined error occurred inside the DirectSound subsystem";
- break;
-#endif
-#ifdef DSERR_INVALIDCALL
- case DSERR_INVALIDCALL:
- str = "This function is not valid for the current state of this object";
- break;
-#endif
-#ifdef DSERR_INVALIDPARAM
- case DSERR_INVALIDPARAM:
- str = "An invalid parameter was passed to the returning function";
- break;
-#endif
-#ifdef DSERR_NOAGGREGATION
- case DSERR_NOAGGREGATION:
- str = "The object does not support aggregation";
- break;
-#endif
-#ifdef DSERR_NODRIVER
- case DSERR_NODRIVER:
- str = "No sound driver is available for use, or the given GUID is not a valid DirectSound device ID";
- break;
-#endif
-#ifdef DSERR_NOINTERFACE
- case DSERR_NOINTERFACE:
- str = "The requested COM interface is not available";
- break;
-#endif
-#ifdef DSERR_OBJECTNOTFOUND
- case DSERR_OBJECTNOTFOUND:
- str = "The requested object was not found";
- break;
-#endif
-#ifdef DSERR_OTHERAPPHASPRIO
- case DSERR_OTHERAPPHASPRIO:
- str = "Another application has a higher priority level, preventing this call from succeeding";
- break;
-#endif
-#ifdef DSERR_OUTOFMEMORY
- case DSERR_OUTOFMEMORY:
- str = "The DirectSound subsystem could not allocate sufficient memory to complete the caller's request";
- break;
-#endif
-#ifdef DSERR_PRIOLEVELNEEDED
- case DSERR_PRIOLEVELNEEDED:
- str = "A cooperative level of DSSCL_PRIORITY or higher is required";
- break;
-#endif
-#ifdef DSERR_SENDLOOP
- case DSERR_SENDLOOP:
- str = "A circular loop of send effects was detected";
- break;
-#endif
-#ifdef DSERR_UNINITIALIZED
- case DSERR_UNINITIALIZED:
- str = "The Initialize method has not been called or has not been called successfully before other methods were called";
- break;
-#endif
-#ifdef DSERR_UNSUPPORTED
- case DSERR_UNSUPPORTED:
- str = "The function called is not supported at this time";
- break;
-#endif
- default:
- AUD_log (AUDIO_CAP, "Reason: Unknown (HRESULT %#lx)\n", hr);
- return;
- }
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) dsound_logerr (
- HRESULT hr,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- dsound_log_hresult (hr);
-}
-
-static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
- HRESULT hr,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- dsound_log_hresult (hr);
-}
-
-static DWORD millis_to_bytes (struct audio_pcm_info *info, DWORD millis)
-{
- return (millis * info->bytes_per_second) / 1000;
-}
-
-#ifdef DEBUG_DSOUND
-static void print_wave_format (WAVEFORMATEX *wfx)
-{
- dolog ("tag = %d\n", wfx->wFormatTag);
- dolog ("nChannels = %d\n", wfx->nChannels);
- dolog ("nSamplesPerSec = %ld\n", wfx->nSamplesPerSec);
- dolog ("nAvgBytesPerSec = %ld\n", wfx->nAvgBytesPerSec);
- dolog ("nBlockAlign = %d\n", wfx->nBlockAlign);
- dolog ("wBitsPerSample = %d\n", wfx->wBitsPerSample);
- dolog ("cbSize = %d\n", wfx->cbSize);
-}
-#endif
-
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
-{
- HRESULT hr;
-
- hr = IDirectSoundBuffer_Restore (dsb);
-
- if (hr != DS_OK) {
- dsound_logerr (hr, "Could not restore playback buffer\n");
- return -1;
- }
- return 0;
-}
-
-#include "dsound_template.h"
-#define DSBTYPE_IN
-#include "dsound_template.h"
-#undef DSBTYPE_IN
-
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp,
- dsound *s)
-{
- HRESULT hr;
-
- hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer status\n");
- return -1;
- }
-
- if (*statusp & DSERR_BUFFERLOST) {
- dsound_restore_out(dsb, s);
- return -1;
- }
-
- return 0;
-}
-
-static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
- DWORD *statusp)
-{
- HRESULT hr;
-
- hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer status\n");
- return -1;
- }
-
- return 0;
-}
-
-static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
-{
- int src_len1 = dst_len;
- int src_len2 = 0;
- int pos = hw->rpos + dst_len;
- struct st_sample *src1 = hw->mix_buf + hw->rpos;
- struct st_sample *src2 = NULL;
-
- if (pos > hw->samples) {
- src_len1 = hw->samples - hw->rpos;
- src2 = hw->mix_buf;
- src_len2 = dst_len - src_len1;
- pos = src_len2;
- }
-
- if (src_len1) {
- hw->clip (dst, src1, src_len1);
- }
-
- if (src_len2) {
- dst = advance (dst, src_len1 << hw->info.shift);
- hw->clip (dst, src2, src_len2);
- }
-
- hw->rpos = pos % hw->samples;
-}
-
-static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
- dsound *s)
-{
- int err;
- LPVOID p1, p2;
- DWORD blen1, blen2, len1, len2;
-
- err = dsound_lock_out (
- dsb,
- &hw->info,
- 0,
- hw->samples << hw->info.shift,
- &p1, &p2,
- &blen1, &blen2,
- 1,
- s
- );
- if (err) {
- return;
- }
-
- len1 = blen1 >> hw->info.shift;
- len2 = blen2 >> hw->info.shift;
-
-#ifdef DEBUG_DSOUND
- dolog ("clear %p,%ld,%ld %p,%ld,%ld\n",
- p1, blen1, len1,
- p2, blen2, len2);
-#endif
-
- if (p1 && len1) {
- audio_pcm_info_clear_buf (&hw->info, p1, len1);
- }
-
- if (p2 && len2) {
- audio_pcm_info_clear_buf (&hw->info, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
-}
-
-static int dsound_open (dsound *s)
-{
- HRESULT hr;
- HWND hwnd;
-
- hwnd = GetForegroundWindow ();
- hr = IDirectSound_SetCooperativeLevel (
- s->dsound,
- hwnd,
- DSSCL_PRIORITY
- );
-
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not set cooperative level for window %p\n",
- hwnd);
- return -1;
- }
-
- return 0;
-}
-
-static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- HRESULT hr;
- DWORD status;
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
- dsound *s = ds->s;
-
- if (!dsb) {
- dolog ("Attempt to control voice without a buffer\n");
- return 0;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (dsound_get_status_out (dsb, &status, s)) {
- return -1;
- }
-
- if (status & DSBSTATUS_PLAYING) {
- dolog ("warning: Voice is already playing\n");
- return 0;
- }
-
- dsound_clear_sample (hw, dsb, s);
-
- hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start playing buffer\n");
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- if (dsound_get_status_out (dsb, &status, s)) {
- return -1;
- }
-
- if (status & DSBSTATUS_PLAYING) {
- hr = IDirectSoundBuffer_Stop (dsb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop playing buffer\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not playing\n");
- }
- break;
- }
- return 0;
-}
-
-static int dsound_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int dsound_run_out (HWVoiceOut *hw, int live)
-{
- int err;
- HRESULT hr;
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
- int len, hwshift;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD wpos, ppos, old_pos;
- LPVOID p1, p2;
- int bufsize;
- dsound *s = ds->s;
- DSoundConf *conf = &s->conf;
-
- if (!dsb) {
- dolog ("Attempt to run empty with playback buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
- bufsize = hw->samples << hwshift;
-
- hr = IDirectSoundBuffer_GetCurrentPosition (
- dsb,
- &ppos,
- ds->first_time ? &wpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer position\n");
- return 0;
- }
-
- len = live << hwshift;
-
- if (ds->first_time) {
- if (conf->latency_millis) {
- DWORD cur_blat;
-
- cur_blat = audio_ring_dist (wpos, ppos, bufsize);
- ds->first_time = 0;
- old_pos = wpos;
- old_pos +=
- millis_to_bytes (&hw->info, conf->latency_millis) - cur_blat;
- old_pos %= bufsize;
- old_pos &= ~hw->info.align;
- }
- else {
- old_pos = wpos;
- }
-#ifdef DEBUG_DSOUND
- ds->played = 0;
- ds->mixed = 0;
-#endif
- }
- else {
- if (ds->old_pos == ppos) {
-#ifdef DEBUG_DSOUND
- dolog ("old_pos == ppos\n");
-#endif
- return 0;
- }
-
-#ifdef DEBUG_DSOUND
- ds->played += audio_ring_dist (ds->old_pos, ppos, hw->bufsize);
-#endif
- old_pos = ds->old_pos;
- }
-
- if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
- len = ppos - old_pos;
- }
- else {
- if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
- len = bufsize - old_pos + ppos;
- }
- }
-
- if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
- dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
- len, bufsize, old_pos, ppos);
- return 0;
- }
-
- len &= ~hw->info.align;
- if (!len) {
- return 0;
- }
-
-#ifdef DEBUG_DSOUND
- ds->old_ppos = ppos;
-#endif
- err = dsound_lock_out (
- dsb,
- &hw->info,
- old_pos,
- len,
- &p1, &p2,
- &blen1, &blen2,
- 0,
- s
- );
- if (err) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- dsound_write_sample (hw, p1, len1);
- }
-
- if (p2 && len2) {
- dsound_write_sample (hw, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
- ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
-
-#ifdef DEBUG_DSOUND
- ds->mixed += decr << hwshift;
-
- dolog ("played %lu mixed %lu diff %ld sec %f\n",
- ds->played,
- ds->mixed,
- ds->mixed - ds->played,
- abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second);
-#endif
- return decr;
-}
-
-static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- HRESULT hr;
- DWORD status;
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
-
- if (!dscb) {
- dolog ("Attempt to control capture voice without a buffer\n");
- return -1;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- dolog ("warning: Voice is already capturing\n");
- return 0;
- }
-
- /* clear ?? */
-
- hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start capturing\n");
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- hr = IDirectSoundCaptureBuffer_Stop (dscb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop capturing\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not capturing\n");
- }
- break;
- }
- return 0;
-}
-
-static int dsound_read (SWVoiceIn *sw, void *buf, int len)
-{
- return audio_pcm_sw_read (sw, buf, len);
-}
-
-static int dsound_run_in (HWVoiceIn *hw)
-{
- int err;
- HRESULT hr;
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
- int live, len, dead;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD cpos, rpos;
- LPVOID p1, p2;
- int hwshift;
- dsound *s = ds->s;
-
- if (!dscb) {
- dolog ("Attempt to run without capture buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- if (!dead) {
- return 0;
- }
-
- hr = IDirectSoundCaptureBuffer_GetCurrentPosition (
- dscb,
- &cpos,
- ds->first_time ? &rpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer position\n");
- return 0;
- }
-
- if (ds->first_time) {
- ds->first_time = 0;
- if (rpos & hw->info.align) {
- ldebug ("warning: Misaligned capture read position %ld(%d)\n",
- rpos, hw->info.align);
- }
- hw->wpos = rpos >> hwshift;
- }
-
- if (cpos & hw->info.align) {
- ldebug ("warning: Misaligned capture position %ld(%d)\n",
- cpos, hw->info.align);
- }
- cpos >>= hwshift;
-
- len = audio_ring_dist (cpos, hw->wpos, hw->samples);
- if (!len) {
- return 0;
- }
- len = audio_MIN (len, dead);
-
- err = dsound_lock_in (
- dscb,
- &hw->info,
- hw->wpos << hwshift,
- len << hwshift,
- &p1,
- &p2,
- &blen1,
- &blen2,
- 0,
- s
- );
- if (err) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1);
- }
-
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2);
- }
-
- dsound_unlock_in (dscb, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
- return decr;
-}
-
-static DSoundConf glob_conf = {
- .bufsize_in = 16384,
- .bufsize_out = 16384,
- .latency_millis = 10
-};
-
-static void dsound_audio_fini (void *opaque)
-{
- HRESULT hr;
- dsound *s = opaque;
-
- if (!s->dsound) {
- g_free(s);
- return;
- }
-
- hr = IDirectSound_Release (s->dsound);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSound\n");
- }
- s->dsound = NULL;
-
- if (!s->dsound_capture) {
- g_free(s);
- return;
- }
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
-
- g_free(s);
-}
-
-static void *dsound_audio_init (void)
-{
- int err;
- HRESULT hr;
- dsound *s = g_malloc0(sizeof(dsound));
-
- s->conf = glob_conf;
- hr = CoInitialize (NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize COM\n");
- g_free(s);
- return NULL;
- }
-
- hr = CoCreateInstance (
- &CLSID_DirectSound,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSound,
- (void **) &s->dsound
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create DirectSound instance\n");
- g_free(s);
- return NULL;
- }
-
- hr = IDirectSound_Initialize (s->dsound, NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize DirectSound\n");
-
- hr = IDirectSound_Release (s->dsound);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSound\n");
- }
- g_free(s);
- return NULL;
- }
-
- hr = CoCreateInstance (
- &CLSID_DirectSoundCapture,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSoundCapture,
- (void **) &s->dsound_capture
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
- }
- else {
- hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
- }
- }
-
- err = dsound_open (s);
- if (err) {
- dsound_audio_fini (s);
- return NULL;
- }
-
- return s;
-}
-
-static struct audio_option dsound_options[] = {
- {
- .name = "LATENCY_MILLIS",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.latency_millis,
- .descr = "(undocumented)"
- },
- {
- .name = "BUFSIZE_OUT",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.bufsize_out,
- .descr = "(undocumented)"
- },
- {
- .name = "BUFSIZE_IN",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.bufsize_in,
- .descr = "(undocumented)"
- },
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops dsound_pcm_ops = {
- .init_out = dsound_init_out,
- .fini_out = dsound_fini_out,
- .run_out = dsound_run_out,
- .write = dsound_write,
- .ctl_out = dsound_ctl_out,
-
- .init_in = dsound_init_in,
- .fini_in = dsound_fini_in,
- .run_in = dsound_run_in,
- .read = dsound_read,
- .ctl_in = dsound_ctl_in
-};
-
-struct audio_driver dsound_audio_driver = {
- .name = "dsound",
- .descr = "DirectSound http://wikipedia.org/wiki/DirectSound",
- .options = dsound_options,
- .init = dsound_audio_init,
- .fini = dsound_audio_fini,
- .pcm_ops = &dsound_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = INT_MAX,
- .max_voices_in = 1,
- .voice_size_out = sizeof (DSoundVoiceOut),
- .voice_size_in = sizeof (DSoundVoiceIn)
-};
diff --git a/qemu/audio/mixeng.c b/qemu/audio/mixeng.c
deleted file mode 100644
index 981b97a96..000000000
--- a/qemu/audio/mixeng.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- * Copyright (c) 1998 Fabrice Bellard
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "audio.h"
-
-#define AUDIO_CAP "mixeng"
-#include "audio_int.h"
-
-/* 8 bit */
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-
-/* Signed 8 bit */
-#define BSIZE 8
-#define ITYPE int
-#define IN_MIN SCHAR_MIN
-#define IN_MAX SCHAR_MAX
-#define SIGNED
-#define SHIFT 8
-#include "mixeng_template.h"
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef BSIZE
-#undef ITYPE
-#undef SHIFT
-
-/* Unsigned 8 bit */
-#define BSIZE 8
-#define ITYPE uint
-#define IN_MIN 0
-#define IN_MAX UCHAR_MAX
-#define SHIFT 8
-#include "mixeng_template.h"
-#undef IN_MAX
-#undef IN_MIN
-#undef BSIZE
-#undef ITYPE
-#undef SHIFT
-
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-
-/* Signed 16 bit */
-#define BSIZE 16
-#define ITYPE int
-#define IN_MIN SHRT_MIN
-#define IN_MAX SHRT_MAX
-#define SIGNED
-#define SHIFT 16
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap16 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef BSIZE
-#undef ITYPE
-#undef SHIFT
-
-/* Unsigned 16 bit */
-#define BSIZE 16
-#define ITYPE uint
-#define IN_MIN 0
-#define IN_MAX USHRT_MAX
-#define SHIFT 16
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap16 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef IN_MAX
-#undef IN_MIN
-#undef BSIZE
-#undef ITYPE
-#undef SHIFT
-
-/* Signed 32 bit */
-#define BSIZE 32
-#define ITYPE int
-#define IN_MIN INT32_MIN
-#define IN_MAX INT32_MAX
-#define SIGNED
-#define SHIFT 32
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap32 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef BSIZE
-#undef ITYPE
-#undef SHIFT
-
-/* Unsigned 32 bit */
-#define BSIZE 32
-#define ITYPE uint
-#define IN_MIN 0
-#define IN_MAX UINT32_MAX
-#define SHIFT 32
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap32 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef IN_MAX
-#undef IN_MIN
-#undef BSIZE
-#undef ITYPE
-#undef SHIFT
-
-t_sample *mixeng_conv[2][2][2][3] = {
- {
- {
- {
- conv_natural_uint8_t_to_mono,
- conv_natural_uint16_t_to_mono,
- conv_natural_uint32_t_to_mono
- },
- {
- conv_natural_uint8_t_to_mono,
- conv_swap_uint16_t_to_mono,
- conv_swap_uint32_t_to_mono,
- }
- },
- {
- {
- conv_natural_int8_t_to_mono,
- conv_natural_int16_t_to_mono,
- conv_natural_int32_t_to_mono
- },
- {
- conv_natural_int8_t_to_mono,
- conv_swap_int16_t_to_mono,
- conv_swap_int32_t_to_mono
- }
- }
- },
- {
- {
- {
- conv_natural_uint8_t_to_stereo,
- conv_natural_uint16_t_to_stereo,
- conv_natural_uint32_t_to_stereo
- },
- {
- conv_natural_uint8_t_to_stereo,
- conv_swap_uint16_t_to_stereo,
- conv_swap_uint32_t_to_stereo
- }
- },
- {
- {
- conv_natural_int8_t_to_stereo,
- conv_natural_int16_t_to_stereo,
- conv_natural_int32_t_to_stereo
- },
- {
- conv_natural_int8_t_to_stereo,
- conv_swap_int16_t_to_stereo,
- conv_swap_int32_t_to_stereo,
- }
- }
- }
-};
-
-f_sample *mixeng_clip[2][2][2][3] = {
- {
- {
- {
- clip_natural_uint8_t_from_mono,
- clip_natural_uint16_t_from_mono,
- clip_natural_uint32_t_from_mono
- },
- {
- clip_natural_uint8_t_from_mono,
- clip_swap_uint16_t_from_mono,
- clip_swap_uint32_t_from_mono
- }
- },
- {
- {
- clip_natural_int8_t_from_mono,
- clip_natural_int16_t_from_mono,
- clip_natural_int32_t_from_mono
- },
- {
- clip_natural_int8_t_from_mono,
- clip_swap_int16_t_from_mono,
- clip_swap_int32_t_from_mono
- }
- }
- },
- {
- {
- {
- clip_natural_uint8_t_from_stereo,
- clip_natural_uint16_t_from_stereo,
- clip_natural_uint32_t_from_stereo
- },
- {
- clip_natural_uint8_t_from_stereo,
- clip_swap_uint16_t_from_stereo,
- clip_swap_uint32_t_from_stereo
- }
- },
- {
- {
- clip_natural_int8_t_from_stereo,
- clip_natural_int16_t_from_stereo,
- clip_natural_int32_t_from_stereo
- },
- {
- clip_natural_int8_t_from_stereo,
- clip_swap_int16_t_from_stereo,
- clip_swap_int32_t_from_stereo
- }
- }
- }
-};
-
-/*
- * August 21, 1998
- * Copyright 1998 Fabrice Bellard.
- *
- * [Rewrote completly the code of Lance Norskog And Sundry
- * Contributors with a more efficient algorithm.]
- *
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
- */
-
-/*
- * Sound Tools rate change effect file.
- */
-/*
- * Linear Interpolation.
- *
- * The use of fractional increment allows us to use no buffer. It
- * avoid the problems at the end of the buffer we had with the old
- * method which stored a possibly big buffer of size
- * lcm(in_rate,out_rate).
- *
- * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
- * the input & output frequencies are equal, a delay of one sample is
- * introduced. Limited to processing 32-bit count worth of samples.
- *
- * 1 << FRAC_BITS evaluating to zero in several places. Changed with
- * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
- */
-
-/* Private data */
-struct rate {
- uint64_t opos;
- uint64_t opos_inc;
- uint32_t ipos; /* position in the input stream (integer) */
- struct st_sample ilast; /* last sample in the input stream */
-};
-
-/*
- * Prepare processing.
- */
-void *st_rate_start (int inrate, int outrate)
-{
- struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
-
- if (!rate) {
- dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
- return NULL;
- }
-
- rate->opos = 0;
-
- /* increment */
- rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
-
- rate->ipos = 0;
- rate->ilast.l = 0;
- rate->ilast.r = 0;
- return rate;
-}
-
-#define NAME st_rate_flow_mix
-#define OP(a, b) a += b
-#include "rate_template.h"
-
-#define NAME st_rate_flow
-#define OP(a, b) a = b
-#include "rate_template.h"
-
-void st_rate_stop (void *opaque)
-{
- g_free (opaque);
-}
-
-void mixeng_clear (struct st_sample *buf, int len)
-{
- memset (buf, 0, len * sizeof (struct st_sample));
-}
-
-void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
-{
- if (vol->mute) {
- mixeng_clear (buf, len);
- return;
- }
-
- while (len--) {
-#ifdef FLOAT_MIXENG
- buf->l = buf->l * vol->l;
- buf->r = buf->r * vol->r;
-#else
- buf->l = (buf->l * vol->l) >> 32;
- buf->r = (buf->r * vol->r) >> 32;
-#endif
- buf += 1;
- }
-}
diff --git a/qemu/audio/mixeng.h b/qemu/audio/mixeng.h
deleted file mode 100644
index 9de443b01..000000000
--- a/qemu/audio/mixeng.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * QEMU Mixing engine header
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#ifndef QEMU_MIXENG_H
-#define QEMU_MIXENG_H
-
-#ifdef FLOAT_MIXENG
-typedef float mixeng_real;
-struct mixeng_volume { int mute; mixeng_real r; mixeng_real l; };
-struct st_sample { mixeng_real l; mixeng_real r; };
-#else
-struct mixeng_volume { int mute; int64_t r; int64_t l; };
-struct st_sample { int64_t l; int64_t r; };
-#endif
-
-typedef void (t_sample) (struct st_sample *dst, const void *src, int samples);
-typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
-
-extern t_sample *mixeng_conv[2][2][2][3];
-extern f_sample *mixeng_clip[2][2][2][3];
-
-void *st_rate_start (int inrate, int outrate);
-void st_rate_flow (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
- int *isamp, int *osamp);
-void st_rate_flow_mix (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
- int *isamp, int *osamp);
-void st_rate_stop (void *opaque);
-void mixeng_clear (struct st_sample *buf, int len);
-void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol);
-
-#endif /* mixeng.h */
diff --git a/qemu/audio/mixeng_template.h b/qemu/audio/mixeng_template.h
deleted file mode 100644
index 77cc89b9e..000000000
--- a/qemu/audio/mixeng_template.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-
-/*
- * Tusen tack till Mike Nordell
- * dec++'ified by Dscho
- */
-
-#ifndef SIGNED
-#define HALF (IN_MAX >> 1)
-#endif
-
-#define ET glue (ENDIAN_CONVERSION, glue (glue (glue (_, ITYPE), BSIZE), _t))
-#define IN_T glue (glue (ITYPE, BSIZE), _t)
-
-#ifdef FLOAT_MIXENG
-static inline mixeng_real glue (conv_, ET) (IN_T v)
-{
- IN_T nv = ENDIAN_CONVERT (v);
-
-#ifdef RECIPROCAL
-#ifdef SIGNED
- return nv * (1.f / (mixeng_real) (IN_MAX - IN_MIN));
-#else
- return (nv - HALF) * (1.f / (mixeng_real) IN_MAX);
-#endif
-#else /* !RECIPROCAL */
-#ifdef SIGNED
- return nv / (mixeng_real) ((mixeng_real) IN_MAX - IN_MIN);
-#else
- return (nv - HALF) / (mixeng_real) IN_MAX;
-#endif
-#endif
-}
-
-static inline IN_T glue (clip_, ET) (mixeng_real v)
-{
- if (v >= 0.5) {
- return IN_MAX;
- }
- else if (v < -0.5) {
- return IN_MIN;
- }
-
-#ifdef SIGNED
- return ENDIAN_CONVERT ((IN_T) (v * ((mixeng_real) IN_MAX - IN_MIN)));
-#else
- return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
-#endif
-}
-
-#else /* !FLOAT_MIXENG */
-
-static inline int64_t glue (conv_, ET) (IN_T v)
-{
- IN_T nv = ENDIAN_CONVERT (v);
-#ifdef SIGNED
- return ((int64_t) nv) << (32 - SHIFT);
-#else
- return ((int64_t) nv - HALF) << (32 - SHIFT);
-#endif
-}
-
-static inline IN_T glue (clip_, ET) (int64_t v)
-{
- if (v >= 0x7f000000) {
- return IN_MAX;
- }
- else if (v < -2147483648LL) {
- return IN_MIN;
- }
-
-#ifdef SIGNED
- return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
-#else
- return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
-#endif
-}
-#endif
-
-static void glue (glue (conv_, ET), _to_stereo)
- (struct st_sample *dst, const void *src, int samples)
-{
- struct st_sample *out = dst;
- IN_T *in = (IN_T *) src;
-
- while (samples--) {
- out->l = glue (conv_, ET) (*in++);
- out->r = glue (conv_, ET) (*in++);
- out += 1;
- }
-}
-
-static void glue (glue (conv_, ET), _to_mono)
- (struct st_sample *dst, const void *src, int samples)
-{
- struct st_sample *out = dst;
- IN_T *in = (IN_T *) src;
-
- while (samples--) {
- out->l = glue (conv_, ET) (in[0]);
- out->r = out->l;
- out += 1;
- in += 1;
- }
-}
-
-static void glue (glue (clip_, ET), _from_stereo)
- (void *dst, const struct st_sample *src, int samples)
-{
- const struct st_sample *in = src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue (clip_, ET) (in->l);
- *out++ = glue (clip_, ET) (in->r);
- in += 1;
- }
-}
-
-static void glue (glue (clip_, ET), _from_mono)
- (void *dst, const struct st_sample *src, int samples)
-{
- const struct st_sample *in = src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue (clip_, ET) (in->l + in->r);
- in += 1;
- }
-}
-
-#undef ET
-#undef HALF
-#undef IN_T
diff --git a/qemu/audio/noaudio.c b/qemu/audio/noaudio.c
deleted file mode 100644
index b360c199a..000000000
--- a/qemu/audio/noaudio.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * QEMU Timer based audio emulation
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "audio.h"
-#include "qemu/timer.h"
-
-#define AUDIO_CAP "noaudio"
-#include "audio_int.h"
-
-typedef struct NoVoiceOut {
- HWVoiceOut hw;
- int64_t old_ticks;
-} NoVoiceOut;
-
-typedef struct NoVoiceIn {
- HWVoiceIn hw;
- int64_t old_ticks;
-} NoVoiceIn;
-
-static int no_run_out (HWVoiceOut *hw, int live)
-{
- NoVoiceOut *no = (NoVoiceOut *) hw;
- int decr, samples;
- int64_t now;
- int64_t ticks;
- int64_t bytes;
-
- now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- ticks = now - no->old_ticks;
- bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND);
- bytes = audio_MIN(bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
-
- no->old_ticks = now;
- decr = audio_MIN (live, samples);
- hw->rpos = (hw->rpos + decr) % hw->samples;
- return decr;
-}
-
-static int no_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write(sw, buf, len);
-}
-
-static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
-{
- audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
- return 0;
-}
-
-static void no_fini_out (HWVoiceOut *hw)
-{
- (void) hw;
-}
-
-static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
-{
- audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
- return 0;
-}
-
-static void no_fini_in (HWVoiceIn *hw)
-{
- (void) hw;
-}
-
-static int no_run_in (HWVoiceIn *hw)
-{
- NoVoiceIn *no = (NoVoiceIn *) hw;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- int samples = 0;
-
- if (dead) {
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t ticks = now - no->old_ticks;
- int64_t bytes =
- muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND);
-
- no->old_ticks = now;
- bytes = audio_MIN (bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
- samples = audio_MIN (samples, dead);
- }
- return samples;
-}
-
-static int no_read (SWVoiceIn *sw, void *buf, int size)
-{
- /* use custom code here instead of audio_pcm_sw_read() to avoid
- * useless resampling/mixing */
- int samples = size >> sw->info.shift;
- int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
- int to_clear = audio_MIN (samples, total);
- sw->total_hw_samples_acquired += total;
- audio_pcm_info_clear_buf (&sw->info, buf, to_clear);
- return to_clear << sw->info.shift;
-}
-
-static int no_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static void *no_audio_init (void)
-{
- return &no_audio_init;
-}
-
-static void no_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-static struct audio_pcm_ops no_pcm_ops = {
- .init_out = no_init_out,
- .fini_out = no_fini_out,
- .run_out = no_run_out,
- .write = no_write,
- .ctl_out = no_ctl_out,
-
- .init_in = no_init_in,
- .fini_in = no_fini_in,
- .run_in = no_run_in,
- .read = no_read,
- .ctl_in = no_ctl_in
-};
-
-struct audio_driver no_audio_driver = {
- .name = "none",
- .descr = "Timer based audio emulation",
- .options = NULL,
- .init = no_audio_init,
- .fini = no_audio_fini,
- .pcm_ops = &no_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = INT_MAX,
- .max_voices_in = INT_MAX,
- .voice_size_out = sizeof (NoVoiceOut),
- .voice_size_in = sizeof (NoVoiceIn)
-};
diff --git a/qemu/audio/ossaudio.c b/qemu/audio/ossaudio.c
deleted file mode 100644
index 349e9dd53..000000000
--- a/qemu/audio/ossaudio.c
+++ /dev/null
@@ -1,940 +0,0 @@
-/*
- * QEMU OSS audio driver
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-#include "qemu-common.h"
-#include "qemu/main-loop.h"
-#include "qemu/host-utils.h"
-#include "audio.h"
-#include "trace.h"
-
-#define AUDIO_CAP "oss"
-#include "audio_int.h"
-
-#if defined OSS_GETVERSION && defined SNDCTL_DSP_POLICY
-#define USE_DSP_POLICY
-#endif
-
-typedef struct OSSConf {
- int try_mmap;
- int nfrags;
- int fragsize;
- const char *devpath_out;
- const char *devpath_in;
- int exclusive;
- int policy;
-} OSSConf;
-
-typedef struct OSSVoiceOut {
- HWVoiceOut hw;
- void *pcm_buf;
- int fd;
- int wpos;
- int nfrags;
- int fragsize;
- int mmapped;
- int pending;
- OSSConf *conf;
-} OSSVoiceOut;
-
-typedef struct OSSVoiceIn {
- HWVoiceIn hw;
- void *pcm_buf;
- int fd;
- int nfrags;
- int fragsize;
- OSSConf *conf;
-} OSSVoiceIn;
-
-struct oss_params {
- int freq;
- audfmt_e fmt;
- int nchannels;
- int nfrags;
- int fragsize;
-};
-
-static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
-}
-
-static void GCC_FMT_ATTR (3, 4) oss_logerr2 (
- int err,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
-}
-
-static void oss_anal_close (int *fdp)
-{
- int err;
-
- qemu_set_fd_handler (*fdp, NULL, NULL, NULL);
- err = close (*fdp);
- if (err) {
- oss_logerr (errno, "Failed to close file(fd=%d)\n", *fdp);
- }
- *fdp = -1;
-}
-
-static void oss_helper_poll_out (void *opaque)
-{
- (void) opaque;
- audio_run ("oss_poll_out");
-}
-
-static void oss_helper_poll_in (void *opaque)
-{
- (void) opaque;
- audio_run ("oss_poll_in");
-}
-
-static void oss_poll_out (HWVoiceOut *hw)
-{
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
-
- qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL);
-}
-
-static void oss_poll_in (HWVoiceIn *hw)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
-
- qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);
-}
-
-static int oss_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int aud_to_ossfmt (audfmt_e fmt, int endianness)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- return AFMT_S8;
-
- case AUD_FMT_U8:
- return AFMT_U8;
-
- case AUD_FMT_S16:
- if (endianness) {
- return AFMT_S16_BE;
- }
- else {
- return AFMT_S16_LE;
- }
-
- case AUD_FMT_U16:
- if (endianness) {
- return AFMT_U16_BE;
- }
- else {
- return AFMT_U16_LE;
- }
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return AFMT_U8;
- }
-}
-
-static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness)
-{
- switch (ossfmt) {
- case AFMT_S8:
- *endianness = 0;
- *fmt = AUD_FMT_S8;
- break;
-
- case AFMT_U8:
- *endianness = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case AFMT_S16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case AFMT_U16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case AFMT_S16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case AFMT_U16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- default:
- dolog ("Unrecognized audio format %d\n", ossfmt);
- return -1;
- }
-
- return 0;
-}
-
-#if defined DEBUG_MISMATCHES || defined DEBUG
-static void oss_dump_info (struct oss_params *req, struct oss_params *obt)
-{
- dolog ("parameter | requested value | obtained value\n");
- dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
- dolog ("channels | %10d | %10d\n",
- req->nchannels, obt->nchannels);
- dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
- dolog ("nfrags | %10d | %10d\n", req->nfrags, obt->nfrags);
- dolog ("fragsize | %10d | %10d\n",
- req->fragsize, obt->fragsize);
-}
-#endif
-
-#ifdef USE_DSP_POLICY
-static int oss_get_version (int fd, int *version, const char *typ)
-{
- if (ioctl (fd, OSS_GETVERSION, &version)) {
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- /*
- * Looks like atm (20100109) FreeBSD knows OSS_GETVERSION
- * since 7.x, but currently only on the mixer device (or in
- * the Linuxolator), and in the native version that part of
- * the code is in fact never reached so the ioctl fails anyway.
- * Until this is fixed, just check the errno and if its what
- * FreeBSD's sound drivers return atm assume they are new enough.
- */
- if (errno == EINVAL) {
- *version = 0x040000;
- return 0;
- }
-#endif
- oss_logerr2 (errno, typ, "Failed to get OSS version\n");
- return -1;
- }
- return 0;
-}
-#endif
-
-static int oss_open (int in, struct oss_params *req,
- struct oss_params *obt, int *pfd, OSSConf* conf)
-{
- int fd;
- int oflags = conf->exclusive ? O_EXCL : 0;
- audio_buf_info abinfo;
- int fmt, freq, nchannels;
- int setfragment = 1;
- const char *dspname = in ? conf->devpath_in : conf->devpath_out;
- const char *typ = in ? "ADC" : "DAC";
-
- /* Kludge needed to have working mmap on Linux */
- oflags |= conf->try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
-
- fd = open (dspname, oflags | O_NONBLOCK);
- if (-1 == fd) {
- oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname);
- return -1;
- }
-
- freq = req->freq;
- nchannels = req->nchannels;
- fmt = req->fmt;
-
- if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
- oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
- oss_logerr2 (errno, typ, "Failed to set number of channels %d\n",
- req->nchannels);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
- oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_NONBLOCK, NULL)) {
- oss_logerr2 (errno, typ, "Failed to set non-blocking mode\n");
- goto err;
- }
-
-#ifdef USE_DSP_POLICY
- if (conf->policy >= 0) {
- int version;
-
- if (!oss_get_version (fd, &version, typ)) {
- trace_oss_version(version);
-
- if (version >= 0x040000) {
- int policy = conf->policy;
- if (ioctl (fd, SNDCTL_DSP_POLICY, &policy)) {
- oss_logerr2 (errno, typ,
- "Failed to set timing policy to %d\n",
- conf->policy);
- goto err;
- }
- setfragment = 0;
- }
- }
- }
-#endif
-
- if (setfragment) {
- int mmmmssss = (req->nfrags << 16) | ctz32 (req->fragsize);
- if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
- oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n",
- req->nfrags, req->fragsize);
- goto err;
- }
- }
-
- if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) {
- oss_logerr2 (errno, typ, "Failed to get buffer length\n");
- goto err;
- }
-
- if (!abinfo.fragstotal || !abinfo.fragsize) {
- AUD_log (AUDIO_CAP, "Returned bogus buffer information(%d, %d) for %s\n",
- abinfo.fragstotal, abinfo.fragsize, typ);
- goto err;
- }
-
- obt->fmt = fmt;
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->nfrags = abinfo.fragstotal;
- obt->fragsize = abinfo.fragsize;
- *pfd = fd;
-
-#ifdef DEBUG_MISMATCHES
- if ((req->fmt != obt->fmt) ||
- (req->nchannels != obt->nchannels) ||
- (req->freq != obt->freq) ||
- (req->fragsize != obt->fragsize) ||
- (req->nfrags != obt->nfrags)) {
- dolog ("Audio parameters mismatch\n");
- oss_dump_info (req, obt);
- }
-#endif
-
-#ifdef DEBUG
- oss_dump_info (req, obt);
-#endif
- return 0;
-
- err:
- oss_anal_close (&fd);
- return -1;
-}
-
-static void oss_write_pending (OSSVoiceOut *oss)
-{
- HWVoiceOut *hw = &oss->hw;
-
- if (oss->mmapped) {
- return;
- }
-
- while (oss->pending) {
- int samples_written;
- ssize_t bytes_written;
- int samples_till_end = hw->samples - oss->wpos;
- int samples_to_write = audio_MIN (oss->pending, samples_till_end);
- int bytes_to_write = samples_to_write << hw->info.shift;
- void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift);
-
- bytes_written = write (oss->fd, pcm, bytes_to_write);
- if (bytes_written < 0) {
- if (errno != EAGAIN) {
- oss_logerr (errno, "failed to write %d bytes\n",
- bytes_to_write);
- }
- break;
- }
-
- if (bytes_written & hw->info.align) {
- dolog ("misaligned write asked for %d, but got %zd\n",
- bytes_to_write, bytes_written);
- return;
- }
-
- samples_written = bytes_written >> hw->info.shift;
- oss->pending -= samples_written;
- oss->wpos = (oss->wpos + samples_written) % hw->samples;
- if (bytes_written - bytes_to_write) {
- break;
- }
- }
-}
-
-static int oss_run_out (HWVoiceOut *hw, int live)
-{
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
- int err, decr;
- struct audio_buf_info abinfo;
- struct count_info cntinfo;
- int bufsize;
-
- bufsize = hw->samples << hw->info.shift;
-
- if (oss->mmapped) {
- int bytes, pos;
-
- err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
- if (err < 0) {
- oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
- return 0;
- }
-
- pos = hw->rpos << hw->info.shift;
- bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize);
- decr = audio_MIN (bytes >> hw->info.shift, live);
- }
- else {
- err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
- if (err < 0) {
- oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
- return 0;
- }
-
- if (abinfo.bytes > bufsize) {
- trace_oss_invalid_available_size(abinfo.bytes, bufsize);
- abinfo.bytes = bufsize;
- }
-
- if (abinfo.bytes < 0) {
- trace_oss_invalid_available_size(abinfo.bytes, bufsize);
- return 0;
- }
-
- decr = audio_MIN (abinfo.bytes >> hw->info.shift, live);
- if (!decr) {
- return 0;
- }
- }
-
- decr = audio_pcm_hw_clip_out (hw, oss->pcm_buf, decr, oss->pending);
- oss->pending += decr;
- oss_write_pending (oss);
-
- return decr;
-}
-
-static void oss_fini_out (HWVoiceOut *hw)
-{
- int err;
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
-
- ldebug ("oss_fini\n");
- oss_anal_close (&oss->fd);
-
- if (oss->pcm_buf) {
- if (oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
- if (err) {
- oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
- oss->pcm_buf, hw->samples << hw->info.shift);
- }
- }
- else {
- g_free (oss->pcm_buf);
- }
- oss->pcm_buf = NULL;
- }
-}
-
-static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
- struct oss_params req, obt;
- int endianness;
- int err;
- int fd;
- audfmt_e effective_fmt;
- struct audsettings obt_as;
- OSSConf *conf = drv_opaque;
-
- oss->fd = -1;
-
- req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.fragsize = conf->fragsize;
- req.nfrags = conf->nfrags;
-
- if (oss_open (0, &req, &obt, &fd, conf)) {
- return -1;
- }
-
- err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
- if (err) {
- oss_anal_close (&fd);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- oss->nfrags = obt.nfrags;
- oss->fragsize = obt.fragsize;
-
- if (obt.nfrags * obt.fragsize & hw->info.align) {
- dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",
- obt.nfrags * obt.fragsize, hw->info.align + 1);
- }
-
- hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
-
- oss->mmapped = 0;
- if (conf->try_mmap) {
- oss->pcm_buf = mmap (
- NULL,
- hw->samples << hw->info.shift,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fd,
- 0
- );
- if (oss->pcm_buf == MAP_FAILED) {
- oss_logerr (errno, "Failed to map %d bytes of DAC\n",
- hw->samples << hw->info.shift);
- }
- else {
- int err;
- int trig = 0;
- if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
- }
- else {
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (
- errno,
- "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- );
- }
- else {
- oss->mmapped = 1;
- }
- }
-
- if (!oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
- if (err) {
- oss_logerr (errno, "Failed to unmap buffer %p size %d\n",
- oss->pcm_buf, hw->samples << hw->info.shift);
- }
- }
- }
- }
-
- if (!oss->mmapped) {
- oss->pcm_buf = audio_calloc (
- AUDIO_FUNC,
- hw->samples,
- 1 << hw->info.shift
- );
- if (!oss->pcm_buf) {
- dolog (
- "Could not allocate DAC buffer (%d samples, each %d bytes)\n",
- hw->samples,
- 1 << hw->info.shift
- );
- oss_anal_close (&fd);
- return -1;
- }
- }
-
- oss->fd = fd;
- oss->conf = conf;
- return 0;
-}
-
-static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- int trig;
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- {
- va_list ap;
- int poll_mode;
-
- va_start (ap, cmd);
- poll_mode = va_arg (ap, int);
- va_end (ap);
-
- ldebug ("enabling voice\n");
- if (poll_mode) {
- oss_poll_out (hw);
- poll_mode = 0;
- }
- hw->poll_mode = poll_mode;
-
- if (!oss->mmapped) {
- return 0;
- }
-
- audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (
- errno,
- "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- );
- return -1;
- }
- }
- break;
-
- case VOICE_DISABLE:
- if (hw->poll_mode) {
- qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
- hw->poll_mode = 0;
- }
-
- if (!oss->mmapped) {
- return 0;
- }
-
- ldebug ("disabling voice\n");
- trig = 0;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
- return -1;
- }
- break;
- }
- return 0;
-}
-
-static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
- struct oss_params req, obt;
- int endianness;
- int err;
- int fd;
- audfmt_e effective_fmt;
- struct audsettings obt_as;
- OSSConf *conf = drv_opaque;
-
- oss->fd = -1;
-
- req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.fragsize = conf->fragsize;
- req.nfrags = conf->nfrags;
- if (oss_open (1, &req, &obt, &fd, conf)) {
- return -1;
- }
-
- err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
- if (err) {
- oss_anal_close (&fd);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- oss->nfrags = obt.nfrags;
- oss->fragsize = obt.fragsize;
-
- if (obt.nfrags * obt.fragsize & hw->info.align) {
- dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",
- obt.nfrags * obt.fragsize, hw->info.align + 1);
- }
-
- hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
- oss->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!oss->pcm_buf) {
- dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- oss_anal_close (&fd);
- return -1;
- }
-
- oss->fd = fd;
- oss->conf = conf;
- return 0;
-}
-
-static void oss_fini_in (HWVoiceIn *hw)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
-
- oss_anal_close (&oss->fd);
-
- g_free(oss->pcm_buf);
- oss->pcm_buf = NULL;
-}
-
-static int oss_run_in (HWVoiceIn *hw)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int i;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- size_t read_samples = 0;
- struct {
- int add;
- int len;
- } bufs[2] = {
- { .add = hw->wpos, .len = 0 },
- { .add = 0, .len = 0 }
- };
-
- if (!dead) {
- return 0;
- }
-
- if (hw->wpos + dead > hw->samples) {
- bufs[0].len = (hw->samples - hw->wpos) << hwshift;
- bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift;
- }
- else {
- bufs[0].len = dead << hwshift;
- }
-
- for (i = 0; i < 2; ++i) {
- ssize_t nread;
-
- if (bufs[i].len) {
- void *p = advance (oss->pcm_buf, bufs[i].add << hwshift);
- nread = read (oss->fd, p, bufs[i].len);
-
- if (nread > 0) {
- if (nread & hw->info.align) {
- dolog ("warning: Misaligned read %zd (requested %d), "
- "alignment %d\n", nread, bufs[i].add << hwshift,
- hw->info.align + 1);
- }
- read_samples += nread >> hwshift;
- hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift);
- }
-
- if (bufs[i].len - nread) {
- if (nread == -1) {
- switch (errno) {
- case EINTR:
- case EAGAIN:
- break;
- default:
- oss_logerr (
- errno,
- "Failed to read %d bytes of audio (to %p)\n",
- bufs[i].len, p
- );
- break;
- }
- }
- break;
- }
- }
- }
-
- hw->wpos = (hw->wpos + read_samples) % hw->samples;
- return read_samples;
-}
-
-static int oss_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- {
- va_list ap;
- int poll_mode;
-
- va_start (ap, cmd);
- poll_mode = va_arg (ap, int);
- va_end (ap);
-
- if (poll_mode) {
- oss_poll_in (hw);
- poll_mode = 0;
- }
- hw->poll_mode = poll_mode;
- }
- break;
-
- case VOICE_DISABLE:
- if (hw->poll_mode) {
- hw->poll_mode = 0;
- qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
- }
- break;
- }
- return 0;
-}
-
-static OSSConf glob_conf = {
- .try_mmap = 0,
- .nfrags = 4,
- .fragsize = 4096,
- .devpath_out = "/dev/dsp",
- .devpath_in = "/dev/dsp",
- .exclusive = 0,
- .policy = 5
-};
-
-static void *oss_audio_init (void)
-{
- OSSConf *conf = g_malloc(sizeof(OSSConf));
- *conf = glob_conf;
-
- if (access(conf->devpath_in, R_OK | W_OK) < 0 ||
- access(conf->devpath_out, R_OK | W_OK) < 0) {
- g_free(conf);
- return NULL;
- }
- return conf;
-}
-
-static void oss_audio_fini (void *opaque)
-{
- g_free(opaque);
-}
-
-static struct audio_option oss_options[] = {
- {
- .name = "FRAGSIZE",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.fragsize,
- .descr = "Fragment size in bytes"
- },
- {
- .name = "NFRAGS",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.nfrags,
- .descr = "Number of fragments"
- },
- {
- .name = "MMAP",
- .tag = AUD_OPT_BOOL,
- .valp = &glob_conf.try_mmap,
- .descr = "Try using memory mapped access"
- },
- {
- .name = "DAC_DEV",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.devpath_out,
- .descr = "Path to DAC device"
- },
- {
- .name = "ADC_DEV",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.devpath_in,
- .descr = "Path to ADC device"
- },
- {
- .name = "EXCLUSIVE",
- .tag = AUD_OPT_BOOL,
- .valp = &glob_conf.exclusive,
- .descr = "Open device in exclusive mode (vmix wont work)"
- },
-#ifdef USE_DSP_POLICY
- {
- .name = "POLICY",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.policy,
- .descr = "Set the timing policy of the device, -1 to use fragment mode",
- },
-#endif
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops oss_pcm_ops = {
- .init_out = oss_init_out,
- .fini_out = oss_fini_out,
- .run_out = oss_run_out,
- .write = oss_write,
- .ctl_out = oss_ctl_out,
-
- .init_in = oss_init_in,
- .fini_in = oss_fini_in,
- .run_in = oss_run_in,
- .read = oss_read,
- .ctl_in = oss_ctl_in
-};
-
-struct audio_driver oss_audio_driver = {
- .name = "oss",
- .descr = "OSS http://www.opensound.com",
- .options = oss_options,
- .init = oss_audio_init,
- .fini = oss_audio_fini,
- .pcm_ops = &oss_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = INT_MAX,
- .max_voices_in = INT_MAX,
- .voice_size_out = sizeof (OSSVoiceOut),
- .voice_size_in = sizeof (OSSVoiceIn)
-};
diff --git a/qemu/audio/paaudio.c b/qemu/audio/paaudio.c
deleted file mode 100644
index 57678e72e..000000000
--- a/qemu/audio/paaudio.c
+++ /dev/null
@@ -1,954 +0,0 @@
-/* public domain */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "audio.h"
-
-#include <pulse/pulseaudio.h>
-
-#define AUDIO_CAP "pulseaudio"
-#include "audio_int.h"
-#include "audio_pt_int.h"
-
-typedef struct {
- int samples;
- char *server;
- char *sink;
- char *source;
-} PAConf;
-
-typedef struct {
- PAConf conf;
- pa_threaded_mainloop *mainloop;
- pa_context *context;
-} paaudio;
-
-typedef struct {
- HWVoiceOut hw;
- int done;
- int live;
- int decr;
- int rpos;
- pa_stream *stream;
- void *pcm_buf;
- struct audio_pt pt;
- paaudio *g;
-} PAVoiceOut;
-
-typedef struct {
- HWVoiceIn hw;
- int done;
- int dead;
- int incr;
- int wpos;
- pa_stream *stream;
- void *pcm_buf;
- struct audio_pt pt;
- const void *read_data;
- size_t read_index, read_length;
- paaudio *g;
-} PAVoiceIn;
-
-static void qpa_audio_fini(void *opaque);
-
-static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
-}
-
-#ifndef PA_CONTEXT_IS_GOOD
-static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
-{
- return
- x == PA_CONTEXT_CONNECTING ||
- x == PA_CONTEXT_AUTHORIZING ||
- x == PA_CONTEXT_SETTING_NAME ||
- x == PA_CONTEXT_READY;
-}
-#endif
-
-#ifndef PA_STREAM_IS_GOOD
-static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
-{
- return
- x == PA_STREAM_CREATING ||
- x == PA_STREAM_READY;
-}
-#endif
-
-#define CHECK_SUCCESS_GOTO(c, rerror, expression, label) \
- do { \
- if (!(expression)) { \
- if (rerror) { \
- *(rerror) = pa_context_errno ((c)->context); \
- } \
- goto label; \
- } \
- } while (0);
-
-#define CHECK_DEAD_GOTO(c, stream, rerror, label) \
- do { \
- if (!(c)->context || !PA_CONTEXT_IS_GOOD (pa_context_get_state((c)->context)) || \
- !(stream) || !PA_STREAM_IS_GOOD (pa_stream_get_state ((stream)))) { \
- if (((c)->context && pa_context_get_state ((c)->context) == PA_CONTEXT_FAILED) || \
- ((stream) && pa_stream_get_state ((stream)) == PA_STREAM_FAILED)) { \
- if (rerror) { \
- *(rerror) = pa_context_errno ((c)->context); \
- } \
- } else { \
- if (rerror) { \
- *(rerror) = PA_ERR_BADSTATE; \
- } \
- } \
- goto label; \
- } \
- } while (0);
-
-static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror)
-{
- paaudio *g = p->g;
-
- pa_threaded_mainloop_lock (g->mainloop);
-
- CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
-
- while (length > 0) {
- size_t l;
-
- while (!p->read_data) {
- int r;
-
- r = pa_stream_peek (p->stream, &p->read_data, &p->read_length);
- CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
-
- if (!p->read_data) {
- pa_threaded_mainloop_wait (g->mainloop);
- CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
- } else {
- p->read_index = 0;
- }
- }
-
- l = p->read_length < length ? p->read_length : length;
- memcpy (data, (const uint8_t *) p->read_data+p->read_index, l);
-
- data = (uint8_t *) data + l;
- length -= l;
-
- p->read_index += l;
- p->read_length -= l;
-
- if (!p->read_length) {
- int r;
-
- r = pa_stream_drop (p->stream);
- p->read_data = NULL;
- p->read_length = 0;
- p->read_index = 0;
-
- CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
- }
- }
-
- pa_threaded_mainloop_unlock (g->mainloop);
- return 0;
-
-unlock_and_fail:
- pa_threaded_mainloop_unlock (g->mainloop);
- return -1;
-}
-
-static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, int *rerror)
-{
- paaudio *g = p->g;
-
- pa_threaded_mainloop_lock (g->mainloop);
-
- CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
-
- while (length > 0) {
- size_t l;
- int r;
-
- while (!(l = pa_stream_writable_size (p->stream))) {
- pa_threaded_mainloop_wait (g->mainloop);
- CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
- }
-
- CHECK_SUCCESS_GOTO (g, rerror, l != (size_t) -1, unlock_and_fail);
-
- if (l > length) {
- l = length;
- }
-
- r = pa_stream_write (p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
- CHECK_SUCCESS_GOTO (g, rerror, r >= 0, unlock_and_fail);
-
- data = (const uint8_t *) data + l;
- length -= l;
- }
-
- pa_threaded_mainloop_unlock (g->mainloop);
- return 0;
-
-unlock_and_fail:
- pa_threaded_mainloop_unlock (g->mainloop);
- return -1;
-}
-
-static void *qpa_thread_out (void *arg)
-{
- PAVoiceOut *pa = arg;
- HWVoiceOut *hw = &pa->hw;
-
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- for (;;) {
- int decr, to_mix, rpos;
-
- for (;;) {
- if (pa->done) {
- goto exit;
- }
-
- if (pa->live > 0) {
- break;
- }
-
- if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
- goto exit;
- }
- }
-
- decr = to_mix = audio_MIN (pa->live, pa->g->conf.samples >> 2);
- rpos = pa->rpos;
-
- if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- while (to_mix) {
- int error;
- int chunk = audio_MIN (to_mix, hw->samples - rpos);
- struct st_sample *src = hw->mix_buf + rpos;
-
- hw->clip (pa->pcm_buf, src, chunk);
-
- if (qpa_simple_write (pa, pa->pcm_buf,
- chunk << hw->info.shift, &error) < 0) {
- qpa_logerr (error, "pa_simple_write failed\n");
- return NULL;
- }
-
- rpos = (rpos + chunk) % hw->samples;
- to_mix -= chunk;
- }
-
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- pa->rpos = rpos;
- pa->live -= decr;
- pa->decr += decr;
- }
-
- exit:
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
- return NULL;
-}
-
-static int qpa_run_out (HWVoiceOut *hw, int live)
-{
- int decr;
- PAVoiceOut *pa = (PAVoiceOut *) hw;
-
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return 0;
- }
-
- decr = audio_MIN (live, pa->decr);
- pa->decr -= decr;
- pa->live = live - decr;
- hw->rpos = pa->rpos;
- if (pa->live > 0) {
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
- }
- else {
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
- }
- return decr;
-}
-
-static int qpa_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-/* capture */
-static void *qpa_thread_in (void *arg)
-{
- PAVoiceIn *pa = arg;
- HWVoiceIn *hw = &pa->hw;
-
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- for (;;) {
- int incr, to_grab, wpos;
-
- for (;;) {
- if (pa->done) {
- goto exit;
- }
-
- if (pa->dead > 0) {
- break;
- }
-
- if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
- goto exit;
- }
- }
-
- incr = to_grab = audio_MIN (pa->dead, pa->g->conf.samples >> 2);
- wpos = pa->wpos;
-
- if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- while (to_grab) {
- int error;
- int chunk = audio_MIN (to_grab, hw->samples - wpos);
- void *buf = advance (pa->pcm_buf, wpos);
-
- if (qpa_simple_read (pa, buf,
- chunk << hw->info.shift, &error) < 0) {
- qpa_logerr (error, "pa_simple_read failed\n");
- return NULL;
- }
-
- hw->conv (hw->conv_buf + wpos, buf, chunk);
- wpos = (wpos + chunk) % hw->samples;
- to_grab -= chunk;
- }
-
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- pa->wpos = wpos;
- pa->dead -= incr;
- pa->incr += incr;
- }
-
- exit:
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
- return NULL;
-}
-
-static int qpa_run_in (HWVoiceIn *hw)
-{
- int live, incr, dead;
- PAVoiceIn *pa = (PAVoiceIn *) hw;
-
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return 0;
- }
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- incr = audio_MIN (dead, pa->incr);
- pa->incr -= incr;
- pa->dead = dead - incr;
- hw->wpos = pa->wpos;
- if (pa->dead > 0) {
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
- }
- else {
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
- }
- return incr;
-}
-
-static int qpa_read (SWVoiceIn *sw, void *buf, int len)
-{
- return audio_pcm_sw_read (sw, buf, len);
-}
-
-static pa_sample_format_t audfmt_to_pa (audfmt_e afmt, int endianness)
-{
- int format;
-
- switch (afmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- format = PA_SAMPLE_U8;
- break;
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- format = endianness ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
- break;
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
- break;
- default:
- dolog ("Internal logic error: Bad audio format %d\n", afmt);
- format = PA_SAMPLE_U8;
- break;
- }
- return format;
-}
-
-static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
-{
- switch (fmt) {
- case PA_SAMPLE_U8:
- return AUD_FMT_U8;
- case PA_SAMPLE_S16BE:
- *endianness = 1;
- return AUD_FMT_S16;
- case PA_SAMPLE_S16LE:
- *endianness = 0;
- return AUD_FMT_S16;
- case PA_SAMPLE_S32BE:
- *endianness = 1;
- return AUD_FMT_S32;
- case PA_SAMPLE_S32LE:
- *endianness = 0;
- return AUD_FMT_S32;
- default:
- dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt);
- return AUD_FMT_U8;
- }
-}
-
-static void context_state_cb (pa_context *c, void *userdata)
-{
- paaudio *g = userdata;
-
- switch (pa_context_get_state(c)) {
- case PA_CONTEXT_READY:
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- pa_threaded_mainloop_signal (g->mainloop, 0);
- break;
-
- case PA_CONTEXT_UNCONNECTED:
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- break;
- }
-}
-
-static void stream_state_cb (pa_stream *s, void * userdata)
-{
- paaudio *g = userdata;
-
- switch (pa_stream_get_state (s)) {
-
- case PA_STREAM_READY:
- case PA_STREAM_FAILED:
- case PA_STREAM_TERMINATED:
- pa_threaded_mainloop_signal (g->mainloop, 0);
- break;
-
- case PA_STREAM_UNCONNECTED:
- case PA_STREAM_CREATING:
- break;
- }
-}
-
-static void stream_request_cb (pa_stream *s, size_t length, void *userdata)
-{
- paaudio *g = userdata;
-
- pa_threaded_mainloop_signal (g->mainloop, 0);
-}
-
-static pa_stream *qpa_simple_new (
- paaudio *g,
- const char *name,
- pa_stream_direction_t dir,
- const char *dev,
- const pa_sample_spec *ss,
- const pa_channel_map *map,
- const pa_buffer_attr *attr,
- int *rerror)
-{
- int r;
- pa_stream *stream;
-
- pa_threaded_mainloop_lock (g->mainloop);
-
- stream = pa_stream_new (g->context, name, ss, map);
- if (!stream) {
- goto fail;
- }
-
- pa_stream_set_state_callback (stream, stream_state_cb, g);
- pa_stream_set_read_callback (stream, stream_request_cb, g);
- pa_stream_set_write_callback (stream, stream_request_cb, g);
-
- if (dir == PA_STREAM_PLAYBACK) {
- r = pa_stream_connect_playback (stream, dev, attr,
- PA_STREAM_INTERPOLATE_TIMING
-#ifdef PA_STREAM_ADJUST_LATENCY
- |PA_STREAM_ADJUST_LATENCY
-#endif
- |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
- } else {
- r = pa_stream_connect_record (stream, dev, attr,
- PA_STREAM_INTERPOLATE_TIMING
-#ifdef PA_STREAM_ADJUST_LATENCY
- |PA_STREAM_ADJUST_LATENCY
-#endif
- |PA_STREAM_AUTO_TIMING_UPDATE);
- }
-
- if (r < 0) {
- goto fail;
- }
-
- pa_threaded_mainloop_unlock (g->mainloop);
-
- return stream;
-
-fail:
- pa_threaded_mainloop_unlock (g->mainloop);
-
- if (stream) {
- pa_stream_unref (stream);
- }
-
- *rerror = pa_context_errno (g->context);
-
- return NULL;
-}
-
-static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- int error;
- pa_sample_spec ss;
- pa_buffer_attr ba;
- struct audsettings obt_as = *as;
- PAVoiceOut *pa = (PAVoiceOut *) hw;
- paaudio *g = pa->g = drv_opaque;
-
- ss.format = audfmt_to_pa (as->fmt, as->endianness);
- ss.channels = as->nchannels;
- ss.rate = as->freq;
-
- /*
- * qemu audio tick runs at 100 Hz (by default), so processing
- * data chunks worth 10 ms of sound should be a good fit.
- */
- ba.tlength = pa_usec_to_bytes (10 * 1000, &ss);
- ba.minreq = pa_usec_to_bytes (5 * 1000, &ss);
- ba.maxlength = -1;
- ba.prebuf = -1;
-
- obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
-
- pa->stream = qpa_simple_new (
- g,
- "qemu",
- PA_STREAM_PLAYBACK,
- g->conf.sink,
- &ss,
- NULL, /* channel map */
- &ba, /* buffering attributes */
- &error
- );
- if (!pa->stream) {
- qpa_logerr (error, "pa_simple_new for playback failed\n");
- goto fail1;
- }
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = g->conf.samples;
- pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- pa->rpos = hw->rpos;
- if (!pa->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- goto fail2;
- }
-
- if (audio_pt_init (&pa->pt, qpa_thread_out, hw, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
-
- return 0;
-
- fail3:
- g_free (pa->pcm_buf);
- pa->pcm_buf = NULL;
- fail2:
- if (pa->stream) {
- pa_stream_unref (pa->stream);
- pa->stream = NULL;
- }
- fail1:
- return -1;
-}
-
-static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
-{
- int error;
- pa_sample_spec ss;
- struct audsettings obt_as = *as;
- PAVoiceIn *pa = (PAVoiceIn *) hw;
- paaudio *g = pa->g = drv_opaque;
-
- ss.format = audfmt_to_pa (as->fmt, as->endianness);
- ss.channels = as->nchannels;
- ss.rate = as->freq;
-
- obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
-
- pa->stream = qpa_simple_new (
- g,
- "qemu",
- PA_STREAM_RECORD,
- g->conf.source,
- &ss,
- NULL, /* channel map */
- NULL, /* buffering attributes */
- &error
- );
- if (!pa->stream) {
- qpa_logerr (error, "pa_simple_new for capture failed\n");
- goto fail1;
- }
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = g->conf.samples;
- pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- pa->wpos = hw->wpos;
- if (!pa->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- goto fail2;
- }
-
- if (audio_pt_init (&pa->pt, qpa_thread_in, hw, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
-
- return 0;
-
- fail3:
- g_free (pa->pcm_buf);
- pa->pcm_buf = NULL;
- fail2:
- if (pa->stream) {
- pa_stream_unref (pa->stream);
- pa->stream = NULL;
- }
- fail1:
- return -1;
-}
-
-static void qpa_fini_out (HWVoiceOut *hw)
-{
- void *ret;
- PAVoiceOut *pa = (PAVoiceOut *) hw;
-
- audio_pt_lock (&pa->pt, AUDIO_FUNC);
- pa->done = 1;
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
- audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
-
- if (pa->stream) {
- pa_stream_unref (pa->stream);
- pa->stream = NULL;
- }
-
- audio_pt_fini (&pa->pt, AUDIO_FUNC);
- g_free (pa->pcm_buf);
- pa->pcm_buf = NULL;
-}
-
-static void qpa_fini_in (HWVoiceIn *hw)
-{
- void *ret;
- PAVoiceIn *pa = (PAVoiceIn *) hw;
-
- audio_pt_lock (&pa->pt, AUDIO_FUNC);
- pa->done = 1;
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
- audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
-
- if (pa->stream) {
- pa_stream_unref (pa->stream);
- pa->stream = NULL;
- }
-
- audio_pt_fini (&pa->pt, AUDIO_FUNC);
- g_free (pa->pcm_buf);
- pa->pcm_buf = NULL;
-}
-
-static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- PAVoiceOut *pa = (PAVoiceOut *) hw;
- pa_operation *op;
- pa_cvolume v;
- paaudio *g = pa->g;
-
-#ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */
- pa_cvolume_init (&v); /* function is present in 0.9.13+ */
-#endif
-
- switch (cmd) {
- case VOICE_VOLUME:
- {
- SWVoiceOut *sw;
- va_list ap;
-
- va_start (ap, cmd);
- sw = va_arg (ap, SWVoiceOut *);
- va_end (ap);
-
- v.channels = 2;
- v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
- v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
-
- pa_threaded_mainloop_lock (g->mainloop);
-
- op = pa_context_set_sink_input_volume (g->context,
- pa_stream_get_index (pa->stream),
- &v, NULL, NULL);
- if (!op)
- qpa_logerr (pa_context_errno (g->context),
- "set_sink_input_volume() failed\n");
- else
- pa_operation_unref (op);
-
- op = pa_context_set_sink_input_mute (g->context,
- pa_stream_get_index (pa->stream),
- sw->vol.mute, NULL, NULL);
- if (!op) {
- qpa_logerr (pa_context_errno (g->context),
- "set_sink_input_mute() failed\n");
- } else {
- pa_operation_unref (op);
- }
-
- pa_threaded_mainloop_unlock (g->mainloop);
- }
- }
- return 0;
-}
-
-static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- PAVoiceIn *pa = (PAVoiceIn *) hw;
- pa_operation *op;
- pa_cvolume v;
- paaudio *g = pa->g;
-
-#ifdef PA_CHECK_VERSION
- pa_cvolume_init (&v);
-#endif
-
- switch (cmd) {
- case VOICE_VOLUME:
- {
- SWVoiceIn *sw;
- va_list ap;
-
- va_start (ap, cmd);
- sw = va_arg (ap, SWVoiceIn *);
- va_end (ap);
-
- v.channels = 2;
- v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX;
- v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX;
-
- pa_threaded_mainloop_lock (g->mainloop);
-
- /* FIXME: use the upcoming "set_source_output_{volume,mute}" */
- op = pa_context_set_source_volume_by_index (g->context,
- pa_stream_get_device_index (pa->stream),
- &v, NULL, NULL);
- if (!op) {
- qpa_logerr (pa_context_errno (g->context),
- "set_source_volume() failed\n");
- } else {
- pa_operation_unref(op);
- }
-
- op = pa_context_set_source_mute_by_index (g->context,
- pa_stream_get_index (pa->stream),
- sw->vol.mute, NULL, NULL);
- if (!op) {
- qpa_logerr (pa_context_errno (g->context),
- "set_source_mute() failed\n");
- } else {
- pa_operation_unref (op);
- }
-
- pa_threaded_mainloop_unlock (g->mainloop);
- }
- }
- return 0;
-}
-
-/* common */
-static PAConf glob_conf = {
- .samples = 4096,
-};
-
-static void *qpa_audio_init (void)
-{
- paaudio *g = g_malloc(sizeof(paaudio));
- g->conf = glob_conf;
- g->mainloop = NULL;
- g->context = NULL;
-
- g->mainloop = pa_threaded_mainloop_new ();
- if (!g->mainloop) {
- goto fail;
- }
-
- g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop),
- g->conf.server);
- if (!g->context) {
- goto fail;
- }
-
- pa_context_set_state_callback (g->context, context_state_cb, g);
-
- if (pa_context_connect (g->context, g->conf.server, 0, NULL) < 0) {
- qpa_logerr (pa_context_errno (g->context),
- "pa_context_connect() failed\n");
- goto fail;
- }
-
- pa_threaded_mainloop_lock (g->mainloop);
-
- if (pa_threaded_mainloop_start (g->mainloop) < 0) {
- goto unlock_and_fail;
- }
-
- for (;;) {
- pa_context_state_t state;
-
- state = pa_context_get_state (g->context);
-
- if (state == PA_CONTEXT_READY) {
- break;
- }
-
- if (!PA_CONTEXT_IS_GOOD (state)) {
- qpa_logerr (pa_context_errno (g->context),
- "Wrong context state\n");
- goto unlock_and_fail;
- }
-
- /* Wait until the context is ready */
- pa_threaded_mainloop_wait (g->mainloop);
- }
-
- pa_threaded_mainloop_unlock (g->mainloop);
-
- return g;
-
-unlock_and_fail:
- pa_threaded_mainloop_unlock (g->mainloop);
-fail:
- AUD_log (AUDIO_CAP, "Failed to initialize PA context");
- qpa_audio_fini(g);
- return NULL;
-}
-
-static void qpa_audio_fini (void *opaque)
-{
- paaudio *g = opaque;
-
- if (g->mainloop) {
- pa_threaded_mainloop_stop (g->mainloop);
- }
-
- if (g->context) {
- pa_context_disconnect (g->context);
- pa_context_unref (g->context);
- }
-
- if (g->mainloop) {
- pa_threaded_mainloop_free (g->mainloop);
- }
-
- g_free(g);
-}
-
-struct audio_option qpa_options[] = {
- {
- .name = "SAMPLES",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.samples,
- .descr = "buffer size in samples"
- },
- {
- .name = "SERVER",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.server,
- .descr = "server address"
- },
- {
- .name = "SINK",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.sink,
- .descr = "sink device name"
- },
- {
- .name = "SOURCE",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.source,
- .descr = "source device name"
- },
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops qpa_pcm_ops = {
- .init_out = qpa_init_out,
- .fini_out = qpa_fini_out,
- .run_out = qpa_run_out,
- .write = qpa_write,
- .ctl_out = qpa_ctl_out,
-
- .init_in = qpa_init_in,
- .fini_in = qpa_fini_in,
- .run_in = qpa_run_in,
- .read = qpa_read,
- .ctl_in = qpa_ctl_in
-};
-
-struct audio_driver pa_audio_driver = {
- .name = "pa",
- .descr = "http://www.pulseaudio.org/",
- .options = qpa_options,
- .init = qpa_audio_init,
- .fini = qpa_audio_fini,
- .pcm_ops = &qpa_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = INT_MAX,
- .max_voices_in = INT_MAX,
- .voice_size_out = sizeof (PAVoiceOut),
- .voice_size_in = sizeof (PAVoiceIn),
- .ctl_caps = VOICE_VOLUME_CAP
-};
diff --git a/qemu/audio/rate_template.h b/qemu/audio/rate_template.h
deleted file mode 100644
index bd4b1c768..000000000
--- a/qemu/audio/rate_template.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- * Copyright (c) 1998 Fabrice Bellard
- *
- * 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.
- */
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
- int *isamp, int *osamp)
-{
- struct rate *rate = opaque;
- struct st_sample *istart, *iend;
- struct st_sample *ostart, *oend;
- struct st_sample ilast, icur, out;
-#ifdef FLOAT_MIXENG
- mixeng_real t;
-#else
- int64_t t;
-#endif
-
- ilast = rate->ilast;
-
- istart = ibuf;
- iend = ibuf + *isamp;
-
- ostart = obuf;
- oend = obuf + *osamp;
-
- if (rate->opos_inc == (1ULL + UINT_MAX)) {
- int i, n = *isamp > *osamp ? *osamp : *isamp;
- for (i = 0; i < n; i++) {
- OP (obuf[i].l, ibuf[i].l);
- OP (obuf[i].r, ibuf[i].r);
- }
- *isamp = n;
- *osamp = n;
- return;
- }
-
- while (obuf < oend) {
-
- /* Safety catch to make sure we have input samples. */
- if (ibuf >= iend) {
- break;
- }
-
- /* read as many input samples so that ipos > opos */
-
- while (rate->ipos <= (rate->opos >> 32)) {
- ilast = *ibuf++;
- rate->ipos++;
- /* See if we finished the input buffer yet */
- if (ibuf >= iend) {
- goto the_end;
- }
- }
-
- icur = *ibuf;
-
- /* interpolate */
-#ifdef FLOAT_MIXENG
-#ifdef RECIPROCAL
- t = (rate->opos & UINT_MAX) * (1.f / UINT_MAX);
-#else
- t = (rate->opos & UINT_MAX) / (mixeng_real) UINT_MAX;
-#endif
- out.l = (ilast.l * (1.0 - t)) + icur.l * t;
- out.r = (ilast.r * (1.0 - t)) + icur.r * t;
-#else
- t = rate->opos & 0xffffffff;
- out.l = (ilast.l * ((int64_t) UINT_MAX - t) + icur.l * t) >> 32;
- out.r = (ilast.r * ((int64_t) UINT_MAX - t) + icur.r * t) >> 32;
-#endif
-
- /* output sample & increment position */
- OP (obuf->l, out.l);
- OP (obuf->r, out.r);
- obuf += 1;
- rate->opos += rate->opos_inc;
- }
-
-the_end:
- *isamp = ibuf - istart;
- *osamp = obuf - ostart;
- rate->ilast = ilast;
-}
-
-#undef NAME
-#undef OP
diff --git a/qemu/audio/sdlaudio.c b/qemu/audio/sdlaudio.c
deleted file mode 100644
index db69fe141..000000000
--- a/qemu/audio/sdlaudio.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * QEMU SDL audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include <SDL.h>
-#include <SDL_thread.h>
-#include "qemu-common.h"
-#include "audio.h"
-
-#ifndef _WIN32
-#ifdef __sun__
-#define _POSIX_PTHREAD_SEMANTICS 1
-#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-#include <pthread.h>
-#endif
-#endif
-
-#define AUDIO_CAP "sdl"
-#include "audio_int.h"
-
-typedef struct SDLVoiceOut {
- HWVoiceOut hw;
- int live;
- int rpos;
- int decr;
-} SDLVoiceOut;
-
-static struct {
- int nb_samples;
-} conf = {
- .nb_samples = 1024
-};
-
-static struct SDLAudioState {
- int exit;
- SDL_mutex *mutex;
- SDL_sem *sem;
- int initialized;
- bool driver_created;
-} glob_sdl;
-typedef struct SDLAudioState SDLAudioState;
-
-static void GCC_FMT_ATTR (1, 2) sdl_logerr (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", SDL_GetError ());
-}
-
-static int sdl_lock (SDLAudioState *s, const char *forfn)
-{
- if (SDL_LockMutex (s->mutex)) {
- sdl_logerr ("SDL_LockMutex for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock (SDLAudioState *s, const char *forfn)
-{
- if (SDL_UnlockMutex (s->mutex)) {
- sdl_logerr ("SDL_UnlockMutex for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_post (SDLAudioState *s, const char *forfn)
-{
- if (SDL_SemPost (s->sem)) {
- sdl_logerr ("SDL_SemPost for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_wait (SDLAudioState *s, const char *forfn)
-{
- if (SDL_SemWait (s->sem)) {
- sdl_logerr ("SDL_SemWait for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)
-{
- if (sdl_unlock (s, forfn)) {
- return -1;
- }
-
- return sdl_post (s, forfn);
-}
-
-static int aud_to_sdlfmt (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- return AUDIO_S8;
-
- case AUD_FMT_U8:
- return AUDIO_U8;
-
- case AUD_FMT_S16:
- return AUDIO_S16LSB;
-
- case AUD_FMT_U16:
- return AUDIO_U16LSB;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return AUDIO_U8;
- }
-}
-
-static int sdl_to_audfmt(int sdlfmt, audfmt_e *fmt, int *endianness)
-{
- switch (sdlfmt) {
- case AUDIO_S8:
- *endianness = 0;
- *fmt = AUD_FMT_S8;
- break;
-
- case AUDIO_U8:
- *endianness = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case AUDIO_S16LSB:
- *endianness = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case AUDIO_U16LSB:
- *endianness = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case AUDIO_S16MSB:
- *endianness = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case AUDIO_U16MSB:
- *endianness = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- default:
- dolog ("Unrecognized SDL audio format %d\n", sdlfmt);
- return -1;
- }
-
- return 0;
-}
-
-static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
-{
- int status;
-#ifndef _WIN32
- int err;
- sigset_t new, old;
-
- /* Make sure potential threads created by SDL don't hog signals. */
- err = sigfillset (&new);
- if (err) {
- dolog ("sdl_open: sigfillset failed: %s\n", strerror (errno));
- return -1;
- }
- err = pthread_sigmask (SIG_BLOCK, &new, &old);
- if (err) {
- dolog ("sdl_open: pthread_sigmask failed: %s\n", strerror (err));
- return -1;
- }
-#endif
-
- status = SDL_OpenAudio (req, obt);
- if (status) {
- sdl_logerr ("SDL_OpenAudio failed\n");
- }
-
-#ifndef _WIN32
- err = pthread_sigmask (SIG_SETMASK, &old, NULL);
- if (err) {
- dolog ("sdl_open: pthread_sigmask (restore) failed: %s\n",
- strerror (errno));
- /* We have failed to restore original signal mask, all bets are off,
- so exit the process */
- exit (EXIT_FAILURE);
- }
-#endif
- return status;
-}
-
-static void sdl_close (SDLAudioState *s)
-{
- if (s->initialized) {
- sdl_lock (s, "sdl_close");
- s->exit = 1;
- sdl_unlock_and_post (s, "sdl_close");
- SDL_PauseAudio (1);
- SDL_CloseAudio ();
- s->initialized = 0;
- }
-}
-
-static void sdl_callback (void *opaque, Uint8 *buf, int len)
-{
- SDLVoiceOut *sdl = opaque;
- SDLAudioState *s = &glob_sdl;
- HWVoiceOut *hw = &sdl->hw;
- int samples = len >> hw->info.shift;
-
- if (s->exit) {
- return;
- }
-
- while (samples) {
- int to_mix, decr;
-
- /* dolog ("in callback samples=%d\n", samples); */
- sdl_wait (s, "sdl_callback");
- if (s->exit) {
- return;
- }
-
- if (sdl_lock (s, "sdl_callback")) {
- return;
- }
-
- if (audio_bug (AUDIO_FUNC, sdl->live < 0 || sdl->live > hw->samples)) {
- dolog ("sdl->live=%d hw->samples=%d\n",
- sdl->live, hw->samples);
- return;
- }
-
- if (!sdl->live) {
- goto again;
- }
-
- /* dolog ("in callback live=%d\n", live); */
- to_mix = audio_MIN (samples, sdl->live);
- decr = to_mix;
- while (to_mix) {
- int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
- struct st_sample *src = hw->mix_buf + hw->rpos;
-
- /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
- hw->clip (buf, src, chunk);
- sdl->rpos = (sdl->rpos + chunk) % hw->samples;
- to_mix -= chunk;
- buf += chunk << hw->info.shift;
- }
- samples -= decr;
- sdl->live -= decr;
- sdl->decr += decr;
-
- again:
- if (sdl_unlock (s, "sdl_callback")) {
- return;
- }
- }
- /* dolog ("done len=%d\n", len); */
-}
-
-static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int sdl_run_out (HWVoiceOut *hw, int live)
-{
- int decr;
- SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
- SDLAudioState *s = &glob_sdl;
-
- if (sdl_lock (s, "sdl_run_out")) {
- return 0;
- }
-
- if (sdl->decr > live) {
- ldebug ("sdl->decr %d live %d sdl->live %d\n",
- sdl->decr,
- live,
- sdl->live);
- }
-
- decr = audio_MIN (sdl->decr, live);
- sdl->decr -= decr;
-
- sdl->live = live - decr;
- hw->rpos = sdl->rpos;
-
- if (sdl->live > 0) {
- sdl_unlock_and_post (s, "sdl_run_out");
- }
- else {
- sdl_unlock (s, "sdl_run_out");
- }
- return decr;
-}
-
-static void sdl_fini_out (HWVoiceOut *hw)
-{
- (void) hw;
-
- sdl_close (&glob_sdl);
-}
-
-static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
- SDLAudioState *s = &glob_sdl;
- SDL_AudioSpec req, obt;
- int endianness;
- int err;
- audfmt_e effective_fmt;
- struct audsettings obt_as;
-
- req.freq = as->freq;
- req.format = aud_to_sdlfmt (as->fmt);
- req.channels = as->nchannels;
- req.samples = conf.nb_samples;
- req.callback = sdl_callback;
- req.userdata = sdl;
-
- if (sdl_open (&req, &obt)) {
- return -1;
- }
-
- err = sdl_to_audfmt(obt.format, &effective_fmt, &endianness);
- if (err) {
- sdl_close (s);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.channels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- s->initialized = 1;
- s->exit = 0;
- SDL_PauseAudio (0);
- return 0;
-}
-
-static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- SDL_PauseAudio (0);
- break;
-
- case VOICE_DISABLE:
- SDL_PauseAudio (1);
- break;
- }
- return 0;
-}
-
-static void *sdl_audio_init (void)
-{
- SDLAudioState *s = &glob_sdl;
- if (s->driver_created) {
- sdl_logerr("Can't create multiple sdl backends\n");
- return NULL;
- }
-
- if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
- sdl_logerr ("SDL failed to initialize audio subsystem\n");
- return NULL;
- }
-
- s->mutex = SDL_CreateMutex ();
- if (!s->mutex) {
- sdl_logerr ("Failed to create SDL mutex\n");
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-
- s->sem = SDL_CreateSemaphore (0);
- if (!s->sem) {
- sdl_logerr ("Failed to create SDL semaphore\n");
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-
- s->driver_created = true;
- return s;
-}
-
-static void sdl_audio_fini (void *opaque)
-{
- SDLAudioState *s = opaque;
- sdl_close (s);
- SDL_DestroySemaphore (s->sem);
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- s->driver_created = false;
-}
-
-static struct audio_option sdl_options[] = {
- {
- .name = "SAMPLES",
- .tag = AUD_OPT_INT,
- .valp = &conf.nb_samples,
- .descr = "Size of SDL buffer in samples"
- },
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops sdl_pcm_ops = {
- .init_out = sdl_init_out,
- .fini_out = sdl_fini_out,
- .run_out = sdl_run_out,
- .write = sdl_write_out,
- .ctl_out = sdl_ctl_out,
-};
-
-struct audio_driver sdl_audio_driver = {
- .name = "sdl",
- .descr = "SDL http://www.libsdl.org",
- .options = sdl_options,
- .init = sdl_audio_init,
- .fini = sdl_audio_fini,
- .pcm_ops = &sdl_pcm_ops,
- .can_be_default = 1,
- .max_voices_out = 1,
- .max_voices_in = 0,
- .voice_size_out = sizeof (SDLVoiceOut),
- .voice_size_in = 0
-};
diff --git a/qemu/audio/spiceaudio.c b/qemu/audio/spiceaudio.c
deleted file mode 100644
index dea71d37a..000000000
--- a/qemu/audio/spiceaudio.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * maintained by Gerd Hoffmann <kraxel@redhat.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "qemu/error-report.h"
-#include "qemu/timer.h"
-#include "ui/qemu-spice.h"
-
-#define AUDIO_CAP "spice"
-#include "audio.h"
-#include "audio_int.h"
-
-#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
-#define LINE_OUT_SAMPLES (480 * 4)
-#else
-#define LINE_OUT_SAMPLES (256 * 4)
-#endif
-
-#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
-#define LINE_IN_SAMPLES (480 * 4)
-#else
-#define LINE_IN_SAMPLES (256 * 4)
-#endif
-
-typedef struct SpiceRateCtl {
- int64_t start_ticks;
- int64_t bytes_sent;
-} SpiceRateCtl;
-
-typedef struct SpiceVoiceOut {
- HWVoiceOut hw;
- SpicePlaybackInstance sin;
- SpiceRateCtl rate;
- int active;
- uint32_t *frame;
- uint32_t *fpos;
- uint32_t fsize;
-} SpiceVoiceOut;
-
-typedef struct SpiceVoiceIn {
- HWVoiceIn hw;
- SpiceRecordInstance sin;
- SpiceRateCtl rate;
- int active;
- uint32_t samples[LINE_IN_SAMPLES];
-} SpiceVoiceIn;
-
-static const SpicePlaybackInterface playback_sif = {
- .base.type = SPICE_INTERFACE_PLAYBACK,
- .base.description = "playback",
- .base.major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
- .base.minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
-};
-
-static const SpiceRecordInterface record_sif = {
- .base.type = SPICE_INTERFACE_RECORD,
- .base.description = "record",
- .base.major_version = SPICE_INTERFACE_RECORD_MAJOR,
- .base.minor_version = SPICE_INTERFACE_RECORD_MINOR,
-};
-
-static void *spice_audio_init (void)
-{
- if (!using_spice) {
- return NULL;
- }
- return &spice_audio_init;
-}
-
-static void spice_audio_fini (void *opaque)
-{
- /* nothing */
-}
-
-static void rate_start (SpiceRateCtl *rate)
-{
- memset (rate, 0, sizeof (*rate));
- rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-}
-
-static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
-{
- int64_t now;
- int64_t ticks;
- int64_t bytes;
- int64_t samples;
-
- now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- ticks = now - rate->start_ticks;
- bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND);
- samples = (bytes - rate->bytes_sent) >> info->shift;
- if (samples < 0 || samples > 65536) {
- error_report("Resetting rate control (%" PRId64 " samples)", samples);
- rate_start(rate);
- samples = 0;
- }
- rate->bytes_sent += samples << info->shift;
- return samples;
-}
-
-/* playback */
-
-static int line_out_init(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
- struct audsettings settings;
-
-#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
- settings.freq = spice_server_get_best_playback_rate(NULL);
-#else
- settings.freq = SPICE_INTERFACE_PLAYBACK_FREQ;
-#endif
- settings.nchannels = SPICE_INTERFACE_PLAYBACK_CHAN;
- settings.fmt = AUD_FMT_S16;
- settings.endianness = AUDIO_HOST_ENDIANNESS;
-
- audio_pcm_init_info (&hw->info, &settings);
- hw->samples = LINE_OUT_SAMPLES;
- out->active = 0;
-
- out->sin.base.sif = &playback_sif.base;
- qemu_spice_add_interface (&out->sin.base);
-#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
- spice_server_set_playback_rate(&out->sin, settings.freq);
-#endif
- return 0;
-}
-
-static void line_out_fini (HWVoiceOut *hw)
-{
- SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
-
- spice_server_remove_interface (&out->sin.base);
-}
-
-static int line_out_run (HWVoiceOut *hw, int live)
-{
- SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
- int rpos, decr;
- int samples;
-
- if (!live) {
- return 0;
- }
-
- decr = rate_get_samples (&hw->info, &out->rate);
- decr = audio_MIN (live, decr);
-
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int len = audio_MIN (samples, left_till_end_samples);
-
- if (!out->frame) {
- spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize);
- out->fpos = out->frame;
- }
- if (out->frame) {
- len = audio_MIN (len, out->fsize);
- hw->clip (out->fpos, hw->mix_buf + rpos, len);
- out->fsize -= len;
- out->fpos += len;
- if (out->fsize == 0) {
- spice_server_playback_put_samples (&out->sin, out->frame);
- out->frame = out->fpos = NULL;
- }
- }
- rpos = (rpos + len) % hw->samples;
- samples -= len;
- }
- hw->rpos = rpos;
- return decr;
-}
-
-static int line_out_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
-{
- SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (out->active) {
- break;
- }
- out->active = 1;
- rate_start (&out->rate);
- spice_server_playback_start (&out->sin);
- break;
- case VOICE_DISABLE:
- if (!out->active) {
- break;
- }
- out->active = 0;
- if (out->frame) {
- memset (out->fpos, 0, out->fsize << 2);
- spice_server_playback_put_samples (&out->sin, out->frame);
- out->frame = out->fpos = NULL;
- }
- spice_server_playback_stop (&out->sin);
- break;
- case VOICE_VOLUME:
- {
-#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
- SWVoiceOut *sw;
- va_list ap;
- uint16_t vol[2];
-
- va_start (ap, cmd);
- sw = va_arg (ap, SWVoiceOut *);
- va_end (ap);
-
- vol[0] = sw->vol.l / ((1ULL << 16) + 1);
- vol[1] = sw->vol.r / ((1ULL << 16) + 1);
- spice_server_playback_set_volume (&out->sin, 2, vol);
- spice_server_playback_set_mute (&out->sin, sw->vol.mute);
-#endif
- break;
- }
- }
-
- return 0;
-}
-
-/* record */
-
-static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
-{
- SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
- struct audsettings settings;
-
-#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
- settings.freq = spice_server_get_best_record_rate(NULL);
-#else
- settings.freq = SPICE_INTERFACE_RECORD_FREQ;
-#endif
- settings.nchannels = SPICE_INTERFACE_RECORD_CHAN;
- settings.fmt = AUD_FMT_S16;
- settings.endianness = AUDIO_HOST_ENDIANNESS;
-
- audio_pcm_init_info (&hw->info, &settings);
- hw->samples = LINE_IN_SAMPLES;
- in->active = 0;
-
- in->sin.base.sif = &record_sif.base;
- qemu_spice_add_interface (&in->sin.base);
-#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
- spice_server_set_record_rate(&in->sin, settings.freq);
-#endif
- return 0;
-}
-
-static void line_in_fini (HWVoiceIn *hw)
-{
- SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
-
- spice_server_remove_interface (&in->sin.base);
-}
-
-static int line_in_run (HWVoiceIn *hw)
-{
- SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
- int num_samples;
- int ready;
- int len[2];
- uint64_t delta_samp;
- const uint32_t *samples;
-
- if (!(num_samples = hw->samples - audio_pcm_hw_get_live_in (hw))) {
- return 0;
- }
-
- delta_samp = rate_get_samples (&hw->info, &in->rate);
- num_samples = audio_MIN (num_samples, delta_samp);
-
- ready = spice_server_record_get_samples (&in->sin, in->samples, num_samples);
- samples = in->samples;
- if (ready == 0) {
- static const uint32_t silence[LINE_IN_SAMPLES];
- samples = silence;
- ready = LINE_IN_SAMPLES;
- }
-
- num_samples = audio_MIN (ready, num_samples);
-
- if (hw->wpos + num_samples > hw->samples) {
- len[0] = hw->samples - hw->wpos;
- len[1] = num_samples - len[0];
- } else {
- len[0] = num_samples;
- len[1] = 0;
- }
-
- hw->conv (hw->conv_buf + hw->wpos, samples, len[0]);
-
- if (len[1]) {
- hw->conv (hw->conv_buf, samples + len[0], len[1]);
- }
-
- hw->wpos = (hw->wpos + num_samples) % hw->samples;
-
- return num_samples;
-}
-
-static int line_in_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)
-{
- SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (in->active) {
- break;
- }
- in->active = 1;
- rate_start (&in->rate);
- spice_server_record_start (&in->sin);
- break;
- case VOICE_DISABLE:
- if (!in->active) {
- break;
- }
- in->active = 0;
- spice_server_record_stop (&in->sin);
- break;
- case VOICE_VOLUME:
- {
-#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2))
- SWVoiceIn *sw;
- va_list ap;
- uint16_t vol[2];
-
- va_start (ap, cmd);
- sw = va_arg (ap, SWVoiceIn *);
- va_end (ap);
-
- vol[0] = sw->vol.l / ((1ULL << 16) + 1);
- vol[1] = sw->vol.r / ((1ULL << 16) + 1);
- spice_server_record_set_volume (&in->sin, 2, vol);
- spice_server_record_set_mute (&in->sin, sw->vol.mute);
-#endif
- break;
- }
- }
-
- return 0;
-}
-
-static struct audio_option audio_options[] = {
- { /* end of list */ },
-};
-
-static struct audio_pcm_ops audio_callbacks = {
- .init_out = line_out_init,
- .fini_out = line_out_fini,
- .run_out = line_out_run,
- .write = line_out_write,
- .ctl_out = line_out_ctl,
-
- .init_in = line_in_init,
- .fini_in = line_in_fini,
- .run_in = line_in_run,
- .read = line_in_read,
- .ctl_in = line_in_ctl,
-};
-
-struct audio_driver spice_audio_driver = {
- .name = "spice",
- .descr = "spice audio driver",
- .options = audio_options,
- .init = spice_audio_init,
- .fini = spice_audio_fini,
- .pcm_ops = &audio_callbacks,
- .max_voices_out = 1,
- .max_voices_in = 1,
- .voice_size_out = sizeof (SpiceVoiceOut),
- .voice_size_in = sizeof (SpiceVoiceIn),
-#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
- .ctl_caps = VOICE_VOLUME_CAP
-#endif
-};
-
-void qemu_spice_audio_init (void)
-{
- spice_audio_driver.can_be_default = 1;
-}
diff --git a/qemu/audio/wavaudio.c b/qemu/audio/wavaudio.c
deleted file mode 100644
index 345952e51..000000000
--- a/qemu/audio/wavaudio.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * QEMU WAV audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * 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.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "qemu/timer.h"
-#include "audio.h"
-
-#define AUDIO_CAP "wav"
-#include "audio_int.h"
-
-typedef struct WAVVoiceOut {
- HWVoiceOut hw;
- FILE *f;
- int64_t old_ticks;
- void *pcm_buf;
- int total_samples;
-} WAVVoiceOut;
-
-typedef struct {
- struct audsettings settings;
- const char *wav_path;
-} WAVConf;
-
-static int wav_run_out (HWVoiceOut *hw, int live)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- int rpos, decr, samples;
- uint8_t *dst;
- struct st_sample *src;
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t ticks = now - wav->old_ticks;
- int64_t bytes =
- muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND);
-
- if (bytes > INT_MAX) {
- samples = INT_MAX >> hw->info.shift;
- }
- else {
- samples = bytes >> hw->info.shift;
- }
-
- wav->old_ticks = now;
- decr = audio_MIN (live, samples);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = hw->mix_buf + rpos;
- dst = advance (wav->pcm_buf, rpos << hw->info.shift);
-
- hw->clip (dst, src, convert_samples);
- if (fwrite (dst, convert_samples << hw->info.shift, 1, wav->f) != 1) {
- dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n",
- convert_samples << hw->info.shift, strerror (errno));
- }
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- wav->total_samples += convert_samples;
- }
-
- hw->rpos = rpos;
- return decr;
-}
-
-static int wav_write_out (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-/* VICE code: Store number as little endian. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-static int wav_init_out(HWVoiceOut *hw, struct audsettings *as,
- void *drv_opaque)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- int bits16 = 0, stereo = 0;
- uint8_t hdr[] = {
- 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
- 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
- 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
- };
- WAVConf *conf = drv_opaque;
- struct audsettings wav_as = conf->settings;
-
- stereo = wav_as.nchannels == 2;
- switch (wav_as.fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- bits16 = 0;
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- bits16 = 1;
- break;
-
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- dolog ("WAVE files can not handle 32bit formats\n");
- return -1;
- }
-
- hdr[34] = bits16 ? 0x10 : 0x08;
-
- wav_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &wav_as);
-
- hw->samples = 1024;
- wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!wav->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- return -1;
- }
-
- le_store (hdr + 22, hw->info.nchannels, 2);
- le_store (hdr + 24, hw->info.freq, 4);
- le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
- le_store (hdr + 32, 1 << (bits16 + stereo), 2);
-
- wav->f = fopen (conf->wav_path, "wb");
- if (!wav->f) {
- dolog ("Failed to open wave file `%s'\nReason: %s\n",
- conf->wav_path, strerror (errno));
- g_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
- return -1;
- }
-
- if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) {
- dolog ("wav_init_out: failed to write header\nReason: %s\n",
- strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static void wav_fini_out (HWVoiceOut *hw)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- uint8_t rlen[4];
- uint8_t dlen[4];
- uint32_t datalen = wav->total_samples << hw->info.shift;
- uint32_t rifflen = datalen + 36;
-
- if (!wav->f) {
- return;
- }
-
- le_store (rlen, rifflen, 4);
- le_store (dlen, datalen, 4);
-
- if (fseek (wav->f, 4, SEEK_SET)) {
- dolog ("wav_fini_out: fseek to rlen failed\nReason: %s\n",
- strerror(errno));
- goto doclose;
- }
- if (fwrite (rlen, 4, 1, wav->f) != 1) {
- dolog ("wav_fini_out: failed to write rlen\nReason: %s\n",
- strerror (errno));
- goto doclose;
- }
- if (fseek (wav->f, 32, SEEK_CUR)) {
- dolog ("wav_fini_out: fseek to dlen failed\nReason: %s\n",
- strerror (errno));
- goto doclose;
- }
- if (fwrite (dlen, 4, 1, wav->f) != 1) {
- dolog ("wav_fini_out: failed to write dlen\nReaons: %s\n",
- strerror (errno));
- goto doclose;
- }
-
- doclose:
- if (fclose (wav->f)) {
- dolog ("wav_fini_out: fclose %p failed\nReason: %s\n",
- wav->f, strerror (errno));
- }
- wav->f = NULL;
-
- g_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
-}
-
-static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static WAVConf glob_conf = {
- .settings.freq = 44100,
- .settings.nchannels = 2,
- .settings.fmt = AUD_FMT_S16,
- .wav_path = "qemu.wav"
-};
-
-static void *wav_audio_init (void)
-{
- WAVConf *conf = g_malloc(sizeof(WAVConf));
- *conf = glob_conf;
- return conf;
-}
-
-static void wav_audio_fini (void *opaque)
-{
- ldebug ("wav_fini");
- g_free(opaque);
-}
-
-static struct audio_option wav_options[] = {
- {
- .name = "FREQUENCY",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.settings.freq,
- .descr = "Frequency"
- },
- {
- .name = "FORMAT",
- .tag = AUD_OPT_FMT,
- .valp = &glob_conf.settings.fmt,
- .descr = "Format"
- },
- {
- .name = "DAC_FIXED_CHANNELS",
- .tag = AUD_OPT_INT,
- .valp = &glob_conf.settings.nchannels,
- .descr = "Number of channels (1 - mono, 2 - stereo)"
- },
- {
- .name = "PATH",
- .tag = AUD_OPT_STR,
- .valp = &glob_conf.wav_path,
- .descr = "Path to wave file"
- },
- { /* End of list */ }
-};
-
-static struct audio_pcm_ops wav_pcm_ops = {
- .init_out = wav_init_out,
- .fini_out = wav_fini_out,
- .run_out = wav_run_out,
- .write = wav_write_out,
- .ctl_out = wav_ctl_out,
-};
-
-struct audio_driver wav_audio_driver = {
- .name = "wav",
- .descr = "WAV renderer http://wikipedia.org/wiki/WAV",
- .options = wav_options,
- .init = wav_audio_init,
- .fini = wav_audio_fini,
- .pcm_ops = &wav_pcm_ops,
- .can_be_default = 0,
- .max_voices_out = 1,
- .max_voices_in = 0,
- .voice_size_out = sizeof (WAVVoiceOut),
- .voice_size_in = 0
-};
diff --git a/qemu/audio/wavcapture.c b/qemu/audio/wavcapture.c
deleted file mode 100644
index 8bfb9e765..000000000
--- a/qemu/audio/wavcapture.c
+++ /dev/null
@@ -1,195 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "monitor/monitor.h"
-#include "qemu/error-report.h"
-#include "audio.h"
-
-typedef struct {
- FILE *f;
- int bytes;
- char *path;
- int freq;
- int bits;
- int nchannels;
- CaptureVoiceOut *cap;
-} WAVState;
-
-/* VICE code: Store number as little endian. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-static void wav_notify (void *opaque, audcnotification_e cmd)
-{
- (void) opaque;
- (void) cmd;
-}
-
-static void wav_destroy (void *opaque)
-{
- WAVState *wav = opaque;
- uint8_t rlen[4];
- uint8_t dlen[4];
- uint32_t datalen = wav->bytes;
- uint32_t rifflen = datalen + 36;
- Monitor *mon = cur_mon;
-
- if (wav->f) {
- le_store (rlen, rifflen, 4);
- le_store (dlen, datalen, 4);
-
- if (fseek (wav->f, 4, SEEK_SET)) {
- monitor_printf (mon, "wav_destroy: rlen fseek failed\nReason: %s\n",
- strerror (errno));
- goto doclose;
- }
- if (fwrite (rlen, 4, 1, wav->f) != 1) {
- monitor_printf (mon, "wav_destroy: rlen fwrite failed\nReason %s\n",
- strerror (errno));
- goto doclose;
- }
- if (fseek (wav->f, 32, SEEK_CUR)) {
- monitor_printf (mon, "wav_destroy: dlen fseek failed\nReason %s\n",
- strerror (errno));
- goto doclose;
- }
- if (fwrite (dlen, 1, 4, wav->f) != 4) {
- monitor_printf (mon, "wav_destroy: dlen fwrite failed\nReason %s\n",
- strerror (errno));
- goto doclose;
- }
- doclose:
- if (fclose (wav->f)) {
- error_report("wav_destroy: fclose failed: %s", strerror(errno));
- }
- }
-
- g_free (wav->path);
-}
-
-static void wav_capture (void *opaque, void *buf, int size)
-{
- WAVState *wav = opaque;
-
- if (fwrite (buf, size, 1, wav->f) != 1) {
- monitor_printf (cur_mon, "wav_capture: fwrite error\nReason: %s",
- strerror (errno));
- }
- wav->bytes += size;
-}
-
-static void wav_capture_destroy (void *opaque)
-{
- WAVState *wav = opaque;
-
- AUD_del_capture (wav->cap, wav);
-}
-
-static void wav_capture_info (void *opaque)
-{
- WAVState *wav = opaque;
- char *path = wav->path;
-
- monitor_printf (cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
- wav->freq, wav->bits, wav->nchannels,
- path ? path : "<not available>", wav->bytes);
-}
-
-static struct capture_ops wav_capture_ops = {
- .destroy = wav_capture_destroy,
- .info = wav_capture_info
-};
-
-int wav_start_capture (CaptureState *s, const char *path, int freq,
- int bits, int nchannels)
-{
- Monitor *mon = cur_mon;
- WAVState *wav;
- uint8_t hdr[] = {
- 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
- 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
- 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
- };
- struct audsettings as;
- struct audio_capture_ops ops;
- int stereo, bits16, shift;
- CaptureVoiceOut *cap;
-
- if (bits != 8 && bits != 16) {
- monitor_printf (mon, "incorrect bit count %d, must be 8 or 16\n", bits);
- return -1;
- }
-
- if (nchannels != 1 && nchannels != 2) {
- monitor_printf (mon, "incorrect channel count %d, must be 1 or 2\n",
- nchannels);
- return -1;
- }
-
- stereo = nchannels == 2;
- bits16 = bits == 16;
-
- as.freq = freq;
- as.nchannels = 1 << stereo;
- as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
- as.endianness = 0;
-
- ops.notify = wav_notify;
- ops.capture = wav_capture;
- ops.destroy = wav_destroy;
-
- wav = g_malloc0 (sizeof (*wav));
-
- shift = bits16 + stereo;
- hdr[34] = bits16 ? 0x10 : 0x08;
-
- le_store (hdr + 22, as.nchannels, 2);
- le_store (hdr + 24, freq, 4);
- le_store (hdr + 28, freq << shift, 4);
- le_store (hdr + 32, 1 << shift, 2);
-
- wav->f = fopen (path, "wb");
- if (!wav->f) {
- monitor_printf (mon, "Failed to open wave file `%s'\nReason: %s\n",
- path, strerror (errno));
- g_free (wav);
- return -1;
- }
-
- wav->path = g_strdup (path);
- wav->bits = bits;
- wav->nchannels = nchannels;
- wav->freq = freq;
-
- if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) {
- monitor_printf (mon, "Failed to write header\nReason: %s\n",
- strerror (errno));
- goto error_free;
- }
-
- cap = AUD_add_capture (&as, &ops, wav);
- if (!cap) {
- monitor_printf (mon, "Failed to add audio capture\n");
- goto error_free;
- }
-
- wav->cap = cap;
- s->opaque = wav;
- s->ops = wav_capture_ops;
- return 0;
-
-error_free:
- g_free (wav->path);
- if (fclose (wav->f)) {
- monitor_printf (mon, "Failed to close wave file\nReason: %s\n",
- strerror (errno));
- }
- g_free (wav);
- return -1;
-}