aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sound/pcm/dsp.c
diff options
context:
space:
mode:
authorAriff Abdullah <ariff@FreeBSD.org>2006-11-26 12:24:06 +0000
committerAriff Abdullah <ariff@FreeBSD.org>2006-11-26 12:24:06 +0000
commita580b31a54a7d147994d0036c97bba9056c6b38f (patch)
treebe8f05cc6b2e41975dd084107c4db8978e7c9734 /sys/dev/sound/pcm/dsp.c
parent4bc4dc4c4ba2a75a53aa3d9e43300c2b3fc11946 (diff)
downloadsrc-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.c33
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;
}