Modificare dati in ingresso su porta midi in e inviarli su porta midi thru o out

Ciao a tutti, stò reallizzando un prototipo con Arduino.

Il concetto è:

midi in (collegato ad arduino)-> modifica dati in ingresso con bottoni collegati ad arduino -> midi out (collegato ad arduino).

Ho trovato molti esempi che considerano la ricezione e la trasmissione di dati midi ma nessuno che tratti della modifica di dati in ingresso e il loro relativo invio....

Qualcuno ha visto qualcosa in giro o ha dei link da consigliarmi?

Grazie

Andrea

schiller:
Ho trovato molti esempi che considerano la ricezione e la trasmissione di dati midi ma nessuno che tratti della modifica di dati in ingresso e il loro relativo invio....

Non vedo dove sia il problema, prima ricevi il messaggio midi in ingresso, effettui la modifica che desideri, lo trasmetti su out, su thru non è possibile perché è un canale passante e i messaggi midi devono rimanere inalterati.
Si presuppone che conosci l'interfaccia midi, come sono strutturati i messaggi e come manipolarli, se ti mancano queste basi allora prima di pensare a modificare i messaggi è bene che prima studi queste cose.

Ok e grazie,

Andrea

ho dichiarato le variabili,
la velocità sulla porta seriale
i tre byte dei messaggi midi vengono letti, memorizzati e scritti sulla porta in uscita.

Ora, suppongo che l' operazione di incremento del secondo byte (che ho chiamato dataByte1 e nel protocollo midi identifica il pitch della nota) vada eseguita subito dopo aver letto il valore e prima della funzione " playNote(statusByte, dataByte1, dataByte2);"

La mia supposizione è corretta?
Ho provato ad eseguire l' operazione in differenti maniere ma non ho avuto risultati..

Questo è il mio codice di partenza:

byte statusByte, dataByte1, dataByte2;

void setup(){
    Serial.begin(31250);
  }
  void loop(){
  if(Serial.available() > 0) 
  {
    statusByte = Serial.read();
     dataByte1 = Serial.read();
      dataByte2 = Serial.read();
       playNote(statusByte, dataByte1, dataByte2);
  
 }
  }

   void playNote(byte cmd , byte pitch, byte velocity){
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
 
}

Qualche consiglio?

grazie..

Ho cambiato questa riga del codice da cosi:

if(Serial.available() > 0)

a cosi per leggere tre byte (command, data1, data2)

if(Serial.available() >= 3)

E aggiunto questa linea di codice per incrementare (ad esempio) di 24 semitoni le note in ingresso sul pin rx:

dataByte1 += 24;

La trasposizione funziona ma ora il codice riesce a gestire solo una messaggio midi di note on / note off alla volta.. insomma non funziona se mando due o piu note contemporaneamente in ingresso:

Qualcuno ha idea di quale potrebbe essere il motivo?

Grazie..

byte statusByte, dataByte1, dataByte2;

void setup(){
    Serial.begin(31250);
  }
  void loop(){
  if(Serial.available() >= 3)
  {
    statusByte = Serial.read();
     dataByte1 = Serial.read();
     dataByte1 += 24;
     
      dataByte2 = Serial.read();
       playNote(statusByte, dataByte1, dataByte2);
  
 }
  }

   void playNote(byte cmd , byte pitch, byte velocity){
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
 
}

Per riassumere sto compilando un programma per modificare dei dati in ingresso ad Arduino e trasmetterli in uscita.
Il codice legge messaggi di tre byte e modifica il secondo byte incrementandone il valore o diminuendolo tramite la variabile " transpose"

dunque, il codice sopra funzionava parecchio male, diversi problemi nella lettura, interpretazione e trasmissione dei messaggi midi.

Cosi ho cambiato direzione includendo la libreria midi e utilizzando la funzione callback

Problema: Arduino non mi da messaggi di errore nella compilazione ma in uscita non ho i byte modificati..

Cosa stò sbagliando?

Grazie..

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( channel, note+transpose, velocity );
}

void noteoff(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOFF( channel, note+transpose, velocity );
}

void setup() {
        MIDI.begin();
        MIDI.setHandleNoteOn(noteon);
        MIDI.setHandleNoteOff(noteoff);
}

void loop() {
        MIDI.read();
}?

dunque, ho fatto diversi tentativi, nell' ultimo ho usato la libreria midi e la funzione callback.
Tuttavia non funziona perchè sembra che la libreria midi non sia in grado di generare dei messaggi midi tramite callback.
Ho provato all' inizio anche a non utilizzare la libreria midi ma avevo diversi problemi.

nella teoria il problema non sembra difficile ma nella pratica sembra irrisolvibile..

#include <MIDI.h>

byte transpose = 7;       // raise a fifth

void noteon(byte note, byte velocity, byte channel) {
    digitalWrite( 13, HIGH );         // turn on LED
    MIDI.sendNoteOn( note+transpose, velocity, channel );
}

void noteoff(byte note, byte velocity, byte channel) {
    digitalWrite( 13, LOW );          // turn off LED
    MIDI.sendNoteOff( note+transpose, velocity, channel );
}

void setup() {
        pinMode( 13, OUTPUT );                                        // LED
        MIDI.begin();      
        MIDI.setInputChannel( MIDI_CHANNEL_OMNI );      // listen to all channels
        MIDI.turnThruOff();                                                 // turn off thru mode
        MIDI.setHandleNoteOn(noteon);                             // call noteon when a note on message is received
        MIDI.setHandleNoteOff(noteoff);                            // call noteoff when a note off message is received
}

void loop() {
        MIDI.read();

}

astrobeed:

schiller:
Ho trovato molti esempi che considerano la ricezione e la trasmissione di dati midi ma nessuno che tratti della modifica di dati in ingresso e il loro relativo invio....

Non vedo dove sia il problema, prima ricevi il messaggio midi in ingresso, effettui la modifica che desideri, lo trasmetti su out, su thru non è possibile perché è un canale passante e i messaggi midi devono rimanere inalterati.
Si presuppone che conosci l'interfaccia midi, come sono strutturati i messaggi e come manipolarli, se ti mancano queste basi allora prima di pensare a modificare i messaggi è bene che prima studi queste cose.

Il problema stava nel dover dichiarare in ordine diverso, gli attributi della funzione void e dell istruzione send message. Questo in accordo alla documentazione della libreria MIDI.

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( note + transpose, velocity, channel );
}

Ora il codice funziona ma ho un nuovo problema.

Ho aggiunto un pulsante di midi panic che funziona bene e un pulsante di tipo switch per applicare la modifica dei messaggi in ingresso ad Arduino in tempo reale.
Quando il bottone è premuto i dati vengono modificati.
Il problema è che se premo il bottone durante un messaggio di note off, la trasposizione (modifica) parte da quel messaggio e il precedente messaggio di note on rimane "incastrato" e continua a suonare.

Esempio:

Time note message
00 C1 ON
01 C1 OFF
02 C1 ON
03 D1 OFF <----- bottone di transpose viene premuto. Note off message for C1 è modificato. C1 continua a suonare.
04 D1 ON C1 ancora in stato di ON
05 D1 OFF C1 ancora in stato di ON
... .. .... C1 ancora in stato di ON

Ho pensato di inserire in void loop() delle istruzioni come:

Quando il bottone è premuto (HIGH)
se il messaggio corrente è di note off
non modificare.
Se il messaggio corrente è di note on
modificalo.
Esegui questa istruzione una sola volta.

Quando il bottone non è premuto
se il messaggio corrente è di note off
non modificare.
Se il messaggio corrente è di note on
modificalo.
Esegui questa istruzione una sola volta.

Consigli? Secondo voi è la strada giusta?

Grazie..

#include <MIDI.h>

const int InputTriggerTranspose = 7; // port for the push button transpose switch
byte transpose = 0;  

byte last_type, last_ch, last_note, last_vel;

const int InputTriggerPanic = 2; // port for the working midi panic button
int Panic = 0;


void noteon(byte channel, byte note, byte velocity) {
    digitalWrite( 13, HIGH );         
    last_type = 1;
    last_ch = channel;
    last_note = note;
    last_vel = velocity;

}

void noteoff(byte channel, byte note, byte velocity) {
    digitalWrite( 13, LOW );         
    last_type = 2;
    last_ch = channel;
    last_note = note;
    last_vel = velocity;
}

void setup() {
          
        pinMode (2, INPUT);  
        pinMode (7, INPUT);    
        pinMode( 13, OUTPUT );
 
        MIDI.begin();      
        MIDI.setInputChannel( MIDI_CHANNEL_OMNI );      // listen to all channels
        MIDI.turnThruOff();                                                 // turn off thru mode
        MIDI.setHandleNoteOn(noteon);                             // call noteon when a note on message is received
        MIDI.setHandleNoteOff(noteoff);                            // call noteoff when a note off message is received
 
        last_type = 0;
}

void loop() {
    
        Panic = digitalRead(InputTriggerPanic); 
        if (Panic == HIGH) {
        MIDI.sendControlChange(120, 0, last_ch);  // midi panic message
}

        transpose = digitalRead(InputTriggerTranspose);
        if (transpose == HIGH) {
          transpose = 7;}

in pratica, partendo dal codice qui sopra:

dovrei costruire un array dove memorizzare gli ultimi 5 messaggi di note on,
quando arriva un messaggio di note off dovrei cercare nell' array il corrispondente messaggio di note on (dei tre byte hanno il primo identico)
se non ne trovo nessuno, (perchè nel frattempo il note off è stato modificato dalla variabile transpose) applico l' inverso della variabile transpose e ripeto la ricerca
infine quando trovo il messaggio corrispondente lo rimuovo dalla lista e termino la ricerca..

Ho intuito che è necessario utilizzare array e che per rimuovere un messaggio dalla lista è sufficiente settare il suo valore a zero, ma al momento son fermo qui..

Nel frattempo questo forum a quanto pare è diventato il mio blog personale.

Avete presente Alien? tipo sopravvissuto che scrive il diario di bordo tra i morti..