Author: Michael Minn (MichaelMinn.com)
10 March 2012
Describes installation and operation of MMUSBAUDIO, a Linux kernel module device driver for some USB audio devices.
MMUSBAUDIO (formerly known as USBUA100) is a Linux kernel module device driver permitting access to the following audio devices through the Open Sound System (OSS) interface (/dev/dsp, /dev/midi, etc.)
All of the devices above (except the Focusrite Sapphire) are already supported by the Advanced Linux Sound Architecture (ALSA), which is included and integrated with all significant Linux distributions. ALSA also includes an OSS compatibility module so that older OSS-only applications can use ALSA drivers.
MMUSBAUDIO was created before ALSA contained USB audio device support and is being maintained because it provides somewhat more reliable OSS compatibility than ALSA. It can also be useful if you wish to avoid the configuration complexity and module overhead associated with ALSA. MMUSBAUDIO can coexist side-by-side with ALSA, as described below.
Note that the "Advanced Mode" on the UA-1 and UA-5 is supported by MMUSBAUDIO but NOT by ALSA. Advanced Mode sends/receives 24-bit audio words to/from the device with a vendor-specific device class. "Basic Mode" sends/receives 16-bit audio words with the standard USB audio device class. ALSA does support Basic Mode and these devices can be used with ALSA by setting the Basic/Advanced switch on the device to "Basic". (reference)
MMUSBAUDIO is available as source code only and compilation is not slow or difficult. MMUSBAUDIO should compile with no problem on Red Hat/Fedora or Ubuntu installations that use 2.6 kernels. The Makefile may require some tweaking on other installations.
From a terminal, execute the following to decompress the source into a "mmusbaudio" directory:
$ tar -zxvf mmusbaudio-*.tar.gz $ cd mmusbaudio
Make: AS SUPERUSER, perform a simple make and make install. The makefile should detect whether to use the 2.4 or 2.6 version.
$ make $ sudo make install $ sudo modprobe mmusbaudio
Compliation problems: Since there is no config script, system config problems will be detected during make.
You must have the Linux kernel headers installed - sudo apt-get install linux-headers-generic on Ubuntu. Otherwise compliation will die with a message like this:
make: *** /lib/modules/2.6.35-30-generic/build: No such file or directory. Stop.
If your kernel does not have the legacy OSS device registration stubs enabled (and most contemporary distros do not), you will get messages like this and you will need to use mmsoundcore (described below):
WARNING: "register_sound_midi" [/home/michael/mmusbaudio/mmusbaudio.ko] undefined! WARNING: "register_sound_mixer" [/home/michael/mmusbaudio/mmusbaudio.ko] undefined! WARNING: "unregister_sound_dsp" [/home/michael/mmusbaudio/mmusbaudio.ko] undefined! WARNING: "register_sound_dsp" [/home/michael/mmusbaudio/mmusbaudio.ko] undefined! WARNING: "unregister_sound_mixer" [/home/michael/mmusbaudio/mmusbaudio.ko] undefined! WARNING: "unregister_sound_midi" [/home/michael/mmusbaudio/mmusbaudio.ko] undefined!
If you ignore these warnings, attemps to load the module will result in failure message and errors like this in dmesg:
[ 696.359256] mmusbaudio: no symbol version for unregister_sound_midi [ 696.359268] mmusbaudio: Unknown symbol unregister_sound_midi (err -22) [ 696.359629] mmusbaudio: no symbol version for unregister_sound_mixer [ 696.359635] mmusbaudio: Unknown symbol unregister_sound_mixer (err -22) [ 696.359905] mmusbaudio: no symbol version for register_sound_dsp [ 696.359911] mmusbaudio: Unknown symbol register_sound_dsp (err -22) [ 696.362304] mmusbaudio: no symbol version for unregister_sound_dsp [ 696.362313] mmusbaudio: Unknown symbol unregister_sound_dsp (err -22) [ 696.362559] mmusbaudio: no symbol version for register_sound_mixer [ 696.362565] mmusbaudio: Unknown symbol register_sound_mixer (err -22) [ 696.363286] mmusbaudio: no symbol version for register_sound_midi [ 696.363291] mmusbaudio: Unknown symbol register_sound_midi (err -22)
mmsoundcore: Since ALSA has superseded OSS as the standard sound system in most distributions, the kernels commonly do not include the legacy register_* and unregister_* functions needed to use OSS device drivers. MMUSBAUDIO includes a an optional module called mmsoundcore that implements these functions. It is in the mmsoundcore subdirectory of the source code and should be compiled and installed like the mmusbaudio module.
$ cd mmsoundcore $ make $ sudo make install $ sudo modprobe mmsoundcore $ cd .. $ make $ sudo make install $ sudo modprobe mmusbaudio
Note that after mmsoundcore is made and installed, the mmusbaudio module must be compiled again. The mmsoundcore compilation copies its Module.symvers file up to the main mmusbaudio directory so that mmusbaudio knows to use the OSS registration functions in mmsoundcore. Otherwise you will get linker warnings about undefined symbols and the module will not load.
Spurious dmesg Warnings: As of this writing, the device_add() called by mmsoundcore throws some nasty looking stack dumps into dmesg when a device is plugged in. This seems to be a bug of some kind and the messages can be ignored
[ 1147.848380] ------------[ cut here ]------------ [ 1147.848400] WARNING: at /build/buildd/linux-2.6.35/fs/sysfs/dir.c:451 sysfs_add_one+0xa1/0x110() [ 1147.848407] Hardware name: 1000HD [ 1147.848411] sysfs: cannot create duplicate filename '/devices/virtual/mmsoundcore' [ 1147.848548] Pid: 21, comm: khubd Tainted: G W 2.6.35-30-generic #54-Ubuntu [ 1147.848554] Call Trace: [ 1147.848570] [] warn_slowpath_common+0x72/0xa0 [ 1147.848579] [ ] ? sysfs_add_one+0xa1/0x110 [ 1147.848587] [ ] ? sysfs_add_one+0xa1/0x110 [ 1147.848595] [ ] warn_slowpath_fmt+0x33/0x40 [ 1147.848604] [ ] sysfs_add_one+0xa1/0x110 [ 1147.848612] [ ] create_dir+0x61/0xa0 [ 1147.848621] [ ] sysfs_create_dir+0x71/0xb0 [ 1147.848630] [ ] kobject_add_internal+0x92/0x1d0 [ 1147.848639] [ ] kobject_add_varg+0x2d/0x50 [ 1147.848646] [ ] kobject_add+0x2c/0x60 [ 1147.848658] [ ] get_device_parent+0x15b/0x1c0 [ 1147.848667] [ ] device_add+0x79/0x3b0
Configure to load on boot: OSS assigns audio devices (i.e. /dev/dsp, /dev/dsp1, etc.) on a first-come, first-serve basis, which may load the system's native card driver first and give MMUSBAUDIO /dev/dsp1. If you want your USB device to be your primary sound device, you will need to manually edit the module configuration files.
If you use your USB sound device primarily with audio players or recorders, the following load configuration step is not necessary. Load behavior depends on the order of boot scripts on your particular distribution and if you have your USB device plugged in at boot time, the USB stack may be loaded before ALSA, assigning the USB device to /dev/dsp (and effectively disabling flash audio). The only reliable course of action is to plug in the USB device after booting up, assuring that /dev/dsp2 will be assigned to the USB device.
Your computer's native audio card is probably configured in one of three files (depending on kernel version and distribution): /etc/modprobe.conf, /etc/modprobe.d/sound (Debian) or /etc/modules.conf (2.4 kernels). You should comment out any lines that begin with "alias sound". An example from my Toshiba 1905 (with a i810 audio chip) is given below:
#alias sound-slot-0 audio #alias sound-slot-0 i810_audio alias sound-slot-0 mmusbaudio alias sound-service-0-0 off
Also note the "sound-service" line. Because MMUSBAUDIO does not support /dev/mixer, applications that use /dev/mixer (such as the old xmms) will work with MMUSBAUDIO but write a huge number of error messages to /var/log/messages. Turning sound service 0 (the mixer) to slot 0 (the primary sound device)
Coexisting with ALSA: MMUSBAUDIO can exist side-by-side with ALSA if you want ALSA to support other audio devices such as an internal sound card. However you will need to remove the snd-usb-audio kernel module (/lib/modules/*/kernel/sound/usb/snd-usb-audio.ko or /lib/modules/*/ubuntu/sound/alsa-driver/usb/snd-usb-audio.ko on Ubuntu) so it doesn't claim the device before MMUSBAUDIO. USB devices will register with soundcore and be available as /dev/dsp*. After pluggin in / powering up the USB device, you can execute a dmesg command to list exactly which devices are assigned.
On some distributions (like Fedora), /dev/dsp devices are created by udev with 660 protection, making the device inaccessible to non-root users. That can be changed by adding this line to one of the udev rules files (/etc/udev/rules.d/50-udev-default.rules):
# OSS audio devices KERNEL=="dsp*" MODE="0666"
Unfortunately, the current versions of the Adobe Flash Player for Linux are hard-coded to use ALSA and cannot be directly configured to use OSS or MMUSBAUDIO. There are workarounds, but they are not for the faint of heart.
OSS version 4 includes the libflashsupport library which permits Flash to use OSS and, accordingly, MMUSBAUDIO. From the code, this library seems to have originated from Adobe and is some kind of compatibility layer between Flash and the underlying sound system.
The libflashsupport packages for Ubuntu and Fedora are set up for the PulseAudio daemon, and unless you're running PulseAudio, you will need to compile libflashsupport from source.
Download the OSS v.4 source code from the OSS developer site and decompress it. The library source code is located in the oss/lib subdirectory of the main code directory.
bunzip2 oss*.bz2 tar -xvf oss* cd oss*/oss/lib
Configure: If your MMUSBAUDIO device is something other than /dev/dsp (i.e. you start the USB device after the internal sound card is loaded - see above), you will want to change the OSS device name, which is configured as a constant in the open_dsp() function in flashsupport.c. Edit that file and change:
char s[1024] = "", *devdsp = "/dev/dsp", *home; to char s[1024] = "", *devdsp = "/dev/dsp2", *home;
Compile the code into a shared library and install it in /usr/lib:
cc -shared -fPIC -m32 -O2 -Wall flashsupport.c -o libflashsupport.so sudo install -s libflashsupport.so /usr/lib sudo ldconfig
If you get an error like:
/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory
You will need to install the package libc6-dev-i386 (on Ubuntu/Debian) or glibc-devel (on Fedora/RedHat).
sudo apt-get install libc6-dev-i386
Plug in the USB device and restart your browser. The audio of Flash videos should now be heard in your USB device.
Alternatively, you might consider Gnash an alternative GNU player for SWF files
The Roland UA-5 is a USB audio convertor providing 24-bit audio at 44.1 / 48 / 96 KHz sampling rates through balanced or unbalanced connectors. Roland UA-100 is a USB desktop music production tool providing MIDI input/output and 16-bit / 44.1KHz digital audio. The Roland UA-1EX is a small USB device that provides 16- and 24-bit audio at 32/44.1/48/96 KHz with unbalanced RCA or Toslink optical connectors.
MMUSBAUDIO provides access to the MIDI ports of the Roland UA-100, UM-1 and SC-8850 through the /dev/midixx device files. The exact file names (i.e. /dev/midi00, /dev/midi01) are assigned dynamically and therefore system dependent. Despite an extraordinary effort, I was unable to get MMUSBAUDIO to work with /dev/sequencer due to the arcane complexity of the OSS interface. Therefore, MMUSBAUDIO MIDI devices will not be visible under /dev/sequencer and any program (such as playmidi or kmid) that uses /dev/sequencer will not work with MMUSBAUDIO.
MMUSBAUDIO provides output conversion for 8, 16, and 24 bit PCM (Little Endian) audio. The UA-100 supposedly has the capability for 20-bit audio, but I couldn't figure out how to access it and it's obsolete in this 24-bit world anyway. Although the UA-100 has two stereo audio output channels (i.e. two stereo D/A convertors or four channels), the USB protocol requires sending data for both channels simultaneously. To simplify implementation, only one audio device file (i.e. /dev/dsp or /dev/dsp1) is provided. While it writes stereo output only to the first output channel, it supports quadraphonic (4-channel) writes which write to both but is useless because the UA-100 has only two analog output connectors.
The UA-5 and UA-1EX provide full-duplex playback/recording at 44.1Khz and 48Khz, but will allow you to only play OR record at 96Khz. Sample rate on the UA-5 is selected by a knob on the front of the device and the device must be powered off/on to change the rate - simply turning the knob without rebooting the device will change nothing. MMUSBAUDIO automatically detects the selected rate. MMUSBAUDIO's sample rate conversion algorithm is very rudamentary and you will get significant audio artifacts when playing at a different rate from the device. MMUSBAUDIO provides no record rate conversion.
The Focusrite Sapphire 6 is a 48 Khz / 16-bit USB 1.1 interface that uses vendor specific endpoints. Supposedly it contains Focusrite's distinctive and legendary preamp design, although the fact that its price point is significantly below what their stand-alone preamps cost, I suspect this is just an ordinary USB audio interface with Focusrite's name stamped on it. I attempted to stream audio to and from the isochronous endpoints and successfully got audio input and output. However, the device will periodically and unpredictably lock up, requiring replugging. Unless I got a bad piece of hardware, there may be other components to the protocol needed to work with this device than simple streaming of audio packets. As of this writing ALSA does not support this device. You can use MMUSBAUDIO with this device, but the aforementioned lockups will likely make the device too inconvienent to work with. A Linux USB device dump listing is provided below.
All of the supported devices use protocols similar to the USB-Audio and USB-MIDI standards. Therefore, MMUSBAUDIO should be relatively easy to upgrade for other devices.
The Makefile may require tweaking on some distributions. Audio input and output is relatively clean on my 600Mhz and 2.4Ghz laptops. There are occasional timing glitches that result in sporadic tics and dropouts, but this seems to be related to the fact that unmodified Linux is not a real-time OS.
MMUSBAUDIO provides no /dev/mixer support for either the UA-100 or UA-5.
Edirol, Roland's desktop music hardware distributor in the United States, has declined either to develop Linux drivers or provide specs so the open source community could develop a driver. Therefore, MMUSBAUDIO was developed based on work done by other Linux devlopers as well as USB traces on Windoze and extensive experimentation. As such, I cannot guarantee full-featured and problem-free operation and this product is offered to the open-source community without a warranty of any kind.
MMUSBAUDIO comes with mmusbplay and mmusbrecord, two simple command line utilities for playing and recording to .wav files:
mmusbplay wav_file [dsp_device] mmusbrecord [ -d dsp_device ] [ -r sample_rate] [ -b bit_resolution ] output_file
They are provided primarily for testing MMUSBAUDIO. They both play/record 24-bit/96Khz audio with the UA-5. 24/96 audio is not supported by other OSS devices. They do not support any file format other than .wav (i.e. RIFF).
Device Files:
Initial Test: You should initially test mmusbaudio with mmusbplay, a simple program included in the mmusbaudio tarball for playing .wav sound files. You will need an .wav audio file, which is called audio.wav below but can be named anything you want:
$ mmusbplay audio.wav
Ripping a .wav file: If you do not have a .wav file on your Linux or Windoze partitions, you can "rip" one from a CD using the cdda2wav program that ships with most Linux distributions. Insert a CD in your computer's CD-ROM drive and type the following. If you want to use something other than track #1, change the number after the -t option. You can also change "audio" to any file name you want.
$ cdda2wav -D /dev/cdrom -t 1 audio.wav
Audio Players: If you are getting audio output with mmusbplay, you should be able to use any audio program that can be configured to use OSS (i.e. /dev/dsp). Personally, I use XMMS (the X multimedia system), a player similar to winamp that comes with many standard Linux distributions.
ALSA Library Problems: Because of the ubiquity of ALSA, many audio programs are initially configured to use the ALSA sound libraries, which will not work with MMUSBAUDIO. For example, if the "play" script (which uses usually uses SOX) is setup to use ALSA, you may get messages like this:
# play -d /dev/dsp audio.wav ALSA lib pcm.c:2146:(snd_pcm_open_noupdate) Unknown PCM /dev/dsp sox: Failed writing /dev/dsp: cannot open audio device
Error Messages: The MMUSBAUDIO kernel module lists it's operational and error messages to the /var/log/messages system file, which can be viewed with the "dmesg" command. You can also open the file directly with "vi" as superuser. If MMUSBAUDIO is loading successfully, there should be messages somewhere near the end of the listing indicating which device files are being used, which should look something like this:
Jun 23 16:43:10: MMUSBAUDIO: Linux USB Driver for Roland MIDI interfaces v2008.03.21 Jun 23 16:43:10: MMUSBAUDIO: Registered UA-100 as /dev/dsp - interface 1/0, endpoint 1 Jun 23 16:43:10: MMUSBAUDIO: Registered UA-100 A as /dev/midi00 Jun 23 16:43:10: MMUSBAUDIO: Registered UA-100 B as /dev/midi01 Jun 23 16:43:10: MMUSBAUDIO: Registered UA-100 CTRL as /dev/midi02
This indicates that the audio device is /dev/dsp and the three MIDI ports (two in/out ports and one port for UA-100 control messages) are /dev/midi00, /dev/midi01 and /dev/midi02.
USB Device Listing: If you can't find these messages, perhaps MMUSBAUDIO was not loaded. You can verify that the USB subsystem has successfully recognized both MMUSBAUDIO and your hardware by typing:
$ cat /proc/bus/usb/devices
You will get some rather cryptic output giving information about the USB devices connected to your computer. At the end of the list should be something that looks like this
C:* #Ifs= 3 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=01(Isoc) MxPS= 0 Ivl= 1ms I: If#= 0 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=01(Isoc) MxPS= 360 Ivl= 1ms I: If#= 1 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=81(I) Atr=01(Isoc) MxPS= 0 Ivl= 1ms I: If#= 1 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=81(I) Atr=01(Isoc) MxPS= 184 Ivl= 1ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=02(O) Atr=02(Bulk) MxPS= 32 Ivl= 1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 32 Ivl= 1ms I: If#= 2 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=02(O) Atr=02(Bulk) MxPS= 32 Ivl= 1ms E: Ad=82(I) Atr=03(Int.) MxPS= 32 Ivl= 2ms
The UA-5 will give a listing similar to the one below. The exact listing depends on the sampling frequency.
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=ff(vend.) Sub=00 Prot=ff MxPS= 8 #Cfgs= 1 P: Vendor=0582 ProdID=0010 Rev= 1.00 S: Manufacturer=Roland S: Product=EDIROL UA-5 C:* #Ifs= 4 Cfg#= 1 Atr=c0 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none) I: If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio I: If#= 1 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=09(Isoc) MxPS= 288 Ivl=1ms I: If#= 2 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none) I: If#= 2 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none) E: Ad=82(I) Atr=05(Isoc) MxPS= 288 Ivl=1ms I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none) E: Ad=03(O) Atr=02(Bulk) MxPS= 8 Ivl=0ms E: Ad=84(I) Atr=02(Bulk) MxPS= 8 Ivl=0ms
This is a listing of the "endpoints" used for reading and writing to the MMUSBAUDIO. The important part is "Driver=mmusbaudio". If it reads "Driver=(none)", the USB subsystem has not recognized MMUSBAUDIO. If it reads "Driver=midi", that is fine because it is connected to the USB-MIDI class driver. Some endpoints are not used by MMUSBAUDIO, but at least one interface should indicate Driver=mmusbaudio. If you can't find anything like these lines in the listing, the USB subsystem has not detected your hardware and you should verify that your cable is connected correctly and the device is on.
Manual Load / Unload: You can manually load MMUSBAUDIO with the modprobe command AS SUPERUSER:
/sbin/modprobe mmusbaudio
You can also load modules with the insmod command AS SUPERUSER:
/sbin/insmod soundcore /sbin/insmod mmusbaudio
The modules can be unloaded with rmmod:
/sbin/rmmod mmusbaudio
The OSS mixer mechanism is inadequate for dealing with internal signal paths are as complex as the UA-100s. Therefore, I implemented UA100MIX, a MOTIF/LESSTIF graphical mixer interface for controlling the internal mixer and effects of the UA-100. This will not, of course, work with other USB MIDI devices like the UM-1.
There are some quirks to the order of SYSEX messages that the UA-100 needs and you may need to click on selection boxes more than once to get the commands to work. The UA-100 has an extensive collection of audio effects and while capability for turning them on has been provided, only a handful of the dialogs needed to adjust the parameters for each effect have been written. Because the UA-100 is obsolete, no further fixes or upgrades are planned for UA100MIX.
Compilation of UA100MIX will require some MOTIF library (such as LessTif or OpenMotif) which is usually included in most distributions. Because the UA-100 is obsolete, UA100MIX does not compile by default and must be explicitly made and copied to the binary directory of your choice.
make ua100mix
If you get compile errors when making ua100mix that indicate there is no "Xm.h" file, you probably do not have a MOTIF library installed on your system. You can easily download one from the LESSTIF web site.
The executable is called "ua100mix" and can be started by typing that on an X-Windows console.
The mixer assumes some familiarity with the audio paths of the UA-100. There are five channels:
Note that there is no recording level control. I have found that in practice, recording level should be set by the analog controls to maximize digital headroom on recorded tracks.
For each channel:
The UA-100 has the capability for either ONE very complex effect (FULL EFFECT) that can be applied to any input or assigned to one of the two system effects busses, OR THREE "compact" effects: an insertion effect that can be applied to one input and two system effects (a chorus and a reverb or delay) that are applied to the system effects busses. These are selected with the four buttons on the right of the UA100MIX dialog. Note that if a FULL effect is selected, the INSERTION and SYSTEM effects are turned off...and vice-versa.
The type of effect is selected in a combo box at the top of the appropriate dialog. THE PARAMETERS FOR MOST EFFECTS HAVE NOT BEEN IMPLEMENTED YET. When you select an effect, the default settings are applied for now. For the few effects with parameters, the meaning of a slider can be discerned by holding the mouse pointer over a slider...a tooltip bubble will pop up describing the purpose of the slider. This was chosen over short cryptic names to preserve space.
FULL effects can be applied to any input or to one of the two system effects busses. INSERTION effects can be applied to any input. The selection of where the effect is placed is a combo box next to the effect type combo box.
UA100MIX has the capability to save and load settings to/from the same .uax files that the MS-Windows version of the the mixer uses. This capability has not been tested extensively and is probably buggy.
UA100MIX works by sending system exclusive (SYSEX) messages to the UA-100 control port. The code (around line 302) contains a hard-coded string that defines this device as /dev/midi02 - which will be the device name if MMUSBAUDIO is used on a system where the UA-100 is the only MIDI device. You can change the MIDI device in the File->Midi Port dropdown menu when the program is running, although this change does not persist between invocations of the program. For a permanent change, you must alter the line in the source code
The UA-100 ships with a CD containing some awkwardly written HTML reference materials that are installed with the MS-Windows software in "/Program Files/Roland". If you have the UA-100 software installed on your Windows partition, you may want to consult this material for further details. You can also copy it off of the CD-ROM into a Linux directory.
Although the device descriptor for the UA-100 indicates that it is vendor specific, the MIDI implementation appears to comply with the official MIDI Device Class Definition. The MIDI endpoints of the UA-100 as well as the UM-1 and SC-8850 can also be accessed with USB-MIDI, the semi-official Linux USB MIDI class driver. However, I am not sure if you can use the class driver (yet) to access more than one of the MIDI ports (called Cable ID in the class driver), thus making it impossible to use both a MIDI output port and the UA-100 system control port for mixer control sysex MIDI messages. For that reason (and for convenience) MIDI endpoint handling is provided in MMUSBAUDIO.
The audio implementation is a bit more complex and non-standard. The module source code provides further documentation if you're interested.
I did make a request to the people at Edirol (the American distributor of Roland's desktop music products) for specs. Their response was that no Linux drivers were currently planned and that it would be difficult for them to provide me with enough complete information to develop a driver.
On a side note, I had problems with depmod issuing errors for unresolved symbols from usbcore.o and even some kernel symbols (like kmalloc). The solution is to include the linux/modversions.h file in the module source.
MIDI data is sent and received to/from the bulk transfer endpoints (interface #2, alternate 0, endpoints 0x02 and 0x82) in 4-byte chunks with a preceeding "burst" byte that indicates the destination/source port for following 3 bytes of data. All MIDI messages under status 0xf0 (SYSEX) are two or three bytes long and fit in a single 4-byte chunk. Messages over status byte 0xf0 are split into multiple consecutive chunks with the appropriate burst bytes specified below.
For MIDI sends, the upper 4 bits of the "burst" byte are the source/destination port (described below). The lower 4 bits are either the upper 4 bits of the MIDI message status byte, 4 for the beginning or middle of a SYSEX message, 6 if there are two bytes in the last SYSEX chunk, and 5 if there is one byte in the last chunk of a SYSEX message. For MIDI receives the protocol is basically the same with the upper four bits representing the input port.
Example: 19 90 30 70 is a note on message sent to port 2.
For UA-100 sends, the "burst byte" is 0x00 for MIDI OUT 1, 0x10 for MIDI OUT 2 and 0x20 for the UA-100 control port which receives SYSEX messages to change the internal mixer and effect settings. MIDI receives are basically the same: 0x00 for MIDI IN 1 and 0x00 for MIDI IN 2.
For the UM-1, there is only one input and output port, so the upper 4 bits of the "burst byte" are always 0x00.
For the SC-8850, the "burst byte" indicates which of the four "parts" (i.e. 16-channel banks) should receive the MIDI output: 0x00 for Part A, 0x10 for Part B, 0x20 for Part C and 0x30 for Part D. However, unlike the other devices, for MIDI input: 0x40 for MIDI IN 1 and 0x50 for MIDI IN 2
Chunks smaller than 4 bytes (such as two-byte program change messages) are padded with trailing NULLs to a 4-byte length.
I desperately attempted to find a way to provide a way of registering the MIDI ports so they could be used by /dev/sequencer, but there are apparently some interrupts used by /dev/sequencer that caused the USB subsystem to issue some cryptic interrupt messages.
On the UA-100 Audio data is written using a isosynchronous transfers to interface #0, address #1, alternate #1 for output and interface #1, address #81, alternate #1 for input. URBs are sent isosynchronously (e.g. urb->transfer_flags = USB_ISO_ASAP). While the 2.4 kernel versions of MMUSBAUDIO submitted URBs on demand from the write() function, the current versions use an internal ring buffer and recycles URBs from the completion callbacks. This technique is also used by the ALSA drivers.
To time isosynchronous writes correctly and provide minimal latency, each URB contains 1ms of data. Since 1ms at 44.1Khz equals 44.1 samples, URBs are sent with 44 samples but every 10th URB contains 45 samples.
With the UA-5, 48Khz and 96Khz rates divide evenly on 1ms boundaries so this variable length protocol is unnecessary at those rates.
For Reads, however, each frame must be sent at full length (184 bytes) or you will get a nasty kernel message in /var/log/messages: "usb-uhci.c: interrupt, status 2, frame# xxx" The "actual_length" field of each packets indicates the (variable) number of bytes returned in each packet.
Previous versions of MMUSBAUDIO used write URBs contain 10 isosynchronous packets totaling 441 samples apiece, i.e. 10ms per URB at 44.1Khz sample rate. This works out to 3528 bytes for write URBs with 8 byte samples (two 16-bit stereo channels) as nine packets of 352 bytes and one packet of 360 bytes. However, this scheme increased latency so the variable length URB scheme is used instead.
UA-100 interleaves 16-bit/44Khz PCM samples for the two output devices: L1, R1, L2, R2. If input is stereo, MMUSBAUDIO sends the data only to output device WAVE 1. If input is mono, MMUSBAUDIO sends the data to both channels of WAVE 1. Since MMUSBAUDIO sends URBs on demand, rather than continuously with a circular buffer as in the Linux audio class driver, it was not possible to create two separate Linux devices for wave 1 and wave 2. The UA-5 always sends/receives two channels of 24-bit audio (i.e. 6 bytes per sample)
Upgrade of MMUSBAUDIO for the 2.6 kernel was a massive pain since I chose to also move to a ring-buffer instead of URB submission on-demand.
The biggest problem was that when calling usb_unlink_urb() with the outbound URBs when closing the write() stream, some URBs would not unlink, even though their completion handler has been called. The usb_unlink_urb() function will return -ENODEV because the urb-"dev pointer is NULL and the URB structure seems to be filled with spurious data.
Calling usb_free_urb() with the mystery URB will result in a kjournald system crash. Because this affects writes to journaled file systems like EXT3 or REISERFS, this error is not logged and the system will simply freeze. I was only able to find this by testing from the console (without X Windows) and watching the error messages on the terminal.
This seemed to be related to my memset(0) to clear newly allocated URBs. usb_alloc_urb() apparently does more than just kmalloc() and this was causing problems. However, I am leaving in my old kludge to simply leave any errant URBs unfreed. This means that some URBs probably get stuck somewhere in kernel memory and will probably result in the exhaustion of kernel memory and some kind of kernel destabilization if the module is used frequently on a system that stays on for long durations. Be forewarned and if you have a solution, write me.
Note that any unfreed URBs are logged in /var/log/messages and you can observe for yourself how often this problem is occurring.
The other changes between 2.4 and 2.6 primarily involve the USB structures and function call parameters. One oddity - although the urb->interval field was always set to zero with isochronous transfers in the 2.4 kernel, it has to be set to non-zero for or usb_submit_urb() returns -EINVAL.
References:
Audio Device Class Definition
Audio Data Formats Definition
MIDI Device Class Definition
Intel USB Documentation Page
/proc/bus/usb/devices listings --------------- == Edirol UA-1EX == T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=ff(vend.) Sub=00 Prot=ff MxPS= 8 #Cfgs= 1 P: Vendor=0582 ProdID=0096 Rev= 1.00 S: Manufacturer=EDIROL S: Product=UA-1EX C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=200mA I: If#= 0 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=02 Prot=00 Driver=(none) I: If#= 0 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=02 Prot=00 Driver=(none) E: Ad=01(O) Atr=09(Isoc) MxPS= 288 Ivl=1ms I: If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=02 Prot=00 Driver=(none) I: If#= 1 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=02 Prot=00 Driver=(none) E: Ad=82(I) Atr=05(Isoc) MxPS= 288 Ivl=1ms == Edirol UA-5 == T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=ff(vend.) Sub=00 Prot=ff MxPS= 8 #Cfgs= 1 P: Vendor=0582 ProdID=0010 Rev= 1.00 S: Manufacturer=Roland S: Product=EDIROL UA-5 C:* #Ifs= 4 Cfg#= 1 Atr=c0 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio I: If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio I: If#= 1 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=09(Isoc) MxPS= 288 Ivl=1ms I: If#= 2 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio I: If#= 2 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=82(I) Atr=05(Isoc) MxPS= 288 Ivl=1ms I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=03(O) Atr=02(Bulk) MxPS= 8 Ivl=0ms E: Ad=84(I) Atr=02(Bulk) MxPS= 8 Ivl=0ms == Roland SC-8850 == T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=ff(vend.) Sub=00 Prot=ff MxPS= 8 #Cfgs= 1 P: Vendor=0582 ProdID=0003 Rev= 1.11 C:* #Ifs= 3 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none) I: If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none) I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I: If#= 2 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=2ms == Roland UA-100 == T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=ff(vend.) Sub=00 Prot=ff MxPS= 8 #Cfgs= 1 P: Vendor=0582 ProdID=0000 Rev= 1.09 C:* #Ifs= 3 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 0 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=01(O) Atr=01(Isoc) MxPS= 360 Ivl=1ms I: If#= 1 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=81(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=81(I) Atr=01(Isoc) MxPS= 184 Ivl=1ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=02(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms I: If#= 2 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=mmusbaudio E: Ad=02(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms E: Ad=82(I) Atr=03(Int.) MxPS= 32 Ivl=2ms == DigiTech GSP 1101 (rackmount guitar efx box) == T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=1210 ProdID=0011 Rev= 0.01 S: Manufacturer=DigiTech S: Product=DigiTech GSP1101 C:* #Ifs= 5 Cfg#= 1 Atr=60 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=00 Driver=(none) I: If#= 1 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=00 Driver=(none) I: If#= 1 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=00 Driver=(none) E: Ad=01(O) Atr=0d(Isoc) MxPS= 192 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 1 Cls=01(audio) Sub=02 Prot=00 Driver=(none) E: Ad=01(O) Atr=0d(Isoc) MxPS= 288 Ivl=1ms I: If#= 2 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=00 Driver=(none) I: If#= 2 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=00 Driver=(none) E: Ad=82(I) Atr=0d(Isoc) MxPS= 192 Ivl=1ms I: If#= 2 Alt= 2 #EPs= 1 Cls=01(audio) Sub=02 Prot=00 Driver=(none) E: Ad=82(I) Atr=0d(Isoc) MxPS= 288 Ivl=1ms I: If#= 6 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=00 Driver=(none) I: If#= 7 Alt= 0 #EPs= 2 Cls=01(audio) Sub=03 Prot=00 Driver=(none) E: Ad=04(O) Atr=02(Bulk) MxPS= 16 Ivl=0ms E: Ad=84(I) Atr=02(Bulk) MxPS= 16 Ivl=0ms == Line 6 PODxt Live (guitar effects box - NOT SUPPORTED) == T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=ff(vend.) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0e41 ProdID=4650 Rev= 0.01 S: Manufacturer=Line 6 S: Product=PODxt Live C:* #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr= 98mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) E: Ad=01(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=82(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 0 Alt= 1 #EPs= 4 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) E: Ad=01(O) Atr=01(Isoc) MxPS= 240 Ivl=1ms E: Ad=82(I) Atr=01(Isoc) MxPS= 252 Ivl=1ms E: Ad=03(O) Atr=03(Int.) MxPS= 16 Ivl=5ms E: Ad=84(I) Atr=03(Int.) MxPS= 16 Ivl=5ms I: If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) E: Ad=05(O) Atr=03(Int.) MxPS= 16 Ivl=5ms E: Ad=86(I) Atr=03(Int.) MxPS= 16 Ivl=5ms == Focusrite Sapphire 6 (PARTIAL SUPPORT) == Bus 007 Device 006: ID 1235:0010 Novation EMS Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x1235 Novation EMS idProduct 0x0010 bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 64 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 498mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 1 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 1 Transfer Type Isochronous Synch Type None Usage Type Data wMaxPacketSize 0x024c 1x 588 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 1 Transfer Type Isochronous Synch Type None Usage Type Data wMaxPacketSize 0x0126 1x 294 bytes bInterval 1 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0010 1x 16 bytes bInterval 1 == Zoom B2.1U Bass Effects Pedal == Bus 007 Device 004: ID 08bb:2904 Texas Instruments Japan PCM2904 Audio Codec Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x08bb Texas Instruments Japan idProduct 0x2904 PCM2904 Audio Codec bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 1191 bNumInterfaces 4 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 1 Control Device bInterfaceProtocol 0 iInterface 0 AudioControl Interface Descriptor: bLength 10 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 1.00 wTotalLength 62 bInCollection 2 baInterfaceNr( 0) 1 baInterfaceNr( 1) 2 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 1 wTerminalType 0x0101 USB Streaming bAssocTerminal 0 bNrChannels 2 wChannelConfig 0x0003 Left Front (L) Right Front (R) iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 2 wTerminalType 0x0301 Speaker bAssocTerminal 0 bSourceID 3 iTerminal 0 AudioControl Interface Descriptor: bLength 10 bDescriptorType 36 bDescriptorSubtype 6 (FEATURE_UNIT) bUnitID 3 bSourceID 1 bControlSize 1 bmaControls( 0) 0x01 Mute bmaControls( 1) 0x02 Volume bmaControls( 2) 0x02 Volume iFeature 0 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 4 wTerminalType 0x0201 Microphone bAssocTerminal 0 bNrChannels 2 wChannelConfig 0x0003 Left Front (L) Right Front (R) iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 5 wTerminalType 0x0101 USB Streaming bAssocTerminal 0 bSourceID 4 iTerminal 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 3 Discrete tSamFreq[ 0] 32000 tSamFreq[ 1] 44100 tSamFreq[ 2] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 9 Transfer Type Isochronous Synch Type Adaptive Usage Type Data wMaxPacketSize 0x00c0 1x 192 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 512 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 2 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 3 Discrete tSamFreq[ 0] 32000 tSamFreq[ 1] 44100 tSamFreq[ 2] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 9 Transfer Type Isochronous Synch Type Adaptive Usage Type Data wMaxPacketSize 0x0060 1x 96 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 512 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 3 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 1 bBitResolution 8 bSamFreqType 3 Discrete tSamFreq[ 0] 32000 tSamFreq[ 1] 44100 tSamFreq[ 2] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 9 Transfer Type Isochronous Synch Type Adaptive Usage Type Data wMaxPacketSize 0x0060 1x 96 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 512 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 4 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 1 bBitResolution 8 bSamFreqType 3 Discrete tSamFreq[ 0] 32000 tSamFreq[ 1] 44100 tSamFreq[ 2] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 9 Transfer Type Isochronous Synch Type Adaptive Usage Type Data wMaxPacketSize 0x0030 1x 48 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 512 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 5 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 0 frames wFormatTag 2 PCM8 AudioStreaming Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 1 bBitResolution 8 bSamFreqType 3 Discrete tSamFreq[ 0] 32000 tSamFreq[ 1] 44100 tSamFreq[ 2] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 9 Transfer Type Isochronous Synch Type Adaptive Usage Type Data wMaxPacketSize 0x0060 1x 96 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 512 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 6 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 1 bDelay 0 frames wFormatTag 2 PCM8 AudioStreaming Interface Descriptor: bLength 17 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 1 bBitResolution 8 bSamFreqType 3 Discrete tSamFreq[ 0] 32000 tSamFreq[ 1] 44100 tSamFreq[ 2] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 9 Transfer Type Isochronous Synch Type Adaptive Usage Type Data wMaxPacketSize 0x0030 1x 48 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 512 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x00c4 1x 196 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 2 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0062 1x 98 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 3 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 44100 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x00b4 1x 180 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 4 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 44100 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x005a 1x 90 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 5 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 32000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0084 1x 132 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 6 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 32000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0042 1x 66 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 7 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 22050 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x005c 1x 92 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 8 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 22050 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x002e 1x 46 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 9 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 16000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0044 1x 68 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 10 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 16000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0022 1x 34 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 11 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 1 bBitResolution 8 bSamFreqType 1 Discrete tSamFreq[ 0] 16000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0022 1x 34 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 12 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 1 bBitResolution 8 bSamFreqType 1 Discrete tSamFreq[ 0] 16000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0011 1x 17 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 13 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 1 bBitResolution 8 bSamFreqType 1 Discrete tSamFreq[ 0] 8000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0012 1x 18 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 14 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 1 bBitResolution 8 bSamFreqType 1 Discrete tSamFreq[ 0] 8000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 5 Transfer Type Isochronous Synch Type Asynchronous Usage Type Data wMaxPacketSize 0x0009 1x 9 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 15 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 11025 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x0030 1x 48 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 16 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 1 Discrete tSamFreq[ 0] 11025 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x0018 1x 24 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 17 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 1 bBitResolution 8 bSamFreqType 1 Discrete tSamFreq[ 0] 11025 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x0018 1x 24 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 18 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 5 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 11 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 1 bBitResolution 8 bSamFreqType 1 Discrete tSamFreq[ 0] 11025 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x000c 1x 12 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x00 bLockDelayUnits 2 Decoded PCM samples wLockDelay 0 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.00 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 31 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 10
A listing of the UA-100 SYSEX messages (derived from Roland's documentation) is given below:
Data Transmission F0: Start SysEx 41: Manufacturer (Roland) 10: Device ID 00: Model ID 1 11: Model ID 2 12: Command (Transmit data) aa: Address aa aa: aa: dd: Data dd: ck: checksum = 128 - ((sum of address & data bytes) & 0x3f); f7: end of SysEx Examples: F0 41 10 00 11 12 00 40 02 00 01 00 3D F7 (select Stereo-EQ as Mic2 insertion effect) f0 41 10 00 11 12 00 40 50 03 64 09 f7 (master level of 64) In URB buffer, the message is split into 3 byte chunks with a 24h is placed before every chunk except for a 25h before the final chunk. 24 f0 41 10 24 00 11 12 24 00 40 02 24 00 01 00 25 f7 Note that for messages with multiple data bytes (length > 1), the first data byte (usually the significant one) comes first. ------------------------------------------------------------------------ 00 40 00 00 01 PC Mode (VT Effect Mode) - sent by UA-100? 00 40 00 00 03 PC Mode (Compact Effect Mode) 00 40 00 00 04 PC Mode (Full Effect Mode) 00 40 00 00 05 VT Mode 00 40 00 00 06 Vocal Mode 00 40 00 00 07 Guitar Mode 00 40 00 00 08 GAME Mode 00 40 00 00 09 BYPASS Mode 00 40 00 01 0x Copyright (0 off, 1 on) n = 1 (line, mic1, mic1+2), 2 (mic2), 3 (wave1), 4 (wave2), 5 (sys effect 1), 6 (sys effect 2) 00 40 0n 00 xx 00 Effect type (listed below) 00 40 0n 03 xx Effect parameter 1 00 40 0n 04 xx Effect parameter 2 00 40 0n 05 xx Effect parameter 3 00 40 0n 06 xx Effect parameter 4 00 40 0n 07 xx Effect parameter 5 00 40 0n 08 xx Effect parameter 6 00 40 0n 09 xx Effect parameter 7 00 40 0n 0A xx Effect parameter 8 00 40 0n 0B xx Effect parameter 9 00 40 0n 0C xx Effect parameter 10 00 40 0n 0D xx Effect parameter 11 00 40 0n 0E xx Effect parameter 12 00 40 0n 0F xx Effect parameter 13 00 40 0n 10 xx Effect parameter 14 00 40 0n 11 xx Effect parameter 15 00 40 0n 12 xx Effect parameter 16 00 40 0n 13 xx Effect parameter 17 00 40 0n 14 xx Effect parameter 18 00 40 0n 15 xx Effect parameter 19 00 40 0n 16 xx Effect parameter 20 00 40 0n 17 xx Effect parameter 21 00 40 0n 18 xx Effect parameter 22 00 40 0n 19 xx Effect parameter 23 00 40 0n 1A xx Effect parameter 24 00 40 0n 1B xx Effect parameter 25 00 40 0n 1C xx Effect parameter 26 00 40 0n 1D xx Effect parameter 27 00 40 0n 1E xx Effect parameter 28 00 40 0n 1F xx Effect parameter 29 00 40 0n 20 xx Effect parameter 30 00 40 0n 21 xx Effect parameter 31 00 40 0n 22 xx Effect parameter 32 00 40 0n 23 xx Effect parameter 33 00 40 0n 24 xx Effect parameter 34 00 40 0n 25 xx Effect parameter 35 00 40 0n 26 xx Effect parameter 36 00 40 0n 27 xx Effect parameter 37 00 40 0n 28 xx Effect parameter 38 00 40 0n 29 xx Effect parameter 39 00 40 0n 2A xx Effect parameter 40 00 40 10 00 00 Mic input mode 00 40 10 00 01 Line input mode 00 40 10 00 02 MIC1+MIC2 Mode (not in VT mode) 00 40 10 01 xx Input pan 1 (0 - 40 - 7f) 00 40 10 02 xx Input pan 2 (0 - 40 - 7f) 00 40 10 03 0x Monitor (0 off, 1 on) n = 1 (line, mic1, mic1+2), 2 (mic2), 3 (wave1), 4 (wave2), 5 (sys effect 1), 6 (sys effect 2) 00 40 1n 00 xx Effect 1 send level (full/compact effect mode) 00 40 1n 02 xx Effect 2 send level (full/compact effect mode) 00 40 1n 04 xx Submaster send level (not in VT mode) 00 40 1n 05 xx Fader level (not in VT mode) 00 40 1n 06 0x Mute (0 off, 1 on) 00 40 1n 07 0x Solo (0 off, 1 on) 00 40 40 00 01 VT effect mode 00 40 40 00 03 Compact effect mode (1 insertion + 2 system effects) 00 40 40 00 04 Full effect mode (1 effect) 00 40 40 01 0x Line/Mic1/Mic1+2 insertion effect on/off (0 off, 1 on) 00 40 40 02 0x Mic2 insertion effect on/off (0 off, 1 on) 00 40 40 03 0x Wave1 insertion effect on/off (0 off, 1 on) 00 40 40 04 0x Wave2 insertion effect on/off (0 off, 1 on) 00 40 40 05 0x System effect 1 on/off (0 off, 1 on) 00 40 40 06 0x System effect 2 on/off (0 off, 1 on) 00 40 40 07 xx Effect 1 master return 00 40 40 08 xx Effect 1 submaster return 00 40 40 09 xx Effect 2 master return 00 40 40 0A xx Effect 2 submaster return 00 40 40 0B 0x Vocal Transform 1 receive channel (0 - F) 00 40 40 0C 0x Vocal Transform 1 note enabled (0 off, 1 on) 00 40 40 0D 0x Vocal Transform 1 bend enabled (0 off, 1 on) 00 40 40 0E 0x Vocal Transform 2 receive channel (0 - F) 00 40 40 0F 0x Vocal Transform 2 note enabled (0 off, 1 on) 00 40 40 10 0x Vocal Transform 2 bend enabled (0 off, 1 on) 00 40 50 00 0x Record source (Mixer: 0 line/mic, 1 mic2, 2 wave1, 3 wave2, 4-7 ch 1-4, 8 submaster, 9 master) (VT: 0 line/mic, 1 mic3, 2 wave1, 3 wave2, 4 VT-out, 5 master) 00 40 50 01 0x Output (see record source) 00 40 50 02 xx Recording level 00 40 50 03 xx Master level n = 0 (Voice Transformer), 1 (Vocal), 2 (Guitar), 3 (Game) (NOT FOR PC MODE) 00 40 6n 00 xx Preset effect parameter 1 (0 - 39) 00 40 6n 01 xx Preset effect parameter 2 (0 - 39) 00 40 6n 02 xx Preset effect parameter 3 (0 - 39) 00 40 6n 03 xx Preset effect parameter 4 (0 - 39) 00 40 6n 04 xx Preset effect default Value 1 (0 - 127) 00 40 6n 05 xx Preset effect default Value 2 (0 - 127) 00 40 6n 06 xx Preset effect default Value 3 (0 - 127) 00 40 6n 07 xx Preset effect default Value 4 (0 - 127) 00 40 6n 08 xx Preset effect default Value 5 (0 - 127) 00 40 6n 09 xx Preset effect default Value 6 (0 - 127) 00 40 6n 0A xx Preset effect default Value 7 (0 - 127) 00 40 6n 0B xx Preset effect default Value 8 (0 - 127) 00 40 6n 0C xx Preset effect default Value 9 (0 - 127) 00 40 6n 0D xx Preset effect default Value 10 (0 - 127) 00 40 6n 0E xx Preset effect default Value 11 (0 - 127) 00 40 6n 0F xx Preset effect default Value 12 (0 - 127) 00 40 6n 10 xx Preset effect default Value 13 (0 - 127) 00 40 6n 11 xx Preset effect default Value 14 (0 - 127) 00 40 6n 12 xx Preset effect default Value 15 (0 - 127) 00 40 6n 13 xx Preset effect default Value 16 (0 - 127) 00 40 6n 14 xx Preset effect default Value 17 (0 - 127) 00 40 6n 15 xx Preset effect default Value 18 (0 - 127) 00 40 6n 16 xx Preset effect default Value 19 (0 - 127) 00 40 6n 17 xx Preset effect default Value 20 (0 - 127) 00 40 6n 18 xx Preset effect default Value 21 (0 - 127) 00 40 6n 19 xx Preset effect default Value 22 (0 - 127) 00 40 6n 1A xx Preset effect default Value 23 (0 - 127) 00 40 6n 1B xx Preset effect default Value 24 (0 - 127) 00 40 6n 1C xx Preset effect default Value 25 (0 - 127) 00 40 6n 1D xx Preset effect default Value 26 (0 - 127) 00 40 6n 1E xx Preset effect default Value 27 (0 - 127) 00 40 6n 1F xx Preset effect default Value 28 (0 - 127) 00 40 6n 20 xx Preset effect default Value 29 (0 - 127) 00 40 6n 21 xx Preset effect default Value 30 (0 - 127) 00 40 6n 22 xx Preset effect default Value 31 (0 - 127) 00 40 6n 23 xx Preset effect default Value 32 (0 - 127) 00 40 6n 24 xx Preset effect default Value 33 (0 - 127) 00 40 6n 25 xx Preset effect default Value 34 (0 - 127) 00 40 6n 26 xx Preset effect default Value 35 (0 - 127) 00 40 6n 27 xx Preset effect default Value 36 (0 - 127) 00 40 6n 28 xx Preset effect default Value 37 (0 - 127) 00 40 6n 29 xx Preset effect default Value 38 (0 - 127) 00 40 6n 2A xx Preset effect default Value 39 (0 - 127) 00 40 6n 2B xx Preset effect default Value 40 (0 - 127) 00 40 60 7F 00 Preset effect parameter write --------------------------------------------------------- System Effect 1 0021: Delay 0022: Chorus System Effect 2 0031: Delay 0032: Reverb Full Effects 0011: High Quality Reverb 0012: Mic Simulator 0013: Vocoder 0014: Vocal Multi 0016: Game with 3D Reverb 0300: Rotary Multi (same parameters as insertion #47) 0400: Guitar Multi 1 (same parameters as insertion #48) 0401: Guitar Multi 2 (same parameters as insertion #49) 0402: Guitar Multi 3 (same parameters as insertion #50) 0403: Clean Guitar Multi 1 (same parameters as insertion #51) 0404: Clean Guitar Multi 2 (same parameters as insertion #52) 0405: Bass Multi (same parameters as insertion #53) 0406: Electric Piano Multi (same parameters as insertion #54) 0500: Keyboard Multi ( (same parameters as insertion #55) Insertion Effects 0000: (00) Noise Suppressor 0100: (01) Stereo Equalizer 0101: (02) Spectrum 0102: (03) Enhancer 0103: (04) Humanizer 0110: (05) Overdrive 0111: (06) Distortion 0120: (07) Phaser 0121: (08) Auto Wah 0122: (09) Rotary 0123: (10) Stereo Flanger 0124: (11) Step Flanger 0125: (12) Tremolo 0126: (13) Auto Pan 0130: (14) Compressor 0131: (15) Limiter 0140: (16) Hexa Chorus 0141: (17) Tremolo Chorus 0142: (18) Stereo Chorus 0143: (19) Space D 0144: (20) 3D Chorus 0150: (21) Stereo Delay 0151: (22) Modulation Delay 0152: (23) 3 Tap Delay 0153: (24) 4 Tap Delay 0154: (25) Time Control Delay 0155: (26) Reverb 0156: (27) Gate Reverb 0157: (28) 3D Delay 0160: (29) 2-voice Pitch Shifter 0161: (30) Feedback Pitch Shifter 0170: (31) 3D Auto 0171: (32) 3D Manual 0172: (33) Lo-Fi 1 0173: (34) Lo-Fi 2 0200: (35) Overdrive/Chorus 0201: (36) Overdrive/Flanger 0202: (37) Overdrive/Delay 0203: (38) Distortion/Chorus 0204: (39) Distortion/Flanger 0205: (40) Distortion/Delay 0206: (41) Enhancer/Chorus 0207: (42) Enhancer/Flanger 0208: (43) Enhancer/Delay 0209: (44) Chorus/Delay 020a: (45) Flanger/Delay 020b: (46) Chorus/Flanger 0300: (47) Rotary Multi 0400: (48) Guitar Multi1 0401: (49) Guitar Multi2 0402: (50) Guitar Multi3 0403: (51) Clean Guitar Multi1 0404: (52) Clean Guitar Multi2 0405: (53) Bass Multi 0406: (54) E.Piano Multi 0500: (55) Keyboard Multi 1100: (56) Chorus/Delay 1101: (57) Flanger/Delay 1102: (58) Chorus/Flanger 1103: (59) Overdrive/Distortion1,2 1104: (60) Overdrive/Distortion/Rotary 1105: (61) Overdrive/Distortion/Phaser 1106: (62) Overdrive/Distortion/Auto-wah 1107: (63) Phaser/Rotary 1108: (64) Phaser/Auto-wah
Version 2012.03.10:
Fix compilation problems with file_operations.unlocked_ioctlVersion 2011.08.23:
Add support for file_operations.unlocked_ioctl in kernels above 2.6.34 - fixes compilation errorVersion 2011.07.01:
Add mmsoundcore module to provide legacy OSS register_*/unregister_* functions in new distros
Add support for endpoints with multiple sample rates (default to 44,100 when available)Version 2011.02.07:
Add B2.1U supportVersion 2010.11.21:
Add M-1000 supportVersion 2010.08.19:
Add UA-25 EX supportVersion 2010.07.14:
Partial Focusrite Sapphire 6 supportVersion 2010.03.02:
Fix bug with not seeing interface 0 on UA-1G
assign_roland_audio_device() called with probe interface number to see all endpointsVersion 2010.02.15:
Use file->private_data directly rather than as int: needed to compile in 64-bit architecture
Replaced deprecated info() and err() message calls with pr_info() and pr_err()Version 2009.12.17:
Add support for Ion TTUSB turntable
Implement parsing of standard USB audio class descriptors
Eliminate mmfakealsa from distribution (deprecated by libflashsupport)
Eliminate mmjackplay from distribution (JACK can use OSS)Version 2009.08.03:
Add support for UA-1G (with thanks to Gabriel Hautclocq)Version 2008.11.12:
Changed file_operations structures to be compatible with the 2.6.25 kernel (Fedora Core 9)
Add support for UA-1/5 basic mode (USB audio class)Version 2008.05.12:
Added support for DigiTech GSP 1101
Explored support for Line 6 PODxt Live: proprietary interface, strange playback rate issue
Added detection of standard USB audio class interfaces (class=0x01)Version 2007.06.22:
Additional functions in mmfakealsa: snd_format_mask*, get_period_size_min/max, get_buffer_size_min/max
Increase default buffer size to 100 URBs (100ms)
Fix tarball extraction pathVersion 2007.05.08:
Created mmjackplay so audio files could be mastered through Jamin
Created mmfakealsa (mmfakealsa.so) to permit ALSA-enabled applications to use mmusbaudio via OSS
Added rudamentary support for poll() to permit mmfakealsa mmap-ingVersion 2006.12.29:
Rewrote to eliminate standalone configuration and circular buffer URB resubmission
URB resubmission causing kernel oops with quick Flash player open() and close()
URBs now submitted on demand
Wrote null_audio_device diagnostic module
Add try_module_get(THIS_MODULE) and module_put(THIS_MODULE) to modify module use counter
Module use counter prevents browser crash when rmmod mmusbaudioVersion 2006.10.31:
Bug fix - had a length = copy_from_user() in midi write, which set length to zero and produced no MIDI output
Documentation upgrade for ALSA / SuSE play problems using ALSA librariesVersion 2006.10.10:
Changes for 2.6.15 kernel (Fedora core 5)
Added new file_operations fields unlocked_ioctl and compat_ioctl (new as of 2.6.11 kernel)
Removed open / close / format kernel messages
Fix bug with copy_to/from_user() while in a spin_lock() (see http://lkml.org/lkml/2005/9/9/141)
spinlocks removed from audio_read() - are they needed anywhere?
Fix spurious -512 error in URB loop when device is closedVersion 2006.05.31:
Upgrade to support UA-1EX.
Change mmusbaudio_find_audio_endpoints() to assign devices based on endpoint rather than simply using endpoints as signatures for device type. Needed since UA-1EX and UA-5 use different endpoint addresses.Version 2006.02.09:
Implement fake mixer device so XMMS/ALSA don't clog system logs with error messages
Add time and level display to mmusbrecord
Separate device_channels into device_read and device_write for UA-100
Initial memset(0) of read URB transfer buffer to get rid of nasty start transient when recordingVersion 2005.01.15:
Fix bug not copying R channel when recording stereo.
Fix bug with invalid source index increment causing R channel ticks when playing mono files.Version 2004.11.16:
Extensive rewrite for the 2.6 kernel that uses self-submitting URBs that read from a ring buffer.Version 2004.10.16:
Ignore but acknowledge unused UA-5 interfaces to avoid unnecessary /var/log/messages errors
Discovered SNDCTL_DSP_GETOSPACE is used like poll() by mplayer to get free space - implemented it
Moved mmcdplay to a separate command line project.Version 2004.02.14:
Added a conditional compilation option so MMUSBAUDIO can be compiled to operate either as part of OSS or as a stand-alone module that uses the existing /dev/dsp* and /dev/midi* files.Version 2003.08.09:
Replaced purb_t and urb_t with struct urb - typedefs have been removed in new kernel code
Added hotplugging support (MODULE_DEVICE_TABLE)
Moved UA100MIX source selector to fader from dropdown
Removed preallocation of devices on module load (didn't work anyway)
Simplified format conversions using floating-point indexing
Added correct handling of SNDCTL_DSP_STEREO ioctl for monophonic
Extensive rewrite to support the UA-5
Added MMUSBPLAY and MMUSBRECORDVersion 2003.04.14:
Renamed to MMUSBAUDIO
Moved OSS calls for device reservation to init/cleanup routines so soundcore will allocate devices based on when the module is loaded rather than when the device is turned on. This permits the sound-slot-* assignments in /etc/modules.conf to work consistently (i.e. if mmusbaudio is assigned to /dev/dsp, it will always be /dev/dsp regardless of whether the module is on when the computer is booted)
Makefile cleanup so source includes will be found based on uname -r
Added ioctl SND_DSP_GETFMTS so shell play command will work
Added linux/modversions.h to module source so depmod does not give unresolves symbol errors
Fixed disconnect() to release all devices associated with usb_device - bug caused MIDI devices to be unavailable if rebooting device
Added MMCDPLAYVersion 2003.01.18:
Makefile include path for Red Hat 8.0
Returned to one frame per URB protocol (differing length URBs) to reduce latency;
Added a sleep to retries on usb_set_interface() to reduce timeout errors on open
Handling for SNDCTL_DSP_GETOSPACE for Real Player
Added check to make sure not opening an already opened MIDI device - writing to the same MIDI device from two different applications causes kernel oops crash there is no handling for multithreading.
Added handling for sample rates not even dividends of 44100 - for NPR News via RealPlayerVersion 2002.10.25:
Reverted to old protocol with all audio URB submission handled in foreground (no ring buffer). The uneven URB length protocol was too messy and caused frequent timeout errors.
Isolated format conversion in separate function
Was having problem with read timeouts - retry multiple calls to sleep_on_interruptible() - same as writes (probably related to old URB submission technique)
Added midi port as required UA100MIX command line option - removed settings file as command line optionVersion 2002.07.23:
Used 1 frame per write URB - 32 frame sequence with 128 URB buffer - to reduce latency
Added handling for sample rates below 44,100, mono and 8-bit resolution
Ring buffer of URBs - URB completion callback submits the next URB
Foreground process just fills free URB transfer buffers
mmusbaudiomix converted to MOTIFVersion 2002.01.31:
Fixed bug with MIDI nonblocking read skipping events (read leaves URB submitted between read() calls)
Converted all parameters to combo boxes for more accurate setting
Fixed compilation problems?Version 2001.11.28:
Removed closing save prompt
Record select also resends line/mic mode
Fixed load of insertion effect
Effect path change resets effect so effect type/parameters will be sent to new path
Parameters: Guitar Multi I, Clean Guitar Multi I, Reverb insertion
Incorporated Naoki Takehiro's SMP patch with initialization of read and write spin locks
Added support for ioctl SNDCTL_DSP_SPEED - only supports 44,100
Changed MIDI read to nonblockingVersion 2001.07.01: Documentation corrections, corrected bug handling sysex input and output, release to Source Forge.
Version 2001.06.24: Initial public release
I wish to acknowledge a huge debt of gratitude to Daisuke Nagano for developing the USB-MIDI kernel module that supports MIDI on the Roland desktop music products. Thanks also go out to Roland and Tom for writing USB Snoopy/SniffUSB the MS-Windows software USB packet sniffer used to investigate the UA-100 USB protocol. Markus did further work to figure out the strange audio write URB protocol.