Forum: Mikrocontroller und Digitale Elektronik Teensy MIDI und SysEx-Daten über 255byte


von Jonas (Gast)


Lesenswert?

Ich habe meinen Teensy 3.2 mit meinem Blofeld Synthesizer via einem USB 
Host Board, das USB-MIDI in MIDI umwandelt verbunden (möchte mir einen 
Controller für den Synth bauen).

Controller-Daten senden und empfangen klappt und auch der Empfang von 
kleinen SysEx-Daten vom Synth funktioniert. Ich möchte aber auch einen 
Sound-Dump empfangen, der 256byte groß ist. In der MIDI.h - Bibliothek 
kann man die maximale Größe des SysEx-Arrays verändern, die 
standartmäßig auf 255byte gestellt ist.
1
#define MIDI_SYSEX_ARRAY_SIZE 255   // Maximum size is 65535 bytes.

Wenn ich die Größe des Arrays dort nun vergrößere auf 256 oder mehr, 
hängt sich der Teensy auf, sobald er irgendwelche SysEx-Daten vom Synth 
empfängt (auch kurze).

Die Daten greife ich folgendermaßen ab:
1
  if (MIDI.read()) {
2
  byte type = MIDI.getType();
3
  switch (type) {
4
     case ControlChange:
5
        cc = MIDI.getData1();
6
        val = MIDI.getData2();
7
        Serial.print("CC: ");
8
        Serial.print(cc);
9
        Serial.print(" Value: ");
10
        Serial.println(val);
11
        break;
12
     case SystemExclusive: 
13
       const byte* SysExA = MIDI.getSysExArray();
14
        ArLenght = MIDI.getData1();
15
        for (int i=0;i<ArLenght;i++)
16
          {
17
            Serial.print(" ");
18
            Serial.print(SysExA[i]);
19
            Serial.print("; ");
20
          }
21
        Serial.println();
22
        break;
23
  }
24
  }

Irgendjemand eine Idee woran das liegt und wie man das behebt?

von Thomas E. (picalic)


Lesenswert?

Es liegt wahrscheinlich daran:

Jonas schrieb:
> ArLenght = MIDI.getData1();

(In Unkenntnis der Library gehe ich einfach mal davon aus, daß 
MIDI.getData1() ein empfangenes MIDI Byte zurückgibt)

Hintergrund: über MIDI können nur Datenbytes mit Werten bis max. 127 
übertragen werden, da jedes Byte mit MSB=1 (also >= 0x80 bzw. 128) als 
neues Statusbyte interpretiert wird.
Die Länge eines SysEx-Datensatzes muss also irgendwie anders übertragen 
werden, als einfach nur in einem Datenbyte, wenn der Zahlenwert 127 
überschreitet.

: Bearbeitet durch User
von Clemens L. (c_l)


Lesenswert?

Die Library macht dies für jedes SysEx:
1
mMessage.data1 = (mPendingMessageIndex+1) & 0xFF;  
2
mMessage.data2 = (mPendingMessageIndex+1) >> 8;

Du musst also die Länge aus diesen beiden Werten wieder zusammensetzen:
1
ArLenght = MIDI.getData1() | (MIDI.getData2() << 8);

: Bearbeitet durch User
von Joe F. (easylife)


Lesenswert?

vielleicht auch

unsigned int ArLenght = MIDI.getSysExArrayLength();

lt. http://forum.arduino.cc/index.php?topic=137628.0

von Jonas (Gast)


Lesenswert?

Erstmal Danke für eure Antworten!

Die Array-Längen Bestimmung hätte so wohl tatsächlich nicht geklappt, 
wie ich es vor hatte, ich denke
1
unsigned int ArLenght = MIDI.getSysExArrayLength();
tut es aber.

Leider löst es aber nicht mein Problem.
Ich habe jetzt mal alles auskommentiert und mir nur einen Text ausgeben 
lassen:
1
  if (MIDI.read()) {
2
  byte type = MIDI.getType();
3
  switch (type) {
4
     case ControlChange:
5
        cc = MIDI.getData1();
6
        val = MIDI.getData2();
7
        Serial.print("CC: ");
8
        Serial.print(cc);
9
        Serial.print(" Value: ");
10
        Serial.println(val);
11
        break;
12
     case SystemExclusive:
13
        Serial.println("Jawoll");
14
        break;
15
  }
16
  }

Wenn es irgendwas mit der Array-Lenght zutun hätte, müsste es ja jetzt 
funktionieren, da ich ja nur abfrage, welchen Typ von Daten ich 
empfange.
Mit MIDI_SYSEX_ARRAY_SIZE = 255 spuckt er mir ganz artig mein "Jawoll" 
aus, wenn ich die aber auch nur ein Byte höher setze, reagiert der 
Teensy garnicht nicht mehr, sobald die ersten SysEx-Daten vom Synth 
gesendet wurden.. Also auch ControlChange Daten werden nicht mehr 
ausgespuckt, bis ich den Teensy neu starte..

von Jonas (Gast)


Lesenswert?

Okay anscheinend hab ich die Lösung gefunden, falls jemand auch auf das 
Problem stößt:

In der midi.ccp - Datei (aus der MIDI-Bibliothek)
1
case 0xF7:
2
            if (getTypeFromStatusByte(mPendingMessage[0]) == SystemExclusive) {
3
              
4
              // Store System Exclusive array in midimsg structure
5
              for (byte i=0;i<MIDI_SYSEX_ARRAY_SIZE;i++) {

das Statement zu
1
for (unsigned int i=0;i<MIDI_SYSEX_ARRAY_SIZE;i++) {

ändern und dann funktionierts!

von Clemens L. (c_l)


Lesenswert?

In der aktuellen Version der MIDI-Bibliothek (4.2) ist das eh anders 
gelöst. (Und das Standard-Limit ist 128 Bytes.)

von Jonas (Gast)


Lesenswert?

Die lässt sich aber so ohne Weiteres nicht mitm Teensy benutzen.. 
Jedenfalls hab ich die nicht zum Laufen bekommen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.