[SCM] gsequencer/upstream: enhanced midi parser
jkraehemann-guest at users.alioth.debian.org
jkraehemann-guest at users.alioth.debian.org
Sun Jun 14 16:07:04 UTC 2015
The following commit has been merged in the upstream branch:
commit ec1efae9f88761c487e5eaa0ec3b7ac82f811e2f
Author: Joël Krähemann <weedlight at gmail.com>
Date: Wed Apr 29 11:54:48 2015 +0000
enhanced midi parser
diff --git a/Makefile.midi2ags b/Makefile.midi2ags
new file mode 100644
index 0000000..aefa862
--- /dev/null
+++ b/Makefile.midi2ags
@@ -0,0 +1,14 @@
+CFLAGS = `pkg-config --cflags gtk+-2.0 libxml-2.0` -I./src
+LDFLAGS = `pkg-config --libs gtk+-2.0 libxml-2.0`
+
+midi2ags: main.o ags_midi_parser.o ags_marshal.o
+ gcc -g -o midi2ags main.o ags_marshal.o ags_midi_parser.o $(LDFLAGS)
+
+main.o: src/midi2ags/main.c src/midi2ags/midi/ags_midi_parser.c
+ gcc -g -c -o main.o src/midi2ags/main.c $(CFLAGS)
+
+ags_marshal.o: src/midi2ags/midi/ags_marshal.c
+ gcc -g -c -o ags_marshal.o src/midi2ags/midi/ags_marshal.c $(CFLAGS)
+
+ags_midi_parser.o: src/midi2ags/midi/ags_midi_parser.c src/midi2ags/midi/ags_marshal.c
+ gcc -g -c -o ags_midi_parser.o src/midi2ags/midi/ags_midi_parser.c $(CFLAGS)
diff --git a/Makefile.midi2ags~ b/Makefile.midi2ags~
new file mode 100644
index 0000000..8d0fd77
--- /dev/null
+++ b/Makefile.midi2ags~
@@ -0,0 +1,14 @@
+CFLAGS = `pkg-config --cflags gtk+-2.0 libxml-2.0` -I./src
+LDFLAGS = `pkg-config --libs gtk+-2.0 libxml-2.0`
+
+midi2ags: main.o ags_midi_parser.o ags_marshal.o
+ gcc -g -o midi2ags main.o ags_midi_parser.o $(LDFLAGS)
+
+main.o: src/midi2ags/main.c src/midi2ags/midi/ags_midi_parser.c
+ gcc -g -c -o main.o src/midi2ags/main.c $(CFLAGS)
+
+ags_marshal.o: src/midi2ags/midi/ags_marshal.c
+ gcc -g -c -o ags_marshal.o src/midi2ags/midi/ags_marshal.c $(CFLAGS)
+
+ags_midi_parser.o: src/midi2ags/midi/ags_midi_parser.c src/midi2ags/midi/ags_marshal.c
+ gcc -g -c -o ags_midi_parser.o src/midi2ags/midi/ags_midi_parser.c $(CFLAGS)
diff --git a/src/midi2ags/main.c b/src/midi2ags/main.c
new file mode 100644
index 0000000..a7aa306
--- /dev/null
+++ b/src/midi2ags/main.c
@@ -0,0 +1,40 @@
+#include <glib.h>
+#include <glib-object.h>
+
+#include <midi2ags/midi/ags_midi_parser.h>
+
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ AgsMidiParser *midi_parser;
+
+ xmlDoc *doc;
+ FILE *out;
+
+ xmlChar *buffer;
+ gchar *filename;
+ size_t length;
+ int fd;
+
+ if(argc == 2){
+ filename = argv[1];
+ }else{
+ return;
+ }
+
+ fd = fopen(filename, "r\0");
+ fseek(fd, 0, SEEK_SET);
+ midi_parser = ags_midi_parser_new(fd);
+
+ doc = ags_midi_parser_parse_full(midi_parser);
+
+ xmlDocDumpFormatMemoryEnc(doc, &(buffer), &length, "UTF-8", TRUE);
+
+ fwrite(buffer, length, sizeof(xmlChar), stdout);
+ fflush(stdout);
+
+
+ return(0);
+}
diff --git a/src/midi2ags/main.c~ b/src/midi2ags/main.c~
new file mode 100644
index 0000000..a093ed7
--- /dev/null
+++ b/src/midi2ags/main.c~
@@ -0,0 +1,40 @@
+#include <glib.h>
+#include <glib-object.h>
+
+#include <midi2ags/midi/ags_midi_parser.h>
+
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ AgsMidiParser *midi_parser;
+
+ xmlDoc *doc;
+ FILE *out;
+
+ xmlChar *buffer;
+ gchar *filename;
+ size_t length;
+ int fd;
+
+ if(argc == 2){
+ filename = argv[1];
+ }else{
+ return;
+ }
+
+ fd = open(filename, 0);
+ lseek(fd, 0, SEEK_SET);
+ midi_parser = ags_midi_parser_new(fd);
+
+ doc = ags_midi_parser_parse_full(midi_parser);
+
+ xmlDocDumpFormatMemoryEnc(doc, &(buffer), &length, "UTF-8", TRUE);
+
+ fwrite(buffer, length, sizeof(xmlChar), stdout);
+ fflush(stdout);
+
+
+ return(0);
+}
diff --git a/src/ags-client/object/ags_marshal.c b/src/midi2ags/midi/ags_marshal.c
similarity index 55%
copy from src/ags-client/object/ags_marshal.c
copy to src/midi2ags/midi/ags_marshal.c
index 260a9a5..ab8534a 100644
--- a/src/ags-client/object/ags_marshal.c
+++ b/src/midi2ags/midi/ags_marshal.c
@@ -49,21 +49,21 @@
#endif /* !G_ENABLE_DEBUG */
-/* OBJECT:VOID (ags_marshallers.list:1) */
+/* INT:VOID (ags_marshallers.list:1) */
void
-g_cclosure_user_marshal_OBJECT__VOID (GClosure *closure,
- GValue *return_value G_GNUC_UNUSED,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
+g_cclosure_user_marshal_INT__VOID (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
{
- typedef GObject* (*GMarshalFunc_OBJECT__VOID) (gpointer data1,
- gpointer data2);
- register GMarshalFunc_OBJECT__VOID callback;
+ typedef gint (*GMarshalFunc_INT__VOID) (gpointer data1,
+ gpointer data2);
+ register GMarshalFunc_INT__VOID callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
- GObject* v_return;
+ gint v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 1);
@@ -78,30 +78,67 @@ g_cclosure_user_marshal_OBJECT__VOID (GClosure *closure,
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
- callback = (GMarshalFunc_OBJECT__VOID) (marshal_data ? marshal_data : cc->callback);
+ callback = (GMarshalFunc_INT__VOID) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
data2);
- g_value_take_object (return_value, v_return);
+ g_value_set_int (return_value, v_return);
}
-/* OBJECT:POINTER (ags_marshallers.list:2) */
+/* POINTER:VOID (ags_marshallers.list:2) */
void
-g_cclosure_user_marshal_OBJECT__POINTER (GClosure *closure,
- GValue *return_value G_GNUC_UNUSED,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
+g_cclosure_user_marshal_POINTER__VOID (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
{
- typedef GObject* (*GMarshalFunc_OBJECT__POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer data2);
- register GMarshalFunc_OBJECT__POINTER callback;
+ typedef gpointer (*GMarshalFunc_POINTER__VOID) (gpointer data1,
+ gpointer data2);
+ register GMarshalFunc_POINTER__VOID callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
- GObject* v_return;
+ gpointer v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 1);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_POINTER__VOID) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ data2);
+
+ g_value_set_pointer (return_value, v_return);
+}
+
+/* POINTER:UINT (ags_marshallers.list:3) */
+void
+g_cclosure_user_marshal_POINTER__UINT (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gpointer (*GMarshalFunc_POINTER__UINT) (gpointer data1,
+ guint arg_1,
+ gpointer data2);
+ register GMarshalFunc_POINTER__UINT callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gpointer v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 2);
@@ -116,12 +153,12 @@ g_cclosure_user_marshal_OBJECT__POINTER (GClosure *closure,
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
- callback = (GMarshalFunc_OBJECT__POINTER) (marshal_data ? marshal_data : cc->callback);
+ callback = (GMarshalFunc_POINTER__UINT) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
- g_marshal_value_peek_pointer (param_values + 1),
+ g_marshal_value_peek_uint (param_values + 1),
data2);
- g_value_take_object (return_value, v_return);
+ g_value_set_pointer (return_value, v_return);
}
diff --git a/src/midi2ags/midi/ags_marshal.h b/src/midi2ags/midi/ags_marshal.h
new file mode 100644
index 0000000..0043dbc
--- /dev/null
+++ b/src/midi2ags/midi/ags_marshal.h
@@ -0,0 +1,36 @@
+
+#ifndef __g_cclosure_user_marshal_MARSHAL_H__
+#define __g_cclosure_user_marshal_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* INT:VOID (ags_marshallers.list:1) */
+extern void g_cclosure_user_marshal_INT__VOID (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* POINTER:VOID (ags_marshallers.list:2) */
+extern void g_cclosure_user_marshal_POINTER__VOID (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* POINTER:UINT (ags_marshallers.list:3) */
+extern void g_cclosure_user_marshal_POINTER__UINT (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+G_END_DECLS
+
+#endif /* __g_cclosure_user_marshal_MARSHAL_H__ */
+
diff --git a/src/midi2ags/midi/ags_marshallers.list b/src/midi2ags/midi/ags_marshallers.list
new file mode 100644
index 0000000..79cd91d
--- /dev/null
+++ b/src/midi2ags/midi/ags_marshallers.list
@@ -0,0 +1,3 @@
+INT:VOID
+POINTER:VOID
+POINTER:UINT
diff --git a/src/midi2ags/midi/ags_marshallers.list~ b/src/midi2ags/midi/ags_marshallers.list~
new file mode 100644
index 0000000..bd89eef
--- /dev/null
+++ b/src/midi2ags/midi/ags_marshallers.list~
@@ -0,0 +1,3 @@
+INT:VOID
+POINTER:VOID
+POINTER:UINT
\ No newline at end of file
diff --git a/src/midi2ags/midi/ags_midi_parser.c b/src/midi2ags/midi/ags_midi_parser.c
index ce1ccc1..3c86568 100644
--- a/src/midi2ags/midi/ags_midi_parser.c
+++ b/src/midi2ags/midi/ags_midi_parser.c
@@ -16,16 +16,58 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <ags/audio/midi/ags_midi_parser.h>
+#include <midi2ags/midi/ags_midi_parser.h>
+#include <midi2ags/midi/ags_marshal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
void ags_midi_parser_class_init(AgsMidiParserClass *midi_parser);
void ags_midi_parser_init(AgsMidiParser *midi_parser);
+void ags_midi_parser_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec);
+void ags_midi_parser_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec);
void ags_midi_parser_finalize(GObject *gobject);
-#define AGS_MIDI_PARSE_MSB16(x) ((x[0] << 8) | (x[1]))
-#define AGS_MIDI_PARSE_MSB24(x) ((x[0] << 16) | (x[1] << 8) | (x[2]))
-#define AGS_MIDI_PARSE_MSB32(x) ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3]))
-#define AGS_MIDI_PARSE_MSB64(x) ((x[0] << 56) | (x[1] << 48) | (x[2] << 40) | (x[3] << 32) | (x[4] << 24) | (x[5] << 16) | (x[6] << 8) | (x[7]))
+int ags_midi_parser_real_midi_getc(AgsMidiParser *midi_parser);
+void ags_midi_parser_real_on_error(AgsMidiParser *midi_parser,
+ GError **error);
+
+xmlDoc* ags_midi_parser_real_parse_full(AgsMidiParser *midi_parser);
+xmlNode* ags_midi_parser_real_parse_header(AgsMidiParser *midi_parser);
+xmlNode* ags_midi_parser_real_parse_track(AgsMidiParser *midi_parser);
+
+xmlNode* ags_midi_parser_real_key_on(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_key_off(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_key_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_parameter(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_pitch_bend(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_program(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_channel_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_not_defined(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_real_sysex(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_system_common(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_real_meta_event(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_sequence_number(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_end_of_track(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_smpte(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_tempo(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_time_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_key_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_text_event(AgsMidiParser *midi_parser, guint meta_type);
+
+#define AGS_MIDI_PARSER_MAX_TEXT_LENGTH (4096)
#define AGS_MIDI_EVENT "event\0"
@@ -39,7 +81,41 @@ void ags_midi_parser_finalize(GObject *gobject);
* #AgsMidiParser reads your midi parsers.
*/
+enum{
+ PROP_0,
+ PROP_FD,
+};
+
+enum{
+ MIDI_GETC,
+ ON_ERROR,
+ PARSE_FULL,
+ PARSE_HEADER,
+ PARSE_TRACK,
+ KEY_ON,
+ KEY_OFF,
+ KEY_PRESSURE,
+ CHANGE_PARAMETER,
+ CHANGE_PITCH_BEND,
+ CHANGE_PROGRAM,
+ CHANGE_CHANNEL_PRESSURE,
+ NOT_DEFINED,
+ SYSEX,
+ SYSTEM_COMMON,
+ META_EVENT,
+ SEQUENCE_NUMBER,
+ END_OF_TRACK,
+ SMPTE,
+ TEMPO,
+ TIME_SIGNATURE,
+ KEY_SIGNATURE,
+ SEQUENCER_META_EVENT,
+ TEXT_EVENT,
+ LAST_SIGNAL,
+};
+
static gpointer ags_midi_parser_parent_class = NULL;
+static guint midi_parser_signals[LAST_SIGNAL];
GType
ags_midi_parser_get_type(void)
@@ -71,20 +147,543 @@ void
ags_midi_parser_class_init(AgsMidiParserClass *midi_parser)
{
GObjectClass *gobject;
-
+ GParamSpec *param_spec;
+
ags_midi_parser_parent_class = g_type_class_peek_parent(midi_parser);
/* GObjectClass */
gobject = (GObjectClass *) midi_parser;
+
+ gobject->set_property = ags_midi_parser_set_property;
+ gobject->get_property = ags_midi_parser_get_property;
gobject->finalize = ags_midi_parser_finalize;
+
+ /**
+ * AgsMidiParser:dsp-channels:
+ *
+ * The dsp channel count
+ *
+ * Since: 0.4.2
+ */
+ param_spec = g_param_spec_int("fd\0",
+ "the file descriptor fd\0",
+ "The file to parse as fd\0",
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READABLE | G_PARAM_WRITABLE);
+ g_object_class_install_property(gobject,
+ PROP_FD,
+ param_spec);
+
+ /* AgsMidiParser */
+ midi_parser->midi_getc = ags_midi_parser_real_midi_getc;
+ midi_parser->on_error = ags_midi_parser_real_on_error;
+
+ midi_parser->parse_header = ags_midi_parser_real_parse_header;
+ midi_parser->parse_track = ags_midi_parser_real_parse_track;
+
+ midi_parser->key_on = ags_midi_parser_real_key_on;
+ midi_parser->key_off = ags_midi_parser_real_key_off;
+ midi_parser->key_pressure = ags_midi_parser_real_key_pressure;
+ midi_parser->change_parameter = ags_midi_parser_real_change_parameter;
+ midi_parser->change_pitch_bend = ags_midi_parser_real_change_pitch_bend;
+ midi_parser->change_program = ags_midi_parser_real_change_program;
+ midi_parser->change_channel_pressure = ags_midi_parser_real_change_channel_pressure;
+ midi_parser->not_defined = ags_midi_parser_real_not_defined;
+
+ midi_parser->sysex = ags_midi_parser_real_sysex;
+ midi_parser->system_common = ags_midi_parser_real_system_common;
+
+ midi_parser->meta_event = ags_midi_parser_real_meta_event;
+ midi_parser->sequence_number = ags_midi_parser_real_sequence_number;
+ midi_parser->end_of_track = ags_midi_parser_real_end_of_track;
+ midi_parser->smpte = ags_midi_parser_real_smpte;
+ midi_parser->tempo = ags_midi_parser_real_tempo;
+ midi_parser->time_signature = ags_midi_parser_real_time_signature;
+ midi_parser->key_signature = ags_midi_parser_real_key_signature;
+ midi_parser->sequencer_meta_event = ags_midi_parser_real_sequencer_meta_event;
+ midi_parser->text_event = ags_midi_parser_real_text_event;
+
+ midi_parser->parse_full = ags_midi_parser_real_parse_full;
+
+ /* signals */
+ /**
+ * AgsMidiParser::midi-getc:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::midi-getc signal is emited during parsing of event.
+ */
+ midi_parser_signals[MIDI_GETC] =
+ g_signal_new("midi-getc\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, midi_getc),
+ NULL, NULL,
+ g_cclosure_user_marshal_INT__VOID,
+ G_TYPE_INT, 0);
+
+ /**
+ * AgsMidiParser::on-error:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::on-error signal is emited during parsing of event.
+ */
+ midi_parser_signals[ON_ERROR] =
+ g_signal_new("on-error\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, on_error),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__VOID,
+ G_TYPE_POINTER, 0);
+
+
+ /**
+ * AgsMidiParser::parse-header:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the header
+ *
+ * The ::parse-header signal is emited during parsing of header.
+ */
+ midi_parser_signals[PARSE_HEADER] =
+ g_signal_new("parse-header\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, parse_header),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__VOID,
+ G_TYPE_POINTER, 0);
+
+ /**
+ * AgsMidiParser::parse-track:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the track
+ *
+ * The ::parse-track signal is emited during parsing of track.
+ */
+ midi_parser_signals[PARSE_TRACK] =
+ g_signal_new("parse-track\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, parse_track),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__VOID,
+ G_TYPE_POINTER, 0);
+
+ /**
+ * AgsMidiParser::key-on:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::key-on signal is emited during parsing of event.
+ */
+ midi_parser_signals[KEY_ON] =
+ g_signal_new("key-on\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, key_on),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::key-off:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::key-off signal is emited during parsing of event.
+ */
+ midi_parser_signals[KEY_OFF] =
+ g_signal_new("key-off\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, key_off),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::key-pressure:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::key-pressure signal is emited during parsing of event.
+ */
+ midi_parser_signals[KEY_PRESSURE] =
+ g_signal_new("key-pressure\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, key_pressure),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::change-parameter:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::change-parameter signal is emited during parsing of event.
+ */
+ midi_parser_signals[CHANGE_PARAMETER] =
+ g_signal_new("change-parameter\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, change_parameter),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::change-pitch-bend:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::change-pitch-bend signal is emited during parsing of event.
+ */
+ midi_parser_signals[CHANGE_PITCH_BEND] =
+ g_signal_new("change-pitch-bend\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, change_pitch_bend),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::change-program:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::change-program signal is emited during parsing of event.
+ */
+ midi_parser_signals[CHANGE_PROGRAM] =
+ g_signal_new("change-program\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, change_program),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::change-channel-pressure:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::change-channel-pressure signal is emited during parsing of event.
+ */
+ midi_parser_signals[CHANGE_CHANNEL_PRESSURE] =
+ g_signal_new("change-channel-pressure\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, change_channel_pressure),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::not-defined:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::not-defined signal is emited during parsing of event.
+ */
+ midi_parser_signals[NOT_DEFINED] =
+ g_signal_new("not-defined\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, not_defined),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::sysex:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::sysex signal is emited during parsing of event.
+ */
+ midi_parser_signals[SYSEX] =
+ g_signal_new("sysex\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, sysex),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::system-common:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::system-common signal is emited during parsing of event.
+ */
+ midi_parser_signals[SYSTEM_COMMON] =
+ g_signal_new("system-common\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, system_common),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::meta-event:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::meta-event signal is emited during parsing of event.
+ */
+ midi_parser_signals[META_EVENT] =
+ g_signal_new("meta-event\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, meta_event),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::sequence-number:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::sequence-number signal is emited during parsing of event.
+ */
+ midi_parser_signals[SEQUENCE_NUMBER] =
+ g_signal_new("sequence-number\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, sequence_number),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::end-of-track:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::end-of-track signal is emited during parsing of event.
+ */
+ midi_parser_signals[END_OF_TRACK] =
+ g_signal_new("end-of-track\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, end_of_track),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::smpte:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::smpte signal is emited during parsing of event.
+ */
+ midi_parser_signals[SMPTE] =
+ g_signal_new("smpte\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, smpte),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::tempo:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::tempo signal is emited during parsing of event.
+ */
+ midi_parser_signals[TEMPO] =
+ g_signal_new("tempo\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, tempo),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::time-signature:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::time-signature signal is emited during parsing of event.
+ */
+ midi_parser_signals[TIME_SIGNATURE] =
+ g_signal_new("time-signature\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, time_signature),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::key-signature:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::key-signature signal is emited during parsing of event.
+ */
+ midi_parser_signals[KEY_SIGNATURE] =
+ g_signal_new("key-signature\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, key_signature),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::sequencer-meta-event:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::sequencer-meta-event signal is emited during parsing of event.
+ */
+ midi_parser_signals[SEQUENCER_META_EVENT] =
+ g_signal_new("sequencer-meta-event\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, sequencer_meta_event),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::text-event:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::text-event signal is emited during parsing of event.
+ */
+ midi_parser_signals[TEXT_EVENT] =
+ g_signal_new("text-event\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, text_event),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__UINT,
+ G_TYPE_POINTER, 1,
+ G_TYPE_UINT);
+
+ /**
+ * AgsMidiParser::parse-full:
+ * @midi_parser: the parser
+ *
+ * Returns: The XML node representing the event
+ *
+ * The ::parse-full signal is emited during parsing of midi file.
+ */
+ midi_parser_signals[PARSE_FULL] =
+ g_signal_new("parse-full\0",
+ G_TYPE_FROM_CLASS(midi_parser),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(AgsMidiParserClass, parse_full),
+ NULL, NULL,
+ g_cclosure_user_marshal_POINTER__VOID,
+ G_TYPE_POINTER, 0);
}
void
ags_midi_parser_init(AgsMidiParser *midi_parser)
{
- midi_parser->fd = -1;
+ midi_parser->flags = 0;
+
+ midi_parser->file = NULL;
midi_parser->nth_chunk = 0;
+
+ midi_parser->file_length = 0;
+ midi_parser->offset = 0;
+
+ midi_parser->current_time = 0;
+}
+
+void
+ags_midi_parser_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ AgsMidiParser *midi_parser;
+
+ midi_parser = AGS_MIDI_PARSER(gobject);
+
+ switch(prop_id){
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+ break;
+ }
+}
+
+void
+ags_midi_parser_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ AgsMidiParser *midi_parser;
+
+ midi_parser = AGS_MIDI_PARSER(gobject);
+
+ switch(prop_id){
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+ break;
+ }
}
void
@@ -92,585 +691,1553 @@ ags_midi_parser_finalize(GObject *gobject)
{
G_OBJECT_CLASS(ags_midi_parser_parent_class)->finalize(gobject);
}
+
+gint16
+ags_midi_parser_read_gint16(AgsMidiParser *midi_parser)
+{
+ char str[2];
+ gint16 value = 0;
+
+ str[0] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+ str[1] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+
+ value = (str[0] & 0xff);
+ value = (value<<8) + (str[1] & 0xff);
+
+ return(value);
}
-char*
-ags_midi_parser_read_chunk(AgsMidiParser *midi_parser,
- guint *message_type, guint *message_length,
- GError **error)
+gint32
+ags_midi_parser_read_gint24(AgsMidiParser *midi_parser)
{
- char chunk_type[4];
- char chunk_length[4];
- char *data;
+ char str[4];
+ gint32 value = 0;
+
+ str[0] = (char) 0x00;
+ str[1] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+ str[2] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+ str[3] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+
+ value = (value<<8) + (str[1] & 0xff);
+ value = (value<<8) + (str[2] & 0xff);
+ value = (value<<8) + (str[3] & 0xff);
+
+ return(value);
+}
- guint midi_type;
- guint data_length;
+gint32
+ags_midi_parser_read_gint32(AgsMidiParser *midi_parser)
+{
+ char str[4];
+ gint32 value;
- read(midi_parser->fd, chunk_type, 4 * sizeof(char));
+ str[0] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+ str[1] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+ str[2] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+ str[3] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+
+ value = (str[0] & 0xff);
+ value = (value<<8) + (str[1] & 0xff);
+ value = (value<<8) + (str[2] & 0xff);
+ value = (value<<8) + (str[3] & 0xff);
+
+ return(value);
+}
- if(!g_strncmp(AGS_MIDI_PARSER_MTHD,
- chunk_type,
- 4)){
- midi_type = AGS_MIDI_CHUNK_HEADER;
- }else if(!g_strncmp(AGS_MIDI_PARSER_MTCK,
- chunk_type,
- 4)){
- midi_type = AGS_MIDI_CHUNK_TRACK;
- }else{
- midi_type = AGS_MIDI_CHUNK_UNKNOWN;
- }
+long
+ags_midi_parser_read_varlength(AgsMidiParser *midi_parser)
+{
+ long value;
+ guint i;
+ char c;
- read(midi_parser->fd, chunk_length, 4 * sizeof(char));
- data_length = AGS_MIDI_PARSE_MSB32(chunk_length);
+ c = ags_midi_parser_midi_getc(midi_parser);
+ value = c;
+ i = 1;
+
+ if(c & 0x80){
+ value &= 0x7F;
+
+ do{
+ value = (value << 7) + ((c = ags_midi_parser_midi_getc(midi_parser)) & 0x7F);
+ i++;
+ }while(c & 0x80);
+ }
+
+ return(value);
+}
- data = (char *) malloc(data_length * sizeof(char));
- read(midi_parser->fd, data, data_length * sizeof(char));
+gchar*
+ags_midi_parser_read_text(AgsMidiParser *midi_parser,
+ gint length)
+{
+ gchar text[AGS_MIDI_PARSER_MAX_TEXT_LENGTH];
+ gchar c;
+ guint i;
- midi_parser->nth_chunk += 1;
+ memset(text, 0, AGS_MIDI_PARSER_MAX_TEXT_LENGTH * sizeof(char));
+ i = 0;
- if(message_type != NULL){
- *message_type = midi_type;
+ while((c = (char) 0xff & ags_midi_parser_midi_getc(midi_parser)) != '\0' && (length <= 0 ||
+ i < length) &&
+ c != EOF){
+ if(c == '\0' || !(g_ascii_isalnum(c) ||
+ g_ascii_ispunct(c) ||
+ c == ' ')){
+ break;
+ }
+
+ text[i] = c;
+ i++;
}
- if(message_length != NULL){
- *message_length = data_length;
+ text[i] = '\0';
+
+ return(g_strdup(text));
+}
+
+gdouble
+ags_midi_parser_ticks_to_sec(AgsMidiParser *midi_parser,
+ guint ticks, gint division, guint tempo)
+{
+ if(division > 0){
+ return ((gdouble) (((gdouble)(ticks) * (gdouble)(tempo)) /
+ ((gdouble)(division) * 1000000.0)));
+ }else{
+ gdouble smpte_format, smpte_resolution;
+
+ smpte_format = (gdouble) ((0xff00 & division) >> 8);
+ smpte_resolution = (gdouble) (0xff & division);
+
+ return((gdouble) ((gdouble) ticks / (smpte_format * smpte_resolution *
+ 1000000.0)));
}
+}
+
+int
+ags_midi_parser_midi_getc(AgsMidiParser *midi_parser)
+{
+ int c;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), '\0');
- return(data);
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[MIDI_GETC], 0,
+ &c);
+ g_object_unref((GObject *) midi_parser);
+
+ return(c);
+}
+
+int
+ags_midi_parser_real_midi_getc(AgsMidiParser *midi_parser)
+{
+ int c;
+
+ c = fgetc(midi_parser->file);
+
+ if(c == EOF){
+ g_warning("reached end of file\0");
+ midi_parser->flags |= AGS_MIDI_PARSER_EOF;
+ }
+
+ return(c);
}
void
-ags_midi_parser_write_chunk(AgsMidiParser *midi_parser,
- char *chunk, size_t length)
+ags_midi_parser_on_error(AgsMidiParser *midi_parser,
+ GError **error)
{
- write(midi_parser->fd, chunk, length);
+ g_return_if_fail(AGS_IS_MIDI_PARSER(midi_parser));
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[ON_ERROR], 0,
+ error);
+ g_object_unref((GObject *) midi_parser);
}
void
-ags_midi_parser_seek(AgsMidiParser *midi_parser, guint n_chunks, gint whence)
+ags_midi_parser_real_on_error(AgsMidiParser *midi_parser,
+ GError **error)
{
- char chunk_head[8];
- guint start_chunk;
- guint data_length;
+}
- switch(whence){
- case SEEK_CUR:
- start_chunk = midi_parser->nth_chunk;
+xmlDoc*
+ags_midi_parser_parse_full(AgsMidiParser *midi_parser)
+{
+ xmlDoc *doc;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[PARSE_FULL], 0,
+ &doc);
+ g_object_unref((GObject *) midi_parser);
- while(midi_parser->nth_chunk - start_chunk < n_chunks){
- read(midi_parser->fd, chunk_head, 8 * sizeof(char));
- data_length = AGS_MIDI_PARSE_MSB32(&(chunk_head[4]));
-
- seek(midi_parser->fd, SEEK_CUR, data_length);
-
- midi_parser->nth_chunk += 1;
- }
+ return(doc);
+}
- break;
- case SEEK_SET:
- midi_parser->nth_chunk = 0;
- seek(midi_parser->fd, SEEK_SET, 0);
+xmlDoc*
+ags_midi_parser_real_parse_full(AgsMidiParser *midi_parser)
+{
+ xmlDoc *doc;
+ xmlNode *root_node;
+ xmlNode *tracks_node;
+ xmlNode *current;
+ gchar c;
+
+ GError *error;
+
+ doc = xmlNewDoc("1.0\0");
+ root_node = xmlNewNode(NULL, "midi\0");
+ xmlDocSetRootElement(doc, root_node);
- while(midi_parser->nth_chunk < n_chunks){
- read(midi_parser->fd, chunk_head, 8 * sizeof(char));
- data_length = AGS_MIDI_PARSE_MSB32(&(chunk_head[4]));
-
- seek(midi_parser->fd, SEEK_CUR, data_length);
+ tracks_node = xmlNewNode(NULL, "midi-tracks\0");
- midi_parser->nth_chunk += 1;
- }
+ error = NULL;
- break;
- case SEEK_END:
- //TODO:JK: implement me
- break;
+ current = ags_midi_parser_parse_header(midi_parser);
+ xmlAddChild(root_node,
+ current);
+ g_message("parsed header\0");
+
+ xmlAddChild(root_node,
+ tracks_node);
+ c = 0x0;
+
+ while(((AGS_MIDI_PARSER_EOF & (midi_parser->flags))) == 0){
+ current = ags_midi_parser_parse_track(midi_parser);
+
+ if(current != NULL){
+ xmlAddChild(tracks_node,
+ current);
+ g_message("parsed track\0");
+ }else{
+ g_warning("skipped input\0");
+ }
}
+
+
+ return(doc);
}
-void
-ags_midi_parser_flush(AgsMidiParser *midi_parser)
+xmlNode*
+ags_midi_parser_parse_header(AgsMidiParser *midi_parser)
{
- flush(midi_parser->fd);
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[PARSE_HEADER], 0,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
}
xmlNode*
-ags_midi_parser_parse_header(AgsMidiParser *parser,
- char *chunk_data,
- guint chunk_type,
- guint chunk_length)
+ags_midi_parser_real_parse_header(AgsMidiParser *midi_parser)
{
xmlNode *node;
- char chunk_format[2];
- char chunk_tracks[2];
- char chunk_division[2];
+ static gchar header[] = "MThd";
+ guint format;
+ guint count;
+ guint division;
+ guint offset;
+ guint times;
+ guint beat, clicks;
+ guint n;
+ gchar c;
- guint track_format;
- guint track_count;
- guint track_division;
+ n = 0;
- node = xmlNewNode(NULL,
- "midi-header\0");
-
- memcpy(chunk_format, data, 2 * sizeof(char));
- track_format = AGS_MIDI_PARSE_MSB16(chunk_format);
-
- switch(track_format){
- case 0:
- {
- xmlNewProp(node,
- "track-format\0",
- "single\0");
- }
- break;
- case 1:
- {
- xmlNewProp(node,
- "track-format\0",
- "simoultaneous\0");
- }
- break;
- case 2
- {
- xmlNewProp(node,
- "track-format\0",
- "independant\0");
+ while(n < 4 &&
+ (AGS_MIDI_PARSER_EOF & (midi_parser->flags)) == 0){
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == header[n]){
+ n++;
+ }else{
+ n = 0;
}
- break;
}
- memcpy(chunk_tracks, &(data[2]), 2 * sizeof(char));
- track_count = AGS_MIDI_PARSE_MSB16(chunk_tracks);
+ node = xmlNewNode(NULL,
+ "midi-header\0");
+
+ offset = (guint) ags_midi_parser_read_gint32(midi_parser);
+ format = (guint) ags_midi_parser_read_gint16(midi_parser);
+ count = (guint) ags_midi_parser_read_gint16(midi_parser);
+ division = (guint) ags_midi_parser_read_gint16(midi_parser);
xmlNewProp(node,
- "track-count\0",
- g_strdup_printf("%d\0", track_count));
-
- memcpy(chunk_division, &(data[4]), 2 * sizeof(char));
- track_division = AGS_MIDI_PARSE_MSB16(chunk_division);
+ "format\0",
+ g_strdup_printf("%d\0", format));
+
+ if(division & 0x8000){
+ /* SMPTE */
+ times = 0; /* Can't do beats */
- if((track_division & (1 << 15)) != 0){
- xmlNewProp(node,
- "smtpe\0",
- "false\0");
-
xmlNewProp(node,
- "delta-time\0",
- g_strdup_printf("%d\0",
- (track_division & (~(1 << 15)))));
+ "division\0",
+ g_strdup_printf("%d %d\0", -((-(division>>8))&0xff), division&0xff));
}else{
xmlNewProp(node,
- "smtpe\0",
- "true\0");
+ "division\0",
+ g_strdup_printf("%d\0", division));
+ }
+
+ if(format > 2){
+ fprintf(stderr, "Can't deal with format %d files\n", format);
+ exit(-1);
+ }
+
+ beat =
+ clicks = division;
- xmlNewProp(node,
- "delta-time\0",
- g_strdup_printf("%d\0",
- (track_division & (~(0xff)))));
+ xmlNewProp(node,
+ "beat\0",
+ g_strdup_printf("%d\0", beat));
- xmlNewProp(node,
- "smtpe-fps\0",
- g_strdup_printf("%d\0",
- (track_division & (~(0x7f00)))));
- }
+ xmlNewProp(node,
+ "track-count\0",
+ g_strdup_printf("%d\0", count));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_parse_track(AgsMidiParser *midi_parser)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[PARSE_TRACK], 0,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
return(node);
}
xmlNode*
-ags_midi_parser_parse_track(AgsMidiParser *parser,
- char *chunk_data,
- guint chunk_type,
- guint chunk_length)
-{
- xmlNode *node, *message_node;
-
- char chunk_delta_time[8];
- char voice_message[4];
- guint64 delta_time;
- guint imask;
- guint key, control, value, program, pressure, pitch;
- guint velocity;
- guint offset;
- guint i;
+ags_midi_parser_real_parse_track(AgsMidiParser *midi_parser)
+{
+ xmlNode *node, *current;
+ static gchar track[] = "MTrk";
+ gint offset, start_offset;
+ long delta_time;
+ guint status;
+ guint n;
+ gchar c;
+
+ n = 0;
- node = xmlNewNode(NULL,
- "midi-track\0");
-
- /* delta time */
- for(offset = 0; offset < 8; offset++){
- if((&(chunk_data[offset]) & (1 << 7)) != 0){
- break;
+ while(n < 4 &&
+ (AGS_MIDI_PARSER_EOF & (midi_parser->flags)) == 0){
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == track[n]){
+ n++;
+ }else{
+ n = 0;
}
}
- for(i = 0; i < offset + 1; i++){
- chunk_delta_time[i] = chunk_data[offset - i];
+ if((AGS_MIDI_PARSER_EOF & (midi_parser->flags)) != 0){
+ return(NULL);
+ }
+
+ node = xmlNewNode(NULL, "midi-track\0");
+
+ offset = ags_midi_parser_read_gint32(midi_parser);
+ g_message("n = %d\noffset = %d\0", n, offset);
+ start_offset = ftell(midi_parser->file);
+
+ if(offset < 0){
+ return(NULL);
}
-
- delta_time = AGS_MIDI_PARSE_MSB64(chunk_delta_time);
- offset++;
-
- xmlNewProp(node,
- "delta-time\0",
- g_strdup_printf("%d\0", delta_time));
- for(; offset < chunk_length;){
- message_node = xmlNewNode(NULL,
- "midi-message\0");
+ midi_parser->current_time = 0;
+
+ for(; ftell(midi_parser->file) < start_offset + offset; ){
+ delta_time = ags_midi_parser_read_varlength(midi_parser);
+ midi_parser->current_time += delta_time;
+
+ status = ags_midi_parser_midi_getc(midi_parser);
- if((chunk_data[offset] & (0x80)) != 0 ||
- (chunk_data[offset] & (0x90)) != 0 ||
- (chunk_data[offset] & (0xa0)) != 0){
- /* definitely voice message */
- imask = 0x0f;
-
- xmlNewProp(message_node,
- "type\0",
- "voice-message\0");
-
- key = chunk_data[offset + 1];
- velocity = chunk_data[offset + 2];
-
- if((~imask) & chunk_data[offset] == 0x80){
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "note-off\0");
- }else if((~imask) & chunk_data[offset] == 0x90){
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "note-on\0");
- }else{
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "polyphonic\0");
+ if((0xf0 & (0xf0 & status)) != 0xf0){
+ current = ags_midi_parser_channel_message(midi_parser,
+ status);
+
+ if(current != NULL){
+ xmlNewProp(current,
+ "delta-time\0",
+ g_strdup_printf("%d\0", midi_parser->current_time));
+
+ xmlAddChild(node,
+ current);
}
+
+ g_message("channel message");
+ }else{
+ g_message("status message");
- xmlNewProp(message_node,
- "key\0",
- g_strdup_printf("%d\0", key));
-
- xmlNewProp(message_node,
- "velocity\0",
- g_strdup_printf("%d\0", velocity));
+ switch(status){
+ case 0xf0:
+ {
+ /* start of system exclusive */
+ ags_midi_parser_sysex(midi_parser,
+ status);
- offset += 3;
- }else if(chunk_data[offset] == 0xb0){
- /* voice or channel mode message */
- imask = 0x0f;
+ }
+ case 0xf1:
+ case 0xf2:
+ case 0xf3:
+ case 0xf4:
+ case 0xf5:
+ case 0xf6:
+ {
+ ags_midi_parser_system_common(midi_parser,
+ status);
+ }
+ break;
+ case 0xf7:
+ {
+ /* sysex continuation or arbitrary stuff */
+ g_message("sysex end\0");
+ }
+ break;
+ case 0xff:
+ {
+ /* meta event */
+ current = ags_midi_parser_meta_event(midi_parser,
+ status);
+
+ if(current != NULL){
+ xmlNewProp(current,
+ "delta-time\0",
+ g_strdup_printf("%d\0", midi_parser->current_time));
+
+ xmlAddChild(node,
+ current);
+ }
+ }
+ break;
+ default:
+ g_warning("bad byte\0");
+ break;
+ }
+ }
+ }
+
+ return(node);
+}
- control = chunk_data[offset + 1];
- value = chunk_data[offset + 2];
+xmlNode*
+ags_midi_parser_channel_message(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
- if(control < 120){
- xmlNewProp(message_node,
- "type\0",
- "voice-message\0");
+ node = NULL;
+
+ switch(status & 0xf0){
+ case 0x80:
+ {
+ node = ags_midi_parser_key_off(midi_parser, status);
+ }
+ break;
+ case 0x90:
+ {
+ node = ags_midi_parser_key_on(midi_parser, status);
+ }
+ break;
+ case 0xa0:
+ {
+ node = ags_midi_parser_key_pressure(midi_parser, status);
+ }
+ break;
+ case 0xb0:
+ {
+ node = ags_midi_parser_change_parameter(midi_parser, status);
+ }
+ break;
+ case 0xc0:
+ {
+ node = ags_midi_parser_change_program(midi_parser, status);
+ }
+ break;
+ case 0xd0:
+ {
+ node = ags_midi_parser_change_channel_pressure(midi_parser, status);
+ }
+ break;
+ case 0xe0:
+ {
+ node = ags_midi_parser_change_pitch_bend(midi_parser, status);
+ }
+ break;
+ }
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "control-change\0");
+ return(node);
+}
- xmlNewProp(message_node,
- "control\0",
- g_strdup_printf("%d\0", control));
+xmlNode*
+ags_midi_parser_real_key_on(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int channel, note, velocity;
- xmlNewProp(message_node,
- "value\0",
- g_strdup_printf("%d\0", value));
- }else{
- xmlNewProp(message_node,
- "type\0",
- "mode-message\0");
-
- switch(control){
- case 120:
- {
- xmlNewProp(message_node,
- "mode\0",
- "all-sound-off\0");
- }
- break;
- case 121:
- {
- xmlNewProp(message_node,
- "mode\0",
- "reset-control-all\0");
-
- xmlNewProp(message_node,
- "value\0",
- g_strdup_printf("%d\0", value));
- }
- break;
- case 122:
- {
- if(value == 0){
- xmlNewProp(message_node,
- "mode\0",
- "local-control-off\0");
- }else{
- xmlNewProp(message_node,
- "mode\0",
- "local-control-on\0");
- }
- }
- break;
- case 123:
- {
- xmlNewProp(message_node,
- "mode\0",
- "all-notes-off");
- }
- break;
- case 124:
- {
- xmlNewProp(message_node,
- "mode\0",
- "omni-mode-on");
- }
- break;
- case 125:
- {
- xmlNewProp(message_node,
- "mode\0",
- "omni-mode-off\0");
- }
- break;
- case 126:
- {
- xmlNewProp(message_node,
- "mode\0",
- "mono-mode-on\0");
-
- xmlNewProp(message_node,
- "omni-off-channels\0",
- g_strdup_printf("%d\0", value));
- }
- break;
- case 127:
- {
- xmlNewProp(message_node,
- "mode\0",
- "poly-mode-on\0");
- }
- break;
- }
- }
-
- offset += 3;
- }else if((chunk_data[offset] & (0xc0)) != 0 ||
- (chunk_data[offset] & (0xd0)) != 0 ||
- (chunk_data[offset] & (0xe0)) != 0){
- imask = 0x0f;
-
- xmlNewProp(message_node,
- "type\0",
- "voice-message\0");
-
- key = chunk_data[offset + 1];
- velocity = chunk_data[offset + 2];
-
- /* definitely voice message */
- if((~imask) & chunk_data[offset] == 0xc0){
- program = chunk_data[offset + 1];
-
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "program-change\0");
-
- xmlNewProp(message_node,
- "program\0",
- g_strdup_printf("%d\0", program));
-
- offset += 2;
- }else if((~imask) & chunk_data[offset] == 0xd0){
- pressure = chunk_data[offset + 1];
-
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "channel-pressure\0");
-
- xmlNewProp(message_node,
- "pressure\0",
- g_strdup_printf("%d\0", pressure));
-
- offset += 2;
- }else{
- pitch = AGS_MIDI_PARSE_MSB16(chunk_data[offset + 1]);
-
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "pitch-bend\0");
-
- xmlNewProp(message_node,
- "pitch\0",
- g_strdup_printf("%d\0", pitch));
-
- offset += 3;
- }
+ channel = 0xf & status;
+ note = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+ velocity = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
- }else if((chunk_data[offset] & (0xf)) &&
- !(chunk_data[offset] & (0x08))){
- /* system common message */
- xmlNewProp(message_node,
- "type\0",
- "system-common\0");
-
- if(chunk_data[offset] == 0xf0){
- guint manufacturer;
- guint start_value, end_value;
- char *reserved;
-
- /* system exclusive */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "sysex\0");
-
- if(chunck_length > 6){
- manufacturer = AGS_MIDI_PARSE_MSB24(chunk_data);
- offset += 3;
- }else{
- manufacturer = chunk_data[0];
- offset++;
- }
-
- xmlNewProp(message_node,
- "manufacturer\0"
- g_strdup_printf("%d\0", manufacturer));
-
- start_value = chunk_data[offset];
- xmlNewProp(message_node,
- "start-value\0"
- g_strdup_printf("%d\0", start_value));
-
- end_value = chunk_data[offset + 3];
- xmlNewProp(message_node,
- "end-value\0"
- g_strdup_printf("%d\0", end_value));
-
- reserverd = AGS_MIDI_PARSE_MSB16(&(chunk_data[1]));
- xmlNewProp(message_node,
- "reserved\0"
- g_strdup_printf("%x\0", reserved));
- }else if(chunk_data[offset] == 0xf1){
- guint frame_type;
- guint frame_value;
-
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "quarter-frame\0");
-
- /* time code quarter frame */
- frame_type = (0xf0 & (&(chunk_data[1]))) >> 4;
-
- xmlNewProp(message_node,
- "message-type\0",
- g_strdup_printf("%x\0", frame_type));
+ node = xmlNewNode(NULL,
+ "midi-message\0");
- frame_type = (0x0f & (&(chunk_data[1])));
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "note-on\0");
- xmlNewProp(message_node,
- "message-value\0",
- g_strdup_printf("%d\0", frame_value));
- }else if(chunk_data[offset] == 0xf2){
- guint beats_count;
+ xmlNewProp(node,
+ "key\0",
+ g_strdup_printf("%d\0", channel));
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "position-pointer\0");
-
- /* song position pointer */
- beats_count = (((0x3f & (chunk_data[0])) << 7) | (0x7f & (chunk_data[1])));
-
- xmlNewProp(message_node,
- "beats-count\0",
- g_strdup_printf("%d\0", beats_count));
- }else if(chunk_data[offset] == 0xf3){
- guint sequence;
-
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "song-select\0");
-
- /* song select */
- sequence = chunk_data[0];
-
- xmlNewProp(message_node,
- "sequence\0",
- g_strdup_printf("%d\0", sequence);
- }else if(chunk_data[offset] == 0xf4){
- g_warning("undefined system common message\0");
- }else if(chunk_data[offset] == 0xf5){
- g_warning("undefined system common message\0");
- }else if(chunk_data[offset] == 0xf6){
- /* tune request to all analog synths */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "tune-on\0");
- }else if(chunk_data[offset] == 0xf7){
- /* end of sysex */
- }
- }else{
- /* real-time message */
- xmlNewProp(message_node,
- "type\0",
- "system-realtime\0");
-
- if(chunk_data[offset] == 0xf8){
- /* timing clock */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "clock\0");
- }else if(chunk_data[offset] == 0xf9){
- g_warning("undefined system realtime message\0");
- }else if(chunk_data[offset] == 0xfa){
- /* start */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "start\0");
- }else if(chunk_data[offset] == 0xfb){
- /* continue */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "continue\0");
- }else if(chunk_data[offset] == 0xfc){
- /* stop */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "stop\0");
- }else if(chunk_data[offset] == 0xfd){
- g_warning("undefined system realtime message\0");
- }else if(chunk_data[offset] == 0xfe){
- /* active sensinge */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "active-sense\0");
- }else if(chunk_data[offset] == 0xff){
- /* reset */
- xmlNewProp(message_node,
- AGS_MIDI_EVENT,
- "reset\0");
- }
- }
- }
+ xmlNewProp(node,
+ "note\0",
+ g_strdup_printf("%d\0", note));
- xmlAddChild(node,
- message_node);
+ xmlNewProp(node,
+ "velocity\0",
+ g_strdup_printf("%d\0", velocity));
+
+ return(node);
}
+
+xmlNode*
+ags_midi_parser_key_on(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
- //TODO:JK: implement me
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[KEY_ON], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
return(node);
}
-AgsMidiParser*
-ags_midi_parser_new()
+xmlNode*
+ags_midi_parser_real_key_off(AgsMidiParser *midi_parser, guint status)
{
- AgsMidiParser *midi_parser;
+ xmlNode *node;
+ int channel, note, velocity;
- midi_parser = (AgsMidiParser *) g_object_new(AGS_TYPE_MIDI_PARSER,
- NULL);
+ channel = 0xf & status;
+ note = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+ velocity = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "note-off\0");
+
+
+ xmlNewProp(node,
+ "key\0",
+ g_strdup_printf("%d\0", channel));
+
+ xmlNewProp(node,
+ "note\0",
+ g_strdup_printf("%d\0", note));
+
+ xmlNewProp(node,
+ "velocity\0",
+ g_strdup_printf("%d\0", velocity));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_key_off(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[KEY_OFF], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_key_pressure(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int channel, note, pressure;
+
+ channel = 0xf & status;
+ note = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+ pressure = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "polyphonic\0");
+
+ xmlNewProp(node,
+ "key\0",
+ g_strdup_printf("%d\0", channel));
+
+ xmlNewProp(node,
+ "note\0",
+ g_strdup_printf("%d\0", note));
+
+ pressure = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+
+ xmlNewProp(node,
+ "pressure\0",
+ g_strdup_printf("%d\0", pressure));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_key_pressure(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[KEY_PRESSURE], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_change_parameter(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int channel, control, value;
+
+ channel = 0xf & status;
+ control = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+ value = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ if(control < 120){
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "change-parameter\0");
+
+ xmlNewProp(node,
+ "channel\0",
+ g_strdup_printf("%d\0", channel));
+
+ xmlNewProp(node,
+ "control\0",
+ g_strdup_printf("%d\0", control));
+
+ xmlNewProp(node,
+ "value\0",
+ g_strdup_printf("%d\0", value));
+ }else{
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "change-mode\0");
+
+ xmlNewProp(node,
+ "channel\0",
+ g_strdup_printf("%d\0", channel));
+
+ switch(control){
+ case 120:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "all-sound-off\0");
+ }
+ break;
+ case 121:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "reset-control-all\0");
+
+ xmlNewProp(node,
+ "value\0",
+ g_strdup_printf("%d\0", value));
+ }
+ break;
+ case 122:
+ {
+ if(value == 0){
+ xmlNewProp(node,
+ "mode\0",
+ "local-control-off\0");
+ }else{
+ xmlNewProp(node,
+ "mode\0",
+ "local-control-on\0");
+ }
+ }
+ break;
+ case 123:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "all-notes-off");
+ }
+ break;
+ case 124:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "omni-mode-on");
+ }
+ break;
+ case 125:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "omni-mode-off\0");
+ }
+ break;
+ case 126:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "mono-mode-on\0");
+
+ xmlNewProp(node,
+ "omni-off-channels\0",
+ g_strdup_printf("%d\0", value));
+ }
+ break;
+ case 127:
+ {
+ xmlNewProp(node,
+ "mode\0",
+ "poly-mode-on\0");
+ }
+ break;
+ }
+ }
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_change_parameter(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[CHANGE_PARAMETER], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_change_pitch_bend(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int channel, pitch, transmitter;
+
+ channel = 0xf & status;
+ pitch = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+ transmitter = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ "channel\0",
+ g_strdup_printf("%d\0", channel));
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "pitch-bend\0");
+
+ xmlNewProp(node,
+ "pitch\0",
+ g_strdup_printf("%d\0", pitch));
+
+ xmlNewProp(node,
+ "transmitter\0",
+ g_strdup_printf("%d\0", transmitter));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_change_pitch_bend(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[CHANGE_PITCH_BEND], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_change_program(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int channel, program;
+
+ channel = 0xf & status;
+ program = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "program-change\0");
+
+ xmlNewProp(node,
+ "channel\0",
+ g_strdup_printf("%d\0", channel));
+
+ xmlNewProp(node,
+ "program\0",
+ g_strdup_printf("%d\0", program));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_change_program(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[CHANGE_PROGRAM], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_change_channel_pressure(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int channel, pressure;
+
+ channel = 0xf & status;
+ pressure = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "channel-pressure\0");
+
+ xmlNewProp(node,
+ "channel\0",
+ g_strdup_printf("%d\0", channel));
+
+ xmlNewProp(node,
+ "pressure\0",
+ g_strdup_printf("%d\0", pressure));
+
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_change_channel_pressure(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[CHANGE_CHANNEL_PRESSURE], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_not_defined(AgsMidiParser *midi_parser, guint status)
+{
+ return(NULL);
+}
+
+xmlNode*
+ags_midi_parser_not_defined(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[NOT_DEFINED], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_sysex(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ gchar c;
+
+ while((c = ags_midi_parser_midi_getc(midi_parser)) != 0xf7 &&
+ c != EOF);
+
+ g_message("discarded sysex\0");
+}
+
+xmlNode*
+ags_midi_parser_sysex(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[SYSEX], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_system_common(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ int c;
+
+ node = NULL;
+
+ switch(status){
+ case 0xf1:
+ {
+ guint quarter_frame;
+
+ quarter_frame = 0xff & (ags_midi_parser_midi_getc(midi_parser));
+ }
+ break;
+ case 0xf2:
+ {
+ guint song_position;
+
+ song_position = 0x7f & (ags_midi_parser_midi_getc(midi_parser)) << 7;
+ song_position = 0x7f & (ags_midi_parser_midi_getc(midi_parser));
+ }
+ break;
+ case 0xf3:
+ {
+ guint song_select;
+
+ song_select = 0x7f & (ags_midi_parser_midi_getc(midi_parser));
+ }
+ break;
+ case 0xf4:
+ {
+ g_message("undefined\0");
+ }
+ break;
+ case 0xf5:
+ {
+ g_message("undefined\0");
+ }
+ break;
+ case 0xf6:
+ {
+ g_message("tune request\0");
+ }
+ break;
+ }
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_system_common(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[SYSTEM_COMMON], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_meta_event(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+ char chunk_meta_length[4];
+ guint meta_type;
+
+ meta_type = 0xff & (ags_midi_parser_midi_getc(midi_parser));
+ midi_parser->offset += 1;
+
+ node = NULL;
+
+ switch(meta_type){
+ case 0x00:
+ {
+ int c;
+
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == 0x02){
+ node = ags_midi_parser_sequence_number(midi_parser, meta_type);
+ }
+ }
+ break;
+ case 0x01: /* Text event */
+ case 0x02: /* Copyright notice */
+ case 0x03: /* Sequence/Track name */
+ case 0x04: /* Instrument name */
+ case 0x05: /* Lyric */
+ case 0x06: /* Marker */
+ case 0x07: /* Cue point */
+ case 0x08:
+ case 0x09:
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ case 0x0f:
+ {
+ /* These are all text events */
+ node = ags_midi_parser_text_event(midi_parser, meta_type);
+ }
+ break;
+ case 0x2f:
+ {
+ int c;
+
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == 0x0){
+ /* End of Track */
+ node = ags_midi_parser_end_of_track(midi_parser, meta_type);
+ }
+ }
+ break;
+ case 0x51:
+ {
+ int c;
+
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == 0x03){
+ /* Set tempo */
+ node = ags_midi_parser_tempo(midi_parser, meta_type);
+ }
+ }
+ break;
+ case 0x54:
+ {
+ int c;
+
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == 0x05){
+ node = ags_midi_parser_smpte(midi_parser, meta_type);
+ }
+ }
+ break;
+ case 0x58:
+ {
+ int c;
+
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == 0x04){
+ node = ags_midi_parser_time_signature(midi_parser, meta_type);
+ }
+ }
+ break;
+ case 0x59:
+ {
+ int c;
+
+ c = ags_midi_parser_midi_getc(midi_parser);
+
+ if(c == 0x02){
+ node = ags_midi_parser_key_signature(midi_parser, meta_type);
+ }
+ }
+ break;
+ case 0x7f:
+ {
+ node = ags_midi_parser_sequencer_meta_event(midi_parser, meta_type);
+ }
+ break;
+ default:
+ {
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "misc\0");
+ }
+ }
+
+ g_message("meta type 0x%x\0", meta_type);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_meta_event(AgsMidiParser *midi_parser, guint status)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[META_EVENT], 0,
+ status,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_sequence_number(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ guint sequence;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ sequence = (guint) ags_midi_parser_read_gint16(midi_parser);
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "sequence-number\0");
+
+ xmlNewProp(node,
+ "sequence\0",
+ g_strdup_printf("%d\0", sequence));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_sequence_number(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[SEQUENCE_NUMBER], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_end_of_track(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "end-of-track\0");
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_end_of_track(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[END_OF_TRACK], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_smpte(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ int hr, mn, se, fr, ff;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ hr = ags_midi_parser_midi_getc(midi_parser);
+ mn = ags_midi_parser_midi_getc(midi_parser);
+ se = ags_midi_parser_midi_getc(midi_parser);
+ fr = ags_midi_parser_midi_getc(midi_parser);
+ ff = ags_midi_parser_midi_getc(midi_parser);
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "smpte\0");
+
+ xmlNewProp(node,
+ "timestamp\0",
+ g_strdup_printf("%d %d %d %d %d\0", hr, mn, se, fr, ff));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_smpte(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[SMPTE], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_tempo(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ gint tempo;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ tempo = ags_midi_parser_read_gint24(midi_parser);
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "tempo-number\0");
+
+ xmlNewProp(node,
+ "tempo\0",
+ g_strdup_printf("%ld\0", tempo));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_tempo(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[TEMPO], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_time_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ int nn, dd, cc, bb;
+ int denom = 1;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ nn = ags_midi_parser_midi_getc(midi_parser);
+ dd = ags_midi_parser_midi_getc(midi_parser);
+ cc = ags_midi_parser_midi_getc(midi_parser);
+ bb = ags_midi_parser_midi_getc(midi_parser);
+
+ while(dd-- > 0){
+ denom *= 2;
+ }
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "time-signature\0");
+
+ xmlNewProp(node,
+ "timesig\0",
+ g_strdup_printf("%d/%d %d %d\0", nn, denom, cc, bb));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_time_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[TIME_SIGNATURE], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_key_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ int sf, mi;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ xmlNewProp(node,
+ AGS_MIDI_EVENT,
+ "key-signature\0");
+
+ sf = ags_midi_parser_midi_getc(midi_parser);
+ mi = ags_midi_parser_midi_getc(midi_parser);
+
+ xmlNewProp(node,
+ "keysig\0",
+ g_strdup_printf("%d %s\0", (sf>127?sf-256:sf), (mi?"minor":"major")));
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_key_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[KEY_SIGNATURE], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ guint len, id, data;
+
+ node = NULL;
+
+ len = ags_midi_parser_midi_getc(midi_parser);
+ id = ags_midi_parser_midi_getc(midi_parser);
+ data = ags_midi_parser_midi_getc(midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[META_EVENT], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_text_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+ gchar *text;
+ guint text_length;
+
+ node = xmlNewNode(NULL,
+ "midi-message\0");
+
+ text_length = ags_midi_parser_read_varlength(midi_parser);
+ text = ags_midi_parser_read_text(midi_parser,
+ text_length);
+
+ switch(0x0f & meta_type){
+ case 0x01: /* Text event */
+ break;
+ case 0x02:
+ {
+ /* Copyright notice */
+ xmlNewProp(node,
+ "copyright\0",
+ text);
+ }
+ break;
+ case 0x03:
+ {
+ /* Sequence/Track name */
+ xmlNewProp(node,
+ "sequence-name\0",
+ text);
+ }
+ break;
+ case 0x04:
+ {
+ /* Instrument name */
+ xmlNewProp(node,
+ "instrument-name\0",
+ text);
+ }
+ break;
+ case 0x05: /* Lyric */
+ break;
+ case 0x06: /* Marker */
+ break;
+ case 0x07: /* Cue point */
+ break;
+ case 0x08:
+ break;
+ case 0x09:
+ break;
+ case 0x0a:
+ break;
+ case 0x0b:
+ break;
+ case 0x0c:
+ break;
+ case 0x0d:
+ break;
+ case 0x0e:
+ break;
+ case 0x0f:
+ break;
+ default:
+ g_warning("unknown text event\0");
+ }
+
+ return(node);
+}
+
+xmlNode*
+ags_midi_parser_text_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+ xmlNode *node;
+
+ g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+
+ g_object_ref((GObject *) midi_parser);
+ g_signal_emit(G_OBJECT(midi_parser),
+ midi_parser_signals[TEXT_EVENT], 0,
+ meta_type,
+ &node);
+ g_object_unref((GObject *) midi_parser);
+
+ return(node);
+}
+
+AgsMidiParser*
+ags_midi_parser_new(FILE *file)
+{
+ AgsMidiParser *midi_parser;
+ struct stat sb;
+
+ midi_parser = (AgsMidiParser *) g_object_new(AGS_TYPE_MIDI_PARSER,
+ NULL);
+
+ midi_parser->file = file;
+
return(midi_parser);
}
diff --git a/src/midi2ags/midi/ags_midi_parser.h b/src/midi2ags/midi/ags_midi_parser.h
index f2dc896..e0f152f 100644
--- a/src/midi2ags/midi/ags_midi_parser.h
+++ b/src/midi2ags/midi/ags_midi_parser.h
@@ -22,6 +22,8 @@
#include <glib.h>
#include <glib-object.h>
+#include <libxml/tree.h>
+
#define AGS_TYPE_MIDI_PARSER (ags_midi_parser_get_type ())
#define AGS_MIDI_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_MIDI_PARSER, AgsMidiParser))
#define AGS_MIDI_PARSER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST((class), AGS_TYPE_MIDI_PARSER, AgsMidiParserClass))
@@ -30,12 +32,17 @@
#define AGS_MIDI_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), AGS_TYPE_MIDI_PARSER, AgsMidiParserClass))
#define AGS_MIDI_PARSER_MTHD "MThd\0"
-#define AGS_MIDI_PARSER_MTCK "MTck\0"
+#define AGS_MIDI_PARSER_MTCK "MTrk\0"
typedef struct _AgsMidiParser AgsMidiParser;
typedef struct _AgsMidiParserClass AgsMidiParserClass;
typedef enum{
+ AGS_MIDI_PARSER_EOF = 1,
+ AGS_MIDI_PARSER_EOT = 1 << 1,
+}AgsMidiParserFlags;
+
+typedef enum{
AGS_MIDI_CHUNK_HEADER = 1,
AGS_MIDI_CHUNK_TRACK = 1 << 1,
AGS_MIDI_CHUNK_UNKNOWN = 1 << 2,
@@ -45,34 +52,99 @@ struct _AgsMidiParser
{
GObject gobject;
- int fd;
+ guint flags;
+
+ FILE *file;
guint nth_chunk;
+
+ size_t file_length;
+ size_t offset;
+
+ guint current_time;
};
struct _AgsMidiParserClass
{
GObjectClass gobject;
+
+ int (*midi_getc)(AgsMidiParser *midi_parser);
+ void (*on_error)(AgsMidiParser *midi_parser,
+ GError **error);
+
+ xmlNode* (*parse_header)(AgsMidiParser *midi_parser);
+ xmlNode* (*parse_track)(AgsMidiParser *midi_parser);
+
+ xmlNode* (*key_on)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*key_off)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*key_pressure)(AgsMidiParser *midi_parser, guint status);
+
+ xmlNode* (*change_parameter)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*change_pitch_bend)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*change_program)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*change_channel_pressure)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*not_defined)(AgsMidiParser *midi_parser, guint status);
+
+ xmlNode* (*sysex)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*system_common)(AgsMidiParser *midi_parser, guint status);
+
+ xmlNode* (*meta_event)(AgsMidiParser *midi_parser, guint status);
+ xmlNode* (*sequence_number)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*end_of_track)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*smpte)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*tempo)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*time_signature)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*key_signature)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*sequencer_meta_event)(AgsMidiParser *midi_parser, guint meta_type);
+ xmlNode* (*text_event)(AgsMidiParser *midi_parser, guint meta_type);
+
+ xmlDoc* (*parse_full)(AgsMidiParser *midi_parser);
};
GType ags_midi_parser_get_type(void);
-char* ags_midi_parser_read_chunk(AgsMidiParser *midi_parser,
- guint *message_type, guint *message_length,
- GError **error);
-void ags_midi_parser_write_chunk(AgsMidiParser *midi_parser,
- char *chunk, size_t length);
-void ags_midi_parser_seek(AgsMidiParser *midi_parser, guint n_chunks, gint whence);
-void ags_midi_parser_flush(AgsMidiParser *midi_parser);
-
-xmlNode* ags_midi_parser_parse_header(AgsMidiParser *parser,
- char *chunk_data,
- guint chunk_type,
- guint chunk_length);
-xmlNode* ags_midi_parser_parse_track(AgsMidiParser *parser,
- char *chunk_data,
- guint chunk_type,
- guint chunk_length);
-
-AgsMidiParser* ags_midi_parser_new(int fd);
+gint16 ags_midi_parser_read_gint16(AgsMidiParser *midi_parser);
+gint32 ags_midi_parser_read_gint24(AgsMidiParser *midi_parser);
+gint32 ags_midi_parser_read_gint32(AgsMidiParser *midi_parser);
+long ags_midi_parser_read_varlength(AgsMidiParser *midi_parser);
+gchar* ags_midi_parser_read_text(AgsMidiParser *midi_parser,
+ gint length);
+
+gdouble ags_midi_parser_ticks_to_sec(AgsMidiParser *midi_parser,
+ guint ticks, gint division, guint tempo);
+
+int ags_midi_parser_midi_getc(AgsMidiParser *midi_parser);
+void ags_midi_parser_on_error(AgsMidiParser *midi_parser,
+ GError **error);
+
+xmlDoc* ags_midi_parser_parse_full(AgsMidiParser *midi_parser);
+
+xmlNode* ags_midi_parser_parse_header(AgsMidiParser *midi_parser);
+xmlNode* ags_midi_parser_parse_track(AgsMidiParser *midi_parser);
+
+xmlNode* ags_midi_parser_channel_message(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_key_on(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_key_off(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_key_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_parameter(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_pitch_bend(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_program(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_channel_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_not_defined(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_sysex(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_system_common(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_meta_event(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_sequence_number(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_end_of_track(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_smpte(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_tempo(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_time_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_key_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_meta_misc(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_text_event(AgsMidiParser *midi_parser, guint meta_type);
+
+AgsMidiParser* ags_midi_parser_new(FILE *file);
#endif /*__AGS_MIDI_PARSER_H__*/
--
gsequencer packaging
More information about the pkg-multimedia-commits
mailing list