EWI-USB amb la Raspberry Pi
Contingut
- 1 Referències
- 2 EWI-USB + Raspberry Pi amb fluidsynth
- 2.1 Millorar el volum
- 2.2 Millorar la latència (veure més avall, solució udev)
- 2.3 Automatització (1a versió)
- 2.4 Marge de millores
- 2.5 scripts per arrencar amb el sistema
- 2.6 udev: executar un script quan endollo un dispositiu USB
- 2.7 udev: Endollar el EWI-USB
- 2.8 scripts per arrencar fluidsynth amb udev
- 3 EWI-USB + Raspberry Pi + Roland JV-1010
El EWI-USB s'ha de connectar a un ordinador. Tinc el sinte JV-1010 (i el JV-2080), però no em són útils per connectar-hi el EWI-USB. Ara bé, i si utilitzo una Raspberry PI com a plataforma portàtil per aconseguir una configuració mínima i pràctica?
Referències
Autostatic ha escrit (novembre 2013) un article per fer sonar en Salamander Grand Piano a la RP (Using a Raspberry Pi as a piano, http://linux.autostatic.com/).
D'aquest article i els scripts que programa es pot extreure coses interessants que caldria repassar: Jack a baixa latència, desactivar la wifi,... es comenta que és important tenir una SD de bona qualitat (per ex, class 10).
EWI-USB + Raspberry Pi amb fluidsynth
$ sudo apt-get install fluidsynth
Després d'instal.lar el fluidsynth tinc disponible el soundfont /usr/share/sounds/sf2/FluidR3_GM.sf2, però també en puc carregar d'altres. Des del portàtil carrego soundfonts:
$ scp Casio_VL-1.SF2 pi@192.168.1.135:/home/pi $ scp Natural_Oboe.sf2 pi@192.168.1.135:/home/pi
Arrenco el fluidsynth amb un soundfont:
$ fluidsynth -a alsa -m alsa_seq /home/pi/Casio_VL-1.SF2 $ fluidsynth -a alsa -m alsa_seq /usr/share/sounds/sf2/FluidR3_GM.sf2 $ fluidsynth -a alsa -m alsa_seq /home/pi/Natural_Oboe.sf2
Tinc el EWI-USB connectat:
$ aconnect -iol client 0: 'System' [type=kernel] 0 'Timer ' 1 'Announce ' client 14: 'Midi Through' [type=kernel] 0 'Midi Through Port-0' client 20: 'EWI-USB' [type=kernel] 0 'EWI-USB MIDI 1 ' client 128: 'FLUID Synth (2431)' [type=user] 0 'Synth input port (2431:0)'
Faig la connexió ALSA:
$ aconnect 20:0 128:0
I ja sona. Per als soundfonts grans la latència és considerable. Per al soundfont petit la latència és menor. Estic fent les proves amb una Raspberry de 256MB (amb una de 512MB el resultat hauria de ser millor).
El meu EWI-USB el tinc configurat per defecte que soni pel canal 16 (15 si 0-15). Què he de fer per escollir un altre instrument?
> channels chan 0, Yamaha Grand Piano chan 1, Yamaha Grand Piano chan 2, Yamaha Grand Piano chan 3, Yamaha Grand Piano chan 4, Yamaha Grand Piano chan 5, Yamaha Grand Piano chan 6, Yamaha Grand Piano chan 7, Yamaha Grand Piano chan 8, Yamaha Grand Piano chan 9, Standard chan 10, Yamaha Grand Piano chan 11, Yamaha Grand Piano chan 12, Yamaha Grand Piano chan 13, Yamaha Grand Piano chan 14, Yamaha Grand Piano chan 15, Yamaha Grand Piano > inst 1 ... 000-056 Trumpet 000-057 Trombone 000-058 Tuba 000-059 Muted Trumpet 000-060 French Horns 000-061 Brass Section 000-062 Synth Brass 1 000-063 Synth Brass 2 000-064 Soprano Sax 000-065 Alto Sax 000-066 Tenor Sax 000-067 Baritone Sax 000-068 Oboe 000-069 English Horn 000-070 Bassoon 000-071 Clarinet 000-072 Piccolo 000-073 Flute 000-074 Recorder ...
Si vull el so de clarinet faré:
> prog 15 71
i fico el valor 15 perquè per defecte tinc configurat el EWI-USB per tal de què soni pel canal 15.
Millorar el volum
Després hi ha un problema de volum que es soluciona molt fàcilment amb el alsa-mixer:
$ alsamixer
o recordar que el fluidsynth també té l'opció del guany.
$ fluidsynth -a alsa -m alsa_seq -g 1 /home/pi/Natural_Oboe.sf2
He de procurar que no hi hagi saturació en el so. Un valor de -g 5 provoca saturació, és massa alt. -g 1 és correcte, també es pot jugar amb el alsamixer.
Puc jugar amb alsamixer. El problema que tinc és que el Master d' alsamixer està a la meitat cada vegada que arrenco la Raspberry. i alsamixer és un entorn gràfic de consola, i no té opcions de terminal per canviar el volum del master. Però això es pot fer des del terminal fent amixer en comptes de alsamixer:
$ amixer set Master 40%+ > /dev/null
Millorar la latència (veure més avall, solució udev)
Quan arrenco el fluidsynth sempre dóna el missatge de:
fluidsynth: warning: Failed to pin the sample data to RAM; swapping is possible
Evidentment aquest problema amb la RAM ja se l'ha trobat altra gent:
El més important per millorar el rendiment és que a mi m'han deixat la Rasperry Pi Model B de fa uns mesos amb 256MB, però que si n'aconsegueixo una de nova vindrà amb 512MB i per tant el rendiment serà millor...
The Model B was originally shipped with 256MB but recently doubled to 512MB.
$ fluidsynth -a alsa -m alsa_seq /home/pi/Natural_Oboe.sf2 FluidSynth version 1.1.5 Copyright (C) 2000-2011 Peter Hanappe and others. Distributed under the LGPL license. SoundFont(R) is a registered trademark of E-mu Systems, Inc. fluidsynth: warning: Failed to pin the sample data to RAM; swapping is possible. fluidsynth: warning: No preset found on channel 9 [bank=128 prog=0] fluidsynth: warning: Requested a period size of 64, got 256 instead Type 'help' for help topics. > fluidsynth: warning: Failed to set thread to high priority fluidsynth: warning: Failed to set thread to high priority
Dels missatges veig que tinc un problema amb la RAM (ja ho sabia), que tinc un period size de 256 i que no estic treballant amb alta prioritat per a l'audio.
Canviant el valor de -z tampoc soluciona res. Valors més grans de 256 (512, 1024) empitjora la latència. Valor de 64 no l'agafa.
Solució:
$ sudo joe /etc/security/limits.d/pi.conf
pi - rtprio 99 pi - memlock unlimited
i reiniciar. Compte! si poso rtprio 85 en comptes de rtprio 99 també hi ha latència.
Ara ja arrenco amb mode RT i no em dóna el missatge:
$ fluidsynth -a alsa -m alsa_seq -g 1 /home/pi/Natural_Oboe.sf2 version 1.1.5 Copyright (C) 2000-2011 Peter Hanappe and others. Distributed under the LGPL license. SoundFont(R) is a registered trademark of E-mu Systems, Inc. fluidsynth: warning: No preset found on channel 9 [bank=128 prog=0] fluidsynth: warning: Requested a period size of 64, got 256 instead Type 'help' for help topics.
El curiós del cas és que el mode tradicional que feina en el portàtil no funciona, no arregla la latència:
$ sudo adduser pi audio $ groups pi adm dialout cdrom sudo audio video plugdev games users netdev input $ sudo joe /etc/security/limits.conf @audio - rtprio 99 @audio - memlock unlimited
Automatització (1a versió)
Al final queda de la següent manera:
fitxer /home/pi/arrencar_fluidsynth1.sh:
#!/bin/bash /usr/bin/fluidsynth -a alsa -m alsa_seq -g 1 /home/pi/Natural_Oboe.sf2
Marge de millores
NOTA: veure l'apartat UDEV. Els meus problemes de latència es solucionen quan enxufo el EWI-USB un cop arrencada la màquina. En canvi. Si tinc el EWI-USB connectat des del principi, tinc problemes de latència una mica aleatoris, no importa la RAM que tingui... Per tant, veure el script que s'executa en l'apartat udev.
Bàsicament la configuració funciona, però encara obtinc a vegades una certa latència, la qual cosa fa pensar que hi ha alguna variable que me la fa ballar. El fet de què sigui a vegades fa pensar que hi ha algun malfuncionament que es podria corregir.
- Utilitzar la RP de 512 MB
- Utilitzar un USB powered hub (http://www.raspipc.es/tienda.php?ver=articulo&id=1065 - http://es.farnell.com/dynamode/usb-h70-1a2-0/hub-usb-2-0-7-puertos-with-uk-ac/dp/2115058)
- Overclocking de la RP
- provar una altra targeta SD
- http://wiki.linuxaudio.org/wiki/raspberrypi
- http://lists.linuxaudio.org/pipermail/linux-audio-user/2013-April/092322.html
powered USB hub
Yes, that's why I'm now using a powered USB hub and I plug the UA-25 into the hub. The hub has a 5V/3.7A power supply. In my case I also experienced SD corruption when using a GPU frequency higher than 250. Check the current of the adapter, if it's somewhere around 1A you might need a more powerful adapter as the RPi already draws 700mA IIRC.
Una altra variable també pot ser el tipus de targeta SD. No totes tenen la mateixa qualitat:
What kind of SD are you using? I've used different SD cards with different results. I'm now using a cheap OEM class 10 SD card that does get corrupted quickly but performance is better than other SD cards I've used. Whenever I change something I make a backup now. SanDisk SD's are being recommended for use with the RPi.
scripts per arrencar amb el sistema
fitxer /home/pi/arrencar_fluidsynth2.sh:
#!/bin/bash /bin/sleep 2 /usr/bin/amixer set Master 40%+ > /dev/null /bin/sleep 2 FLUIDSYNTH=$(/usr/bin/aconnect -o -l | awk '/FLUID/{print $2."0"}') /bin/sleep 2 #echo $FLUIDSYNTH /usr/bin/aconnect EWI-USB:0 $FLUIDSYNTH /bin/sleep 2
$ sudo chmod a+x /home/pi/arrencar_fluidsynth1.sh $ sudo chmod a+x /home/pi/arrencar_fluidsynth2.sh
Ara faig els scripts d'arrencada:
fitxer /etc/init.d/arrencar_fluidsynth1: (nota: utilitzo sudo -u pi per tal de què el script s'executi com a usuari normal que té permisos d'alta prioritat)
$ sudo joe /etc/init.d/arrencar_fluidsynth1 #! /bin/sh # /etc/init.d/arrencar_fluidsynth1 ### BEGIN INIT INFO # Provides: arrencar_fluidsynth1 # Required-Start: # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: arrencar_fluidsynth1 # Description: arrencar_fluidsynth1 ### END INIT INFO # If you want a command to always run, put it here # Carry out specific functions when asked to by the system case "$1" in start) sudo -u pi /home/pi/arrencar_fluidsynth1.sh ;; esac exit 0
fitxer /etc/init.d/arrencar_fluidsynth2:
$ sudo joe /etc/init.d/arrencar_fluidsynth2 #! /bin/sh # /etc/init.d/arrencar_fluidsynth2 ### BEGIN INIT INFO # Provides: arrencar_fluidsynth2 # Required-Start: # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: arrencar_fluidsynth2 # Description: arrencar_fluidsynth2 ### END INIT INFO # If you want a command to always run, put it here # Carry out specific functions when asked to by the system case "$1" in start) sudo -u pi /home/pi/arrencar_fluidsynth2.sh ;; esac exit 0
sudo chmod 755 /etc/init.d/arrencar_fluidsynth1 sudo chmod 755 /etc/init.d/arrencar_fluidsynth2 sudo update-rc.d arrencar_fluidsynth1 defaults sudo update-rc.d arrencar_fluidsynth2 defaults
El problema està en què no puc ficar en el mateix script l'arrencada del fluidsynth i el aconnect, perquè el fluidsynth sempre es queda amb el prompt (>), i tampoc puc utilitzar &. En una ocasió havia utilitzat xterm, però aquí a la raspberry PI no em val.
Així funciona la connexió. La latència, que em pensava que tenia solucionada, veig que encara falla... Segurament el problema és que estic fent sudo, i per tant estic executant totes aquestes comandes com a root i no com a pi.
Fixem-nos la diferència de fer:
$ groups pi adm dialout cdrom sudo audio video plugdev games users netdev input pi@raspberrypi ~ $ sudo groups root
Per eliminar els scripts d'arrencada:
$ sudo update-rc.d -f arrencar_fluidsynth1 remove $ sudo update-rc.d -f arrencar_fluidsynth2 remove
udev: executar un script quan endollo un dispositiu USB
prova: endollar un ratolí òptic
connecto un ratolí òptic:
$ dmesg ... [11556.310613] usb 1-1.1: new low-speed USB device number 4 using ehci_hcd [11556.410453] input: Logitech USB Optical Mouse as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input12 [11556.410802] generic-usb 0003:046D:C05B.0002: input,hidraw0: USB HID v1.11 Mouse [Logitech USB Optical Mouse] on usb-0000:00:1a.0-1.1/input0
$ udevinfo -a -p /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input12
no tinc disponible udevinfo però puc utilitzar udevadm:
$ sudo udevadm info -a -p /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input12 Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input12': KERNEL=="input12" SUBSYSTEM=="input" DRIVER=="" ATTR{name}=="Logitech USB Optical Mouse" ATTR{phys}=="usb-0000:00:1a.0-1.1/input0" ATTR{uniq}=="" ATTR{properties}=="0" looking at parent device '/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0': KERNELS=="1-1.1:1.0" SUBSYSTEMS=="usb" DRIVERS=="usbhid" ATTRS{bInterfaceNumber}=="00" ATTRS{bAlternateSetting}==" 0" ATTRS{bNumEndpoints}=="01" ATTRS{bInterfaceClass}=="03" ATTRS{bInterfaceSubClass}=="01" ATTRS{bInterfaceProtocol}=="02" ATTRS{supports_autosuspend}=="1" looking at parent device '/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1': KERNELS=="1-1.1" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{configuration}=="" ATTRS{bNumInterfaces}==" 1" ATTRS{bConfigurationValue}=="1" ATTRS{bmAttributes}=="a0" ATTRS{bMaxPower}==" 98mA" ATTRS{urbnum}=="17614" ATTRS{idVendor}=="046d" ATTRS{idProduct}=="c05b" ATTRS{bcdDevice}=="5400" ATTRS{bDeviceClass}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bDeviceProtocol}=="00" ATTRS{bNumConfigurations}=="1" ATTRS{bMaxPacketSize0}=="8" ATTRS{speed}=="1.5" ATTRS{busnum}=="1" ATTRS{devnum}=="4" ATTRS{devpath}=="1.1" ATTRS{version}==" 2.00" ATTRS{maxchild}=="0" ATTRS{quirks}=="0x0" ATTRS{avoid_reset_quirk}=="0" ATTRS{authorized}=="1" ATTRS{manufacturer}=="Logitech" ATTRS{product}=="USB Optical Mouse" ...
Fixar-se amb els següents valors perquè és els que haurem de ficar en el fitxer de regles:
SUBSYSTEMS=="usb" ATTRS{product}=="USB Optical Mouse"
$ sudo joe /etc/udev/rules.d/touchpad.rules #/etc/udev/rules.d/touchpad.rules ACTION=="add", SUBSYSTEMS=="usb", ATTRS{product}=="USB Optical Mouse", RUN+="/home/joan/prova_mouse.sh"
fitxer /home/joan/prova_mouse.sh:
#!/bin/sh ls -la /home/joan/rutes_GPS > /home/joan/hola.txt
I ara efectivament desconnectem el mouse, el tornem a conectar, i podem mirar el contigut del fitxer hola.txt:
$ cat hola.txt total 5232 drwxrwxr-x 2 joan joan 4096 Jun 6 19:00 . drwxr-xr-x 86 joan joan 20480 Jun 6 19:54 .. -rw-rw-r-- 1 joan joan 163256 Jan 30 17:50 080727-trialerada-per-collserola.gpx -rw-r--r-- 1 joan joan 64806 Nov 6 2012 2012-11-04 0859__20121104_0859.gpx -rw-r--r-- 1 joan joan 62978 Nov 6 2012 2012-11-04 1004__20121104_1004.gpx ...
Puc comprovar que el script s'executa fent:
$ sudo udevadm test /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input16 ... run: '/home/joan/prova_mouse.sh'
(compte! perquè pot haver canviat el nom del dispositiu: input16 en comptes de input12). En qualsevol cas, el script s'executa igualment.
udev: Endollar el EWI-USB
$ dmesg ... [ 184.553228] usb 1-1.2: new full-speed USB device number 4 using dwc_otg [ 184.654878] usb 1-1.2: New USB device found, idVendor=09e8, idProduct=006d [ 184.654906] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 184.654922] usb 1-1.2: Product: EWI-USB [ 184.654934] usb 1-1.2: Manufacturer: Akai Professional, LLC. [ 184.850265] usbcore: registered new interface driver snd-usb-audio
$ sudo joe /etc/udev/rules.d/ewiusb.rules #/etc/udev/rules.d/ewiusb.rules ACTION=="add", SUBSYSTEMS=="usb", ATTRS{product}=="EWI-USB", RUN+="/home/pi/ewiscript.sh"
prova:
$ joe /home/pi/ewiscript.sh #!/bin/sh ls -la /home/pi/Desktop > /home/pi/hola.txt $ sudo chmod a+x /home/pi/ewiscript.sh
I ara efectivament desconnectem el EWI, el tornem a conectar, i podem mirar el contigut del fitxer hola.txt
Ara que funciona el script ewiscript.sh, ja puc fer que executi el fluidsynth i les connexions ALSA
scripts per arrencar fluidsynth amb udev
Sempre havia tingut el problema d'arrencar fluidsynth (que sempre apareix el prompt > a pesar de l'opció -i) en una consola diferent. L'ús de & tampoc funciona. Finalment, el problema es pot resoldre utilitzant la utilitat screen (http://www.thegeekstuff.com/2010/07/screen-command-examples/):
$ sudo apt-get install screen NAME screen - screen manager with VT100/ANSI terminal emulation SYNOPSIS screen [ -options ] [ cmd [ args ] ] screen -r [[pid.]tty[.host]] screen -r sessionowner/[[pid.]tty[.host]] $ screen -d -m -S fluidsynth -t "fluidsynth" /usr/bin/fluidsynth -a alsa -m alsa_seq -g 1 /home/pi/Natural_Oboe.sf2 $ screen -d -r fluidsynth $ ps aux | grep fluidsynth
efectivament el procés fluidsynth està arrencat i puc executar noves comandes.
fitxer ewiscript.sh:-c 4 -z 256 -r 44100
#!/bin/sh if [ -z `pidof -s fluidsynth` ]; then screen -d -m -S fluidsynth -t "fluidsynth" /usr/bin/fluidsynth -a alsa -m alsa_seq -g 1 -c 4 -z 256 -r 48000 /home/pi/Natural_Oboe.sf2 /bin/sleep 3 /usr/bin/amixer set Master 40%+ > /dev/null /bin/sleep 2 FLUIDSYNTH=$(/usr/bin/aconnect -o -l | awk '/FLUID/{print $2."0"}') /bin/sleep 2 #echo $FLUIDSYNTH /usr/bin/aconnect EWI-USB:0 $FLUIDSYNTH /bin/sleep 2 fi
Al final, el més important per tal de reduir la latència ha estat l'argument -c 4 (que és el número d'àudio buffers). Augmentar la quantitat no millora el rendiment, però en canvi suprimir l'argument o reduir el valor empitjora clarament la latència. D'altra banda, -z 64 o 128 no ho agafa, i per tant m'he d'acontentar amb -z 256. Segurament el valor de samplerate de 48000 és millor que el de 44100.
EWI-USB + Raspberry Pi + Roland JV-1010
L'altra solució (que no haurà de tenir gens de latència) és utilitzar el JV-1010.
Em baso en:
Necessito un cable que converteixi USB a MIDI:
ara busco un script que em funcioni quan connecti la EWI-USB, i que funcioni tant per a un synth hard (roland) com per a un synth soft (fluidsynth):
ewiscript.sh, versió 1:
#!/bin/sh #script que s'ha d'executar quan connectem el EWI-USB. Dos casos: a) synth hardware (roland); b) synth software (fluidsynth) #mirem si tenim connectat el cable usb-midi if [ -z `/usr/bin/aconnect -iol | grep USB2.0-MIDI | awk '/client/{print $1}'` ]; then #no està connectat: b) synth software (fluidsynth) if [ -z `pidof -s fluidsynth` ]; then screen -d -m -S fluidsynth -t "fluidsynth" /usr/bin/fluidsynth -a alsa -m alsa_seq -g 1 /home/pi/Natural_Oboe.sf2 /bin/sleep 3 /usr/bin/amixer set Master 40%+ > /dev/null /bin/sleep 2 FLUIDSYNTH=$(/usr/bin/aconnect -o -l | awk '/FLUID/{print $2."0"}') /bin/sleep 2 #echo $FLUIDSYNTH /usr/bin/aconnect EWI-USB:0 $FLUIDSYNTH /bin/sleep 2 fi else #a) synth hardware (roland) USBMIDI=$(/usr/bin/aconnect -o -l | awk '/client/' | awk '/USB2.0/{print $2."0"}') /usr/bin/aconnect EWI-USB:0 $USBMIDI /bin/sleep 2 fi
creat per Joan Quintana Compte, abril 2013