* General spl* cleanup. It doesn't serve any purpose anymore.
* Nuke sndstat_busy(). Addition of sndstat_acquire() /
sndstat_release() for sndstat exclusive access. [1]
sys/dev/sound/pcm/sound.c:
* Remove duplicate SLIST_INIT()
* Use sndstat_acquire() / release() to lock / release the entire
sndstat during pcm_unregister(). This should fix LOR #159 [1]
sys/dev/sound/pcm/sound.h:
* Definition of SD_F_SOFTVOL (part of feeder volume)
* Nuke sndstat_busy(). Addition of sndstat_acquire() /
sndstat_release() for exclusive sndstat access. [1]
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
LOR: 159 [1]
Discussed with: yongari [1]
1. Support wide range sampling rate, as low as 1hz up to int32 max
(which is, insane) through new feeder_rate, multiple precisions
choice (32/64 bit converter). This is indeed, quite insane, but it
does give us more room and flexibility. Plenty sysctl options to
adjust resampling characteristics.
2. Support 24/32 bit pcm format conversion through new, much improved,
simplified and optimized feeder_fmt.
Changes:
1. buffer.c / dsp.c / sound.h
* Support for 24/32 AFMT.
2. feeder_rate.c
* New implementation of sampling rate conversion with 32/64 bit
precision, 1 - int32max hz (which is, ridiculous, yet very
addictive). Much improved / smarter buffer management to not
cause any missing samples at the end of conversion process
* Tunable sysctls for various aspect:
hw.snd.feeder_rate_ratemin - minimum allowable sampling rate
(default to 4000)
hw.snd.feeder_rate_ratemax - maximum allowable sampling rate
(default to 1102500)
hw.snd.feeder_rate_buffersize - conversion buffer size
(default to 8192)
hw.snd.feeder_rate_scaling - scaling / conversion method
(please refer to the source for explaination). Default to
previous implementation type.
3. feeder_fmt.c / sound.h
* New implementation, support for 24/32bit conversion, optimized,
and simplified. Few routines has been removed (8 to xlaw, 16 to
8). It just doesn't make sense.
4. channel.c
* Support for 24/32 AFMT
* Fix wrong xruns increment, causing incorrect underruns statistic
while using vchans.
5. vchan.c
* Support for 24/32 AFMT
* Proper speed / rate detection especially for fixed rate ac97.
User can override it using kernel hint:
hint.pcm.<unit>.vchanrate="xxxx".
Notes / Issues:
* Virtual Channels (vchans)
Enabling vchans can really, really help to solve overrun
issues. This is quite understandable, because it operates
entirely within its own buffering system without relying on
hardware interrupt / state. Even if you don't need vchan,
just enable single channel can help much. Few soundcards
(notably via8233x, sblive, possibly others) have their own
hardware multi channel, and this is unfortunately beyond
vchan reachability.
* The arrival of 24/32 also come with a price. Applications
that can do 24/32bit playback need to be recompiled (notably
mplayer). Use (recompiled) mplayer to experiment / test /
debug this various format using -af format=fmt. Note that
24bit seeking in mplayer is a little bit broken, sometimes
can cause silence or loud static noise. Pausing / seeking
few times can solve this problem.
You don't have to rebuild world entirely for this. Simply
copy /usr/src/sys/sys/soundcard.h to
/usr/include/sys/soundcard.h would suffice. Few drivers also
need recompilation, and this can be done via
/usr/src/sys/modules/sound/.
Support for 24bit hardware playback is beyond the scope of
this changes. That would require spessific hardware driver
changes.
* Don't expect playing 9999999999hz is a wise decision. Be
reasonable. The new feeder_rate implemention provide
flexibility, not insanity. You can easily chew up your CPU
with this kind of mind instability. Please use proper
mosquito repellent device for this obvious cracked brain
attempt. As for testing purposes, you can use (again)
mplayer to generate / play with different sampling rate. Use
something like "mplayer -af resample=192000:0:0 <files>".
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested by: multimedia@
- `sound'
The generic sound driver, always required.
- `snd_*'
Device-dependent drivers, named after the sound module names.
Configure accordingly to your hardware.
In addition, rename the `snd_pcm' module to `sound' in order to sync
with the driver names.
Suggested by: cg
because they bogusly check for defined(INTR_MPSAFE) -- something which
never was a #define. Correct the definitions.
This make INTR_TYPE_AV finally get used instead of the lower-priority
INTR_TYPE_TTY, so it's quite possible some improvement will be had
on sound driver performance. It would also make all the drivers
marked INTR_MPSAFE actually run without Giant (which does seem to
work for me), but:
INTR_MPSAFE HAS BEEN REMOVED FROM EVERY SOUND DRIVER!
It needs to be re-added on a case-by-case basis since there is no one
who will vouch for which sound drivers, if any, willy actually operate
correctly without Giant, since there hasn't been testing because of
this bug disabling INTR_MPSAFE.
Found by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
rid of the MTX_DUPOK flag on channel mutexes, which allows witness to
do a better job of lock order checking. Nuke snd_chnmtxcreate() since
it is no longer needed.
Tested by: matk
panic() so that the buffer overflow just beyond this point is always
caught, even when the code is not compiled with INVARIANTS.
Change chn_setblocksize() buffer reallocation code to attempt to avoid
the feed_vchan16() buffer overflow by attempting to always keep the
bufsoft buffer at least as large as the bufhard buffer.
Print a diagnositic message
Danger! %s bufsoft size increasing from %d to %d after CHANNEL_SETBLOCKSIZE()
if our best attempts fail. If feed_vchan16() were to be called by
the interrupt handler while locks are dropped in chn_setblocksize()
to increase the size bufsoft to match the size of bufhard, the panic()
code in feed_vchan16() will be triggered. If the diagnostic message
is printed, it is a warning that a panic is possible if the system
were to see events in an "unlucky" order.
Change the locking code to avoid the need for MTX_RECURSIVE mutexes.
Add the MTX_DUPOK option to the channel mutexes and change the locking
sequence to always lock the parent channel before its children to avoid
the possibility of deadlock.
Actually implement locking assertions for the channel mutexes and fix
the problems found by the resulting assertion violations.
Clean up the locking code in dsp_ioctl().
Allocate the channel buffers using the malloc() M_WAITOK option instead
of M_NOWAIT so that buffer allocation won't fail. Drop locks across
the malloc() calls.
Add/modify KASSERTS() in attempt to detect problems early.
Abuse layering by adding a pointer to the snd_dbuf structure that points
back to the pcm_channel that owns it. This allows sndbuf_resize() to do
proper locking without having to change the its API, which is used by
the hardware drivers.
Don't dereference a NULL pointer when setting hw.snd.maxautovchans
if a hardware driver is not loaded. Noticed by Ryan Sommers
<ryans at gamersimpact.com>.
Tested by: Stefan Ehmann <shoesoft AT gmx.net>
Tested by: matk (Mathew Kanner)
Tested by: Gordon Bergling <gbergling AT 0xfce3.net>
This takes us a lot closer to refcounting dev_t.
This patch originally by cg@ with a few minor changes by me.
It is largely untested, but has been HEADSUP'ed twice, so presumably
people have not found any issues with it.
Submitted by: cg@
previous commit:
Include <sys/mutex.h> and its prerequisite <sys/lock.h> instead of
depending on namespace pollution in <sys/buf.h>. Only do this in the
__FreeBSD_version > 500000 case although the __FreeBSD_version < 500000
case has already rotted.
* be more specific in verbose boot messages
* allow the feeder subsystem to veto pcm* attaching if there is an error
initialising the root feeder
* don't free/malloc a new tmpbuf when resizing a snd_dbuf to the same size as
it currently is
* store the feeder description in the feeder structure instead of mallocing
space for it
no longer possible to unload the driver module while sound is playing
(which resulted in a panic).
- Fix a similar problem with the sndstat device that I found while looking
at the above.
- Append a newline character to error messages in pcm_unregister()
Reviewed by: cg
MFC after: 10 days
* add new channels to the end of the list so channels used in order of
addition
* de-globalise definition of struct snddev_info and provide accessor
functions where necessary.
* move the $FreeBSD$ tag in each .c file into a macro and allow the
/dev/sndstat handler to display these when set to maximum verbosity to aid
debugging.
* allow each device to register its own sndstat handler to reduce the amount
of groping sndstat must do in foreign structs.
if a device has vchans already but they are all busy, allocate another one
at open() time, up to a maximum of hw.snd.maxvchans.
when creating/destroying vchans, don't make/remove a devnode for the
first/last one as it replaces a hardchan.
worked before.
mixer, dsp and sndstat are seperate devices - give them their own cdevsws
instead of demuxing requests sent to a single cdevsw.
use the si_drv1/si_drv2 fields in dev_t structures for holding information
specific to an open instance of mixer/dsp.
nuke /dev/{dsp,dspW,audio}[0-9]* links - this functionality is now provided
using cloning.
various locking fixes.
instead of using two malloced arrays for storing channel lists, use an
slist. convert the sndstat device to use sbufs and optionally provide more
detail about channel state.
vchans are software mixed playback channels. they are not enabled by this
commit. they use the feeder infrastructure to emulate normal playback
channels in a manner transparent to applications, whilst providing as many
channels are desired, especially suitable for devices with only one hardware
playback channel. in the future they will provide additional features.
those wishing to test this functionality will need to add vchan.c to
sys/conf/files and use 'sysctl -w hw.snd.pcm0.vchans' to enable it.
blocksize and auto-rate selection are not yet supported.
this introduces a new buffering mechanism which results in dramatic
simplification of the channel manager.
as several structures have changed, we take the opportunity to move their
definitions into the source files where they are used, make them private and
de-typedef them.
the sound drivers are updated to use snd_setup_intr instead of
bus_setup_intr, and to comply with the de-typedefed structures.
the ac97, mixer and channel layers have been updated with finegrained
locking, as have some drivers- not all though. the rest will follow soon.
modify chn_setblocksize() to pick a default soft-blocksize appropriate to the
sample rate and format in use. it will aim for a power of two size small
enough to generate block sizes of at most 20ms. it will also set the
hard-blocksize taking into account rate/format conversions in use.
update drivers to implement setblocksize correctly:
updated, tested: sb16, emu10k1, maestro, solo
updated, untested: ad1816, ess, mss, sb8, csa
not updated: ds1, es137x, fm801, neomagic, t4dwave, via82c686
i lack hardware to test: ad1816, csa, fm801, neomagic
others will be updated/tested in the next few days.
this gives us several benefits, including:
* easier extensibility- new optional methods can be added to
ac97/mixer/channel classes without having to fixup every driver.
* forward compatibility for drivers, provided no new mandatory methods are
added.
change channel interface - kobj implementation coming soonish
make pcm_makelinks not panic if modular
add pcm_unregister()
these changes support newpcm kld unloading, but this is only implemented
by ds1.c
modify driver capability reporting format to list every audio format
seperately- required for above and because we could not previously indicate
that mono was unsupported.
there should be no functional impact.