Subject: Proposal: Audio: Sampling rate conversion
To: None <tech-kern@netbsd.org>
From: TAMURA Kent <kent@netbsd.org>
List: tech-kern
Date: 03/04/2002 23:32:22
WHAT IS PROPOSED?

The following patch adds
 - sampling rate conversion
 - mono-to-stereo/stereo-to-mono conversion
to the device-independent audio driver.

	http://www.hauN.org/kent/audio-20020304.diff  (57KB)

The patch contains rate/channel conversion code for the
device-independent audio driver and conversion request code for
dev/usb/uaudio.c and dev/pci/auich.c.  It may be a solution for
kern/8854 [1] and port-i386/12695 [2].  I'll commit this if no
objection is posted in 72 hours.

  [1] http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=8854
  [2] http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=12695


BACKGROUND

Some recent audio devices such as USB audio (uaudio in NetBSD)
or ICH (auich) support only higher sampling rates like 44.1kHz
or 48kHz.  We can not play/record non-supported sampling rates
with such devices.  For example, we can not play 44.1kHz audio
data with a 48kHz-only ICH device.  What is more, /dev/audio
requires initialization with 8kHz/mono/8bit/mulaw.  We can never
use /dev/audio with a device which has no 8kHz.


IMPLEMENTATION

The patch extends "struct audio_params" and set_params() of
audio(9).  "struct audio_params" has four new members:
hw_sample_rate, hw_channels, hw_encoding, hw_precision.

If a device-dependent driver does not modify "sample_rate" and
"channels" members of "struct audio_params," does modify
"hw_sample_rate" or "hw_channels", and set
AUDIO_ENCODING_SLINEAR_LE to "hw_encoding" in set_params(), the
device-independent audio driver assumes the device-dependent
driver requests rate/channel conversion and it wants/produces
data of which format is [hw_sample_rate, hw_channels,
hw_encoding, hw_precision].

In audio_write(), the data from application is converted by
sw_code(), which changes encoding and precision.  Then,
rate/channel conversion is performed.  In audio_read(), the data
from a device is applied to rate/channel conversion, and then
sw_code() is invoked.  Rate/channel conversion does not work
against mmapped data.

If a device-dependent driver requests rate/channel conversion,
it must set correct values to not only hw_sample_rate and
hw_channels but also hw_encoding and hw_precision to notice
correct format to the device-independent audio driver.

If a device-dependent driver modifies neither hw_sample_rate nor
hw_channels, the device-independent audio driver should work as
ever.

The patch provides rate/channel conversion only for 16bit/24bit
slinear_le at this moment.  I have checked /dev/audio for the
following devices could be opened successfully and cound play
various audio data.
 - UA-3 (uaudio) http://www.edirol.com/products/prosheets/ua3.html
   only 44.1kHz for playing, 32/44.1/48kHz for recoding
 - RP-U200 (uaudio) http://www.yamaha.com/yec/cavit/products/pd_rpu200_01.htm
   No monaural, 44.1/48kHz for playing, 32/44.1/48kHz for recoding
 - i82440MX/YMH0 on Let's note B5R (auich)
   http://prodb.matsushita.co.jp/products/fr/CF/CF-B5R.html
   48kHz-only codec.

-- 
TAMURA Kent <kent2002@hauN.org> <kent@netbsd.org>