I think I found a workable solution using wineasio. It's ugly, but it's the only way to get decent latency and have the same usability as Aerodrums on windows. Latency is 18ms with 128 sample buffer. 64 sample buffer didn't work, but I didn't look into why.
I compiled wineasio from git which was important because there was some information there that I would have missed otherwise. You can probably install the debian package from kxstudio instead of compiling, but I didn't test it. The repositories can be added using the instructions here:
https://kx.studio/Repositories
at which point you should be able to "apt-get install wineasio". You will still need to follow the rest of these instruction, but you can skip building wineasio.
I built wineasio for 32-bit because libusb-wine is 32-bit. There's still a bit of a mystery there. So I had to install some extra packages (I already had libjack-jackd2-dev installed which is 64bit).
Code: Select all
$ sudo apt-get install libwine-dev libwine-dev:i386 libjack-jackd2-dev:i386
This ends up installing the following packages:
libwine-dev wine64-tools libc6-dev:i386 libcrypt-dev:i386
libwine-dev:i386 linux-libc-dev:i386
libjack-jackd2-dev:i386
The next step is to compile. Note that this is ubuntu specific. I don't know how the paths work out on other systems. You'll see that I had to adjust one of the include paths to point to a place that worked on my system.
Code: Select all
$ wget https://github.com/wineasio/wineasio/releases/download/v1.1.0/wineasio-1.1.0.tar.gz
$ tar xf wineasio-1.1.0.tar.gz
$ cp /path/to/build.patch wineasio-1.1.0/
$ cd wineasio-1.1.0/
$ patch -p0 << build.patch
$ make 32
$ sudo cp build32/wineasio.dll.so /usr/lib/i386-linux-gnu/wine/wineasio.dll.so
$ regsvr32 wineasio.dll
This is build.patch. I will include it in a tarball attached to this post. You'll need to remove the .txt extension that I had to add to upload it.
Code: Select all
--- Makefile.mk
+++ Makefile.mk
@@ -33,7 +33,7 @@
RCEXTRA =
INCLUDE_PATH = -I. -Irtaudio/include
INCLUDE_PATH += -I$(PREFIX)/include/wine
-INCLUDE_PATH += -I$(PREFIX)/include/wine/windows
+INCLUDE_PATH += -I$(PREFIX)/include/wine/wine/windows
INCLUDE_PATH += -I$(PREFIX)/include/wine-development
INCLUDE_PATH += -I$(PREFIX)/include/wine-development/wine/windows
INCLUDE_PATH += -I/opt/wine-stable/include
@@ -107,5 +107,5 @@
$(WINEBUILD) -m$(M) --dll --fake-module -E $(wineasio_dll_MODULE).spec $^ -o $@
build$(M)/$(wineasio_dll_MODULE).so: $(wineasio_dll_OBJS)
- $(WINECC) $^ $(wineasio_dll_LDFLAGS) $(LIBRARIES) \
+ $(WINECC) -m$(M) $^ $(wineasio_dll_LDFLAGS) $(LIBRARIES) \
$(wineasio_dll_DLLS:%=-l%) $(wineasio_dll_LIBRARIES:%=-l%) -o $@
Next you need to install jackd. I don't know if it was already installed or not since my system isn't fresh. The other piece is qjackctl:
At this point you should be able to open qjackctl, start the jack server, and then start aerodrums. In aerodrums you should see the wineasio device and be able to select it. There may not be any sound yet. Some caveats:
1. the latency will be bad until we fix it
2. the volume may be low until we fix it
3. it's not clear to me what device qjackctl takes over by default
4. pulseaudio will not have any output through jack until we fix it
We can fix the latency by editing the registry. This was the important piece I learned from building from source. So run regedit and make these changes:
Code: Select all
HKEY_CURRENT_USER\Software\Wine\WineASIO\fixed buffer size set to 0
HKEY_CURRENT_USER\Software\Wine\WineASIO\preferred buffersize set to 128
You may not need to change the preferred buffer size. It appears that setting the fixed buffer size to 0 allows aerodrums to control the buffer size. You can see this in qjackctl by showing the Messages window.
The volume control of the jackd audio can be adjusted using alsamixer. Just be warned that the ubuntu volume control, at least on my machine, directly adjusts the same mixer setting via pulseaudio. What this means is if you normally have your system at 50% and after starting the jack server from qjackctl, anything played through jack will be at 50% volume. If you adjust the ubuntu volume control to 100% it won't affect anything (because pulseaudio is not routing through jack yet). However, when you stop the jack server, the pulseaudio volume will be at 100%, not 50%. There is a workaround for this using qjackctl scripts.
You can set the alsa device qjackctl uses. When you open qjackctl, click the Settings button. On the settings tab, pick the interface you want to use. You'll want to make sure it looks like the following:
driver = "alsa"
tick the box "Realtime"
set the device to the one you want
samplerate: 44100
frames/period: 128
periods/buffer: 2
To get jack to play nicely with pulseaudio:
First save the qjackctl scripts somewhere. I have mine in ~/bin/ where I keep other scripts. Make sure they are executable (chmod +x). On the Settings->Options tab in qjackctl, tick the following boxes and paste the following into the text fields.
Code: Select all
Exectute script after Startup:
/path/to/bin/qjackctl-start-post.sh
Execute script before Shutdown:
/path/to/bin/qjackctl-stop-pre.sh
Execute script after Shutdown:
/path/to/bin/qjackctl-stop-post.sh
When you start the jack server from qjackctl, pulse will route to jack and system sounds will come out through the jack device. The scripts also attempt to preserve the volume before and after the jack server has started. The scripts also make sure that pulsaudio can play through jackd without user intervention. This is assuming you want to use the same audio device for aerodrums and system audio (like youtube videos).
Note: You may want to experiment with the volume control on the alsa device. At least on my machine, using
Code: Select all
amixer -q -c "$ALSADEV" set Master 100%
100% is far too loud and makes for really low volumes (like 2% song volume) in the aerodrums interface. This is likely to be sound card and headphone dependent.
qjackctl-start-post.sh
Code: Select all
#!/bin/sh
#Get the script's directory not the running directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
# The default sink name is the sink currently in use.
SINK=$(pacmd stat | grep "Default sink name:" | cut -d : -f 2 | cut -d ' ' -f 2)
# Get the volume of the currently used sink.
VOL=$(pulsemixer --get-volume | cut -d ' ' -f 1)
# parse SINK to turn alsa_output.pci-0000_00_1f.3.analog-stereo
# into pci and 0000:00:1f.3
# This way we can construct /sys/bus/pci/devices/0000\:00\:1f.3/sound/card0/id
# which holds the name of the card we can use in amixer.
TMP=$(echo $SINK | cut -d '.' -f 2,3)
BUS=$(echo $TMP | cut -d '-' -f 1)
TMP2=$(echo $TMP | cut -d '-' -f 2)
DEV=$(echo $TMP2 | sed 's/_/:/g')
# I don't know if this is always true. It should be for alsa devices.
ALSADEV=$(cat /sys/bus/$BUS/devices/$DEV/sound/card0/id)
# Save these variables to file. We'll need them from other scripts.
echo "$SINK" > $DIR/pulseaudio-sink
echo "$VOL" > $DIR/pulseaudio-vol
echo "$ALSADEV" > $DIR/pulseaudio-alsadev
# set the jack sink as the currently used sink
pacmd set-default-sink jack_out
sleep 1
# After setting the sink, set the jack sink volume to be the old
# volume. Since we will make the device volume maximum, we should
# get the same volume before and after the switch.
pulsemixer --set-volume "$VOL"
# the device volume is probably where pulseaudio left it. We need to
# make sure it is maximum so that aerodrums has full control of the
# available volume.
amixer -q -c "$ALSADEV" set Master 100%
qjackctl-stop-pre.sh
Code: Select all
#!/bin/sh
ALSADEV=$(cat /home/algo/bin/pulseaudio-alsadev)
# we have to do this prior to stopping the jack server or when pulseaudio
# detect that jack has stopped, it switches. Maybe.
# This guarantees that the volume should be muted before anything changes
# on the pulseaudio side. And prevents having the volume at max unintentionally.
amixer -q -c $ALSADEV set Master 0
qjackctl-stop-post.sh
Code: Select all
#!/bin/sh
SINK=$(cat /home/algo/bin/pulseaudio-sink)
VOL=$(cat /home/algo/bin/pulseaudio-vol)
pacmd set-default-sink $SINK
# don't try to set the volume too quickly or the
# sink change won't have happened yet.
sleep 1
pulsemixer --set-volume $VOL
Using these scripts, you can control the volume from within aerodrums using the drumstick interface.
If you are not using ubuntu 20.04 you may need to modify these instructions. I think Ubuntu 20.04 has the pulseaudio-jack module already installed and /etc/pulse/default.pa is set up to load it. The name of the jack sink may not be the same so the scripts I provided will need to be changed. The master volume on your device may not be called "Master". Little things like that.
This rigamarole is difficult, but I don't know how to make it any easier.