diff options
author | Ariff Abdullah <ariff@FreeBSD.org> | 2006-11-26 12:24:06 +0000 |
---|---|---|
committer | Ariff Abdullah <ariff@FreeBSD.org> | 2006-11-26 12:24:06 +0000 |
commit | a580b31a54a7d147994d0036c97bba9056c6b38f (patch) | |
tree | be8f05cc6b2e41975dd084107c4db8978e7c9734 /sys/dev/sound/pcm/dsp.c | |
parent | 4bc4dc4c4ba2a75a53aa3d9e43300c2b3fc11946 (diff) | |
download | src-a580b31a54a7d147994d0036c97bba9056c6b38f.tar.gz src-a580b31a54a7d147994d0036c97bba9056c6b38f.zip |
Welcome to Once-a-year Sound Mega-Commit. Enjoy numerous updates and fixes
in every sense.
General
-------
- Multichannel safe, endian safe, format safe
* Large part of critical pcm filters such as vchan.c, feeder_rate.c,
feeder_volume.c, feeder_fmt.c and feeder.c has been rewritten so that
using them does not cause the pcm data to be converted to 16bit little
endian.
* Macrosses for accessing pcm data safely are defined within sound.h in
the form of PCM_READ_* / PCM_WRITE_*
* Currently, most of them are probably limited for mono/stereo handling,
but the future addition of true multichannel will be much easier.
- Low latency operation
* Well, this require lot more works to do not just within sound driver,
but we're heading towards right direction. Buffer/block sizing within
channel.c is rewritten to calculate precise allocation for various
combination of sample/data/rate size. As a result, applying correct
SNDCTL_DSP_POLICY value will achive expected latency behaviour simmilar
to what commercial 4front driver do.
* Signal handling fix. ctrl+c of "cat /dev/zero > /dev/dsp" does not
result long delay.
* Eliminate sound truncation if the sound data is too small.
DIY:
1) Download / extract
http://people.freebsd.org/~ariff/lowlatency/shortfiles.tar.gz
2) Do a comparison between "cat state*.au > /dev/dsp" and
"for x in state*.au ; do cat $x > /dev/dsp ; done"
- there should be no "perceivable" differences.
Double close for PR kern/31445.
CAVEAT: Low latency come with (unbearable) price especially for poorly
written applications. Applications that trying to act smarter
by requesting (wrong) blocksize/blockcount will suffer the most.
Fixup samples/patches can be found at:
http://people.freebsd.org/~ariff/ports/
- Switch minimum/maximum sampling rate limit to "1" and "2016000" (48k * 42)
due to closer compatibility with 4front driver.
Discussed with: marcus@ (long time ago?)
- All driver specific sysctls in the form of "hw.snd.pcm%d.*" have been
moved to their own dev sysctl nodes, notably:
hw.snd.pcm%d.vchans -> dev.pcm.%d.vchans
Bump __FreeBSD_version.
Driver specific
---------------
- Ditto for sysctls.
- snd_atiixp, snd_es137x, snd_via8233, snd_hda
* Numerous cleanups and fixes.
* _EXPERIMENTAL_ polling mode support using simple callout_* mechanisme.
This was intended for pure debugging and latency measurement, but proven
good enough in few unexpected and rare cases (such as problematic shared
IRQ with GIANT devices - USB). Polling can be enabled/disabled through
dev.pcm.0.polling. Disabled by default.
- snd_ich
* Fix possible overflow during speed calibration. Delay final
initialization (pcm_setstatus) after calibration finished.
PR: kern/100169
Tested by: Kevin Overman <oberman@es.net>
* Inverted EAPD for few Nec VersaPro.
PR: kern/104715
Submitted by: KAWATA Masahiko <kawata@mta.biglobe.ne.jp>
Thanks to various people, notably Joel Dahl, Yuriy Tsibizov, Kevin Oberman,
those at #freebsd-azalia @ freenode and others for testing.
Joel Dahl will do the manpage update.
Notes
Notes:
svn path=/head/; revision=164614
Diffstat (limited to 'sys/dev/sound/pcm/dsp.c')
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 56f50a7cdfc4..940c3fde57df 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -215,10 +215,12 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) fmt = 0; break; - case SND_DEV_DSPREC: + case SND_DEV_DSPHW: + /* + * HW *specific* access without channel numbering confusion + * caused by "first come first served" by dsp_clone(). + */ fmt = AFMT_U8; - if (flags & FWRITE) - return EINVAL; chnum = PCMCHAN(i_dev); break; @@ -768,7 +770,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread * /* chn_sync may sleep */ if (wrch) { CHN_LOCK(wrch); - chn_sync(wrch, sndbuf_getsize(wrch->bufsoft) - 4); + chn_sync(wrch, 0); CHN_UNLOCK(wrch); } break; @@ -1085,12 +1087,11 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread * case SNDCTL_DSP_GETODELAY: if (wrch) { - struct snd_dbuf *b = wrch->bufhard; struct snd_dbuf *bs = wrch->bufsoft; CHN_LOCK(wrch); /* XXX abusive DMA update: chn_wrupdate(wrch); */ - *arg_i = sndbuf_getready(b) + sndbuf_getready(bs); + *arg_i = sndbuf_getready(bs); CHN_UNLOCK(wrch); } else ret = EINVAL; @@ -2131,31 +2132,29 @@ dsp_oss_syncstart(int sg_id) static int dsp_oss_policy(struct pcm_channel *wrch, struct pcm_channel *rdch, int policy) { - int fragln, fragsz, maxfrags, ret; + int ret; + + if (policy < CHN_POLICY_MIN || policy > CHN_POLICY_MAX) + return EIO; /* Default: success */ ret = 0; - /* Scale policy [0..10] to fragment size [2^4..2^16]. */ - fragln = policy; - RANGE(fragln, 0, 10); - fragln += 4; - fragsz = 1 << fragln; - - maxfrags = CHN_2NDBUFMAXSIZE / fragsz; - if (rdch) { CHN_LOCK(rdch); - ret = chn_setblocksize(rdch, maxfrags, fragsz); + ret = chn_setlatency(rdch, policy); CHN_UNLOCK(rdch); } if (wrch && ret == 0) { CHN_LOCK(wrch); - ret = chn_setblocksize(wrch, maxfrags, fragsz); + ret = chn_setlatency(wrch, policy); CHN_UNLOCK(wrch); } + if (ret) + ret = EIO; + return ret; } |