PDA

View Full Version : Send and receive MIDI (Musical Instruments Digital Interface) messages with ThinBasic



maxer73
08-03-2013, 02:02
Ciao a tutti, sono Max, un nuovo utente ThinBasic da circa 2 settimane,

Mi ha detto Eros di scrivere in italiano (la mia lingua) inquanto il mio inglese è abbastanza scarso.
Scusatemi per questo, io ho studiato inglese a scuola (25 anni fa) quindi sono arrugginito...

Ho scritto del codice per inviare e ricevere messaggi MIDI e dopo giorni e giorni di prove questo funziona,
grazie anche a Eros che mi ha aiutato.

Per chi non lo conosce, il MIDI (Musical Instruments Digital Interface) è un protocollo che viene usato
per inviare e ricevere messaggi di controllo tra vari strumenti musicali digitali oppure tra il computer e questi,
questi messaggi servono ad esempio per fare suonare una determinata nota, per cambiare strumento (pianoforte,
violino, tromba, basso, batteria ecc), per settare il volume, per settare l'intonazionee e tantissime altre funzioni in
tempo reale, tutti gli strumenti musicali digitali (compreso il computer) hanno centinaia di queste funzioni e tramite
l'interfaccia MIDI e questo protocollo (che è uno standard da molti anni) si può controllare in remoto qualsiasi
parametro. http://en.wikipedia.org/wiki/MIDI

Ci sono molti programmi musicali che fanno uso del protocollo MIDI, guardate ad esempio Cubase, Logic, ProTools,
Digital Performer, Ableton Live e con il MIDI è possibile controllare sia altri programmi che ne fanno uso sullo stesso
computer, sia apparecchiature esterne.

Per controllare apparecchiature esterne, il nostro computer deve avere un'interfaccia MIDI che può essere, una
scheda audio professionale, oppure una semplice soundblaster oppure ancora una qualsiasi scheda audio da 10$.

Nel caso di schede audio professionali, esistono già i connettori, dove bisogna semplicemente collegare una
estremità del cavo MIDI e l'altra estremità nello strumento che dobbiamo comandare.

Nel caso invece di schede a basso costo bisogna procurarsi un cavo convertitore che va inserito nella presa
Joystick e dall'altra parte ha connettori MIDI per connettersi ai vari strumenti.

Esistono anche schede MIDI via cavo USB, sono in commercio tantissimi modelli e costano poche decine di $.

Con il MIDI si possono fare anche vari esperimenti particolari, io ad esempio ho scritto vari programmi che girano
sotto piattaforma Android (smartphones e tablets), che inviano mediante protocollo UDP dei messaggi di controllo,
poi ho scritto con TB un'applicazione che riceve i dati UDP, li converte in MIDI e mediante driver virtuali MIDI
(MIDI Yoke NT, LoopBe1 e altri) li invia a programmi musicali come Cubase, dove posso controllare qualsiasi
parametro, tutto questo sulla rete WiFi e col latenza di 5-10 millisecondi.
Questi dati possono anche essere inviati in tempo reale alle apparecchiature musicali esterne.
Io in questo momento uso come porta virtuale MIDI Yoke NT e mi trovo bene http://www.midiox.com/

Venendo al nostro lavoro, usando le API di Windows e precisamente la libreria dinamica "winmm.dll" si può accedere
a tutte le funzionalità MIDI del sistema in uso... per chi non conosce questa libreria, consiglio vivamente di fare una
ricerca su Google, perchè permette di fare molte cose, anche gestire i formati MidiFile, streaming l'audio, streaming
video e cattura da webcam. Nei miei moduli ho messo solo le chiamate per il sistema Midi.

Per conoscere il numero di porte midi Outputs e Inputs del sistema si fa così:

numDevicesOut = midiOutGetNumDevs() 'get number of midi output devices
numDevicesIn = midiInGetNumDevs() 'get number of midi input devices

Tutte le porte midi hanno un indice, per sapere il nome di una porta ad un determinato indice si fa così:

MidiOutGetDevCaps INDEX, OutCaps, Len(OutCaps) 'get the name of midi out at INDEX of port
MidiInGetDevCaps INDEX, InCaps, Len(InCaps) 'get the name of midi in at INDEX of port

Quindi ad esempio per conoscere tutti i Midi Outs si fa così:

For i As Integer = 0 To (numDevicesOut - 1) 'for all Midi outs NOTE: index is base 0
MidiOutGetDevCaps i, OutCaps, Len(OutCaps) 'get the name of index (i) port
PrintL "Device Out " & i & ":" & $TAB & OutCaps.szPname
Next

Per aprire una determinata porta MidiOut o MidiIn si fa così:

init_MIDI_OUT(index) 'index is base 0
init_MIDI_IN(index) 'index is base 0

Ricorda che la porta precedentemente aperta MidiOut o MidiIn che sia va sempre chiusa prima di aprirne
un'altra o alla fine del programma (se si utilizza sempre quella porta) questo si può fare così:

end_MIDI_OUT '<<<=== always CLOSE the Midi Out port that you had previously opened
end_MIDI_IN '<<<=== always CLOSE the Midi In port that you had previously opened

Se si utilizza UI e si ha intenzione ad esempio di aprire una porta all'inizio del programma e chiuderla alla
fine del programma si può fare rispettivamente in %WM_INITDIALOG e in %WM_DESTROY, se invece si
desidera cambiare porta nel corso dell'esecuzione del programma allora ricordatevi di chiudere quella
precedente.

Volendo, si possono aprire più porte contemporaneamente ma bisogna essere sicuri che alla fine del
programma, tutte siano chiuse, altrimenti gli altri programmi non riescono ad accedere a una
determinata porta in quanto non è stata precedentemente chiusa. (questo è simile alla gestione porte UDP)

Allego uno zip con 3 file, ci sono i due moduli Per MidiOut e MidiIn e un semplice esempio che apre la porta 0
per suonare alcune note con le voci GeneralMidi di Windows:

-Main MidiTest.tbasic
-module MidiOut.tbasic
-module MidiIn.tbasic

Se non vi funziona dovete cambiare il numero di porta nell'istruzione

init_MIDI_OUT(0) 'if don't work change to -1 (MidiMapper) 1,2,3,4 etc......

Non sono pratico di TB ma sarebbe bello se si potesse creare una DLL e fare in modo da usare il midi in questo
modo:

Uses "MidiOut"
Uses "MidiIn"
in modo da poterle mettere nella cartella Lib insieme a tutte le altre librerie dinamiche.

Ciao a tutti, spero che questo serva a qualcuno... se avete commenti o modifichè sarò felice di ascoltarvi.
Max

ReneMiner
08-03-2013, 13:51
Cool, my thinBasic can play orchestra now. :)

Thanks for sharing this.

Makes me think of some TBMIDI-module, so thinBasic could load common midifiles to some midi-soundlist (similar to an image- or spritelist where each element has an Index) and plays as



If TBMIDI_LoadFile(Index, "C:\Filename.mid") Then TBMIDI_PlayFile(Index [, Volume [, Channel [, Instrument [, Balance [, Pitch]]]]])


but I think that needs some kind of coding like a task or thread or timer so the music will continue to play without holding the program flue.
the rest would be somewhat like

TBMIDI_Stop(Index)
TBMIDI_SetPosition(Index, Beat? or Time?)
TBMIDI_EjectFile(Index)

and also

TBMIDI_PlayNote(Note, Duration [, Volume [, Instrument [, Balance]]]])

which would offer simple way to create own pieces of music without having a midi-keyboard-device or even to create some music-composing-utility and would allow even me to develop and save to my own Midi-file-format - since I have no idea about the common midi-file-structure.

So currently I would use Function NoteOn() and create a timer for each note to stop it again through NoteOff(). Is that the right way?

ErosOlmi
08-03-2013, 16:48
A MIDI module is something I should start.
I will think about that in next thinBasic versions

Petr Schreiber
09-03-2013, 17:17
Ciao maxer73,

thanks for your code and info - the demo run perfectly on my PC, even the MIDI-In device was correctly detected.
I am looking forward to more examples!


Petr

maxer73
09-03-2013, 19:03
Grazie Eros, spero che in futuro si possano aggiungere questi moduli...

Per chi lavora con la musica sono di fondamentale importanza, visto che apre mondi nuovi,
dove è possibile, come ho già detto comandare in remoto (e viceversa) sia programmi che
strumenti musicali mediante interfaccia MIDI, per l'assurdo è possibile usare uno di quei tanti
mixer o controlli esterni che sono in commercio, per controllare qualsiasi aspetto di TB, ad
esempio in UI, con uno slider muovere una finestra in asse X, con un'altro l'asse Y, con
un'altro fare lo scroll di una ListBox, con un pulsante fisico si può inoltre simulare la pressione
di un Button, una CheckBox ecc...

Con TBGL ad esempio sarebbe possibile controllare, con gli slider la rotazione della vista
camera o di un modello in asse X,Y e Z, premendo un pulsante potrei azzerare la vista ecc...

Fino ad ora ho scritto codice in TB che utilizza la risoluzione proprietaria di 7bit (0-127), ma
il MIDI va ben oltre a questo, permettendo di inviare segnali NRPN a 14bit (0-16383) cosi
che questo sia il valore di ogni controllo da min a max.

In una vista TBGL ad esempio potrei ruotare un modello con la risoluzione di
(360/16384) = 0,02197265625 gradi per ogni tick, questo magari con tre slider su tutti gli
assi, con un altro controllare lo zoom ecc....

Esistono decine di questi controller sul mercato, sono in vendita dai 100$ a parecchie
decine di migliaia di $ (vedi ProTools) e hanno sia prese proprietarie MIDI che USB e se ne
possono collegare molti in cascata arrivando a migliaglia di controlli in tempo reale...

http://www.behringer.com/EN/Products/BCF2000.aspx
http://www.behringer.com/EN/Products/BCR2000.aspx
http://www.sweetwater.com/c808--Mixing_Control_Surfaces

Il bello è che sono tutti motorizzati (hai visto la mia tastiera?)
https://www.youtube.com/watch?v=T62riWsbyNI
sfruttando sia MidiOut che MidiIn hanno retroattività, se io ad esempio farò una modifica
con TB ed invio il midi, essi si sposteranno da soli seguendo le modifiche in modo che
quando andrò a spostarli fisicamente non ci saranno salti di valore.

Spero questo ti faccia capire l'importanza di aggiungere in modo proprietario mediante
librerie, le funzionalità MIDI in ThinBasic.

A tutti gli utenti che leggono il Thread sul MIDI pensando che sia un argomento
prettamente musicale, dico che questo non è vero al 100 per cento, semplicemente
il MIDI è controllo in tempo reale...

Ciao e grazie

Petr Schreiber
10-03-2013, 10:44
Would it be possible to post a tiny example on how to receive events from MIDI controller?

As you wrote - MIDI controller can have wide range of use, and I would like to experiment with it :)


Petr

ErosOlmi
10-03-2013, 11:04
I have created a specific forum area for Midi module: http://www.thinbasic.com/community/images/misc/navbit-home.png (http://www.thinbasic.com/community/index.php)



Forum (http://www.thinbasic.com/community/forum.php)

thinBasic (the language) (http://www.thinbasic.com/community/forumdisplay.php?189-thinBasic-(the-language))

Modules specific issues (http://www.thinbasic.com/community/forumdisplay.php?237-Modules-specific-issues)

Midi (http://www.thinbasic.com/community/forumdisplay.php?389-Midi)






Module is still not existing but I'm working on creating it.

So please post midi thread/post in this new forum.

Ciao
Eros