Forum: Compiler & IDEs Midi Daten in Array speichern


von martin (Gast)


Lesenswert?

Hallo,
sorry, ich steh wirklich an. ich versuche mit Peter Fleury's UART Lib 
Midi Daten in einem Array zu speichern. mich interessieren Sysex cmds, 
mit denen ich einen status setze und NoteOn/Off, die dann je nach eben 
genannten statusbits weiterverarbeitet werden.

irgendwie funktioniert mein code nicht. mittels debug-noteOn (eine idee 
von mir einen ton unterschiedlicher höhe in verschiedenen subprocedures 
auszugeben) hat auch nix gebracht. offenbar hakts bei der 
zusammenstellung der midi commandos.

die idee:

loop(unendlich)
   ist das zeichen ein sysex oder noteon oder noteoff
      speichere es in array an pos 0
   ist das zeichen nur midi daten
      erhöhe index im array und speichere das zeichen im array
   ist das cmd ein noteon/off und sind alle datenbytes (=2) angekommen
      bearbeite noteon/off
   ist das cmd ein sysex und sind alle datenbytes (immer 6) da
      bearbeiter sysex
endloop

kann mir jemand helfen??

mein hauptprogramm:
int main(void) {
  u08 c;        // currently received Byte
  u08 byteCount;    // number of Bytes received
  u08 cmdType;    // type of the midi command
  u08 chan;      // midi channel
  u08 mididata[5]={0};// midi command collector
// ------------ INITIALISATION ---------------------
  hw_init();
  c=NONE;
  byteCount = 0;
  cmdType=NONE;
  chan=NONE;

    for(;;) {

        // -------- CHECK IF UART 1 MIDI DATA IS INCOMMING ----------
    c = (unsigned char)uart1_getc(); // c is int not byte!
        if ( c & UART_NO_DATA ) {
            ;
        }
        else { // interpret midi stuff

      if (c & 0x080) { // is it a command?
        if ((c & MIDI_SYSEX) || (c & MIDI_NOTEON) || (c & MIDI_NOTEOFF)) 
{
          byteCount=0;
          mididata[0] = c;
        }
        if (c & MIDI_EOX) {
          byteCount++;
          //do not handle midi EOX
        }
      }
      else { // normal midi data received
        byteCount++;
        mididata[byteCount] = c; // add incomming data
      } // if myByte - else

    } // if c & uartnodata - else

    // -------- INTERPRET MIDI STUFF  ---------------------------

    if (byteCount==2) {
      if (mididata[0] & MIDI_NOTEON) handle_NOTE(mididata);
      if (mididata[0] & MIDI_NOTEOFF) handle_NOTE(mididata);

      /*debug
      if ((mididata[0] & MIDI_CHANNEL_MASK)==0) {
        // add 1 to channel and send it back
        uart1_putc(mididata[0]+1);
        uart1_putc(mididata[1]);
        uart1_putc(mididata[2]);
      }debug*/


    }
    if (byteCount==5) {
      if (mididata[0] & MIDI_SYSEX) handle_SYSEX(mididata);
    }

  } // for




// ------------- MAIN LOOP END -------------------------


} //void main

von Karl H. (kbuchegg)


Lesenswert?

>     c = (unsigned char)uart1_getc(); // c is int not byte!

c ist nicht int. c ist bei dir ein u08, also wohl ein
Byte. Allerdings liefert die Funktion uart1_getc() einen
int. Warum wohl könnte das so sein?

Das liegt daran, dass die Funktion auch die Möglichkeit
haben möchte, eine Art 'Status' über den Returnwert zu liefern.
Also einen Returnwert der kein Zeichen ist, sondern eine Aussage
darüber treffen soll, wie der Empfang insgesamt abgelaufen ist.
Da aber in einem empfangenen Byte grundsätzlich jedes der 256
möglichen BItmuster vorkommen kann, reicht ein Returnwert
in der Größe eines Bytes nicht aus. Daher ist der Returnwert
ein int.

Nur leider wirfst du sofort diese zusätzliche Information weg :-)

>         if ( c & UART_NO_DATA ) {

Daher kannst du das hier auch nicht auswerten. Die Information
UART_NO_DATA ist durch das runtercasten auf einen unsigned char
schon längst in die ewigen Bit-Jagdgründe eingegangen.

Hast du dir denn die Doku auf
http://homepage.hispeed.ch/peterfleury/group__pfleury__uart.html
zu dieser Library nicht angesehen?

Da steht bei uart_getc() (und uart1_getc()) eindeutig, wie
sich die Return-Werte auf High-Byte und Low-byte verteilen.

von martin (Gast)


Lesenswert?

ok, danke für den hinweis. ich hab den code jetzt geändert. blöder 
fehler. aber es scheint noch ein problem zu geben, nicht einmal der 
debug-ton wird gespielt...



 for(;;) {

        // -------- CHECK IF UART 1 MIDI DATA IS INCOMMING ----------
    i = uart1_getc(); // attention: i is int not a byte!
        if ( i & UART_NO_DATA ) {
            ;
        }
        else { // interpret midi stuff
     if ( c & UART_FRAME_ERROR ) {
                /* Framing Error detected, i.e no stop bit detected */
            }
            if ( c & UART_OVERRUN_ERROR ) {
            }
            if ( c & UART_BUFFER_OVERFLOW ) {
            }

            c = i & 0x00FF;  // Mask-out high byte
     if (DEBUG) debug(c); // spielt einen midi ton in höhe "c"

     if (c & 0x080) { // is it a command?
        if ((c & MIDI_SYSEX) || (c & MIDI_NOTEON) || (c & MIDI_NOTEOFF)) 
{
    byteCount=0;
    mididata[0] = c;
    if (DEBUG) debug(48);
        }
        if (c & MIDI_EOX) {
    byteCount++;
    //do not handle midi EOX
        }
     }
     else { // normal midi data received              byteCount++;
        mididata[byteCount] = c; // add incomming data
     } // if myByte - else

  } // if c & uartnodata - else

  // -------- INTERPRET MIDI STUFF  ---------------------------

  if (byteCount==2) {
    if (mididata[0] & MIDI_NOTEON) handle_NOTE(mididata);
    if (mididata[0] & MIDI_NOTEOFF) handle_NOTE(mididata);
  }
  if (byteCount==5) {
    if (mididata[0] & MIDI_SYSEX) handle_SYSEX(mididata);
  }

  } // for

von Andreas W. (andreasw) Benutzerseite


Lesenswert?

Funktioniert denn die Debugausgabe alleine?
Möglicherweise ist es ja ein Hardwarefehler oder die Baudrate stimmt 
nicht oder die Fusebits sind falsch gesetzt oder...

von Karl H. (kbuchegg)


Lesenswert?

Muss das so sein, dass hier

    else { // normal midi data received              byteCount++;
        mididata[byteCount] = c; // add incomming data

der increment des byteCount unter Kommentar steht.
Laut deiner algorithmischen Zusammenfassung ganz am Anfang
sollte der Inkrement eigentlich erfolgen.


Weiter seh ich mir das nicht an. Code wie deiner, unlogisch
und nicht konsequent eingerückt, offensichtliche Fehler
(wie zb, dass c benutzt wird um Framing Errors festzustellen noch
bevor c einen Wert bekommen hat), all das führt meistens immer
nur zu einem: Code der nicht funktioniert und dem gewaltigen
Schrei nach Hilfe.
Mach erst mal deine Hausaufgaben.

von Martin M. (avrgccnewby)


Lesenswert?

hallo,

hab das eingesehen und die state machine komplett überarbeitet. _asche 
über mein haupt_

das neue teil funktioniert jetzt folgendermaßen:

loop

   get integer from uart
   if integer available
     remove conrtol stuff from data (=c)
     if c=midi command then
         if c = noteON or c =noteOFF
            state=waitfornote
         if c = sysex
            state=waitforvendorid
     else //data is not a command but simply midi data
         if c war noteOn or noteOFF
           hole noten
           state=waitforVelocity
         if c war ...

und so weiter
ist besser lesbar und funktionert (vor allem)
fängt aboluten müll ab und erlaubt wirklich kontrolle über den aktuellen 
zustand.

danke für eure geduld und hilfe! tolles forum.

PS einrückungsfehler sind aufgrund copy-paste passiert - auch hier werde 
ich in zukunft wohl lieber attachments benutzen.

lg
MArtin

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.