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
> 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.
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
Funktioniert denn die Debugausgabe alleine? Möglicherweise ist es ja ein Hardwarefehler oder die Baudrate stimmt nicht oder die Fusebits sind falsch gesetzt oder...
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.