gephex--main--0.4--patch-1867
[email protected] Sat, 26 Mar 2005 21:43:58 +0100 (CET)
| Newsgroups | gmane.comp.video.gephex.devel |
|---|---|
| Message-ID | <[email protected]> |
Archive: [email protected] New revision: gephex--main--0.4--patch-1867 -- Revision: gephex--main--0.4--patch-1867 Archive: [email protected] Creator: The Gephex Source Archive <[email protected]> Date: Sat Mar 26 21:40:53 CET 2005 Standard-date: 2005-03-26 20:40:53 GMT New-files: configs/.arch-ids/macosx.arch.id configs/macosx.arch Modified-files: modules/src/Makefile.am modules/src/libmidi/libmidi.c modules/src/libmidi/libmidi.h modules/src/libmidi/midiutil.c modules/src/libmidi/midiutil.h modules/src/midiinmodule/wavemidiindriver.cpp New-patches: [email protected]/gephex--macport--0.4--patch-28 [email protected]/gephex--macport--0.4--patch-29 [email protected]/gephex--macport--0.4--patch-30 [email protected]/gephex--main--0.4--patch-1867 Summary: [MERGE-REQUEST] Fixed running status in libmidi (bug #115), fixed wavein midi driver in midiinmodule Keywords: Patches applied: * [email protected]/gephex--macport--0.4--patch-28 Sync with main * [email protected]/gephex--macport--0.4--patch-29 Fixed running status support in libmidi (bug #115), improved libmidi docu, use uint8_t instead of unsigned char * [email protected]/gephex--macport--0.4--patch-30 Fixed midiinmodle:waveinmididriver (possible reading of incomplete midi messages) * added files configs/.arch-ids/macosx.arch.id configs/macosx.arch {arch}/gephex/gephex--macport/gephex--macport--0.4/[email protected]/patch-log/patch-28 {arch}/gephex/gephex--macport/gephex--macport--0.4/[email protected]/patch-log/patch-29 {arch}/gephex/gephex--macport/gephex--macport--0.4/[email protected]/patch-log/patch-30 {arch}/gephex/gephex--main/gephex--main--0.4/[email protected]/patch-log/patch-1867 * modified files --- orig/modules/src/Makefile.am +++ mod/modules/src/Makefile.am @@ -63,7 +63,7 @@ imgarithmodule \ isingnoizemodule \ jumpmodule \ - midiccdecmodule + midiccdecmodule \ netcontrolmodule \ noisemodule \ numarithmodule \ --- orig/modules/src/libmidi/libmidi.c +++ mod/modules/src/libmidi/libmidi.c @@ -20,6 +20,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/ +/* + * TODO: can system realtime messages be really interleaved inside other + * midi messages? + */ + #include "libmidi.h" #include <stdlib.h> @@ -28,6 +33,8 @@ #include "midiutil.h" +static const uint8_t NO_STATUS = 0; // not a status byte + struct MidiParser { midi_noteoffT noteoff; @@ -39,7 +46,8 @@ midi_pitchbendT pitchbend; midi_systemexclusiveT systemexclusive; - void* data; + uint8_t running_status; + void* user_data; }; @@ -51,7 +59,7 @@ midi_channelaftertouchT channelaftert, midi_pitchbendT pitchbend, midi_systemexclusiveT systemexclusive, - void* data) + void* user_data) { struct MidiParser* self = (struct MidiParser* ) malloc(sizeof(*self)); @@ -64,7 +72,8 @@ self->pitchbend = pitchbend; self->systemexclusive = systemexclusive; - self->data = data; + self->running_status = NO_STATUS; + self->user_data = user_data; return self; } @@ -74,15 +83,13 @@ free(self); } - - -static __inline int is_system_realtime(unsigned char byte) +static __inline int is_system_realtime(uint8_t byte) { return byte >= 0xf8; } -static int parse_onebytemsg(const unsigned char* buf, - int len, int* overflow, unsigned char* b) +static int parse_onebytemsg(const uint8_t* buf, + int len, int* overflow, uint8_t* b) { int index = 0; @@ -104,8 +111,8 @@ return index; } -static int parse_twobytemsg(const unsigned char* buf, int len, int* overflow, - unsigned char* b1, unsigned char* b2) +static int parse_twobytemsg(const uint8_t* buf, int len, int* overflow, + uint8_t* b1, uint8_t* b2) { int index = 0; @@ -149,7 +156,7 @@ } static int parse_system(struct MidiParser* self, int lower_nibble, - const unsigned char* buf, int len, int* overflow) + const uint8_t* buf, int len, int* overflow) { int index = 0; @@ -203,9 +210,8 @@ return index; } -int midi_parse_data(struct MidiParser* self, const unsigned char* buf, int len) +int midi_parse_data(struct MidiParser* self, const uint8_t* buf, int len) { - int old_status = 0; int status = 0; int index = 0; int overflow = 0; @@ -213,17 +219,18 @@ while (index < len) { int length; - unsigned char status_upper_nibble; - unsigned char status_lower_nibble; + uint8_t status_upper_nibble; + uint8_t status_lower_nibble; status = buf[index]; - if (!midi_is_status((unsigned char) status)) + if (!midi_is_status((uint8_t) status)) { - //running status - status = old_status; + if (midi_is_status(self->running_status)) + status = self->running_status; } else { + self->running_status = (uint8_t) status; ++index; // go to first data byte } @@ -232,14 +239,14 @@ overflow = 0; switch(status_upper_nibble) { - unsigned char b1, b2; + uint8_t b1, b2; case MIDI_NOTE_OFF: length = parse_twobytemsg(buf + index, len-index, &overflow, &b1, &b2); if (length != -1 && self->noteoff) { - self->noteoff(status_lower_nibble, b1, b2, self->data); + self->noteoff(status_lower_nibble, b1, b2, self->user_data); } break; case MIDI_NOTE_ON: @@ -247,7 +254,7 @@ &b1, &b2); if (length != -1 && self->noteon) { - self->noteon(status_lower_nibble, b1, b2, self->data); + self->noteon(status_lower_nibble, b1, b2, self->user_data); } break; case MIDI_AFTERTOUCH: @@ -255,7 +262,7 @@ &b1, &b2); if (length != -1 && self->aftertouch) { - self->aftertouch(status_lower_nibble, b1, b2, self->data); + self->aftertouch(status_lower_nibble, b1, b2, self->user_data); } break; case MIDI_CTRLCHANGE: @@ -263,21 +270,21 @@ &b1, &b2); if (length != -1 && self->controlchange) { - self->controlchange(status_lower_nibble, b1, b2, self->data); + self->controlchange(status_lower_nibble, b1, b2, self->user_data); } break; case MIDI_PROGCHANGE: length = parse_onebytemsg(buf + index, len-index, &overflow, &b1); if (length != -1 && self->programchange) { - self->programchange(status_lower_nibble, b1, self->data); + self->programchange(status_lower_nibble, b1, self->user_data); } break; case MIDI_CHANNEL_AFTERTOUCH: length = parse_onebytemsg(buf + index, len-index, &overflow, &b1); if (length != -1 && self->channelaftertouch) { - self->channelaftertouch(status_lower_nibble, b1, self->data); + self->channelaftertouch(status_lower_nibble, b1, self->user_data); } break; case MIDI_PITCHBEND: @@ -285,7 +292,7 @@ &b1, &b2); if (length != -1 && self->pitchbend) { - self->pitchbend(status_lower_nibble, b1 + (b2 << 7), self->data); + self->pitchbend(status_lower_nibble, b1 + (b2 << 7), self->user_data); } break; case MIDI_SYSTEM: @@ -320,6 +327,11 @@ return index-1; } +void midi_reset(struct MidiParser* self) +{ + self->running_status = NO_STATUS; +} + void midi_set_noteoff_handler(struct MidiParser* self, midi_noteoffT handler) { --- orig/modules/src/libmidi/libmidi.h +++ mod/modules/src/libmidi/libmidi.h @@ -1,6 +1,6 @@ /* This source file is a part of the GePhex Project. - Copyright (C) 2001-2004 + Copyright (C) 2001-2005 Georg Seidel <[email protected]> Martin Bayer <[email protected]> @@ -23,38 +23,40 @@ #ifndef INCLUDED_LIBMIDI_H #define INCLUDED_LIBMIDI_H +#include <inttypes.h> + #ifdef __cplusplus extern "C" { #endif - typedef void (*midi_noteoffT)(unsigned char channel, unsigned char key, - unsigned char velocity, - void* self); - - typedef void (*midi_noteonT)(unsigned char channel, unsigned char key, - unsigned char velocity, void* self); - - typedef void (*midi_aftertouchT)(unsigned char channel, unsigned char key, - unsigned char pressure, - void* self); - - typedef void (*midi_controlchangeT)(unsigned char channel, - unsigned char control, - unsigned char value, - void* self); - - typedef void (*midi_programchangeT)(unsigned char channel, - unsigned char program, void* self); - - typedef void (*midi_channelaftertouchT)(unsigned char channel, - unsigned char pressure, - void* self); + typedef void (*midi_noteoffT)(uint8_t channel, uint8_t key, + uint8_t velocity, + void* user_data); + + typedef void (*midi_noteonT)(uint8_t channel, uint8_t key, + uint8_t velocity, void* user_data); + + typedef void (*midi_aftertouchT)(uint8_t channel, uint8_t key, + uint8_t pressure, + void* user_data); + + typedef void (*midi_controlchangeT)(uint8_t channel, + uint8_t control, + uint8_t value, + void* user_data); + + typedef void (*midi_programchangeT)(uint8_t channel, + uint8_t program, void* user_data); + + typedef void (*midi_channelaftertouchT)(uint8_t channel, + uint8_t pressure, + void* user_data); - typedef void (*midi_pitchbendT)(unsigned char channel, int value, + typedef void (*midi_pitchbendT)(uint8_t channel, int value, void* self); - typedef void (*midi_systemexclusiveT)(const unsigned char* data, int len); + typedef void (*midi_systemexclusiveT)(const uint8_t* data, int len); struct MidiParser; @@ -64,6 +66,9 @@ * Creates a new midiparser with handlers that are called at specific * midi messages. * If a handler is 0, the message of the corresponding type is ignored. + * + * @param user_data pointer to a context the caller wants to be + * passed to the callback functions */ struct MidiParser* midi_create_parser(midi_noteoffT noteoff, midi_noteonT noteon, @@ -73,7 +78,7 @@ midi_channelaftertouchT channelaftert, midi_pitchbendT pitchbend, midi_systemexclusiveT systemexclusive, - void* data); + void* user_data); /** * Destroys a midi parser. @@ -82,8 +87,17 @@ /** * Parses the raw midi data in buf. - * The buffer must start with a valid midi command. + * The buffer must start with a valid midi command + * note that the first status byte may be missing if using running status, + * in this case the status of the last midi message of the last + * call to midi_parse_data() will be used). * If registered with self, the appropriate callbacks will be called. + * + * If the return value (ret) is less than len, there is + * an incomplete midi message at the end of buf. The caller should + * take the bytes buf[ret], ..., buf[len-1] and prepend them + * to the next midi data to be parsed when calling midi_parse_data() again. + * * @param self the MidiParser * @param buf a buffer with raw midi data * @param len the length of the buffer in bytes @@ -91,10 +105,19 @@ * midi command at the end of the buffer, the return value can be * smaller than len. */ - int midi_parse_data(struct MidiParser* self, const unsigned char* buf, + int midi_parse_data(struct MidiParser* self, const uint8_t* buf, int len); /** + * Resets the internal state of the parser (running status). + * Should be called whenever the parsed midi stream is interrupted, + * or if the same parser is used to parse different midi streams. + * + * @param self the MidiParser + */ + void midi_reset(struct MidiParser* self); + + /** * Register a handler that is called at every noteOff message. * @param self the MidiParser * @param handler the handler function --- orig/modules/src/libmidi/midiutil.c +++ mod/modules/src/libmidi/midiutil.c @@ -24,7 +24,7 @@ #include <stdio.h> -int midi_length_of_message(unsigned char status) +int midi_length_of_message(uint8_t status) { int upper_nibble = status & 0xf0; switch (upper_nibble) @@ -60,7 +60,7 @@ } } -int midi_is_status(unsigned char byte) +int midi_is_status(uint8_t byte) { if (byte >= 0x80) return 1; --- orig/modules/src/libmidi/midiutil.h +++ mod/modules/src/libmidi/midiutil.h @@ -23,6 +23,8 @@ #ifndef INCLUDED_MIDIUTIL_H #define INCLUDED_MIDIUTIL_H +#include <inttypes.h> + #ifdef __cplusplus extern "C" { @@ -48,14 +50,14 @@ * or -1 for a variable length message. If status * is invalid, -2 is returned */ - int midi_length_of_message(unsigned char status); + int midi_length_of_message(uint8_t status); /** * Returns wether a byte is a midi status byte. * @param the byte that is tested * @return 1 if byte is a status byte, 0 if it is a data byte */ - int midi_is_status(unsigned char byte); + int midi_is_status(uint8_t byte); #ifdef __cplusplus } --- orig/modules/src/midiinmodule/wavemidiindriver.cpp +++ mod/modules/src/midiinmodule/wavemidiindriver.cpp @@ -58,7 +58,7 @@ static int read_buffer(unsigned char* data, int data_size); //puts a byte into the static buffer -static void put_byte(unsigned char byte); +static void put_bytes(const unsigned char* bytes, int len); //------------------------------------------------------------------------- @@ -260,33 +260,13 @@ void CALLBACK midiCallBack(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); -//puts a block of bytes into the static buffer -static void put_block(unsigned char* block, int len) -{ - EnterCriticalSection(&s_critical_section); - - if (s_midi_buf_len+len <= MIDI_BUF_SIZE) - { - memcpy(s_midi_buf + s_midi_buf_len, block, len); - s_midi_buf_len += len; - } - else - { - /*char buffer[64]; - snprintf(buffer, sizeof(buffer), - "Buffer overflow at midiinmodule::put_block, ignoring %i bytes", - len); - s_log(0, buffer);*/ - } - LeaveCriticalSection(&s_critical_section); -} - static void CALLBACK midiCallBack(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { unsigned char midiStat; /* MIDI_CMD_XXX */ unsigned char midiParam1; /* je nach commando andere bedeutung */ unsigned char midiParam2; /* je nach commando andere bedeutung */ + unsigned char buf[3]; //MidiType* buffer = (MidiType*) dwInstance; @@ -326,17 +306,20 @@ switch (len) { case 0: - put_byte(midiStat); - break; + buf[0] = midiStat; + put_bytes(buf, 1); + break; case 1: - put_byte(midiStat); - put_byte(midiParam1); - break; + buf[0] = midiStat; + buf[1] = midiParam1; + put_bytes(buf, 2); + break; case 2: - put_byte(midiStat); - put_byte(midiParam1); - put_byte(midiParam2); - break; + buf[0] = midiStat; + buf[1] = midiParam1; + buf[2] = midiParam2; + put_bytes(buf, 3); + break; default: { char buffer[64]; @@ -351,7 +334,7 @@ { MIDIHDR* hdr = (MIDIHDR*) dwParam1; //TODO do we need to insert a status byte? - put_block((unsigned char*) hdr->lpData, hdr->dwBytesRecorded); + put_bytes((unsigned char*) hdr->lpData, hdr->dwBytesRecorded); //TODO do we need to reinsert the buffer? }break; @@ -390,12 +373,15 @@ return len; } -static void put_byte(unsigned char byte) +static void put_bytes(const unsigned char* byte, int len) { EnterCriticalSection(&s_critical_section); - if (s_midi_buf_len < MIDI_BUF_SIZE) - s_midi_buf[s_midi_buf_len++] = byte; + if (s_midi_buf_len + len <= MIDI_BUF_SIZE) + { + memcpy(s_midi_buf+s_midi_buf_len, bytes, len); + s_midi_buf_len += len; + } else { /*char buffer[64];