[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