Gambas-it

Programmazione => Progetti degli utenti => Topic aperto da: vuott - 18 Maggio 2010, 23:54:31

Titolo: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 18 Maggio 2010, 23:54:31
Salve,

vorrei scrivere un programma per la lettura e per le gestione dei dati MIDI. Suppongo che la migliore cosa da fare sia far comunicare il mio futuro programma con la scheda audio mediante l'interfaccia "universale" Timidity.

Come faccio ad inviare i dati MIDI a Timidity ? Di quali istruzioni e funzioni ho bisogno ?

Grazie.
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: fsurfing - 19 Maggio 2010, 12:31:03
credo che la cosa migliore sia studiarsi a fondo il funzionamento di timidy, se è utilizzabile tramite comandi da terminale puoi sicuramente comandarlo con comandi shell, in alternativa dovresti trattarlo come una libreria e comandarlo tramite puntatore a funzioni esterne (metodo molto poco conoscuto da me :) )
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 19 Maggio 2010, 15:02:38
Salve,

vorrei scrivere un programma per la lettura e per le gestione dei dati MIDI. Suppongo che la migliore cosa da fare sia far comunicare il mio futuro programma con la scheda audio mediante l'interfaccia "universale" Timidity.

Come faccio ad inviare i dati MIDI a Timidity ? Di quali istruzioni e funzioni ho bisogno ?

Grazie.

Non ho mai provato ma potresti cercare di vedere se gambas legge i midi con la libreria sound..
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 20 Maggio 2010, 11:26:57
Innanzitutto, vorrei ringraziare i 2 colleghi del forum che hanno risposto.

Vorrei, inoltre, domandare a " fsurfing " (e comunque a chiunque possa darmi aiuto), riguardo al suo suggerimento dell'uso di comandi con Shell, se può essere utile al mio caso l'esempio seguente:

<<    SHELL "fluidsynth --connect-jack-outputs --no-shell --verbose --server
--audio-driver=jack --midi-channels=1 --portname=LiquidSynth01
-oshell.port=9800 -oaudio.jack.id=LiquidSynth01 -omidi.driver=alsa_seq
-omidi.portname=LiquidSynth01 -omidi.alsa_seq.id=LiquidSynth01"
          >>

che ho trovato sul seguente sito:
http://www.mail-archive.com/gambas-user@lists.sourceforge.net/msg03891.html

L'autore del progetto usa, inoltre, fuidsinth come demone d'interfaccia (io avevo pensato a timidity).

Che dite ?
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: fsurfing - 20 Maggio 2010, 12:24:28
ti posso solo consigliare una cosa: prova e sbattici la testa finchè non si rompe! :P, naturalmente chiedi pure su singoli quesiti.
credo che comunque l' approccio dell' utente dovrebbe essere valido, prova anche invece di utilizzare un soket a utilizzare un semplice processo, nel forum ci sono degli esempi di utilizzo di process, questo metodo cmq funziona bene se il progrmma che lanci con shell ha un output che puoi analizzare per poter gestire eventuali errori o altro
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 23 Maggio 2010, 23:38:38
Dunque, sono riuscito a richiamare Timidity con il comando Shell, ma mi sono reso conto che è lui il sequencer, e che pertanto io non avevo creato proprio niente. All'inizio avevo pensato a Timidity come demone per la sua universalità.

Ad ogni modo ho cercato un'alternativa per la realizzazione del lettore/gestore di dati Midi, e m'è venuto in mente ALSA. Dando un'occhiata nel sito di ALSA( http://www.alsa-project.org/main/index.php/Main_Page ) ho trovato effettivamente molte informazioni, e mi pare che possa essere utile al caso mio.
Lì si fa riferimento alle API di ALSA: << The ALSA library API is the interface to the ALSA drivers. Developers need to use the functions in this API to achieve native ALSA support for their applications. The ALSA lib documentation is a valuable developer reference to the available functions. >>.
http://www.alsa-project.org/main/index.php/ALSA_Library_API
http://www.alsa-project.org/alsa-doc/alsa-lib/
http://www.alsa-project.org/main/index.php/Tutorials_and_Presentations

La nuova domanda é: e' possibile richiamare le API di ALSA con GAMBAS ? Se sì, con quale istruzione ?
Grazie
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Mario - 24 Maggio 2010, 09:21:18
Ciao Paolo,
scusa se ti rispondo qui sul forum, ma ho problemi con la mia posta elettronica (la storia del ciabattino con le scarpe rotte, hai presente?  ;D)

Da quello che ho capito sul tuo messaggio
Citazione
Event Queues-
-Creation of a queue-
Creating a queue is done usually by calling snd_seq_alloc_queue. You can create a queue with a certain name by snd_seq_alloc_named_queue(), too.

// create a queue and return its id
int my_queue(snd_seq_t *handle)
{
        return snd_seq_alloc_named_queue(handle, "my queue");
}

These functions are the wrapper to the function snd_seq_create_queue(). For releasing the allocated queue, call snd_seq_free_queue() with the obtained queue id.

Once when a queue is created, the two queues are associated to that queue record in fact: one is the realtime queue and another is the tick queue. These two queues are bound together to work synchronously. Hence, when you schedule an event, you have to choose which queue type is used as described in the section Time stamp.

Setting queue tempo
The tempo (or the speed) of the scheduling queue is variable. In the case of tick queue, the tempo is controlled in the manner of MIDI. There are two parameters to define the actual tempo, PPQ (pulse per quarter note) and MIDI tempo. The former defines the base resolution of the ticks, while the latter defines the beat tempo in microseconds. As default, 96 PPQ and 120 BPM are used, respectively. That is, the tempo is set to 500000 (= 60 * 1000000 / 120). Note that PPQ cannot be changed while the queue is running. It must be set before the queue is started.

On the other hand, in the case of realtime queue, the time resolution is fixed to nanoseconds. There is, however, a parameter to change the speed of this queue, called skew. You can make the queue faster or slower by setting the skew value bigger or smaller. In the API, the skew is defined by two values, the skew base and the skew value. The actual skew is the fraction of them, value/base. As default, the skew base is set to 16bit (0x10000) and the skew value is the identical, so that the queue is processed as well as in the real world.

When the tempo of realtime queue is changed, the tempo of the associated tick queue is changed together, too. That's the reason why two queues are created always. This feature can be used to synchronize the event queue with the external synchronization source like SMPTE. In such a case, the realtime queue is skewed to match with the external source, so that both the realtime timestamp and the MIDI timestamp are synchronized.

For setting these tempo parameters, use snd_seq_queue_tempo_t record. For example, to set the tempo of the queue q to 48 PPQ, 60 BPM,
i dati all'apparato MIDI vengono inviati creando una specie di collegamento, quindi si crea la sequenza di dati che si desidera inviare al device, poi si crea questo collegamento, e le funzioni API pensano a inviare i  dati nel momento giusto...  ma forse ho capito male io :)
Come ti dicevo ho lasciato perdere la questione da un po' di tempo (ringraziando il cielo il lavoro è tornato a riempirmi le giornate :D)

Ma se trovo qualcosa in giro, intervengo subito! :D
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 24 Maggio 2010, 13:03:45
Ciao Mario,
grazie ancora per la tua disponibilità.

Vorrei sottoporre a te ed agli altri amici del forum questa risposta ad analoga domanda circa la possibilità di richiamare le API di ALSA con Gambas:

<< Not directly, but you can use EXTERN to call functions directly in the ALSA library.
But why do you need ALSA to write a midi sequencer? Can't you just use the midi port device file?
Benoît Minisini
>>

Letta la risposta di Minisini mi/vi domando:

1) ma allora basta inviare i valori a /dev/midi per far suonare il midi?

2) ad esempio sotto /dev vedo una porta di nome "sequencer"... è questo il nome della porta che mi interessa ?
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 24 Maggio 2010, 14:55:46
1) ma allora basta inviare i valori a /dev/midi per far suonare il midi?

2) ad esempio sotto /dev vedo una porta di nome "sequencer"... è questo il nome della porta che mi interessa ?

Devi provare.....purtroppo non sappiamo risolvere il problema preciso in questione poichè possiamo aiutarti con il linguaggio ma non con tutti gli usi che se ne possono fare.....tu prova e poi torna per risolvere eventuali errori..
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 24 Maggio 2010, 19:22:20
...le informazioni in giro ci sarebbero pure:

Introduction to MIDI programming in Linux
https://ccrma.stanford.edu/~craig/articles/linuxmidi/

...e chissà quanto altro,

ma gli esempi sono solo in C !!!   ???

Come li adatto o recupero con Gambas ?
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 25 Maggio 2010, 00:02:12
Mi pare che Benoit sia stato chiaro...devi usare extern....qui nessuno lo hai mai fatto poichè non se ne sente il bisogno quindi non possiamo aiutarti moltissimo.....
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: fsurfing - 25 Maggio 2010, 12:47:49
come già detto in un altro post esiste un esempio dell' utilizzo di extern realizzato da un vecchio utente , usa la ricerca per trovare il post e li allegato cè il programma di esempio
Titolo: GAMBAS e MIDI: Invio dati per far suonare e far cessare una nota
Inserito da: vuott - 05 Giugno 2010, 13:57:58
Dunque, dopo qualche ricerca e con i preziosi suggerimenti e consigli dell'amico Doriano e di mio fratello Roberto, sono riuscito a far suonare una nota midi !
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 05 Giugno 2010, 15:01:16
Ho editato il tuo messaggio affinchè il codice appaia meno "testuale"...ricorda la prossima volta di racchiudere il codice negli appositi tag oppure usando il tasto con il simbolo #
;)

Comunque complimenti....ora continua almeno per inserire la seconda nota.... :)
Titolo: GAMBAS e MIDI: Programmazione con O.O.S.
Inserito da: vuott - 06 Giugno 2010, 02:49:05
Riporto di seguito lo studio che ho compiuto su O.O.S.:

Invio dati relativi agli eventi Midi con O.O.S.

Uso del dispositivo:  /dev/sequencer



Gli eventi Midi devono essere inviati come flusso di dati (stream) al dispositivo " /dev/sequencer ".Tale dispositivo rappresenta, quindi, il dispositivo in grado di supportare il multimediale Midi, e che permette di programmare il sintetizzatore FM o wavetable o dispositivi esterni sul MIDI bus. Il parametro "device" serve proprio per indirizzare l'evento Midi su una certa periferica, corrisponde al MIDI output da usare ed il suo numero identificativo è 0.

Per la sintesi sonora, laddove le schede audio non posseggano il sintetizzatore interno, è necessario servirsi di un softsynth che gestisca la riproduzione sonora appunto a livello software. Softsynth sono, per esempio, Timidity e Fluidsynth. I Softsynth sono, dunque, programmi specifici (client) aventi il compito di interfacciare i sequencer con la scheda audio gestendo preliminarmente la parte sonora vera e propria.

Ovviamente è necessario che il dispositivo sia connesso al softsynth. Il comando per stabilire tale connessione è "aconnect" seguito dal numero identificativo del client " MidiThrough " e della sua porta, che solitamente è 14:0 , nonché del client softsynth e della sua porta. Il comando " aconnect " può essere attivato mediante il comando SHELL.
Senza questo accorgimento non si potrebbero inviare eventi Midi dal sequencer al softsynth, il quale sulla base dei dati Midi ricevuti gestisce i campioni audio del soundbank e li suona sul dispositivo PCM della scheda audio.

L'invio dei dati al device " /dev/sequencer " avviene mediante l'apertura del device medesimo in scrittura all'inizio del programma. In OSS il dispositivo non può essere aperto due volte.

Con " /dev/sequencer " il flusso di dati, che genera un evento midi, è distinguibile sostanzialmente in gruppi di byte costituiti da 4 valori. Di ciascun gruppo:

 - il 1° valore è sempre = 5 e corrisponde a SEQ_MIDIPUTC.
 - il 2° valore corrisponde al comando midi in sé:
      - Evento Midi+canale per il 1°gruppo di dati;
      - 2° parametro dell'evento per il 2° gruppo;
      - 3° eventuale parametro dell'evento per il 3° gruppo.
 - il 3° valore è sempre = 0 (è il parametro del "device").
 - il 4° valore è sempre = 0.

Il numero complessivo di dati da inviare dipende dal tipo di evento Midi da generare. Solitamente il numero di Byte è 12.


Temporizzazione degli eventi Midi:

tre sono le possibili modalità per determinare dopo quanto tempo (Tempo Delta) un evento Midi avverrà rispetto a quello immediatamente precedente:

1 -  Con un'istruzione da 4 byte

Codice: gambas [Seleziona]


WRITE #file, Chr(2), Chr(valore1) &  Chr(valore2) & Chr(valore3), 4

' Chr(2)  = valore identificativo di TMR_WAIT_ABS (tempo assoluto)
' valore1 = da 0 a 255. Qui 255 dovrebbe essere = 2,6 secondi (255/96 tick).
' valore2 = da 0 a 255. Qui invece: 1 = 2,6 sec. , e 255 = 663 sec. (255 * 2,6)

' Esempio:
WRITE #file, Chr(2), Chr(255) &  Chr(2) & Chr(0), 4
'durata dell'evento Midi = 2,6 + (2,6 * 2) = 7,8 secondi



2 -  Con un'istruzione da 8 byte

Codice: gambas [Seleziona]


WRITE #file, Chr(&h81), Chr(2) &  Chr(0) & Chr(0), & Chr(valore1), & Chr(valore2), & Chr(valore3), & Chr(valore4), 8



NOTA: le due istruzioni, sopra descritte, si comportano diversamente da WAIT, e per questo risultano essere più vantaggiose. Infatti, il programma Midi continua comunque a fluire, e la CPU può svolgere relativamente ad esso ogni altra operazione. Questo perché la gestione delle due istruzioni è demandata specificatamente a "/dev/sequencer".

3 -  Uso di Timer

In alternativa, si può usare un ciclo attivato da Timer, con il quale far accadere i vari eventi Midi ogni tot millesimi di secondo.  Il Timer è abbastanza preciso, nonostante presenti, ad ogni tick, alcuni millesimi di imprecisione. Questo significa che ogni nota può iniziare o terminare con alcuni millisecondi di anticipo di o di ritardo, ma ciò può - volendo - essere considerato accettabile.

Un'altra idea potrebbe essere quella di combinare il TIMER con la funzione TIME, la quale ultima restituisce l'orario sino al millisecondo. Il programma assegnerebbe innanzitutto agli eventi Midi un vero e proprio orario, con definizione al millesimo di secondo, in cui ciascuno di essi deve accadere e, quindi, essere inviato al dispositivo /dev/sequencer. Timer si limiterebbe, in tal caso, ad effettuare semplicemente il ciclo per far verificare in ogni istante se è giunto l'orario prestabilito per l'invio dei dati che determineranno l'evento Midi. Ci si affiderebbe così alla precisione dell'orologio interno del computer; e la funzione TIME farebbe da punto di riferimento certo, superando in tal modo, qualora lo si richieda, l'incerta precisione millesimale della funzione Timer.



Esempio pratico dell'uso di  /dev/sequencer :

Codice: gambas [Seleziona]
  ' Gambas class file

PRIVATE midi AS file

PUBLIC SUB Form_open()

DIM device AS String

device = "/dev/sequencer"
 
  ' apre il flusso di dati per la scrittura
midi = OPEN device FOR WRITE

  END

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PUBLIC SUB ButtonConnessione_Click()

' presuppone il softsynth Timidity installato
' e connette MidiThrough 14:0 a Timidity 128:0
  SHELL "aconnect 14:0 128:0"

END

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PUBLIC SUB ButtonInvioDati_Click()

' Invio dei gruppi di dati:

WRITE #midi, Chr(5) & Chr(&hC0) & Chr(0) & Chr(0)&     ' definisce l'evento Program Change al canale 1
             Chr(5) & Chr(70) & Chr(0) & Chr(0), 8      ' definisce lo strumento musicale

WRITE #midi, Chr(5) & Chr(&h90) & Chr(0) & Chr(0)&      ' definisce l'evento Note ON al canale 1
             Chr(5) & Chr(60) & Chr(0) & Chr(0)&         ' definisce la nota da suonare
             Chr(5) & Chr(100) & Chr(0) & Chr(0), 12    ' definisce la velocità di tocco (velocity)

WRITE #midi, Chr(2) & Chr(255) &  Chr(2) & Chr(0), 4     ' Temporizzazione con istruzione da 4 byte

WRITE #midi, Chr(5) & Chr(&h80) & Chr(0) & Chr(0)&      ' definisce l'evento Note OFF al canale 1
             Chr(5) & Chr(60) & Chr(0) & Chr(0)&         ' definisce la nota da spegnere
             Chr(5) & Chr(100) & Chr(0) & Chr(0), 12    ' definisce la velocità di tocco (velocity)

END




N O T A :

le cose con la versione 4.0 di OSS sono cambiate per "/dev/sequencer".

Da me specificamente contattato, Hannu Savolainen (che ha redatto soundcard.h) ha risposto:
<< The /dev/sequencer API is no longer part of OSS so it will not work. However you can use the /dev/midi API and write raw MIDI messages to it. The /dev/midi API can do the same than /dev/sequencer. All you need to do is to open /dev/midi (or /dev/midi##) and to write standard MIDI messages to it. The device doesn't provide any timing facilities but you can call usleep() to wait between messages. The /dev/sequencer API was removed because the whole concept was wrong and and it proved to be impossible to document it. There were some plans to develop a replacement but I don't think it will ever get implemented.>>

Inoltre, in http://manuals.opensound.com si legge:
<< The third change in OSS 4.0 is that the development of the previous sequencer (/dev/sequencer and /dev/music) API has been halted. >>
<< The /dev/sequencer device interface for MIDI and synthesizer devices has been
abandoned. This part of the OSS API was redundant with the official MIDI 1.0 specification by MMA.
>>

Titolo: GAMBAS e MIDI. Utilizzo di un altro dispositivo: /dev/sequencer2
Inserito da: vuott - 26 Giugno 2010, 12:42:02
versione precedente può comunque compiere un piccolo salto di qualità nella gestione delle funzioni di OSS mediante l'uso del dispositivo " /dev/sequencer2 ".

Con la versione 4.0 anche lo sviluppo del dispositivo /dev/sequencer2 è stato bloccato, e pertanto è inutilizzabile.
Riporto di seguito il suo uso solo ormai a titolo storico.




USO di " /dev/sequencer2 "  (oggi non più possibile)

" /dev/sequencer2 " ha i seguenti vantaggi:
[li]migliore e più ampio utilizzo delle istruzioni per la gestione della temporizzazione.
[/li][/list]

Come già detto, con il dispositivo " /dev/sequencer2 " non è più necessario l'uso dell'istruzione SHELL per connettere il dispositivo al softsynth: esso avviene automaticamente.

Bisogna premettere che il numero del "device, che prima con " /dev/sequencer " era impostato a 0, ora con " /dev/sequencer2 " è da impostarsi a 3 ovvero, qualora 3 non funzioni, a 1 .


Gli eventi richiamabili con " /dev/sequencer2 " sono suddivisi per Classi di eventi:

Classi di eventi      Num. identif.vo
EV_SEQ_LOCAL              &h80
EV_TIMING              &h81
EV_CHN_COMMON              &h92
EV_CHN_VOICE              &h93
EV_CHN_SYSEX              &h92


Le Classi di eventi sono suddivise a loro volta in Sotto-eventi tipi (riporto le Classi ed i loro sotto-eventi più importanti):

Classe di evento        Sotto-evento   Num. identif.vo   Tipo di evento
EV_TIMING   TMR_WAIT_REL             1   Tempo Delta espresso in tick
   TMR_STOP             3   Arresto dell'esecuzione
   TMR_START             4   Avvio del Timer assoluto
   TMR_CONTINUE             5   Continua l'esecuzione dopo l'arresto
   TMR_TEMPO             6   Tempo Metronomico espresso in bpm
   TMR_ECHO             8   Per la sincronizzazione con la marcatura temporale (Timestamp)
EV_CHN_COMMON   MIDI_CTL_CHANGE          &hB0   Control change
   MIDI_PGM_CHANGE          &hC0   Program change
   MIDI_CHN_PRESSURE          &hD0   Channel Aftertouch
   MIDI_PITCH_BEND          &hE0   Pitch Bend
EV_CHN_VOICE   MIDI_NOTEOFF          &h80   Note OFF
   MIDI_NOTEON          &h90   Note ON
   MIDI_KEY_PRESSURE          &hA0   Aftertouch Polyphonic


L'utilizzo di questi dati avviene, come detto, mediante istruzioni formate da 8 byte.



Modello di istruzione per gli eventi EV_CHN_VOICE:

Codice: gambas [Seleziona]


WRITE #flusso_dati, Chr(Classe) & Chr(device) & Chr(Sotto-evento) & Chr(canale) & Chr(nota) & Chr(velocità) & Chr(0) & Chr(0), 8



Legenda:

- flusso_dati    AS file
- Classe          = il numero identificativo della Classe di eventi
- device          = il numero del device (= 1  oppure  3)
- Sotto-evento = il numero identificativo del Sotto-evento
- canale          = il numero del canale (da 0 a 15)
- nota             = numero della nota
- velocità        = velocity

NOTA: I valori del 7° e dell'8° byte sono sempre posti a zero.

Esempi pratici:

1) Per l'invio dell'istruzione Note ON:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h90) & Chr(0) & Chr(60) & Chr(100) & Chr(0) & Chr(0), 8



2) Per l'nvio dell'istruzione Note OFF:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h80) & Chr(0) & Chr(60) & Chr(100) & Chr(0) & Chr(0), 8



3) Per l'invio dell'istruzione Aftertouch Polyphonic:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h93) & Chr(1) & Chr(&hA0) & Chr(0) & Chr(60) & Chr(100) & Chr(0) & Chr(0), 8





Modello di istruzione per gli eventi EV_CHN_COMMON:
 
Codice: gambas [Seleziona]


WRITE #flusso_dati, Chr(Classe) & Chr(device) & Chr(Sotto-evento) & Chr(canale) & Chr(valore1) & Chr(valore2) & Chr(0) & Chr(0), 8



Legenda:

- flusso_dati    AS file
- Classe          = il numero identificativo della Classe di eventi
- device          = il numero del device (= 1  oppure  3)
- Sotto-evento = il numero identificativo del Sotto-evento
- canale          = il numero del canale (da 0 a 15)
- valore1, 2     = valori dei parametri specifici dei Sotto-eventi

NOTA: I valori del 7° e dell'8° byte sono sempre posti a zero.

Alcuni esempi pratici:

1) Per l'invio dell'istruzione Control Change:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h92) & Chr(1) & Chr(&hB0) & Chr(0) & Chr(7) & Chr(100) & Chr(0) & Chr(0), 8

(In questo esempio il valore del Volume è stato posto a 100)


2) Per l'invio dell'istruzione Program Change:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h92) & Chr(1) & Chr(&hC0) & Chr(0) & Chr(70) & Chr(0) & Chr(0) & Chr(0), 8

(In questo esempio è stato scelto lo strumento n. 70: Fagotto)




Modello di istruzione per l'evento EV_TIMING:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(Classe) & Chr(Sotto-evento) & Chr(0) & Chr(0) & Chr(valore1) & Chr(valore2) & Chr(valore3) & Chr(0), 8



Legenda:

- flusso_dati    AS file
- Classe          = il numero identificativo della Classe di eventi
- Sotto-evento = il numero identificativo del Sotto-evento
- valore1,2,3    = valori degli eventuali parametri specifici dei Sotto-eventi

NOTE:
- Hanno almeno un parametro specifico: TMR_WAIT_REL, TMR_TEMPO, TMR_ECHO;
- il 3° ed il 4° byte sono sempre posti a zero;
- si conferma quanto già affermato nel precedente messaggio: gli EV_TIMING risultano più vantaggiosi del comando WAIT, poiché essi, diversamente da WAIT, consentono al programma di continuare comunque a fluire nella lettura, gestione ed esecuzione del proprio codice. Infatti, essendo la gestione delle istruzioni di temporizzazione demandata specificatamente a "/dev/sequencer2 ", la CPU può svolgere ogni altra operazione.


Alcuni esempi pratici:

1) Per l'invio dell'istruzione TMR_WAIT_REL:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h81) & Chr(1) & Chr(0) & Chr(0) & Chr(96) & Chr(0) & Chr(0) & Chr(0), 8

(In questo esempio il valore di TMR_WAIT_REL è stato posto a 96 tick)


2) Per l'invio dell'istruzione TMR_START:
 
Codice: gambas [Seleziona]


WRITE, #flusso_dati, Chr(&h81) & Chr(4) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0), 8

(TMR_START non ha parametri specifici)




Uso pratico delle istruzioni da 8 byte

Ogni qual volta si inviano gruppi di istruzioni per l'esecuzione di uno o più eventi Midi, è indispensabile assolutamente inviare all'inizio un'istruzione TMR_START, richiamata dal valore  4, la quale provvede ad avviare il Timer assoluto.

Invio istruzioni per suonare e far cessare due note:
Codice: gambas [Seleziona]

 
' definisce la variabile flusso_dati come file (stream)
Private flusso_dati AS FILE

PUBLIC SUB Form_Open()

  flusso_dati = OPEN "/dev/sequencer2" FOR WRITE

END

PUBLIC SUB ButtonAvvio_Click()

 ' Invio di TMR_START
WRITE, #flusso_dati, Chr(&h81) & Chr(4) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0), 8

 ' E' possibile impostare il tempo metronomico: 120 bmp
WRITE, #flusso_dati, Chr(&h81) & Chr(6) & Chr(0) & Chr(0) & Chr(120) & Chr(0) & Chr(0) & Chr(0), 8

' 1° evento Midi – Program Change: Fagotto.
  WRITE #flusso_dati, Chr(&h92) & Chr(1) & Chr(&hC0) & Chr(0) & Chr(70) & Chr(0) & Chr(0) & Chr(0), 8

' 2° evento Midi – EV_CHN_VOICE - Note ON
  WRITE #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h90) & Chr(0) & Chr(60) & Chr(100) & Chr(0) & Chr(0), 8

' Temporizzazione (tempo delta)– TMR_REL  = 40 tick
  WRITE #flusso_dati, Chr(&h81) & Chr(1) & Chr(0) & Chr(0) & Chr(40) & Chr(0) & Chr(0) & Chr(0), 8

' 3° evento Midi – EV_CHN_VOICE - Note OFF
  WRITE #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h80) & Chr(0) & Chr(60) & Chr(100) & Chr(0) & Chr(0), 8
' - - -
' 4° evento Midi – EV_CHN_VOICE - Note ON
  WRITE #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h90) & Chr(0) & Chr(72) & Chr(100) & Chr(0) & Chr(0), 8

' Temporizzazione (tempo delta) – TMR_REL  = 40 tick
  WRITE #flusso_dati, Chr(&h81) & Chr(1) & Chr(0) & Chr(0) & Chr(40) & Chr(0) & Chr(0) & Chr(0), 8

' 5° evento Midi – EV_CHN_VOICE - Note OFF
  WRITE #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h80) & Chr(0) & Chr(72) & Chr(100) & Chr(0) & Chr(0), 8

END



Se si vuole mettere in "Pausa" l'esecuzione degli eventi Midi, basta lanciare l'istruzione: TMR_STOP, per esempio mediante un altro tasto, e inviare contemporaneamente un'istruzione Control Change di All Note OFF.

Codice: gambas [Seleziona]


PUBLIC SUB Pausa_Click()

  WRITE #flusso_dati, Chr(&h81) & Chr(3) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0), 8
  WRITE #flusso_dati, Chr(&92) & Chr(1) & Chr(&hB0) & Chr(0) & Chr(123) & Chr(0) & Chr(0) & Chr(0), 8

END



Per riavviare dopo la pausa, utilizzare l'istruzione TMR_CONTINUE (sotto-evento = 5). L'esecuzione ripartirà dall'evento successivo a quello in cui l'esecuzione è stata posta in pausa:

Codice: gambas [Seleziona]


PUBLIC SUB Continua_Click()

  WRITE #flusso_dati, Chr(&h81) & Chr(5) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0), 8
 
END




Il Timestamp con il sotto-evento TMR_ECHO

Nella programmazione Midi l'uso di una marcatura temporale (timestamp) risulta utile se è richiesta la verifica dell'avvenimento di uno o più eventi.
Tale marca temporale può essere ottenuta mediante il sotto-evento TMR_ECHO (numero identificativo: 8 ):
 
Codice: gambas [Seleziona]


WRITE #flusso_dati, Chr(&h81) & Chr(8) & Chr(0) & Chr(0) & Chr(valore1) & Chr(valore2) & Chr(valore3) & Chr(valore4), 8



NOTA: il 3° ed il 4° byte sono sempre posti a zero.

I valori contenuti nei byte 5, 6, 7 ed 8 (ossia: Chr(valore1) & Chr(valore2) & Chr(valore3) & Chr(valore4) ) dell'istruzione di TMR_ECHO costituiscono la "key" indicata in "soundcard.h", ossia la chiave inviata a "/dev/sequencer2" con TMR_ECHO. Poiché in un flusso di istruzioni Midi potrebbero essere necessarie moltissime marcature temporali (timestamp), con valori numerici ovviamente crescenti, si rende necessario l'uso di un dato integer passato al dispositivo con TMR_ECHO come parametro. TMR_ECHO accetta una "chiave" che è un intero definito a scelta del programmatore. Gli ultimi 4 byte dell'istruzione contengono, appunto, i quattro valori numerici utili per la ricostruzione dell'integer.

Dunque con l'invio del sotto-evento TMR_ECHO "/dev/sequencer2"  ci restituisce il valore della "chiave" integer, spezzettato nei valori numerici degli ultimi 4 byte del sotto-evento.
E' quindi necessario poter leggere dal dispositivo "/dev/sequencer2" tali valori dopo l'invio del sotto-evento TMR_ECHO mediante la funzione READ

Semplice esempio pratico del funzionamento di TMR_ECHO:

Codice: gambas [Seleziona]


' definisce la variabile flusso_dati come file (stream)
Private flusso_dati AS FILE

PUBLIC SUB Form_Open()

' il dispositivo viene aperto sia per leggere che per scrivere
   eco_dati = OPEN  "/dev/sequencer2" FOR READ WRITE

END

PUBLIC SUB ButtonProvaTmrEcho_Click()

  Dim eco_dati AS STRING
  Dim j AS INTEGER

' Invia un Note ON
  WRITE #flusso_dati, Chr(&h93) & Chr(1) & Chr(&h90) & Chr(0) & Chr(72) & Chr(100) & Chr(0) & Chr(0), 8

' Quindi invia TMR_ECHO. Nei 4 ultimi byte dovranno essere inseriti 4 numeri a piacere
  WRITE #flusso_dati, Chr(&h81) & Chr(8) & Chr(0) & Chr(0) & Chr(valore1) & Chr(valore2) & Chr(valore3) & Chr(valore4), 8

' Legge gli otto dati da "/dev/sequencer2"
  READ #flusso_dati, eco_dati, -8
' ' ' '
' Verifica empirica della "chiave" marca temporale (timestamp)
  FOR j = 5 to 8
    PRINT Asc(eco_dati, j)  ' Legge dal 5° valore fino all'8°, cioè appunto i 4 valori costituenti l'integer "chiave"
  NEXT

END


NOTA: L'istruzione TMR_ECHO funziona. E' necessario avere l'accortezza di instaurare due cicli diversi: uno per mandare gli eventi Midi, l'altro per leggere da "/dev/sequencer2" i dati di ritorno da TMR_ECHO. Il ciclo può essere, per esempio, attivato con un Timer con delay posto fra i 20 ed i 50 ms.
E' opportuno, per non creare intasamento, inviare un certo numero di eventi Midi insieme con il numero scelto di eventi TMR_ECHO, e poi ad ogni evento di Timer leggere da "/dev/sequencer2" i dati di ritorno di TMR_ECHO. Il ciclo virtuoso, insomma, sarebbe: invio di un gruppo di dati, poi lettura continua delle "chiavi" TMR_ECHO di ritorno afferenti a questo gruppo di eventi Midi;  poi, prima che l'esecuzione del gruppo degli eventi Midi termini, inviare un altro gruppo di eventi Midi, quindi lettura continua delle "chiavi" TMR_ECHO di ritorno di quest'altro gruppo;  e così via fino alla fine.
Tutto ciò è possibile, poiché bisogna non dimenticare che gli eventi Midi temporizzati mediante l'evento di timing TMR_WAIT_REL (che rappresenta il Tempo Delta) vengono "accodati" e gestiti dal dispositivo l'uno dopo l'altro secondo l'ordine temporale della loro attivazione imposto da TMR_WAIT_REL (Tempo Delta), ossia attivati ciascuno "a suo tempo". Mentre, dunque, "/dev/sequencer2" gestisce in modo pienamente autonomo (è utile ricordare anche questa caratteristica) gli eventi Midi, il programma può effettuare tranquillamente la lettura della "eco" di ritorno della "chiave" di TMR_ECHO proveniente da "/dev/sequencer2".




Un ringraziamento ancora all'amico Doriano per la preziosa consulenza tecnica.
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: md9327 - 15 Agosto 2010, 17:05:23
E' passato tantissimo tempo da quando mi dilettavo di elettronica musicale, purtroppo ora sono fuori giro...

La mia è solo per complimentarmi del tuo lavoro, e la documentazione che hai pubblicato!!!
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 25 Agosto 2010, 12:13:45
Gestione del Midi in Gambas con ALSA

Poiché oggi l'uso di O.S.S. non è più possibile, bisognerà imparare la gestione dei dati Midi con ALSA.

Per l'uso di ALSA nella gestione del MIDI vedere la guida che ho scritto nella WIKI:
http://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA (http://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA).
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: md9327 - 25 Agosto 2010, 14:45:31
Ho letto ora il thread, che forse era il caso di trasformarlo in un link sul wiki...

Molto interessante, ma forse anche complesso, anche se istruttivo, per i neofiti, in particolare per chi non conosce il C.
Io, comunque l'ho trovato interessante, e molto importante per la conoscenza dell'uso dei puntatori in Gambas.
Immagino lo studio che ha fatto, e la sola idea di mettersi a spulciare questa parte di Gambas.

Quello che non ho ben afferrato, ma che hai fatto bene a aggiungerlo nel thread, è la questione alzata con Benoit. Da quello che ho capito, Benoit aborrisce l'uso del Pointer così come ha fatto il tuo amico, ma neppur ne ha documentato le caratteristiche (questo molto vero, e non solo...). Ma quello che non ho compreso, è se poi è stata sottintesa una richiesta di migliore implementazione documentativa, oppure...

Comunque, non è che per caso il tuo amico ti dà il permesso di tradurlo in italiano?, forse sarebbe più apprezzato qui nel nostro forum...
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 25 Agosto 2010, 14:58:26
Comunque, non è che per caso il tuo amico ti dà il permesso di tradurlo in italiano?, forse sarebbe più apprezzato qui nel nostro forum...

Sono d'accordo.....la traduzione andrebbe fatta.....è una parte di documentazione mancante e andrebbe integrata.

P.S.

A mio avviso sarebbe più opportuno prendere i tre post che hai scritto e inserirli in una pagina wiki poichè così sono un pò schematicamente freddi.....la mia è un'idea personale...
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 25 Agosto 2010, 15:51:40
Comunque, non è che per caso il tuo amico ti dà il permesso di tradurlo in italiano?, forse sarebbe più apprezzato qui nel nostro forum...

Doriano stesso ha sottolineato l'opportunità della traduzione in italiano per il forum di questa comunità Gambas.
...se ci fosse, dunque, qualche anima pia.....  :-[
In fondo il suo scopo era quello di rendere la sua guida accessibile a tutti (ecco anche la scelta dell'inglese per la comunità non italiana nel forum gestito da B. Minisini).
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 25 Agosto 2010, 15:57:33
Direi che la cosa migliore è creare una pagina wiki per la traduzione in modo che chiunque vuole può partecipare/modificare/migliorare la traduzione.
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 25 Agosto 2010, 17:49:54
Ho iniziato io....trovate le informazioni sul post del documento.
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: md9327 - 26 Agosto 2010, 11:37:32
...ehhh se non ci fosse Cesko...  :-*
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 27 Agosto 2010, 13:05:29
Ho inserito nella WIKI la mia breve guida per la gestione dei dati MIDI con OSS in Gambas, a solo titolo di curiosità dato che ormai OSS è ormai inutilizzabile.

Nella WIKI, come già scritto sopra, è presente anche una lunga guida per la gestione dei dati Midi con Gambas 3 con ALSA:
http://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA (http://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA)
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 27 Agosto 2010, 13:32:49
Ho inserito nella WIKI la mia breve guida per la gestione dei dati MIDI con OSS in Gambas.

È consigliabile iscriversi al wiki ed apportare le modifiche effettuando il login in modo che l'amministratore può capire chi ha modificato le pagine. Grazie... ;)
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: md9327 - 27 Agosto 2010, 13:56:53
Scusa, ma le modifiche non sono ammesse solo agli utenti registrati? Mi sono perso qualcosa?
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: Ceskho - 27 Agosto 2010, 15:18:39
Scusa, ma le modifiche non sono ammesse solo agli utenti registrati? Mi sono perso qualcosa?

No, se le modifiche vengono apportate da un utente iscritto e logato appare il suo user name nella cronologia altrimenti appare solo l'IP
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: md9327 - 27 Agosto 2010, 16:14:25
Appunto, mi ero perso qualcosa...  :-\
Titolo: Re: GAMBAS e MIDI. E' proprio un mistero ?
Inserito da: vuott - 05 Dicembre 2012, 22:53:23
Aggiornamento:

ho riportato in WIKI le modalità, finora da me sperimentate, con le quali è possibile gestire un file Midi:

http://www.gambas-it.org/wiki/index.php?title=Guide_della_comunit%C3%A0#Gestione_dei_dati_MIDI_e_dei_file_.mid