X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=python%2Fmidi.c;h=187268b78efc105fe44dfdeee9c345ea781a3c05;hb=e5380f29f23e204a603f8398368d2a7dc0260aa0;hp=be06bb66cea0f892ba5ae79d9eb2ae5a7fd06ebb;hpb=e18531db1f79fb685fbd16d6a2a67bf4b6c09915;p=lilypond.git diff --git a/python/midi.c b/python/midi.c index be06bb66ce..187268b78e 100644 --- a/python/midi.c +++ b/python/midi.c @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2001--2010 Han-Wen Nienhuys + Copyright (C) 2001--2011 Han-Wen Nienhuys Jan Nieuwenhuizen @@ -40,6 +40,14 @@ each track is an EVENTLIST, where EVENT is #include +char * +compat_itoa (int i) +{ + static char buffer[9]; + snprintf (buffer, 8, "%d", i); + return buffer; +} + /* PyMIDINIT_FUNC isn't defined in Python < 2.3 */ #ifndef PyMODINIT_FUNC # if defined(__cplusplus) @@ -52,7 +60,8 @@ each track is an EVENTLIST, where EVENT is #if 0 int x = 0; int *track = &x; -#define debug_print(f, args...) fprintf (stderr, "%s:%d: track: %p :" f, __FUNCTION__, __LINE__, *track, ##args) +#define urg_debug_print(f, args...) fprintf (stderr, "%s:%d: track: %p: " f, __FUNCTION__, __LINE__, *track, ##args) +#define debug_print(f, args...) fprintf (stderr, f, ##args) #else #define debug_print(f, args...) #endif @@ -61,11 +70,13 @@ static PyObject *Midi_error; static PyObject *Midi_warning; static PyObject * -midi_error (char const *func, char *s) +midi_error (char const *func, char *s, char *t) { - char *dest = (char*) malloc (sizeof (char) * (strlen (func) + strlen (s) + 1)); + char *dest = (char*) malloc (sizeof (char) + * (strlen (func) + strlen (s) + strlen (t) + 1)); strcpy (dest, func); strcat (dest, s); + strcat (dest, t); PyErr_SetString (Midi_error, dest); free (dest); @@ -151,7 +162,7 @@ get_number (unsigned char ** str, unsigned char * end_str, int length) sum = (sum << 8) + (unsigned char) (*str)[i]; *str += length; - debug_print ("%d:\n", sum); + debug_print ("%ld:\n", sum); return sum; } @@ -168,7 +179,7 @@ get_variable_length_number (unsigned char **str, unsigned char * end_str) if (!(x & 0x80)) break; } - debug_print ("%d:\n", sum); + debug_print ("%ld:\n", sum); return sum; } @@ -281,7 +292,7 @@ read_event (unsigned char **track, unsigned char *end, PyObject *time, } static PyObject * -midi_parse_track (unsigned char **track, unsigned char *track_end) +midi_parse_track (unsigned char **track, unsigned char *track_end, int clocks_max) { unsigned int time = 0; unsigned long track_len, track_size; @@ -293,20 +304,22 @@ midi_parse_track (unsigned char **track, unsigned char *track_end) debug_print ("%s", "\n"); if (memcmp (*track, "MTrk", 4)) - return midi_error (__FUNCTION__, ": MTrk expected"); + { + *track[4] = 0; + return midi_error (__FUNCTION__, ": MTrk expected, got: ", *(char**)track); + } *track += 4; track_len = get_number (track, *track + 4, 4); - - debug_print ("track_len: %u\n", track_len); - debug_print ("track_size: %u\n", track_size); + debug_print ("track_len: %lu\n", track_len); + debug_print ("track_size: %lu\n", track_size); debug_print ("track begin: %p\n", track); debug_print ("track end: %p\n", track + track_len); if (track_len > track_size) - return midi_error (__FUNCTION__, ": track size corrupt"); + return midi_error (__FUNCTION__, ": track length corrupt: ", compat_itoa (track_len)); pytrack = PyList_New (0); @@ -325,7 +338,8 @@ midi_parse_track (unsigned char **track, unsigned char *track_end) time += dt; if (dt) pytime = PyInt_FromLong (time); - + if (clocks_max && time > clocks_max) + break; pyev = read_event (track, track_end, pytime, &running_status); if (pyev) @@ -343,21 +357,23 @@ pymidi_parse_track (PyObject *self, PyObject *args) { unsigned char *track, *track_end; unsigned long track_size; + int clocks_max; debug_print ("%s", "\n"); - if (!PyArg_ParseTuple (args, "s#", &track, &track_size)) + if (!PyArg_ParseTuple (args, "s#|i", &track, &track_size, &clocks_max)) return 0; + debug_print ("clocks_max: %d\n", clocks_max); if (track_size < 0) - return midi_error (__FUNCTION__, ": negative track size"); + return midi_error (__FUNCTION__, ": negative track size: ", compat_itoa (track_size)); track_end = track + track_size; - return midi_parse_track (&track, track_end); + return midi_parse_track (&track, track_end, clocks_max); } static PyObject * -midi_parse (unsigned char **midi,unsigned char *midi_end) +midi_parse (unsigned char **midi,unsigned char *midi_end, int clocks_max) { PyObject *pymidi = 0; unsigned long header_len; @@ -371,13 +387,13 @@ midi_parse (unsigned char **midi,unsigned char *midi_end) header_len = get_number (midi, *midi + 4, 4); if (header_len < 6) - return midi_error (__FUNCTION__, ": header too short"); + return midi_error (__FUNCTION__, ": header too short: ", compat_itoa (header_len)); format = get_number (midi, *midi + 2, 2); tracks = get_number (midi, *midi + 2, 2); - if (tracks > 32) - return midi_error (__FUNCTION__, ": too many tracks"); + if (tracks > 256) + return midi_error (__FUNCTION__, ": too many tracks: ", compat_itoa (tracks)); division = get_number (midi, *midi + 2, 2) * 4; @@ -391,7 +407,7 @@ midi_parse (unsigned char **midi,unsigned char *midi_end) /* Tracks */ for (i = 0; i < tracks; i++) - PyList_Append (pymidi, midi_parse_track (midi, midi_end)); + PyList_Append (pymidi, midi_parse_track (midi, midi_end, clocks_max)); pymidi = Py_BuildValue ("(OO)", Py_BuildValue ("(ii)", format, division), pymidi); @@ -403,26 +419,30 @@ pymidi_parse (PyObject *self, PyObject *args) { unsigned char *midi, *midi_end; unsigned long midi_size; + int clocks_max; debug_print ("%s", "\n"); - if (!PyArg_ParseTuple (args, "s#", &midi, &midi_size)) + if (!PyArg_ParseTuple (args, "s#|i", &midi, &midi_size, &clocks_max)) return 0; + debug_print ("clocks_max: %d\n", clocks_max); if (memcmp (midi, "MThd", 4)) - return midi_error (__FUNCTION__, ": MThd expected"); - + { + midi[4] = 0; + return midi_error (__FUNCTION__, ": MThd expected, got: ", (char*)midi); + } + midi += 4; midi_end = midi + midi_size; - return midi_parse (&midi, midi_end); + return midi_parse (&midi, midi_end, clocks_max); } - static PyMethodDef MidiMethods[] = { - {"parse", pymidi_parse, 1}, - {"parse_track", pymidi_parse_track, 1}, + {"parse", pymidi_parse, METH_VARARGS}, + {"parse_track", pymidi_parse_track, METH_VARARGS}, {0, 0} /* Sentinel */ };