diff options
Diffstat (limited to 'audio/ossaudio.c')
-rw-r--r-- | audio/ossaudio.c | 108 |
1 files changed, 71 insertions, 37 deletions
diff --git a/audio/ossaudio.c b/audio/ossaudio.c index ff1a034945..5072742491 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -91,7 +91,7 @@ static void GCC_FMT_ATTR (3, 4) oss_logerr2 ( { va_list ap; - AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ); + AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ); va_start (ap, fmt); AUD_vlog (AUDIO_CAP, fmt, ap); @@ -179,7 +179,7 @@ static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness) return 0; } -#ifdef DEBUG_MISMATCHES +#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"); @@ -253,16 +253,16 @@ static int oss_open (int in, struct oss_params *req, 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)) { -#ifdef DEBUG_MISMATCHES dolog ("Audio parameters mismatch\n"); oss_dump_info (req, obt); -#endif } +#endif #ifdef DEBUG oss_dump_info (req, obt); @@ -283,12 +283,15 @@ static int oss_run_out (HWVoiceOut *hw) st_sample_t *src; struct audio_buf_info abinfo; struct count_info cntinfo; + int bufsize; live = audio_pcm_hw_get_live_out (hw); if (!live) { return 0; } + bufsize = hw->samples << hw->info.shift; + if (oss->mmapped) { int bytes; @@ -300,7 +303,7 @@ static int oss_run_out (HWVoiceOut *hw) if (cntinfo.ptr == oss->old_optr) { if (abs (hw->samples - live) < 64) { - dolog ("warning: overrun\n"); + dolog ("warning: Overrun\n"); } return 0; } @@ -309,7 +312,7 @@ static int oss_run_out (HWVoiceOut *hw) bytes = cntinfo.ptr - oss->old_optr; } else { - bytes = hw->bufsize + cntinfo.ptr - oss->old_optr; + bytes = bufsize + cntinfo.ptr - oss->old_optr; } decr = audio_MIN (bytes >> hw->info.shift, live); @@ -321,9 +324,9 @@ static int oss_run_out (HWVoiceOut *hw) return 0; } - if (abinfo.bytes < 0 || abinfo.bytes > hw->bufsize) { - ldebug ("warning: invalid available size, size=%d bufsize=%d\n", - abinfo.bytes, hw->bufsize); + if (abinfo.bytes < 0 || abinfo.bytes > bufsize) { + ldebug ("warning: Invalid available size, size=%d bufsize=%d\n", + abinfo.bytes, bufsize); return 0; } @@ -362,7 +365,7 @@ static int oss_run_out (HWVoiceOut *hw) int wsamples = written >> hw->info.shift; int wbytes = wsamples << hw->info.shift; if (wbytes != written) { - dolog ("warning: misaligned write %d (requested %d), " + dolog ("warning: Misaligned write %d (requested %d), " "alignment %d\n", wbytes, written, hw->info.align + 1); } @@ -396,10 +399,10 @@ static void oss_fini_out (HWVoiceOut *hw) if (oss->pcm_buf) { if (oss->mmapped) { - err = munmap (oss->pcm_buf, hw->bufsize); + 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->bufsize); + oss->pcm_buf, hw->samples << hw->info.shift); } } else { @@ -409,7 +412,7 @@ static void oss_fini_out (HWVoiceOut *hw) } } -static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) +static int oss_init_out (HWVoiceOut *hw, audsettings_t *as) { OSSVoiceOut *oss = (OSSVoiceOut *) hw; struct oss_params req, obt; @@ -417,10 +420,11 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) int err; int fd; audfmt_e effective_fmt; + audsettings_t obt_as; - req.fmt = aud_to_ossfmt (fmt); - req.freq = freq; - req.nchannels = nchannels; + req.fmt = aud_to_ossfmt (as->fmt); + req.freq = as->freq; + req.nchannels = as->nchannels; req.fragsize = conf.fragsize; req.nfrags = conf.nfrags; @@ -434,24 +438,38 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) return -1; } + obt_as.freq = obt.freq; + obt_as.nchannels = obt.nchannels; + obt_as.fmt = effective_fmt; + audio_pcm_init_info ( &hw->info, - obt.freq, - obt.nchannels, - effective_fmt, + &obt_as, audio_need_to_swap_endian (endianness) ); oss->nfrags = obt.nfrags; oss->fragsize = obt.fragsize; - hw->bufsize = obt.nfrags * 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 (0, hw->bufsize, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, 0); + oss->pcm_buf = mmap ( + 0, + 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->bufsize); + hw->samples << hw->info.shift); } else { int err; int trig = 0; @@ -472,18 +490,24 @@ static int oss_init_out (HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt) } if (!oss->mmapped) { - err = munmap (oss->pcm_buf, hw->bufsize); + 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->bufsize); + oss->pcm_buf, hw->samples << hw->info.shift); } } } } if (!oss->mmapped) { - oss->pcm_buf = qemu_mallocz (hw->bufsize); + oss->pcm_buf = audio_calloc ( + AUDIO_FUNC, + hw->samples, + 1 << hw->info.shift + ); if (!oss->pcm_buf) { + dolog ("Could not allocate DAC buffer (%d bytes)\n", + hw->samples << hw->info.shift); oss_anal_close (&fd); return -1; } @@ -528,8 +552,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static int oss_init_in (HWVoiceIn *hw, - int freq, int nchannels, audfmt_e fmt) +static int oss_init_in (HWVoiceIn *hw, audsettings_t *as) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; struct oss_params req, obt; @@ -537,10 +560,11 @@ static int oss_init_in (HWVoiceIn *hw, int err; int fd; audfmt_e effective_fmt; + audsettings_t obt_as; - req.fmt = aud_to_ossfmt (fmt); - req.freq = freq; - req.nchannels = nchannels; + req.fmt = aud_to_ossfmt (as->fmt); + req.freq = as->freq; + req.nchannels = as->nchannels; req.fragsize = conf.fragsize; req.nfrags = conf.nfrags; if (oss_open (1, &req, &obt, &fd)) { @@ -553,18 +577,28 @@ static int oss_init_in (HWVoiceIn *hw, return -1; } + obt_as.freq = obt.freq; + obt_as.nchannels = obt.nchannels; + obt_as.fmt = effective_fmt; + audio_pcm_init_info ( &hw->info, - obt.freq, - obt.nchannels, - effective_fmt, + &obt_as, audio_need_to_swap_endian (endianness) ); oss->nfrags = obt.nfrags; oss->fragsize = obt.fragsize; - hw->bufsize = obt.nfrags * obt.fragsize; - oss->pcm_buf = qemu_mallocz (hw->bufsize); + + 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 bytes)\n", + hw->samples << hw->info.shift); oss_anal_close (&fd); return -1; } @@ -623,7 +657,7 @@ static int oss_run_in (HWVoiceIn *hw) if (nread > 0) { if (nread & hw->info.align) { - dolog ("warning: misaligned read %d (requested %d), " + dolog ("warning: Misaligned read %d (requested %d), " "alignment %d\n", nread, bufs[i].add << hwshift, hw->info.align + 1); } |