This one simply tries to simplify the logic to select the
buffer sizes. I am not sure it is necessary but the code
seems a bit more readable to me. And at least i have tried
to document how the buffer sizes are computed.
Thanks to luigi for deciphering one of the most cryptic part of
sound driver.
Submitted by: luigi
Approved by: netchild (mentor)
In SNDCTL_DSP_SETFRAGMENT, if you specify both read and
write channels, the existing code first acts on the
read channel, but as a side effect it updates the
arguments (maxfrags, fragsz) passed by the caller according
to acceptable values for the read channel, and then uses the
modified values to act on the write channel.
The problem with this approach is that, given a
(maxfrags, fragsz) user-specified value, the actual
values computed by the read and write channels may differ:
e.g. the read channel might want to allocate more fragments
than what the user specified because it has no side-effects
on the delay and it helps in case of slow readers,
whereas the write channel needs to use as few fragments
as possible to keep the audio latency low (very important
with telephony apps).
This patch stores the values computed by the read channel
into temproary variables so the write channel will use
the actual arguments of the ioctl.
This patch is very helpful with telephony apps such as asterisk.
Submitted by: luigi
Approved by: netchild (mentor)
- Added new codec id for CX20468-21 and VIA1617A.
Submitted by: Chen Lihong <lihong.chen@gmail.com>
- Re-enable SOUND_MIXER_IGAIN, but set the default level as 0 (mute)
Suggested by: luigi
mixer.c:
- Set default value for SOUND_MIXER_IGAIN as 0 (mute) to avoid
feedback problems on some laptops (was disabled by jhb during
ac97.c revision 1.42).
Approved by: netchild (mentor)
erratic system slowdown (beaten to a pulp) and possible panic. This
issue has bugged me for as long as I could remember, until I
realized that it is possible for register base offset to hold zero
value which is definitely a "FALSE".
Approved by: netchild (mentor)
compatible AC97 codec.
- As the driver supports so many variants, create a table ids for
ease of probing and maintenance.
Submitted by: yongari
Reviewed/Tested by: multimedia@
- From luigi:
The code to compute fragment sizes in the ich driver almost
invariably ends up using the full buffer available, no matter
how the user specifies fragment size and number.
With audio telephony (8khz, 16bit-stereo) and the 16k buffer
size this results in an unbearable 500ms delay.
This patch makes sure that we never use more than 4 fragments,
(i don't think we need more unless there are huge interrupt
servicing latencies), and obey to the requested fragment size,
so that latency is acceptable.
Based on this (and after much regression tests), I can conclude
that this driver works best with 2 fragments, thus solving various
long standing issues of ICH driver not capable to flush or play
short files perfectly.
Suggested by: luigi (the idea of smaller fragments)
- MPSAFE conversion.
Approved by: netchild (mentor)
distinct hardware playback channels. DAC configuration can be
accessed through kernel hint - hint.pcm.<unit>.dac="val" with
following possible values:
0 = Enable both DACs (default)
1 = Enable single DAC (DAC1)
2 = Enable single DAC (DAC2)
3 = Enable both DACs, swap position (DAC2 comes first instead
of DAC1)
Special case for ES1370:
Unlike ES1371,2,3/CT5880, volume for each DAC 1 and 2 can be
controlled indepedently (synth for DAC1, pcm for DAC2). It is
possible that user will confuse by this behaviour, since both
DACs are enabled by default. Thus, provide a knob through sysctl
hw.snd.pcm<unit>.single_pcm_mixer:
0 = each DACs will be controlled separately (synth/pcm).
1 = combine both DACs volume mixer controller into a single
"pcm" (default)
As a side note, fixed rate operation (provided by previous
commit) is not a mandatory if the configuration space does not
involve DAC2 (perhaps disabled by user through the above kernel
hint). Unlike DAC2, DAC1 has its own register / control space,
not affected by the speed settings of ADC.
Tested by: multimedia@
Approved by: netchild (mentor)
mask to recdev_l and recdev_r, since each have its own unique mask.
Submitted by: Watanabe Kazuhiro <CQG00620@nifty.ne.jp>
Approved by: netchild (mentor)
It may be the case that you may hear some unwanted noise while
playing back with 24/32 bit. This is a problem in the USB system.
Explanation from Hans Petter Selasky:
---snip---
The current USB sound driver only uses one isochronous
buffer, that is restarted when it is completed. This will lead to a short
period of time, +1ms, where no sound data is sent to the external USB device.
Depending on the load of your computer, this can be as much as 50ms. So the
USB sound driver must use 2 isochronous transfers. At the beginning one will
queue both. Then these are restarted on completion. This will result in a
constant-rate data stream to the external sound device, a minimum sound
buffer equal to the size of the isochronous buffer, and possibly the sound
will reach your ears with less delay. Little delay is a result of constant
data rate. Currently only my USB driver will support that. If one tries that
with the USB driver in *BSD, then it will crash at the first moment one gets
a buffer underrun.
---snip---
Submitted by: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp>
Mono-recording still not tested by: julian
- Return EINVAL if play_format or rec_format is set but the corresponding
sample rate is 0.
- Don't try to set the playback or recording format to 0. Previously,
issuing an AIOSFMT ioctl with an all-zeroes snd_chan_param would
trigger a KASSERT in chn_fmtchain(); I'm unsure about the effects on
a kernel without INVARIANTS. After this commit, issuing AIOSFMT with
an all-zeroes snd_chan_param is equivalent to issuing AIOGFMT.
MFC after: 2 weeks
sampling rate:
- Improve vchan chn_setspeed() strategy. Try to avoid FEEDER_RATE
on parent channel if the requested value is not supported
by the hardware.
- Fix vchan default speed calculation. In any case, vchan should
rely on parent bufsoft speed instead of bufhard since it is
possible that the entire feeder chain might involve FEEDER_RATE.
This is possible under extreme, rare condition if the above
chn_setspeed() strategy failed.
Approved by: netchild (mentor)
- Don't keep the SPDIF state in the driver private struct since it
can be overriden by hand with pciconf(8), query it when needed instead.
Regarding the locking I let Ariff explain it himself:
---snip---
About the locking, that is what I'm intended to do since the beginning.
The reason I'm not putting that along since my first patchset was
because several people especially from amd46 camp reported that it cause
lots of LORs, which is weird considering that I've never encounter such
in a pretty much strict locking environment (i386). However, since our
previous discussion with Pyun YongHyeon about strict locking, I've
decided to bring it back for all the affected drivers, not just for
es137x. It turns out that the root of the problem was within dsp.c
during device open, which has been fixed since dsp.c revision 1.84.
---snip---
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
code which may help.
People with a ich compatible soundcard which want to help out should
change the "#if 1" to a "#if 0" and try if the soundcard still works.
Reports about working or not-working soundcards with this change to
multimedia@ please.
PR: 73987
sampling rate between playback and recording. This can be
disabled / enabled via kernel hints
(hint.pcm.<unit>.fixed_rate=0/4000-48000) or sysctl
hw.snd.pcm<unit>.fixed_rate=0/4000-48000). Default to 48khz
fixed rate. [1]
* Basic cleanup. *_es1371x_* -> *_es137x_*.
* Some locking fixes. [2]
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Discussed with: yongari [2]
See also: http://lists.freebsd.org/pipermail/freebsd-multimedia/2005-September/002758.html [1]
Reported by: Jos Backus <jos at catnook.com> [1]
* 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]
* Added codec id for CMI9761.
* feeder_volume *whitelist* through ac97_fix_volume()
sys/dev/sound/pcm/ac97.h:
* Added AC97_F_SOFTVOL definition.
sys/dev/sound/pcm/channel.c:
* Slight changes for chn_setvolume() to conform with OSS.
* FEEDER_VOLUME is now part of feeder building process.
sys/dev/sound/pcm/mixer.c:
* General spl* cleanup. It doesn't serve any purpose anymore.
* Main hook for feeder_volume.
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested by: multimedia@
While I'm here add KASSERT(9) to notify failure of SYSUNINIT handler.
Reported by: Ben Kaduk < minimarmot AT gmail DOT com >
Tested by: Ben Kaduk < minimarmot AT gmail DOT com >
- Remove an assertion in sound.c, it's not needed (and causes a panic now).
From the conversation via mail between glebius and Ariff:
---snip---
> Well, but which mutex protects now? Do we own anything else
> in pcm_chnalloc()? I see some queue(4) macros in pcm_chnalloc(),
> they should be protected, shouldn't they?
Queue insertion/removal occur during
1) driver loading (which is pretty much single thread /
sequential) or unloading (mutex protected, bail out if there is
any channel with refcount > 0 or busy).
2) vchan_create()/destroy(), (which is *sigh* quite complicated), but
somehow protected by 'master'/parent channel mutex. Other
thread cannot add/remove vchan (or even continue traversing
that queue) unless it can acquire parent channel mutex.
---snip---
Fix the locking in dsp.c to prevent a LOR (AFAIK not on the LOR page).
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested with: INVARIANTS[1] and DIAGNOSTICS[2]
Tested by: netchild [1,2], David Reid <david@jetnet.co.uk> [1]
In case this causes trouble for some other chipsets add a comment how to
proceed. If we don't get bugreports, this should be removed after a while
(some releases?).
PR: 56617 [1], 29465, 39260, 40574, 68225
Submitted by: Matthew E. Gove <mgove@comcast.net> [1]
believe that there are PC98 systems with an OPTi chip.
I don't know enough about this special PC architecture to be sure about
this, so let's find out by letting people with such a system complain in
case this commit breaks the sound system for them. It's easy to revert
then.
PR: 45673
Submitted by: Watanabe Kazuhiro <CQG00620@nifty.ne.jp>
* New definition CHN_F_HAS_VCHAN.
- channel.c
* Use CHN_F_HAS_VCHAN to mark channel with vchan capability instead
of relying on SLIST_EMPTY(&channel->children) == true for better
clarification and future possible usages of children (like
'slave' channel).
* Various fixes, including blocksize / format bps allignment,
better 24bit seeking (mplayer, others).
* Improve format chain building, it's now possible to record something
to a format non-native to the soundcard through various feeder format
converters or to higher sampling rate. This also gains another feature,
like doing vchan mixing on non s16le soundcard such as sb8.
- sound.c
* Increase robustness within various function that handle vchan
creation / termination (these function need a total rewrite, but
that would cause other major rewrite within various places too!).
As far as its robustness can be guaranteed, leave it as is.
* Optimize channel ordering, prefer *real* hardware playback
channels over virtual channels. cat /dev/sndstat should look
better.
* Increase sndstat verbosity to include bufsoft/bufhard allocation.
- vchan.c
* Fix LOR 119.
- http://sources.zabbadoz.net/freebsd/lor.html#119
* Reorder / increase robustness of vchan_create() / destroy().
Enforce destroy_dev() during destroy operation, fix possible
panic / dangling character device.
- http://lists.freebsd.org/pipermail/freebsd-current/2005-May/050308.html
* Tolerate a little bit more during mixing process, this should help
non s16le soundcards.
Note: Recoring in a non-native rate/format may result in overruns. A friendly
application is wavrec from audio/wavplay. The problem is under
investigation.
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
From the PR:
---snip---
The vibra16X supports full duplex. I traced the Windows driver, and what is
does is that it programs one DMA channel 8-bit, and the other 16-bit. There
might be some kind of auto detection logic here, because it always uses 8-bit
for playback, even if I play 16-bit sound ...
---snip---
PR: 80977
Submitted by: Hans Petter Selasky <hselasky@c2i.net>
event handler, dev_clone, which accepts a credential argument.
Implementors of the event can ignore it if they're not interested,
and most do. This avoids having multiple event handler types and
fall-back/precedence logic in devfs.
This changes the kernel API for /dev cloning, and may affect third
party packages containg cloning kernel modules.
Requested by: phk
MFC after: 3 days
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@
This mostly to help CT4730, but apparently it does help other
cards too (especially via8233x). This probably need further test
and confirmation from other people with ac97 cards other than via
/ es137x.
* Aggresive dac power wake up call, again, to help CT4730 (and
probably others).
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested by: multimedia@
- Don't mark MPSAFE (yet).
- DSP_CMD_DMAEXIT_8 doesn't work on old cards, use sb_reset_dsp() instead.
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
* Add kernel hint option to disable DXS channels entirely. Report
from several skype users / Pav Lucistnik indicate that disabling
DXS may fix lots of pop / crackling noise. To disable DXS add
hint.pcm.<unit>.via_dxs_disabled="1" to /boot/device.hints.
Further investigation of the issues regarding DXS showed, that
the problem is in another (more generic) place, but until the
right fix is tested/reviewed this may help a little bit.
Added sysctl's to aid testing/debugging:
hint.pcm.<unit>.via_dxs_disabled=X - Disable / Enable DXS channels entirely
hint.pcm.<unit>.via_dxs_channels=X - Limit DXS channels up to X
hint.pcm.<unit>.via_sgd_channels=X - Limit SGD channels up to X
hint.pcm.<unit>.via_dxs_src=X - Enable / Disable DXS sample rate
converter.
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested by: multimedia@