[gephex-devel] gephex--main--0.4--patch-1867
gephex at sonnenland.kexbox.org
gephex at sonnenland.kexbox.org
Sat Mar 26 21:43:58 CET 2005
Archive: gephex at gephex.org--2004
New revision: gephex--main--0.4--patch-1867
--
Revision: gephex--main--0.4--patch-1867
Archive: gephex at gephex.org--2004
Creator: The Gephex Source Archive <gephex at gephex.org>
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: georg at gephex.org--2005-ibook/gephex--macport--0.4--patch-28
georg at gephex.org--2005-ibook/gephex--macport--0.4--patch-29
georg at gephex.org--2005-ibook/gephex--macport--0.4--patch-30
gephex at gephex.org--2004/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:
* georg at gephex.org--2005-ibook/gephex--macport--0.4--patch-28
Sync with main
* georg at gephex.org--2005-ibook/gephex--macport--0.4--patch-29
Fixed running status support in libmidi (bug #115), improved libmidi docu, use uint8_t instead of unsigned char
* georg at gephex.org--2005-ibook/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/georg at gephex.org--2005-ibook/patch-log/patch-28
{arch}/gephex/gephex--macport/gephex--macport--0.4/georg at gephex.org--2005-ibook/patch-log/patch-29
{arch}/gephex/gephex--macport/gephex--macport--0.4/georg at gephex.org--2005-ibook/patch-log/patch-30
{arch}/gephex/gephex--main/gephex--main--0.4/gephex at gephex.org--2004/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 <georg at gephex.org>
Martin Bayer <martin at gephex.org>
@@ -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];
More information about the gephex-devel
mailing list