[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 09/14] ossaudio: port to -audiodev config
From: |
Kővágó, Zoltán |
Subject: |
[Qemu-devel] [PATCH v4 09/14] ossaudio: port to -audiodev config |
Date: |
Mon, 28 Jan 2019 23:43:32 +0100 |
Signed-off-by: Kővágó, Zoltán <address@hidden>
---
audio/audio_legacy.c | 33 +++++++++
audio/ossaudio.c | 167 +++++++++++++++----------------------------
2 files changed, 90 insertions(+), 110 deletions(-)
diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c
index 0002fce627..3d336259bb 100644
--- a/audio/audio_legacy.c
+++ b/audio/audio_legacy.c
@@ -221,6 +221,35 @@ static void handle_dsound(Audiodev *dev)
&dev->in->has_buffer_len, dev->in);
}
+/* OSS */
+static void handle_oss_per_direction(
+ AudiodevPerDirectionOptions *pdo, AudiodevOssPerDirectionOptions **opdo,
+ bool *has_opdo, const char *try_poll_env, const char *dev_env)
+{
+ *opdo = g_malloc0(sizeof(AudiodevOssPerDirectionOptions));
+ *has_opdo = true;
+
+ get_bool(try_poll_env, &(*opdo)->try_poll, &(*opdo)->has_try_poll);
+ get_str(dev_env, &(*opdo)->dev, &(*opdo)->has_dev);
+
+ get_bytes_to_usecs("QEMU_OSS_FRAGSIZE",
+ &pdo->buffer_len, &pdo->has_buffer_len, pdo);
+ get_int("QEMU_OSS_NFRAGS", &pdo->buffer_count, &pdo->has_buffer_count);
+}
+
+static void handle_oss(Audiodev *dev)
+{
+ AudiodevOssOptions *oopt = &dev->u.oss;
+ handle_oss_per_direction(dev->in, &oopt->oss_in, &oopt->has_oss_in,
+ "QEMU_AUDIO_ADC_TRY_POLL", "QEMU_OSS_ADC_DEV");
+ handle_oss_per_direction(dev->out, &oopt->oss_out, &oopt->has_oss_out,
+ "QEMU_AUDIO_DAC_TRY_POLL", "QEMU_OSS_DAC_DEV");
+
+ get_bool("QEMU_OSS_MMAP", &oopt->try_mmap, &oopt->has_try_mmap);
+ get_bool("QEMU_OSS_EXCLUSIVE", &oopt->exclusive, &oopt->has_exclusive);
+ get_int("QEMU_OSS_POLICY", &oopt->dsp_policy, &oopt->has_dsp_policy);
+}
+
/* general */
static void handle_per_direction(
AudiodevPerDirectionOptions *pdo, const char *prefix)
@@ -276,6 +305,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname)
handle_dsound(e->dev);
break;
+ case AUDIODEV_DRIVER_OSS:
+ handle_oss(e->dev);
+ break;
+
default:
break;
}
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index e0cadbef29..72b9dc3b5f 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -37,16 +37,6 @@
#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;
@@ -56,7 +46,7 @@ typedef struct OSSVoiceOut {
int fragsize;
int mmapped;
int pending;
- OSSConf *conf;
+ Audiodev *dev;
} OSSVoiceOut;
typedef struct OSSVoiceIn {
@@ -65,12 +55,12 @@ typedef struct OSSVoiceIn {
int fd;
int nfrags;
int fragsize;
- OSSConf *conf;
+ Audiodev *dev;
} OSSVoiceIn;
struct oss_params {
int freq;
- AudioFormat fmt;
+ int fmt;
int nchannels;
int nfrags;
int fragsize;
@@ -262,19 +252,26 @@ static int oss_get_version (int fd, int *version, const
char *typ)
}
#endif
-static int oss_open (int in, struct oss_params *req,
- struct oss_params *obt, int *pfd, OSSConf* conf)
+static int oss_open(int in, struct oss_params *req, audsettings *as,
+ struct oss_params *obt, int *pfd, Audiodev *dev)
{
+ AudiodevOssOptions *oopts = &dev->u.oss;
+ AudiodevOssPerDirectionOptions *opdo = in ? oopts->oss_in : oopts->oss_out;
+ AudiodevPerDirectionOptions *pdo = in ? dev->in : dev->out;
int fd;
- int oflags = conf->exclusive ? O_EXCL : 0;
+ int oflags = (oopts->has_exclusive && oopts->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 *dspname = opdo->has_dev ? opdo->dev : "/dev/dsp";
const char *typ = in ? "ADC" : "DAC";
+#ifdef USE_DSP_POLICY
+ int policy = oopts->has_dsp_policy ? oopts->dsp_policy : 5;
+#endif
/* Kludge needed to have working mmap on Linux */
- oflags |= conf->try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
+ oflags |= (oopts->has_try_mmap && oopts->try_mmap) ?
+ O_RDWR : (in ? O_RDONLY : O_WRONLY);
fd = open (dspname, oflags | O_NONBLOCK);
if (-1 == fd) {
@@ -285,6 +282,8 @@ static int oss_open (int in, struct oss_params *req,
freq = req->freq;
nchannels = req->nchannels;
fmt = req->fmt;
+ req->nfrags = pdo->has_buffer_count ? pdo->buffer_count : 4;
+ req->fragsize = audio_buffer_bytes(pdo, as, 23220);
if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
@@ -308,18 +307,18 @@ static int oss_open (int in, struct oss_params *req,
}
#ifdef USE_DSP_POLICY
- if (conf->policy >= 0) {
+ if (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)) {
+ int policy2 = policy;
+ if (ioctl(fd, SNDCTL_DSP_POLICY, &policy2)) {
oss_logerr2 (errno, typ,
"Failed to set timing policy to %d\n",
- conf->policy);
+ policy);
goto err;
}
setfragment = 0;
@@ -502,17 +501,16 @@ static int oss_init_out(HWVoiceOut *hw, struct
audsettings *as,
int fd;
AudioFormat effective_fmt;
struct audsettings obt_as;
- OSSConf *conf = drv_opaque;
+ Audiodev *dev = drv_opaque;
+ AudiodevOssOptions *oopts = &dev->u.oss;
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)) {
+ if (oss_open(0, &req, as, &obt, &fd, dev)) {
return -1;
}
@@ -539,7 +537,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings
*as,
hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
oss->mmapped = 0;
- if (conf->try_mmap) {
+ if (oopts->has_try_mmap && oopts->try_mmap) {
oss->pcm_buf = mmap (
NULL,
hw->samples << hw->info.shift,
@@ -597,7 +595,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings
*as,
}
oss->fd = fd;
- oss->conf = conf;
+ oss->dev = dev;
return 0;
}
@@ -605,16 +603,12 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
int trig;
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
+ AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.oss_out;
switch (cmd) {
case VOICE_ENABLE:
{
- va_list ap;
- int poll_mode;
-
- va_start (ap, cmd);
- poll_mode = va_arg (ap, int);
- va_end (ap);
+ bool poll_mode = opdo->try_poll;
ldebug ("enabling voice\n");
if (poll_mode) {
@@ -669,16 +663,14 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings
*as, void *drv_opaque)
int fd;
AudioFormat effective_fmt;
struct audsettings obt_as;
- OSSConf *conf = drv_opaque;
+ Audiodev *dev = 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)) {
+ if (oss_open(1, &req, as, &obt, &fd, dev)) {
return -1;
}
@@ -712,7 +704,7 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings
*as, void *drv_opaque)
}
oss->fd = fd;
- oss->conf = conf;
+ oss->dev = dev;
return 0;
}
@@ -803,16 +795,12 @@ static int oss_read (SWVoiceIn *sw, void *buf, int size)
static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
{
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
+ AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.oss_out;
switch (cmd) {
case VOICE_ENABLE:
{
- va_list ap;
- int poll_mode;
-
- va_start (ap, cmd);
- poll_mode = va_arg (ap, int);
- va_end (ap);
+ bool poll_mode = opdo->try_poll;
if (poll_mode) {
oss_poll_in (hw);
@@ -832,82 +820,42 @@ static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
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_init_per_direction(AudiodevOssPerDirectionOptions **opdo,
+ bool *has_opdo)
+{
+ if (!*has_opdo) {
+ *opdo = g_malloc0(sizeof(AudiodevOssPerDirectionOptions));
+ *has_opdo = true;
+ }
+
+ if (!(*opdo)->has_try_poll) {
+ (*opdo)->try_poll = true;
+ (*opdo)->has_try_poll = true;
+ }
+}
static void *oss_audio_init(Audiodev *dev)
{
- OSSConf *conf = g_malloc(sizeof(OSSConf));
- *conf = glob_conf;
+ AudiodevOssOptions *oopts;
+ assert(dev->driver == AUDIODEV_DRIVER_OSS);
- if (access(conf->devpath_in, R_OK | W_OK) < 0 ||
- access(conf->devpath_out, R_OK | W_OK) < 0) {
- g_free(conf);
+ oopts = &dev->u.oss;
+ oss_init_per_direction(&oopts->oss_in, &oopts->has_oss_in);
+ oss_init_per_direction(&oopts->oss_out, &oopts->has_oss_out);
+
+ if (access(oopts->oss_in->has_dev ? oopts->oss_in->dev : "/dev/dsp",
+ R_OK | W_OK) < 0 ||
+ access(oopts->oss_out->has_dev ? oopts->oss_out->dev : "/dev/dsp",
+ R_OK | W_OK) < 0) {
return NULL;
}
- return conf;
+ return dev;
}
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 won't 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,
@@ -925,7 +873,6 @@ static struct audio_pcm_ops oss_pcm_ops = {
static 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,
--
2.20.1
- Re: [Qemu-devel] [PATCH v4 01/14] qapi: qapi for audio backends, (continued)
- [Qemu-devel] [PATCH v4 03/14] audio: -audiodev command line option: documentation, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 06/14] coreaudio: port to -audiodev config, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 11/14] sdlaudio: port to -audiodev config, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 13/14] wavaudio: port to -audiodev config, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 14/14] audio: -audiodev command line option: cleanup, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 02/14] audio: use qapi AudioFormat instead of audfmt_e, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 09/14] ossaudio: port to -audiodev config,
Kővágó, Zoltán <=
- [Qemu-devel] [PATCH v4 04/14] audio: -audiodev command line option basic implementation, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 05/14] alsaaudio: port to -audiodev config, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 07/14] dsoundaudio: port to -audiodev config, Kővágó, Zoltán, 2019/01/28
- [Qemu-devel] [PATCH v4 10/14] paaudio: port to -audiodev config, Kővágó, Zoltán, 2019/01/28
- Re: [Qemu-devel] [PATCH v4 00/14] Audio patches (was: Audio 5.1 patches), no-reply, 2019/01/31