EWI-USB amb la Raspberry Pi

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

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.

  1. Utilitzar la RP de 512 MB
  2. 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)
  3. Overclocking de la RP
  4. provar una altra targeta SD

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

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines