midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

[Solved] Using Raspberry Pi as a USB MIDI controlled synth

Sun Oct 12, 2014 7:34 pm

I have Creative E-mu XBoard 49 MIDI USB keyboard which is collecting dust in my room. Recently my cousin (girl, 18) said that she would like to learn to play piano. I know that she's serious about that because she already have learned to play her sister's guitar. I thought that I could lend her my XBoard. But their family have only one computer for them all (4 people), thus she won't have much time to use the XBoard with the computer.

So now I have an idea that I could lend her also my Raspberry if only it could be used as a monitorless synthesizer. I mean - after I configure it once, it should just work immediately each time upon boot. I think, she doesn't need anything fancy - no sequencing or effects, just a MIDI synth capable of loading some General MIDI compatible sound bank and playing it with max 5 voice polyphony through USB connected XBoard.

Is Raspberry capable of doing that? And is there any distribution and software which could be installed and configured with as little effort as possible?
Last edited by midix on Thu Oct 16, 2014 1:15 pm, edited 1 time in total.

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: Using Raspberry Pi as a USB MIDI controlled synth

Wed Oct 15, 2014 9:12 pm

I did it using timidity and custom rc.local script which calls

Code: Select all

aconnect 20:0 128:0
upon boot. And some performance tricks as suggested http://wiki.linuxaudio.org/wiki/raspberrypi:

Code: Select all

## Stop the ntp service
sudo service ntp stop

## Stop the triggerhappy service
sudo service triggerhappy stop

## Remount /dev/shm to prevent memory allocation errors
sudo mount -o remount,size=128M /dev/shm

## Set the CPU scaling governor to performance
echo -n performance | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
Also added other improvements - minimal protection against SD corruption in fstab:

Code: Select all

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    ro,noatime        0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
tmpfs           /tmp            tmpfs   defaults,noatime              0       0 
tmpfs           /var/log        tmpfs   defaults,noatime              0       0 
tmpfs           /var/tmp        tmpfs   defaults,noatime              0       0 
tmpfs           /var/run        tmpfs   defaults,noatime              0       0 
tmpfs           /var/spool      tmpfs   defaults,noatime              0       0 
tmpfs           /var/lock       tmpfs   defaults,noatime              0       0 
tmpfs           /var/cache      tmpfs   defaults,noatime              0       0

# and mount for my remote share, if available
//remotepcip/share /mnt/share cifs rw,guest,_netdev 0 0
And installed better sounds for Timidity:

Code: Select all

sudo apt-get install fluid-soundfont-gm fluid-soundfont-gs
and configured Timidity to use the GM one in /etc/timidity/timidity.cfg and also disabled some CPU hungry features:

Code: Select all

## If you have a slow CPU, uncomment these:
opt EFresamp=d		#disable resampling
opt EFvlpf=d		#disable VLPF
#opt EFreverb=d		#disable reverb
opt EFchorus=d		#disable chorus
#opt EFdelay=d		#disable delay
opt anti-alias=d	#disable sample anti-aliasing
#opt EWPVSETOZ		#disable all Midi Controls
opt p32a		#default to 32 voices with auto reduction
#opt s32kHz		#default sample frequency to 32kHz, affects the quality and cpu mmost
#opt fast-decay		#fast decay notes

# alternatively, you can use the fluid-soundfont:
source /etc/timidity/fluidr3_gm.cfg

Also added medium overclock using raspi-config. Will have to stress-test it using Quake3.

And disabling HDMI audio in boot config:

Code: Select all

hdmi_drive=1
hdmi_ignore_edid_audio=1
Anyway, everything works smoothly, no crackling at all but latency is not good. :( I'll try to play with timidity TIM_ALSA_SEQ_PARAMS options in /etc/default/timidity
Also not sure what sample rate should I select. Currently it's opt s32kHz #default sample frequency to 32kHz but maybe to avoid resampling I should use the default value of ALSA, but not sure what it is.

Tried also fluidsynth, but it was a resource hog and caused lots of crackling.
Last edited by midix on Sun Oct 19, 2014 5:02 pm, edited 3 times in total.

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: Using Raspberry Pi as a USB MIDI controlled synth

Thu Oct 16, 2014 12:42 pm

So, after some blind experimenting with timidity -B option, the latency is acceptable.

At first I tried -B2,8 as recommended in Timidity docs.
Eventually the -Bx,y option is required for reduction of latency, where x is the fragments and y is the bits of audio buffer size. Typically, -B2,8 is enough. This specifies two fragments with 256 samples.
This reduced the latency but gave lots of jitter. Then I tried -B2,16. Timidity failed to start but unfortunately /etc/init.d/timidity did not give any useful info. But trying to playback a file through timidity with this arg clearly explained my fault:

Code: Select all

Buffer Fragments (bit) must be between 1 and 12
I'm still not sure how does that "bits of audio buffer size" relate to fragment size.

Next I tried -B4,8 and this seems to work reliably and without any jitter for both MIDI playback and USB midi keyboard.

Also I used alsamixer command to interactively boost the volume to 100% and this value seems to stick between RPi reboots without any additional scripting.

So, I guess we can call it success - now I have a decent low latency headless (used raspi-config to disable GUI) General-MIDI synth controllable via E-Mu XBoard 49. And it seems to tolerate unexpected power disconnects, unless I don't do this while it is booting. Audio quality maybe is not great, there are some slight background noises but this is not a problem for my case. I hope it will work reliably. I installed also TightVNC but left it disabled, will launch manually if needed.

All that's left is to create a backup of my SD. :ugeek:

gkreidl
Posts: 6048
Joined: Thu Jan 26, 2012 1:07 pm
Location: Germany

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Thu Oct 16, 2014 1:48 pm

You could also try giving timidity a higher priority, especially if you're not doing something else with your RPi.
Minimal Kiosk Browser (kweb)
Slim, fast webkit browser with support for audio+video+playlists+youtube+pdf+download
Optional fullscreen kiosk mode and command interface for embedded applications
Includes omxplayerGUI, an X front end for omxplayer

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Sat Oct 18, 2014 5:17 pm

Thanks for the idea, I added --nicelevel -15 to timidity daemon args.

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Sun Oct 19, 2014 11:59 am

Now it would be great to tell timidity what should happen when I turn some knobs on my MIDI keyboard. Currently volume, vibrato and pitch bend works fine, and knob #13 is used for reverb, but it would be great to have control for panning because some SF2 samples sound in one ear only.

But I guess I can program my XBoard to remap controls as needed and store in its 16 patches.

What I noticed is that timidity s32kHz setting seems to affect sound quality a lot. With it enabled I have some constant background hissing noise and synth sounds seem somewhat dirty.

Will try to leave it commented out but sacrifice some latency. Reverb also seems cool, will try to leave it on, maybe that's not that heavy if I add some little latency.

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Tue Oct 21, 2014 3:36 pm

Oh, I just found that I can adjust reverb and resample settings instead of completely disabling them. It was not easy to find because Google spammed me with "=d" results for both EFresamp and EFreverb.

Even Ubuntu man page for Timidity barely mentions these options.

In case anyone else wants to know, here are some bits I collected from everywhere:
-EFresamp=l Enable Linear resample algorithm
-EFresamp=L Enable Lagrange resample algorithm
-EFresamp=g Enable Gauss-like resample algorithm (default)

listed in order of increasing quality/slowness. Linear uses 2-point (1st
order) interpolation, Lagrange is 4-point (3rd order), and Gauss-like
allows you to specify any order you want between 1 and 34 (odd numbers
are probably best). The default is -N 25 Gauss-like, which is fairly CPU
intensive. Try -N 5, and if that isn't fast enough, drop down to
Lagrange, then linear.
Keep "opt s32kHz" commented out because it greatly reduces quality for no noticeable gain at all.
I guess, I'll have to look into the source files for all available options and play with them to find the best for RPi.

One more thing bothers me - what about sample rate? What sample rate is the least demanding on the RPi's built-in audio and causes less resampling (no matter hardware or software)?

I did

Code: Select all

cat /proc/asound/card0/pcm0p/sub0/hw_params
but it changes the sample rate depending on what I set for Timidity, so I guess, ALSA won't tell me what is the best for the audio drivers and bcm2835.

gkreidl
Posts: 6048
Joined: Thu Jan 26, 2012 1:07 pm
Location: Germany

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Tue Oct 21, 2014 3:43 pm

The GPU of the RPi would make a great sound processor, if someone would be willing to write the software for it.
Minimal Kiosk Browser (kweb)
Slim, fast webkit browser with support for audio+video+playlists+youtube+pdf+download
Optional fullscreen kiosk mode and command interface for embedded applications
Includes omxplayerGUI, an X front end for omxplayer

TheRealJRoss
Posts: 1
Joined: Fri Jan 16, 2015 7:40 pm

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Fri Jan 16, 2015 8:03 pm

Thanks for the idea, I added --nicelevel -15 to timidity daemon args.
I'm looking to follow your work here and replicate using an Alesis QX61. Were you able to fully eliminate the latency after changing the nice level per above?

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Tue Jan 27, 2015 3:30 pm

Yes, it works pretty smoothly now, I don't feel any discomfortable delay. The trick was to tweak timidity buffer and effect settings sacrificing some of sound quality.

midix
Posts: 40
Joined: Sat Jul 27, 2013 2:24 pm

Re: [Solved] Using Raspberry Pi as a USB MIDI controlled syn

Fri Jan 30, 2015 8:15 pm

Here are my working config files.

This one was the most important, it controls latency. It was also somewhat hard to find; at first I tried to hack the init.d timidity script directly but then noticed where TIM_ALSASEQPARAMS are coming from.

So, open /etc/default/timidity

My current setting is

Code: Select all

# Setting overrides (of /etc/timidity.conf) for the ALSA sequencer daemon
TIM_ALSASEQPARAMS="-B8,8 -Os1"
Depending on your effect settings and overclocking, if any, you might be able to set it even lower. I tried
-B4,8
-B8,8
-B16,8
-B32,8

and found that -B8,8 is the best for me - latency is negligible.
I also played back some midi files to test the settings like this:
timidity /home/pi/music/some_instrumen_heavy_midi_file.mid -B8,8

Note that when playing back midi files you might hear lots of jitter, but usually you don't play so many instruments and voices simultaneously on a MIDI keyboard, so don't judge by MIDI file, but try playing on your keyboard and play with maximal voices you will need.

The next config file controls sound quality, so poor little Pi doesn't have to overload itself trying to render sound at the request latency:

/etc/timidity/timidity.conf

Code: Select all


opt EFresamp=l		#disable resampling - noticeably affects quality  and cpu. L - lagranzhe, l linear, c spline, n newton. default is g 25
opt EFvlpf=d		#disable VLPF
opt EFreverb=f,1		#disable reverb, n = normal, g=global, f=freeverb (default), G=global freeverb. ngfgG can specify level after ,
opt EFchorus=d		#disable chorus
#opt EFdelay=d		#disable delay
opt anti-alias=d	#disable sample anti-aliasing
#opt EWPVSETOZ		#disable all Midi Controls
opt p32a		#default to 32 voices with auto reduction
#opt s32kHz		#default sample frequency to 32kHz, affects the quality but no gain
#opt fast-decay		#fast decay notes

source /etc/timidity/fluidr3_gm_nopan.cfg
As you see, I have left some light reverb and set resample to linear. Disabling it caused some sampling artifacts.

Also, I have created my own version of fluidr3 without any panning. Default fluidr3 had some panning and I wanted to get rid of it. I took this:
https://github.com/ChurchOrganist/MuseS ... hare/sound
as the base but it still had some panning in it, so cleaned it up.

Return to “Graphics, sound and multimedia”