Enviar missatges MIDI des de la shell: amidi i echo

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

S'explica dues maneres d'enviar missatges midi per la consola al sintetitzador (hardware o software). La primera és utilitzar l'aplicatiu ALSA amidi. La segona manera és enviar mitjançant echo el senyal directament al dispositiu. Les dues maneres serien equivalents.

A més a més, s'explica com crear els ports virtuals midiraw, que és la manera de poder utilitzar sintetitzadors software com fluidsynth. La idea és que un port midi espera redirigir el missatge a un dispositiu físic. Si vull que el missatge quedi dins de l'ordinador per a ser redirigit cap a un soft synth, aleshores necessito un port virtual.

Tant d'una manera com de l'altra (amidi i echo) utilitzo la funció sleep entre el NOTE ON i el NOTE OFF. No toco una nota fins que no s'ha fet NOTE OFF de l'altra. És a dir, amb aquests dos exemples no s'implementa res de scheduling, que és un tema important: el tractament i la sincronització dels events.

amidi

$ man amidi
amidi - read from and write to ALSA RawMIDI ports

Vull enviar missatges MIDI directament al port MIDI mitjançant scripts en línia de comandes.

Provo el que he trobat en el fil de la llista de distribució LAU (Re: [LAU] sending random midi notes from a bash script, 6-feb-2010):

# play middle C for 2 seconds
# on channel 1 then turn it off
amidi -p hw:1,0 -S "90 3C 7F"
sleep 2
amidi -p hw:1,0 -S "90 3C 00"

i de moment no sento res... intentant que soni amb el fluidsynth...

Ara bé, connectant el sintetitzador Roland JV-2080 sona fantàstic (el JACK no ha d'estar encès, doncs ocuparia el recurs). I és que el EDIROL UA25-EX és el meu dispositiu rawmidi per defecte:

$ cat /proc/asound/devices 
...
 11: [ 1- 0]: raw midi
...

In addidion to the "amidi" ALSA raw midi utility that has been suggested, you can also easily write from a bash script to character devices, either the OSS (/dev/midi*) or the ALSA ones (/dev/snd/midiC*). You can even create a virtual MIDI port using the ALSA module snd-virmidi, so you can write chars to a /dev/midi* node and connect the other side (the ALSA sequencer port) to a synth.

$ ls /dev/snd
controlC0  midiC1D0  pcmC0D0p  pcmC0D2c  pcmC0D4p  pcmC1D0p  timer
controlC1  pcmC0D0c  pcmC0D1c  pcmC0D3c  pcmC1D0c  seq
$ amidi -l
Dir Device    Name
IO  hw:1,0,0  UA-25EX MIDI 1

veiem que coincideix amb el dispositiu midiC1D0 que podem veure a /dev/snd. Els valors es corresponen a Card, Dev, Subdev. Per tant, midiC1D0 és la card #1 (la 0 és la interna) i Dev #0.

Efectivament, la Edirol UA-25EX és la card#1.

$ cat /proc/asound/cards 
 0 [ICH6           ]: ICH4 - Intel ICH6
                      Intel ICH6 with STAC9752,53 at irq 16
 1 [UA25EX         ]: USB-Audio - UA-25EX
                      EDIROL UA-25EX at usb-0000:00:1d.2-1, full speed

miro tots els dispositius:

$ cat /proc/asound/devices 
  2:        : timer
  3:        : sequencer
  4: [ 0- 4]: digital audio playback
  5: [ 0- 3]: digital audio capture
  6: [ 0- 2]: digital audio capture
  7: [ 0- 1]: digital audio capture
  8: [ 0- 0]: digital audio playback
  9: [ 0- 0]: digital audio capture
 10: [ 0]   : control
 11: [ 1- 0]: raw midi
 12: [ 1- 0]: digital audio playback
 13: [ 1- 0]: digital audio capture
 14: [ 1]   : control

i veig que raw midi només n'hi ha un: el 1-0

Amb aconnect -o mostraré els dispositius MIDI amb capacitat de sortida:

$ aconnect -o
cliente 14: 'Midi Through' [tipo=kernel]
    0 'Midi Through Port-0'
cliente 20: 'UA-25EX' [tipo=kernel]
    0 'UA-25EX MIDI 1  '
cliente 128: 'TiMidity' [tipo=usuario]
    0 'TiMidity port 0 'HOWTO Use MIDI Sequencers With Softsynths.
    1 'TiMidity port 1 '
    2 'TiMidity port 2 '
    3 'TiMidity port 3 '
cliente 131: 'FLUID Synth (5291)' [tipo=usuario]
    0 'Synth input port (5291:0)'

i veig que no hi ha cap rawMIDI, i és per això que encara no he aconseguit sentir res. Això no és cert, ja hem dit que la UA-25EX sí que es raw midi,i es correspon a un port físic real. Ara bé, si vull fer sonar el fluidsynth, necessito un Virutal MIDI Port.

Important llegir: HOWTO Use MIDI Sequencers With Softsynths

Què és un Virtual MIDI Device?

But MIDI sequencers like to output their notes to MIDI devcat /proc/asound/devices 
ices that normally route their events to the outside world, i.e., to hardware synths and samplers. With virtual MIDI devices one can keep the MIDI data inside the computer and let it control other software running on the same machine. This HOWTO describes all that is necessary to achieve this goal. 

És a dir, si vull redirigir els missatges MIDI que genero a fluidsynth (o a PD, o a CSound), necessito un port midi virtual per retenir el missatge MIDI a dins de l'ordinador.

To use ALSA's virtual MIDI card the snd-card-virmidi module must be present. In the most recent versions of ALSA (and in the 2.5.x development kernel) that module lost its '-card' middle-fix and was renamed to snd-virmidi. Make sure that you did build this module, it might be missing if you configured ALSA to build only the modules for your actual card(s).

The virmidi module has to be loaded to make the virtual MIDI ports available. You can test-load it by hand with

$ modprobe snd-virmidi snd_index=1

Efectivament, faig (necessari els dos passos)

$ sudo modprobe snd-virmidi -> em sembla que carrego el mòdul
$ sudo modprobe snd-virmidi snd_index=2 -> fico index=2 perquè és el primer index que tinc lliure (tinc dues targetes, la 0 i la 1)
$ aconnect -o
...
cliente 20: 'UA-25EX' [tipo=kernel]
    0 'UA-25EX MIDI 1  '
cliente 24: 'Virtual Raw MIDI 2-0' [tipo=kernel]
    0 'VirMIDI 2-0     '
cliente 25: 'Virtual Raw MIDI 2-1' [tipo=kernel]
    0 'VirMIDI 2-1     '
cliente 26: 'Virtual Raw MIDI 2-2' [tipo=kernel]
    0 'VirMIDI 2-2     '
cliente 27: 'Virtual Raw MIDI 2-3' [tipo=kernel]
    0 'VirMIDI 2-3     '
...

Veig que ja tinc 4 ports midi virtuals.

Efectivament, ara ja tinc tres targetes de so:

$ cat /proc/asound/cards 
 0 [ICH6           ]: ICH4 - Intel ICH6
                      Intel ICH6 with STAC9752,53 at irq 16
 1 [UA25EX         ]: USB-Audio - UA-25EX
                      EDIROL UA-25EX at usb-0000:00:1d.2-1, full speed
 2 [VirMIDI        ]: VirMIDI - VirMIDI
                      Virtual MIDI Card 1

i també:

$ cat /proc/asound/devices 
  2:        : timer
  3:        : sequencer
  4: [ 0- 4]: digital audio playback
  5: [ 0- 3]: digital audio capture
  6: [ 0- 2]: digital audio capture
  7: [ 0- 1]: digital audio capture
  8: [ 0- 0]: digital audio playback
  9: [ 0- 0]: digital audio capture
 10: [ 0]   : control
 11: [ 1- 0]: raw midi
 12: [ 1- 0]: digital audio playback
 13: [ 1- 0]: digital audio capture
 14: [ 1]   : control
 15: [ 2- 3]: raw midi
 16: [ 2- 2]: raw midi
 17: [ 2- 1]: raw midi
 18: [ 2- 0]: raw midi
 19: [ 2]   : control

i també:

ls /dev/snd
controlC0  controlC1  controlC2  midiC1D0  midiC2D0  midiC2D1  midiC2D2  midiC2D3  pcmC0D0c  pcmC0D0p  pcmC0D1c  pcmC0D2c  pcmC0D3c  pcmC0D4p  pcmC1D0c  pcmC1D0p  seq  timer

Si vull linkar aquests dispositius virtuals amb la localització dels dispositius OSS (dev/midi*), faré una cosa similar a:

 $ ln -s /dev/snd/midiC2D0 /dev/midi20
 $ ln -s /dev/snd/midiC2D1 /dev/midi21
 [...]

però això no és necessari.

Now that we have created and configured a VirtualMIDI card we can use it in our applications just like any other MIDI devices. Just insert the needed device, be it an OSS-compatible /dev/midi20 or an ALSA MIDI port like 80:0, at the correct configuration point of your favourite sequencer and synthesizer application.

És a dir, ja estic a punt per provar de fer funcionar el meu exemple d'enviar missatges MIDI des de la consola. Engego el JACK, engego el fluidsynth, i a la pestanya ALSA del JACK connecto el 24:Virtual RAW MIDI 2-0 al fluidsynth.


# play middle C for 2 seconds
# on channel 1 then turn it off
amidi -p hw:2,0 -S "90 3C 7F" \
sleep 2 \
amidi -p hw:2,0 -S "90 3C 00"

Replace your port as needed... en el meu cas 2,0

i ja està, ja funciona. 3C és correspon en hexadecimal a 60, que és el Do central. 90 és la velocity.

Per tant, la manera de tocar la cançó Una Plata d'Enciam des de la línia de comandes serà:

# Una Plata d'Enciam
#Do: 3C; Re: 3E; Mi: 40; Fa: 41: Sol: 43: La: 45; Si; 47; Do: 48
#negra: 0.5; corxea: 0.25; treset de corxea: 0,17

#e f g g a a g a a g f f f f f g e
#e f g g a a g a a g f e f g e

amidi -p hw:2,0 -S "90 40 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 40 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.5
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 40 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 40 00"
#
amidi -p hw:2,0 -S "90 40 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 40 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.5
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 45 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 45 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.17
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 40 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 40 00"
amidi -p hw:2,0 -S "90 41 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 41 00"
amidi -p hw:2,0 -S "90 43 7F"
sleep 0.25
amidi -p hw:2,0 -S "90 43 00"
amidi -p hw:2,0 -S "90 40 7F"
sleep 0.5
amidi -p hw:2,0 -S "90 40 00"

El més correcte és que el script inclogui totes les comandes: arrencar el JACK, el fluidsynth, establir les connexions, i fer sonar la cançó... en cas de què vulgui l'automatització.

Nota: recordem que només necessito el virtual midi port per fer-ho sonar a través del fluidsynth. Sempre puc fer sonar els missatges midi a través del port físic de la targeta de so, i fer-ho sonar pel Roland JV-2080 o pel Casio CTK-731.

Nota: tot això quan treballo amb el MidiShare no ho necessito perquè d'alguna manera el midishare ja és un port midi virtual que sap treballar amb ALSA. (msAlsaSeq - ALSA driver for MidiShare)

echo

L'altra possibilitat és utilitzar echo directament al dispositiu. Utilitzo en aquest cas el sintetitzador hardware: /dev/midi1 o /dev/snd/midiC1D0, que són equivalents (/dev/midi1 és la notació OSS, millor fer servir /dev/snd/midiC1D0 que és el dispositiu ALSA. Hi ha un link entre ells).

Hi ha dos exemples a /way6, que els he tret de la discussió que hi havia a la LAU sobre la manera d'enviar missatges MIDI a la línia de comandes: midiclock i green.

Les comandes bàsiques que s'utilitzen són:

$ echo -ne '\x90\x46\x64' > /dev/snd/midiC1D0
$ sleep 2
$ echo -ne '\x80\x46\x64' > /dev/snd/midiC1D0

és a dir, envio directament el missatge midi al dispositiu. x90 és NOTE ON en hexadecimal, i x80 és NOTE OFF. x46 és el La# (x46 = 4*16 + 6 = 64 + 6 = 70), i x64 és el volum (x64=6*16+4=100)

tune="48-64 2,48-64 2,48-64 2,48-64 2," -> toca la nota x48 4 vegades (blanques)
tune="48-64-50-64-52-64 2," -> és un acord de les notes x48, x50, x52

Com a valor de tempo el programa permet rodona (1), blanca (2), negra (4), corxea (8), negre amb punt (3)

function computetimes() {
	for T in 1 2 3 4 8; do
		let "ms = 2400000 / ( $T * $tempo )"
		TIME[$T]=$ms'e-4s'
	done
}

El 3 és la negre amb punt, doncs 1/4+1/8=3/8= 1/2.66, i aproximem 2.66 a 3. Igual que vaig fer amb el lilypond2musicbox, puc aconseguir fer tresets mirant quin és el mcm (o el MCD).

green (Greensleaves):

#!/bin/bash

# Greensleaves - Ancient traditional song
# Program: Copyright (C) 2002  Pedro Lopez-Cabanillas
# based on a public domain musical arrangement by Aaron Fontaine.
# Download the score from http://www.mutopiaproject.org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

tune="45-64 4,\
      48-64-39-64 2, 4a-64-3b-64 4,\
      4c-64-3c-64 3, 4d-64 8, 4c-64 4,\
      4a-64-37-64 2, 47-64 4,\
      43-64-3b-64 3, 45-64 8, 47-64 4,\
      48-64-39-64 2, 45-64 4,\
      45-64-41-64 3, 44-64 8, 45-64 4,\
      47-64-40-64 2, 44-64 4,\
      40-64-34-64 2, 45-64 4,\
      48-64-39-64 2, 4a-64-3b-64 4,\
      4c-64-3c-64 3, 4d-64 8, 4c-64 4,\
      4a-64-37-64 2, 47-64 4,\
      43-64-3b-64 3, 45-64 8, 47-64 4,\
      48-64-39-64 3, 47-64 8, 45-64 4,\
      44-64-34-64 3, 42-64 8, 44-64 4,\
      45-64-39-64 2, 0 4,\
      45-64-39-64 2, 0 4,\
      4f-64-3c-64 2, 4f-64 4,\
      4f-64-3c-64 3, 4d-64 8, 4c-64 4,\
      4a-64-37-64 2, 47-64 4,\
      43-64-3b-64 3, 45-64 8, 47-64 4,\
      48-64-39-64 2, 45-64 4,\
      45-64-41-64 3, 44-64 8, 45-64 4,\
      47-64-40-64 2, 44-64 4,\
      40-64-34-64 2, 0 4,\
      4f-64-3c-64 2, 4f-64 4,\
      4f-64-3c-64 3, 4d-64 8, 4c-64 4,\
      4a-64-37-64 2, 47-64 4,\
      43-64-3b-64 3, 45-64 8, 47-64 4,\
      48-64-39-64 3, 47-64 8, 45-64 4,\
      44-64-34-64 3, 42-64 8, 44-64 4,\
      45-64-39-64 2, 0 4,\
      45-64-39-64 1,"

#/dev/midi1 és la notació OSS. Amb ALSA és preferible /dev/snd/midiC1D0, i hi ha com un enllaç simbòlic entre ells.
#Si tinc un port virtual puc fer servir per ex midiC2D0, i aleshores puc fer servir el fluidsynth.
#mididev="${1:-/dev/midi1}"
mididev="${1:-/dev/snd/midiC1D0}"
tempo=160 # bpm
declare -a TIME

function computetimes() {
	for T in 1 2 3 4 8; do
		let "ms = 2400000 / ( $T * $tempo )"
		TIME[$T]=$ms'e-4s'
	done
}

function playnotes() {
	if [ "$1" == "0" ]; then
		sleep ${TIME[$2]}
	else
		echo -ne '\x90\x'${1//-/'\x'} >&3
		sleep ${TIME[$2]}
		echo -ne '\x80\x'${1//-/'\x'} >&3
	fi
}

function playtune() {
	echo $1|while read -d, msg length; do
			playnotes $msg $length
		done
}


if [ -e $mididev -a -w $mididev ]; then
	echo
	echo "This is \"Greensleaves\", an ancient traditional song"
	echo "based on a public domain arrangement by Aaron Fontaine."
	echo "Download the score from http://www.mutopiaproject.org"

	hash sleep 
	computetimes
	exec 3>$mididev
	echo -ne '\xb0\x07\x40' >&3	# volume
	echo -ne '\xc0\x18' >&3		# instrument = guitar
	playtune "$tune" 
	exec 3<&-
	echo
else
	echo "`basename $0`: invalid MIDI device ($mididev)"
fi

midiclock.sh

#!/bin/bash

# London Tower Big Ben tune as a simple bash script
# Copyright (C) 2002 Pedro Lopez-Cabanillas
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Usage:
#    $ midiclock /dev/midi0

tune="C 4, E 4, D 4, g 2, C 4, D 4, E 4, C 2, \
      E 4, C 4, D 4, g 2, g 4, D 4, E 4, C 2,"

#/dev/midi1 és la notació OSS. Amb ALSA és preferible /dev/snd/midiC1D0, i hi ha com un enllaç simbòlic entre ells.
#Si tinc un port virtual puc fer servir per ex midiC2D0, i aleshores puc fer servir el fluidsynth.
#mididev="${1:-/dev/midi1}"
mididev="${1:-/dev/snd/midiC1D0}"
tempo=80 # quarters per minute

function playnote() {
	let "ms = 240000 / ($2 * $tempo)"
	echo -ne '\x90' >&3
	echo -ne "$1\144" >&3
	sleep $ms'e-3s'
	echo -ne '\x80' >&3
	echo -ne "$1\000" >&3
}

function playtune() {
	echo $1 | tr "cdefgabCDEFGAB" "<>@ACEGHJLMOQS" | \
		while read -rd, note length; do
			playnote $note $length
		done
}

function playhour() {
	h=$(date +%l)
	while [ $h -gt 0 ]; do
	    playnote $'\x37' 2
	    let "h--"
	done
}

if [ -e $mididev -a -w $mididev ]; then
	exec 3>$mididev
	echo -ne '\xb0\x07\x7f' >&3	# volume = 127
	echo -ne '\xc0\x0e' >&3		# instrument = bells
	playtune "$tune"
	sleep 2
	playhour
	exec 3<&-
else
	echo "`basename $0` : invalid MIDI device ( $mididev )"
fi

Faig una modificació per tal de poder fer triplets...

# per fer triplets i d'altres, faig la següent modificació (similar al que havia fet a lilipond2musicbox:
# rodona: 				1/1
# blanca:				1/2
# negra:					1/4
# corxea:				1/8
# semicorxea:			1/16
# negra amb punt:		3/8
# corxea amb punt:	3/16
# triplet corxees:	1/12
# triplet negres:		1/6

# mcm(3,16)=48
# ho multiplico tot per 1/48

# rodona: 				1/48
# blanca:				1/96
# negra:					1/192
# corxea:				1/384
# semicorxea:			1/768
# negra amb punt:		1/128
# corxea amb punt:	1/256
# triplet corxees:	1/576
# triplet negres:		1/288

function computetimes() {
	for T in 48 96 128 192 256 288 384 576 768; do
		let "ms = 2400000*48 / ( $T * $tempo )"
		TIME[$T]=$ms'e-4s'
	done
}

A partir d'aquí, jo faig el meu script una_plata_denciam2.sh:

#!/bin/bash

# Una Plata d'Enciam (Project 50 Ways to Play Una Plata d'Enciam)
# Joan Quintana Compte - Joanillo - 2010. www.joanillo.org
# this is just an adaptation of the file green released by Pedro Lopez-Cabanillas (thanks!)
# Search the post in the LAU distribution list: [LAU] sending random midi notes from a bash script, feb 2010

# Program: Copyright (C) 2002  Pedro Lopez-Cabanillas
# based on a public domain musical arrangement by Aaron Fontaine.
# Download the score from http://www.mutopiaproject.org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# per fer triplets i d'altres, faig la següent modificació (similar al que havia fet a lilipond2musicbox:
# rodona: 				1/1
# blanca:				1/2
# negra:					1/4
# corxea:				1/8
# semicorxea:			1/16
# negra amb punt:		3/8
# corxea amb punt:	3/16
# triplet corxees:	1/12
# triplet negres:		1/6

# mcm(3,16)=48
# ho multiplico tot per 1/48

# rodona: 				1/48
# blanca:				1/96
# negra:					1/192
# corxea:				1/384
# semicorxea:			1/768
# negra amb punt:		1/128
# corxea amb punt:	1/256
# triplet corxees:	1/576
# triplet negres:		1/288

# i aquests són els valors que ficaré, i així ja puc fer tresets, semicorxees, negra amb punt i corxea amb punt

# 1a veu (una_plata_denciam_v9.pdf)
#tune="4C-64 384,4D-64 384,4F-64 384,4F-64 384,51-64 384,51-64 384,4F-64 192,\
#	51-64 576,51-64 576,4F-64 576,4D-64 384,4D-64 384,4D-64 576,4D-64 576,4D-64 576,4F-64 384,4C-64 384,\
#	4C-64 384,4D-64 384,4F-64 384,4F-64 384,51-64 384,51-64 384,4F-64 192,
#	51-64 576,51-64 576,4F-64 576,4D-64 384,4C-64 384,4D-64 384,4F-64 384,4C-64 192,"

# 2a veu
#tune="48-64 384,4A-64 384,4C-64 384,4C-64 384,4D-64 384,4D-64 384,4C-64 192,\
#	4D-64 576,4D-64 576,4C-64 576,4A-64 384,48-64 384,4A-64 576,4A-64 576,4A-64 576,4C-64 384,48-64 384,\
#	48-64 384,4A-64 384,4C-64 384,4C-64 384,4D-64 384,4D-64 384,4C-64 192,\
#	4D-64 576,4D-64 576,4C-64 576,4A-64 384,48-64 384,4A-64 384,4C-64 384,48-64 192,"

# 3a veu
#tune="40-64 384,41-64 384,43-64 384,48-64 384,47-64 384,45-64 384,43-64 192,\
#	41-64 576,41-64 576,40-64 576,3E-64 384,3E-64 384,3E-64 576,3C-64 576,3E-64 576,40-64 384,3C-64 384,\
#	40-64 384,41-64 384,43-64 384,48-64 384,47-64 384,45-64 384,43-64 192,\
#	41-64 576,41-64 576,40-64 576,3E-64 384,3C-64 384,3E-64 384,40-64 384,3C-64 192,"

tune="4C-64-48-64-40-64 384,4D-64-4A-64-41-64 384,4F-64-4C-64-43-64 384,4F-64-4C-64-48-64 384,51-64-4D-64-47-64 384,51-64-4D-64-45-64 384,4F-64-4C-64-43-64 192,\
	51-64-4D-64-41-64 576,51-64-4D-64-41-64 576,4F-64-4C-64-40-64 576,4D-64-4A-64-3E-64 384,4D-64-48-64-3E-64 384,4D-64-4A-64-3E-64 576,4D-64-4A-64-3C-64 576,4D-64-4A-64-3E-64 576,4F-64-4C-64-40-64 384,4C-64-48-64-3C-64 384,\
	4C-64-48-64-40-64 384,4D-64-4A-64-41-64 384,4F-64-4C-64-43-64 384,4F-64-4C-64-48-64 384,51-64-4D-64-47-64 384,51-64-4D-64-45-64 384,4F-64-4C-64-43-64 192,\
	51-64-4D-64-41-64 576,51-64-4D-64-41-64 576,4F-64-4C-64-40-64 576,4D-64-4A-64-3E-64 384,4C-64-48-64-3C-64 384,4D-64-4A-64-3E-64 384,4F-64-4C-64-40-64 384,4C-64-48-64-3C-64 192,"

#/dev/midi1 és la notació OSS. Amb ALSA és preferible /dev/snd/midiC1D0, i hi ha com un enllaç simbòlic entre ells.
#Si tinc un port virtual puc fer servir per ex midiC2D0, i aleshores puc fer servir el fluidsynth.
#mididev="${1:-/dev/midi1}"
mididev="${1:-/dev/snd/midiC1D0}"
tempo=100 # bpm
declare -a TIME

#function computetimes() {
#	for T in 1 2 3 4 8 16; do
#		let "ms = 2400000 / ( $T * $tempo )"
#		TIME[$T]=$ms'e-4s'
#	done
#}

function computetimes() {
	for T in 48 96 128 192 256 288 384 576 768; do
		let "ms = 2400000*48 / ( $T * $tempo )"
		TIME[$T]=$ms'e-4s'
	done
}

function playnotes() {
	if [ "$1" == "0" ]; then
		sleep ${TIME[$2]}
	else
		echo -ne '\x90\x'${1//-/'\x'} >&3
		sleep ${TIME[$2]}
		echo -ne '\x80\x'${1//-/'\x'} >&3
	fi
}

function playtune() {
	echo $1|while read -d, msg length; do
			playnotes $msg $length
		done
}


if [ -e $mididev -a -w $mididev ]; then
	echo
	echo "This is the project \"50 Ways to play Una Plata d'Enciam\", and now I'm playing this song,"
	echo "Una Plata d'Enciam, sending MIDI messages to a synthesizer from the command line."
	echo "This bash script writes directly to the MIDI port."
	echo "This is a Linux and Free Software project related with Electronic Music and Media Art."
	echo "www.joanillo.org - Joan Quintana (Joanillo)"
	hash sleep 
	computetimes
	exec 3>$mididev
	echo -ne '\xb0\x07\x40' >&3	# volume
	echo -ne '\xc0\x18' >&3		# instrument = guitar
	playtune "$tune" 
	exec 3<&-
	echo
else
	echo "`basename $0`: invalid MIDI device ($mididev)"
fi



creat per Joan Quintana Compte, febrer 2010

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