Recording at 96 kHz: Requires USB 2.0 (duh…)

I recently installed Ubuntu Studio on a spare, many-years old system (a Pentium 3) to try out a new Edirol UA-25EX audio interface that I picked up. I plan to detail my experiences with Studio in a soon-to-come post, but there was one problem I ran into that warrants its own post.

After applying a patch for the device and rebuilding the kernel modules (again, topic for another post), I was easily able to record at 44.1 kHz. Then I ran the following command to record at 96 kHz:

mike@studio:~$ arecord -v -r 96000 -f cd -t wav -D plughw:UA25EX test.wav

After the expected verbose output, the arecord command immediately terminated with the following error message:

arecord: xrun:1090: read/write error, state = PREPARED

Hmm. Not very informative. I thought to run dmesg, though, which gave me more useful information:


[13469.727719] ALSA /home/mike/linux-ubuntu-modules-2.6.24-2.6.24/debian/build/build-rt/sound/alsa-driver/usb/usbaudio.c:864: cannot submit datapipe for urb 0, error -28: not enough bandwidth

Not enough bandwidth. It occurred to me at this point that this system is old enough to pre-date the common availability of USB 2.0. And then I was surprised to find that I didn’t know how to tell from the command line whether a system’s USB controllers are 1.1 or 2.0.

And so, to the point of this article: On a Linux system, how do you determine the versions of your USB controllers?

Simply run lspci -v | grep HCI. Any controllers that say “UHCI” or “OHCI” are USB 1.1; any that say “EHCI” are 2.0. Sure enough, there were only USB 1.1 controllers on the system. I picked up a PCI card with 5 USB 2.0 ports for $15, plugged the audio interface into that, and suddenly I could record at 96 kHz with no problem.

Using the Sash Widget in Java SWT

This is the first in what will be a series of posts detailing some of the problems I ran into when developing an SWT-based GUI in the Eclipse development environment.  I hadn’t developed a GUI in Java since Swing was the new hotness, so SWT was new to me.

Sash Layout Overview

Layout Overview

The main window design called for a toolbar across the top, a table which lists entries from a database, a composite under the table which provides details on the selected entry, and a status bar on the bottom.  It was easy enough to position the widgets using a GridLayout, but I wanted the user to be able to adjust the relative sizes of the table and detail composite, giving either more or less screen real estate to whichever of the two widgets is of the most interest at the moment.  I suspected that a sash was the way to do this, but the SWT snippet library, which is very useful in most cases, contained surprisingly little information on the use of sashes.  After some experimentation, here is what I learned.

Part of the problem was that I was using a GridLayout for the main shell.  Once I switched to using a FormLayout, the sash became trivial to implement.  (This article on layouts is spectacular, by the way.) With the GridLayout, I instantiated the widgets in order from the top to the bottom of the shell, but when I switched to a FormLayout I needed to change the order in which the widgets were created.

The first step when laying out the widgets is to position the sash:

    final Sash sash = new Sash(shell, SWT.BORDER | SWT.HORIZONTAL);
    formData = new FormData();
    formData.top = new FormAttachment(30, 0);
    formData.left = new FormAttachment(0, 0);
    formData.right = new FormAttachment(100, 0);
    formData.height = 3;
    sash.setLayoutData(formData);

When the application is started, this sash is positioned in such a way that 30% of the window space is provided for the toolbar and table at the top of the window, and 70% is provided for the detail composite and status bar at the bottom.

At this point, the general idea is to place the widgets from the top of the shell down, until you reach the sash.  Then you place widgets from the bottom of the shell up, again until you reach the sash.  In my case, I instantiated the toolbar first and attached it to the top of the main shell.  Then I created the table and attached the top of it to the bottom of the toolbar, and the bottom of it to the top of the sash.  The next step was to start at the bottom of the shell by attaching a composite for the status bar to the bottom of the main shell.  Then I attached the bottom of the detail composite to the top of the status bar composite, and the top of the detail composite to the bottom of the sash.

With that updated layout, the selection listener for the sash became relatively simple:

    sash.addListener(SWT.Selection, new Listener () {
        public void handleEvent(Event e) {
            sash.setBounds(e.x, e.y, e.width, e.height);

            FormData formData = new FormData();
            formData.top = new FormAttachment(0, e.y);
            formData.left = new FormAttachment(0, 0);
            formData.right = new FormAttachment(100, 0);
            formData.height = 3;
            sash.setLayoutData(formData);
            shell.layout(true);
        }
    });

When the sash is moved, this listener causes its layout data to be replaced.  The top of the sash is set to the user-specified location, and the layout() method of the shell is invoked, which will cause the table and detail widgets to be resized to accommodate the new sash location (since they are attached to the sash).

Obviously, it’s easy to modify this layout strategy for vertical sashes.  It does get a bit more complex if you want to have multiple sashes in the same window, but even that is not too bad: if I had wanted a vertical sash in the detail composite, I could have simply used a form layout within that composite, building widgets from the left and right sides of the composite until they met the sash in the middle.

So there you go:  a quick summary of my experience with the elusive sash widget.

Where has Mike been?

I’ve been here all along!  Obviously, it’s been many moons since I’ve posted; I intend to remedy that post-haste.  I don’t work regularly on RAS anymore, so I had been feeling that my well of ideas for posts had been drying up.  But I’ve been involved with a number of new projects, and new projects should mean that there are new things to post about.

I don’t think I’ve written Java code since Swing and Ant were considered the new hotness.  I’m now finishing up a Java-based GUI that leverages SWT, and realized that there were a few challenges that I had to pound through the old-fashioned way because, even with the very useful SWT snippets and Javadocs, there was little advice to be found online.  So that’s where I’ll start back up:  over the next few weeks, I will be posting articles that discuss these challenges and how I solved them.