Results 1 to 7 of 7

Thread: Send and receive MIDI (Musical Instruments Digital Interface) messages with ThinBasic

  1. #1
    Junior Member
    Join Date
    Feb 2013
    Location
    Induno Olona (VA) Italy
    Age
    50
    Posts
    15
    Rep Power
    16

    Send and receive MIDI (Musical Instruments Digital Interface) messages with ThinBasic

    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
    Attached Files Attached Files

  2. #2
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,528
    Rep Power
    170
    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?
    I think there are missing some Forum-sections as beta-testing and support

  3. #3
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    A MIDI module is something I should start.
    I will think about that in next thinBasic versions
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  4. #4
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    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
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  5. #5
    Junior Member
    Join Date
    Feb 2013
    Location
    Induno Olona (VA) Italy
    Age
    50
    Posts
    15
    Rep Power
    16
    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?)

    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

  6. #6
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    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
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  7. #7
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    I have created a specific forum area for Midi module:





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

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

    Ciao
    Eros
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

Similar Threads

  1. Cannot get COMM to receive
    By fgasoi in forum COMM (Serial communication)
    Replies: 7
    Last Post: 18-02-2010, 08:51
  2. thinBasic interface under IBasic language
    By RobertoBianchi in forum Module SDK (IBasic version)
    Replies: 5
    Last Post: 19-07-2009, 18:57
  3. thinBasic interface under CGG C/C++ language
    By RobertoBianchi in forum Module SDK (GCC C /C++)
    Replies: 8
    Last Post: 29-04-2009, 14:44
  4. thinBasic interface under Borland C/C++ language
    By RobertoBianchi in forum Module SDK (Borland C /C++)
    Replies: 1
    Last Post: 05-12-2006, 00:24
  5. thinBasic interface under Power Basic
    By ErosOlmi in forum Module SDK (Power Basic version)
    Replies: 2
    Last Post: 18-01-2006, 19:27

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •