[Ex] Simple importation MIDI

Partagez vos scripts, et vos applications AutoIt.
Règles du forum
.
Répondre
handmusician
Niveau 1
Niveau 1
Messages : 9
Enregistré le : sam. 30 juil. 2016 22:27
Status : Hors ligne

[Ex] Simple importation MIDI

#1

Message par handmusician » dim. 31 juil. 2016 11:45

Bonjour à vous,

Je vous présente une méthode simple (juste quelques lignes de code !) pour importer du MIDI dans autoit. Pour cela, j'utilise Midi-Jazz (http://jazz-soft.net/download/Jazz-Plug ... in-1-5.msi). Voici comment procéder après installation du plugin :
; On commence par Importer le plugin dans autoit :
$Jazz=objcreate("JazzPlugin.Ctrl")

; On peut récupérer la liste des différents ports d'entrée et de sortie midi (sous forme d'arrays) :  
$ListMidiIn=$Jazz.MidiInList()
$ListMidiOut=$Jazz.MidiOutList()

; On règle l'entrée et la sortie midi :
$MidiIn="nom de l'entrée midi désirée"
$MidiOut="nom de la sortie midi désirée"
$Jazz.MidiInOpen($MidiIn)
$Jazz.MidiOutOpen($MidiOut)

; On peut aussi faire comme ça ($ID = index du port midi dans $ListMidiIn ou $ListMidiOut):
$Jazz.MidiInOpen($ID_midiin)
$Jazz.MidiOutOpen($ID_midiout)


; Ensuite pour envoyer un message midi sur le port de sortie on procède comme suit :  $Jazz.MidiOut(code midi, parametre 1 (0~127), paramètre 2 (0~127))
; Le code midi peut être soit sous la forme décimal soit sous la forme binaire 0xZn avec Z = 0~9 et A~E, n le canal sur lequel envoyer le code (n = 0~15 pour la forme décimale, pour le binaire : n = 0~9 pour canal 1 à 10, A~F pour canal 11 à 16). Pour le code midi voir ci-dessous :

; Pour jouer une note N sur le canal n avec une velocité V (noteon) :
$Jazz.MidiOut(144+n, N, V)
$Jazz.MidiOut(0x9n, N, V)


; Pour arrêter la note N sur le canal n (noteoff) :
$Jazz.MidiOut(128+n, N, V)
$Jazz.MidiOut(0x8n, N, 0)

; Pour changer le pitch bend (pitch bend = 128*e2 + e1) sur le canal n :
$Jazz.MidiOut(224+n, e1, e2)
$Jazz.MidiOut(0xEn, e1, e2)

; Pour choisir un instrument I sur le canal n (program change):
$Jazz.MidiOut(192+n, I, 0)
$Jazz.MidiOut(0xCn, I, 0)


; Pour paramétrer le controle midi C (1 = vibrato de la note, 7 = volume note, 8 = balance, 10 = Pan, 11 = expression, 64 = sustain, 71 = resonnance, 74 = cutoff, 91 = Reverb, 92 = tremolo, 93 = chorus...) avec la valeur v sur le canal n (control change) :
$Jazz.MidiOut(176+n, C, v)
$Jazz.MidiOut(0xBn, C, v)

; Pour changer la banque d'instrument MSB et LSB sur le canal n :
$Jazz.MidiOut(176+n, 0, msb)
$Jazz.MidiOut(176+n, 32, lsb)
$Jazz.MidiOut(0xBn, 0, msb)
$Jazz.MidiOut(0xBn, 32, lsb)

; Pour arrêter toutes les notes sur tous les canaux (All notes off ou midi panic) :
$Jazz.MidiOut(0xB0,123,0)

; Pour remettre à 0 tous les controles sur tous les canaux (Reset All Controllers):
$Jazz.MidiOut(0xB0,121,0)


; Pour envoyer de multiples notes (faire un accord) ou changer plusieurs controles... en un seul message. code midi comme ci-dessus, a1-a2 : paramètres 1ère note (ou 1er controle...), b1-b2 2ème...
$dim $t[]=[code midi, a1, a2, b1, b2, c1, c3, ...]
$Jazz.MidiOutLong($t)


; Pour obtenir les messages d'entrée midi in on utilise $Jazz.QueryMidiIn() (dès qu'il y a un message, $Jazz.QueryMidiIn() retourne un array [timestamp, code midi en decimal, paramètre 1, paramètre 2]) :
Func midiinmsg($mc)

; On redirige si besoin (avec la variable $midthru = 1) les messages d'entrée vers la sortie (midi thru)
if $midthru then $Jazz.MidiOut($mc[1],$mc[2],$mc[3])

$s=""
switch $mc[1]
        case 144 to 159
                $s="noteon"
        case 128 to 143
                $s="noteoff"
        case 224 to 239
                $s="pitch bend"
        case 192 to 207
                $s="program change"
        case 176 to 191
                $s="control change"
                if $mc[2]=123 then $s="All notes off"
                if $mc[2]=121 then $s="Reset All Controllers"
                if $mc[2]=0 then $s="Banque MSB"
                if $mc[2]=32 then $s="Banque LSB"
        case 160 to 175 , 208 to 223
                $s="after touch"
        case 240 to 255
                $s="System exclusive"
endswitch

; On extrait le canal :
$ch=mod($mc[1],16)+1

; On récupère le message sous forme de texte qu'on peut, par exemple, afficher dans le control input d'une gui :
return "canal = "&$ch&" "&$s&" "&$mc[2]&" "&$mc[3]
endfunc

$midthru=1
$t=$Jazz.QueryMidiIn()
if isarray($t) then $codemidi=midiinmsg($t[1])


; Avant de quitter, on ferme les ports midi ouverts :
$Jazz.MidiInClose("nom du midi in")
$Jazz.MidiOutClose("nom du midi out")
On peut également utiliser les fonctions suivantes :
; Pour effacer la mémoire tampon des messages d'entrée midi in, je ne sais pas vraiment comment utiliser cette fonction :
$Jazz.ClearMidiIn()

; Obtenir des infos sur le port midi (dans un array ["nom du port midi", "fabricant", "version du driver"]) :
$infos_midiin=$Jazz.MidiInInfo($MidiIn)
$infos_midiout=$Jazz.MidiOutInfo($MidiOut)
$infos_midiin=$Jazz.MidiInInfo($ID_midiin)
$infos_midiout=$Jazz.MidiOutInfo($ID_midiout)

; Le temps écoulé en millisecondes depuis la création de l'objet $Jazz :
$temps=$Jazz.Time()

; La version de Jazz-plugin (string) :
$version=$Jazz.version

; Je ne sais pas a quoi sert la 1ère fonction (peut-être comme $Jazz.MidiOutLong mais pour les messages de type system exclusive). Je ne sais pas comment faire fonctionner les autres fonctions :
$Jazz.MidiOutRaw($array)
$Jazz.OnConnectMidiIn()
$Jazz.OnConnectMidiOut()
$Jazz.OnDisconnectMidiIn()
$Jazz.OnDisconnectMidiOut()


Une petite démonstration :
$Jazz=objcreate("JazzPlugin.Ctrl")
$Jazz.MidiOutOpen(0)
$Jazz.MidiOut(0xC0,40,0);
$Jazz.MidiOut(144,50,100)
sleep(2000)
$Jazz.MidiOut(128,50,0)
$Jazz.MidiOutClose(0)
Une autre plus élaborée :
#include <array.au3>
#include <GuiComboBox.au3>
#include <GuiMenu.au3>
#include <GUIConstantsEx.au3>

dim $instruname[]=["Acoustic Grand Piano","Bright Piano","Electric Grand Piano","Honky-tonk piano", "Electric Piano 1","Electric Piano 2","Harpsichord","Clav","Celesta","Glockenspiel","Music Box","Vibraphone", "Marimba","Xylophone","Tubular Bells","Dulcimer","Drawbar Organ","Percussive Organ","Rock Organ","Church Organ","Reed Organ","Accordian","Harmonica","Tango Accordian","Nylon String Guitar","Steel String Guitar","Jazz Guitar","Clean Electric Guitar","Muted Electric Guitar","Overdrive Guitar","Distortion Guitar","Guitar Harmonics","Acoustic Bass","Fingered Bass","Picked Bass","Fretless Bass","Slap Bass 1","Slap Bass 2","Synth Bass 1","Synth Bass 2","Violin","Viola","Cello","Contrabass","Tremolo Strings","Pizzicato Strings","Orchestral Harp","Timpani","String Ensemble 1","String Ensemble 2","Synth Strings 1","Synth Strings 2","Choir Ahh","Choir Oohh","Synth Voice","Orchestral Hit","Trumpet","Trombone","Tuba","Muted Trumpet","French Horn","Brass Section","Synth Brass 1","Synth Brass 2","Soprano Sax","Alto Sax","Tenor Sax","Baritone Sax","Oboe","English Horn","Bassoon","Clarinet","Piccolo","Flute","Recorder","Pan Flute","Blown Bottle","Shakuhachi","Whistle","Ocarina","Square Wav","Sawtooth Wav","Caliope","Chiff","Charang","Voice","Fifth's","Bass&Lead","New Age","Warm","Polysynth","Choir","Bowed","Metallic","Halo","Sweep","FX Rain","FX Soundtrack","FX Crystal","FX Atmosphere","FX Brightness","FX Goblins","FX Echo Drops","FX Star Theme","Sitar","Banjo","Shamisen","Koto","Kalimba","Bagpipe","Fiddle","Shanai","Tinkle Bell","Agogo","Steel Drums","Woodblock","Taiko Drum","Melodic Tom","Synth Drum","Reverse Cymbal","Guitar Fret Noise","Breath Noise","Seashore","Bird Tweet","Telephone Ring","Helicopter","Applause","Gunshot"]
$instru=_ArrayToString($instruname,"|")

$Jazz=objcreate("JazzPlugin.Ctrl")

$list=$Jazz.MidiOutList()
$listi=$Jazz.MidiInList()

$gui=guicreate("MIDI TEST",500,500)
Opt("GUIOnEventMode", 1)

guisetonevent($GUI_EVENT_CLOSE,"exitprog")


GUICtrlCreateLabel("MIDI IN PORTS :",40,15)
$chgin=GUICtrlCreatecombo("",20,35,150)
;~ $inbutt=guictrlcreatebutton("OK",195,35)

GUICtrlSetOnEvent ($chgin,"changemidiin")

$mip=""
$mop=""

for $i in $listi
$mip&=($i&"|")
next
stringtrimright($mip,1)

GUICtrlSetData($chgin, $mip, $listi[0])


GUICtrlCreateLabel("MIDI OUT PORTS :",40,80)
$chgout=GUICtrlCreateCombo("",20,100,150)


GUICtrlSetOnEvent ($chgout,"changemidiout")

for $i in $list
$mop&=($i&"|")
next
stringtrimright($mop,1)
GUICtrlSetData($chgout, $mop, $list[0])

GUICtrlCreateLabel("MIDI GENERAL INSTRUMENTS :",40,150)
$instrument=GUICtrlCreateCombo("",20,170,150)
;~ $outbutt=guictrlcreatebutton("OK",195,100)

GUICtrlSetOnEvent ($instrument,"changeinstru")

GUICtrlSetData($instrument, $instru, $instruname[0])

$midthru=1
$moniton=1

$thru=guictrlcreatebutton("Thru OFF",40,230)
$monit=guictrlcreatebutton("Monitor OFF",100,230)

GUICtrlSetOnEvent($thru,"changethru")
GUICtrlSetOnEvent($monit,"changemonitor")

guictrlcreatelabel("MIDI MONITOR",320,20)
$monitor=guictrlcreateedit("",250,40,220,400)
$console=""

guisetstate()


func exitprog()
        $Jazz.MidiOut(0xB0,123,0)
        $Jazz.MidiInClose()
        $Jazz.MidiOutClose()
        $Jazz=""
        exit
endfunc

func changemidiin()
        $nport=guictrlread($chgin)
        $Jazz.MidiInOpen($nport)
endfunc

func changemidiout()
        $nport=guictrlread($chgout)
        $Jazz.MidiOut(0xB0,123,0)
        $Jazz.MidiOutOpen($nport)
        $ninst=_arraysearch($instruname,guictrlread($instrument))
        $Jazz.MidiOut(0xC0,$ninst,0)
endfunc

func changeinstru()
        $ninst=_arraysearch($instruname,guictrlread($instrument))
        $Jazz.MidiOut(0xC0,$ninst,0)
endfunc

func changethru()
        $midthru=1-$midthru
        if $midthru=0 then $Jazz.MidiOut(0xB0,123,0)
        $z= ($midthru=0) ? guictrlsetdata($thru,"Thru ON") : guictrlsetdata($thru,"Thru Off")
endfunc

func changemonitor()
        $moniton=1-$moniton
        if $moniton=0 then
                $console=""
                guictrlsetdata($monitor,"")
        endif
        $z= ($moniton=0) ? guictrlsetdata($monit,"Monitor ON") : guictrlsetdata($monit,"Monitor OFF")
endfunc

Func midiinmsg($mc)

; On redirige si besoin (avec la variable $midthru = 1) les messages d'entrée vers la sortie (midi thru)
if $midthru then $Jazz.MidiOut($mc[1],$mc[2],$mc[3])

$s=""
switch $mc[1]
        case 144 to 159
                $s="noteon"
        case 128 to 143
                $s="noteoff"
        case 224 to 239
                $s="pitch bend"
        case 192 to 207
                $s="program change"
        case 176 to 191
                $s="control change"
                if $mc[2]=123 then $s="All notes off"
                if $mc[2]=121 then $s="Reset All Controllers"
                if $mc[2]=0 then $s="Banque MSB"
                if $mc[2]=32 then $s="Banque LSB"
        case 160 to 175 , 208 to 223
                $s="after touch"
        case 240 to 255
                $s="System exclusive"
endswitch

; On extrait le canal :
$ch=mod($mc[1],16)+1

if $moniton then
if stringlen($console)>1000 then $console=""
$console&=StringAddCR("canal = "&$ch&" "&$s&" "&$mc[2]&" "&$mc[3]&@CRLF)
guictrlsetdata($monitor, $console)
endif

endfunc

while 1
$t=$Jazz.QueryMidiIn()
if isarray($t) then midiinmsg($t)
wend

Il y a de quoi simplifier encore en créant ses propres fonctions (exemple : openmidiin(), midiout("noteon",50,100), accords()...),
Merci de m'avoir lu !
Modifié en dernier par handmusician le dim. 31 juil. 2016 13:16, modifié 2 fois.

handmusician
Niveau 1
Niveau 1
Messages : 9
Enregistré le : sam. 30 juil. 2016 22:27
Status : Hors ligne

Re: [Ex] Simple importation MIDI

#2

Message par handmusician » dim. 31 juil. 2016 13:06

Merci Thierry pour la mise en forme des scripts, c'est nettement plus lisible comme ca !

Répondre