summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThibault Le Meur <Thibault.LeMeur@supelec.fr>2007-07-12 11:26:35 +0200
committerJaroslav Kysela <perex@suse.cz>2007-07-20 11:11:50 +0200
commitf8c78b82b9e47d933629e7060e4a83a277b15ffe (patch)
treebebe05fcce9dc70f5b6fea2459e3950ca909b1e0
parentbe38114a49853e441e694d690e631937de5fc524 (diff)
downloadlinux-f8c78b82b9e47d933629e7060e4a83a277b15ffe.tar.bz2
[ALSA] usb-audio - Fix audiophile-USB quirk for little-endian
Audiophile-usb fix (corrects little-endianness in 16bit modes, resets interfaces at device initialization, and updates the documentation). Signed-off-by: Thibault Le Meur <Thibault.LeMeur@supelec.fr> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--Documentation/sound/alsa/Audiophile-Usb.txt230
-rw-r--r--sound/usb/usbaudio.c9
2 files changed, 159 insertions, 80 deletions
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt
index e40cce83327c..5b7a5487d505 100644
--- a/Documentation/sound/alsa/Audiophile-Usb.txt
+++ b/Documentation/sound/alsa/Audiophile-Usb.txt
@@ -1,4 +1,4 @@
- Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3
+ Guide to using M-Audio Audiophile USB with ALSA and Jack v1.4
========================================================
Thibault Le Meur <Thibault.LeMeur@supelec.fr>
@@ -6,8 +6,17 @@
This document is a guide to using the M-Audio Audiophile USB (tm) device with
ALSA and JACK.
+History
+=======
+* v1.4 - Thibault Le Meur (2007-07-11)
+ - Added Low Endianness nature of 16bits-modes
+ found by Hakan Lennestal <Hakan.Lennestal@brfsodrahamn.se>
+ - Modifying document structure
+
+
1 - Audiophile USB Specs and correct usage
==========================================
+
This part is a reminder of important facts about the functions and limitations
of the device.
@@ -25,18 +34,18 @@ The device has 4 audio interfaces, and 2 MIDI ports:
The internal DAC/ADC has the following characteristics:
* sample depth of 16 or 24 bits
* sample rate from 8kHz to 96kHz
-* Two ports can't use different sample depths at the same time. Moreover, the
-Audiophile USB documentation gives the following Warning: "Please exit any
-audio application running before switching between bit depths"
+* Two interfaces can't use different sample depths at the same time.
+Moreover, the Audiophile USB documentation gives the following Warning:
+"Please exit any audio application running before switching between bit depths"
Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
activated at the same time depending on the audio mode selected:
- * 16-bit/48kHz ==> 4 channels in/4 channels out
+ * 16-bit/48kHz ==> 4 channels in + 4 channels out
- Ai+Ao+Di+Do
- * 24-bit/48kHz ==> 4 channels in/2 channels out,
- or 2 channels in/4 channels out
+ * 24-bit/48kHz ==> 4 channels in + 2 channels out,
+ or 2 channels in + 4 channels out
- Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do
- * 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only)
+ * 24-bit/96kHz ==> 2 channels in _or_ 2 channels out (half duplex only)
- Ai or Ao or Di or Do
Important facts about the Digital interface:
@@ -52,44 +61,53 @@ source is connected
synchronization error (for instance sound played at an odd sample rate)
-2 - Audiophile USB support in ALSA
-==================================
+2 - Audiophile USB MIDI support in ALSA
+=======================================
-2.1 - MIDI ports
-----------------
-The Audiophile USB MIDI ports will be automatically supported once the
+The Audiophile USB MIDI ports will be automatically supported once the
following modules have been loaded:
* snd-usb-audio
* snd-seq-midi
No additional setting is required.
-2.2 - Audio ports
------------------
+
+3 - Audiophile USB Audio support in ALSA
+========================================
Audio functions of the Audiophile USB device are handled by the snd-usb-audio
module. This module can work in a default mode (without any device-specific
parameter), or in an "advanced" mode with the device-specific parameter called
"device_setup".
-2.2.1 - Default Alsa driver mode
-
-The default behavior of the snd-usb-audio driver is to parse the device
-capabilities at startup and enable all functions inside the device (including
-all ports at any supported sample rates and sample depths). This approach
-has the advantage to let the driver easily switch from sample rates/depths
-automatically according to the need of the application claiming the device.
-
-In this case the Audiophile ports are mapped to alsa pcm devices in the
-following way (I suppose the device's index is 1):
+3.1 - Default Alsa driver mode
+------------------------------
+
+The default behavior of the snd-usb-audio driver is to list the device
+capabilities at startup and activate the required mode when required
+by the applications: for instance if the user is recording in a
+24bit-depth-mode and immediately after wants to switch to a 16bit-depth mode,
+the snd-usb-audio module will reconfigure the device on the fly.
+
+This approach has the advantage to let the driver automatically switch from sample
+rates/depths automatically according to the user's needs. However, those who
+are using the device under windows know that this is not how the device is meant to
+work: under windows applications must be closed before using the m-audio control
+panel to switch the device working mode. Thus as we'll see in next section, this
+Default Alsa driver mode can lead to device misconfigurations.
+
+Let's get back to the Default Alsa driver mode for now. In this case the
+Audiophile interfaces are mapped to alsa pcm devices in the following
+way (I suppose the device's index is 1):
* hw:1,0 is Ao in playback and Di in capture
* hw:1,1 is Do in playback and Ai in capture
* hw:1,2 is Do in AC3/DTS passthrough mode
-You must note as well that the device uses Big Endian byte encoding so that
-supported audio format are S16_BE for 16-bit depth modes and S24_3BE for
-24-bits depth mode. One exception is the hw:1,2 port which is Little Endian
-compliant and thus uses S16_LE.
+In this mode, the device uses Big Endian byte-encoding so that
+supported audio format are S16_BE for 16-bit depth modes and S24_3BE for
+24-bits depth mode. One exception is the hw:1,2 port which is reported
+to be Little Endian compliant (supposedly supporting S16_LE) but processes
+in fact only S16_BE streams.
Examples:
* playing a S24_3BE encoded raw file to the Ao port
@@ -99,21 +117,23 @@ Examples:
* playing a S16_BE encoded raw file to the Do port
% aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw
-If you're happy with the default Alsa driver setup and don't experience any
+If you're happy with the default Alsa driver mode and don't experience any
issue with this mode, then you can skip the following chapter.
-2.2.2 - Advanced module setup
+3.2 - Advanced module setup
+---------------------------
Due to the hardware constraints described above, the device initialization made
by the Alsa driver in default mode may result in a corrupted state of the
device. For instance, a particularly annoying issue is that the sound captured
-from the Ai port sounds distorted (as if boosted with an excessive high volume
-gain).
+from the Ai interface sounds distorted (as if boosted with an excessive high
+volume gain).
For people having this problem, the snd-usb-audio module has a new module
-parameter called "device_setup".
+parameter called "device_setup" (this parameter was introduced in kernel
+release 2.6.17)
-2.2.2.1 - Initializing the working mode of the Audiophile USB
+3.2.1 - Initializing the working mode of the Audiophile USB
As far as the Audiophile USB device is concerned, this value let the user
specify:
@@ -121,33 +141,57 @@ specify:
* the sample rate
* whether the Di port is used or not
-Here is a list of supported device_setup values for this device:
- * device_setup=0x00 (or omitted)
- - Alsa driver default mode
- - maintains backward compatibility with setups that do not use this
- parameter by not introducing any change
- - results sometimes in corrupted sound as described earlier
+When initialized with "device_setup=0x00", the snd-usb-audio module has
+the same behaviour as when the parameter is omitted (see paragraph "Default
+Alsa driver mode" above)
+
+Others modes are described in the following subsections.
+
+3.2.1.1 - 16-bit modes
+
+The two supported modes are:
+
* device_setup=0x01
- 16bits 48kHz mode with Di disabled
- Ai,Ao,Do can be used at the same time
- hw:1,0 is not available in capture mode
- hw:1,2 is not available
+
* device_setup=0x11
- 16bits 48kHz mode with Di enabled
- Ai,Ao,Di,Do can be used at the same time
- hw:1,0 is available in capture mode
- hw:1,2 is not available
+
+In this modes the device operates only at 16bits-modes. Before kernel 2.6.23,
+the devices where reported to be Big-Endian when in fact they were Little-Endian
+so that playing a file was a matter of using:
+ % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw
+where "test_S16_LE.raw" was in fact a little-endian sample file.
+
+Thanks to Hakan Lennestal (who discovered the Little-Endiannes of the device in
+these modes) a fix has been committed (expected in kernel 2.6.23) and
+Alsa now reports Little-Endian interfaces. Thus playing a file now is as simple as
+using:
+ % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw
+
+3.2.1.2 - 24-bit modes
+
+The three supported modes are:
+
* device_setup=0x09
- 24bits 48kHz mode with Di disabled
- Ai,Ao,Do can be used at the same time
- hw:1,0 is not available in capture mode
- hw:1,2 is not available
+
* device_setup=0x19
- 24bits 48kHz mode with Di enabled
- 3 ports from {Ai,Ao,Di,Do} can be used at the same time
- hw:1,0 is available in capture mode and an active digital source must be
connected to Di
- hw:1,2 is not available
+
* device_setup=0x0D or 0x10
- 24bits 96kHz mode
- Di is enabled by default for this mode but does not need to be connected
@@ -155,34 +199,61 @@ Here is a list of supported device_setup values for this device:
- Only 1 port from {Ai,Ao,Di,Do} can be used at the same time
- hw:1,0 is available in captured mode
- hw:1,2 is not available
+
+In these modes the device is only Big-Endian compliant (see "Default Alsa driver
+mode" above for an aplay command example)
+
+3.2.1.3 - AC3 w/ DTS passthru mode
+
+This mode is untested, I have no AC3 compliant device to test it. I uses:
+
* device_setup=0x03
- 16bits 48kHz mode with only the Do port enabled
- AC3 with DTS passthru (not tested)
- Caution with this setup the Do port is mapped to the pcm device hw:1,0
-2.2.2.2 - Setting and switching configurations with the device_setup parameter
+3.2.2 - How to use the device_setup parameter
+----------------------------------------------
The parameter can be given:
+
* By manually probing the device (as root):
# modprobe -r snd-usb-audio
# modprobe snd-usb-audio index=1 device_setup=0x09
+
* Or while configuring the modules options in your modules configuration file
- For Fedora distributions, edit the /etc/modprobe.conf file:
alias snd-card-1 snd-usb-audio
options snd-usb-audio index=1 device_setup=0x09
-IMPORTANT NOTE WHEN SWITCHING CONFIGURATION:
--------------------------------------------
- * You may need to _first_ initialize the module with the correct device_setup
- parameter and _only_after_ turn on the Audiophile USB device
- * This is especially true when switching the sample depth:
+CAUTION when initializaing the device
+-------------------------------------
+
+ * Correct initialization on the device requires that device_setup is given to
+ the module BEFORE the device is turned on. So, if you use the "manual probing"
+ method described above, take care to power-on the device AFTER this initialization.
+
+ * Failing to respect this will lead in a misconfiguration of the device. In this case
+ turn off the device, unproble the snd-usb-audio module, then probe it again with
+ correct device_setup parameter and then (and only then) turn on the device again.
+
+ * If you've correctly initialized the device in a valid mode and then want to switch
+ to another mode (possibly with another sample-depth), please use also the following
+ procedure:
- first turn off the device
- de-register the snd-usb-audio module (modprobe -r)
- change the device_setup parameter by changing the device_setup
option in /etc/modprobe.conf
- turn on the device
+ * A workaround for this last issue has been applied to kernel 2.6.23, but it may not
+ be enough to ensure the 'stability' of the device initialization.
+
+3.2.3 - Technical details for hackers
+-------------------------------------
+This section is for hackers, wanting to understand details about the device
+internals and how Alsa supports it.
-2.2.2.3 - Audiophile USB's device_setup structure
+3.2.3.1 - Audiophile USB's device_setup structure
If you want to understand the device_setup magic numbers for the Audiophile
USB, you need some very basic understanding of binary computation. However,
@@ -228,12 +299,12 @@ Caution:
- choosing b2 will prepare all interfaces for 24bits/96kHz but you'll
only be able to use one at the same time
-2.2.3 - USB implementation details for this device
+3.2.3.2 - USB implementation details for this device
You may safely skip this section if you're not interested in driver
-development.
+hacking.
-This section describes some internal aspects of the device and summarize the
+This section describes some internal aspects of the device and summarizes the
data I got by usb-snooping the windows and Linux drivers.
The M-Audio Audiophile USB has 7 USB Interfaces:
@@ -293,43 +364,45 @@ parse_audio_endpoints function uses a quirk called
"audiophile_skip_setting_quirk" in order to prevent AltSettings not
corresponding to device_setup from being registered in the driver.
-3 - Audiophile USB and Jack support
+4 - Audiophile USB and Jack support
===================================
This section deals with support of the Audiophile USB device in Jack.
-The main issue regarding this support is that the device is Big Endian
-compliant.
-3.1 - Using the plug alsa plugin
---------------------------------
+There are 2 main potential issues when using Jackd with the device:
+* support for Big-Endian devices in 24-bit modes
+* support for 4-in / 4-out channels
-Jack doesn't directly support big endian devices. Thus, one way to have support
-for this device with Alsa is to use the Alsa "plug" converter.
+4.1 - Direct support in Jackd
+-----------------------------
+
+Jack supports big endian devices only in recent versions (thanks to
+Andreas Steinmetz for his first big-endian patch). I can't remember
+extacly when this support was released into jackd, let's just say that
+with jackd version 0.103.0 it's almost ok (just a small bug is affecting
+16bits Big-Endian devices, but since you've read carefully the above
+paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices
+are now Little Endians ;-) ).
+
+You can run jackd with the following command for playback with Ao and
+record with Ai:
+ % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
+
+4.2 - Using Alsa plughw
+-----------------------
+If you don't have a recent Jackd installed, you can downgrade to using
+the Alsa "plug" converter.
For instance here is one way to run Jack with 2 playback channels on Ao and 2
capture channels from Ai:
% jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1
-
However you may see the following warning message:
"You appear to be using the ALSA software "plug" layer, probably a result of
using the "default" ALSA device. This is less efficient than it could be.
Consider using a hardware device instead rather than using the plug layer."
-3.2 - Patching alsa to use direct pcm device
---------------------------------------------
-A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
-However it has not been included in the CVS tree.
-
-You can find it at the following URL:
-http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687&
-atid=425939
-
-After having applied the patch you can run jackd with the following command
-line:
- % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
-
-3.2 - Getting 2 input and/or output interfaces in Jack
+4.3 - Getting 2 input and/or output interfaces in Jack
------------------------------------------------------
As you can see, starting the Jack server this way will only enable 1 stereo
@@ -339,6 +412,7 @@ This is due to the following restrictions:
* Jack can only open one capture device and one playback device at a time
* The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1
(and optionally hw:1,2)
+
If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to
combine the Alsa devices into one logical "complex" device.
@@ -348,13 +422,11 @@ It is related to another device (ice1712) but can be adapted to suit
the Audiophile USB.
Enabling multiple Audiophile USB interfaces for Jackd will certainly require:
-* patching Jack with the previously mentioned "Big Endian" patch
-* patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page)
-* patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page)
+* Making sure your Jackd version has the MMAP_COMPLEX patch (see the ice1712 page)
+* (maybe) patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page)
* define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc
file
* start jackd with this device
-I had no success in testing this for now, but this may be due to my OS
-configuration. If you have any success with this kind of setup, please
-drop me an email.
+I had no success in testing this for now, if you have any success with this kind
+of setup, please drop me an email.
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 8ebc1adb5ed9..834b0aff5ec1 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2350,7 +2350,9 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *
return 1;
break;
case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
- return 1;
+ if (device_setup[chip->index] == 0x00 ||
+ fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
+ return 1;
}
return 0;
}
@@ -3251,6 +3253,11 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
int iface, int altno)
{
+ /* Reset ALL ifaces to 0 altsetting.
+ * Call it for every possible altsetting of every interface.
+ */
+ usb_set_interface(chip->dev, iface, 0);
+
if (device_setup[chip->index] & AUDIOPHILE_SET) {
if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
&& altno != 6)