diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/audio/ossaudio.c | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/audio/ossaudio.c')
-rw-r--r-- | qemu/audio/ossaudio.c | 940 |
1 files changed, 0 insertions, 940 deletions
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) -}; |