clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit 33870d38ec7ba6376b0c61d0c12299e591d88488
parent 5765b805215b0282fa11c47943ee0013a849a03a
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date:   Thu, 29 Sep 2016 15:20:41 +0200

midi helper: bug fixes and improvements

Diffstat:
Minclude/clap/helpers/midi-parser.c | 36+++++++++++++++++++++++++++++++-----
Minclude/clap/helpers/midi-parser.h | 19++++++++++++++++++-
Mtests/midi-parser/midi-parser.c | 8++++++--
3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/include/clap/helpers/midi-parser.c b/include/clap/helpers/midi-parser.c @@ -154,15 +154,15 @@ clap_midi_parse_be32(const uint8_t *in) return (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3]; } -static inline uint32_t +static inline uint64_t clap_midi_parse_variable_length(struct clap_midi_parser *parser, int32_t *offset) { - uint32_t value = 0; - int32_t i = *offset; + uint64_t value = 0; + int32_t i = *offset; for (; i < parser->size; ++i) { value = (value << 7) | (parser->in[i] & 0x7f); - if (!(parser->in[i] & 0x8f)) + if (!(parser->in[i] & 0x80)) break; } *offset = i + 1; @@ -202,6 +202,29 @@ clap_midi_parse_track(struct clap_midi_parser *parser) return CLAP_MIDI_PARSER_TRACK; } +static inline bool +clap_midi_parse_vtime(struct clap_midi_parser * restrict parser) +{ + uint8_t nbytes = 0; + bool cont = false; // continue flag + + parser->vtime = 0; + for (nbytes = 0; cont; ++nbytes) { + if (parser->size < 1 + nbytes) + return false; + + uint8_t b = parser->in[nbytes]; + parser->vtime = (parser->vtime << 7) | (b & 0x7f); + + cont = b & 0x80; + } + + parser->in += nbytes; + parser->size -= nbytes; + + return true; +} + static inline enum clap_midi_parser_status clap_midi_parse_channel_event(struct clap_midi_parser *parser) { @@ -246,7 +269,10 @@ clap_midi_parse_meta_event(struct clap_midi_parser *parser) static inline enum clap_midi_parser_status clap_midi_parse_event(struct clap_midi_parser *parser) { - if ((parser->in[0] >> 4) <= 0xe) + if (!clap_midi_parse_vtime(parser)) + return CLAP_MIDI_PARSER_EOB; + + if (parser->in[0] < 0xf0) return clap_midi_parse_channel_event(parser); if (parser->in[0] == 0xff) return clap_midi_parse_meta_event(parser); diff --git a/include/clap/helpers/midi-parser.h b/include/clap/helpers/midi-parser.h @@ -24,6 +24,23 @@ enum clap_midi_parser_status CLAP_MIDI_PARSER_TRACK_SYSEX = 5, }; +enum clap_midi_file_format +{ + CLAP_MIDI_FILE_FORMAT_SINGLE_TRACK = 0, + CLAP_MIDI_FILE_FORMAT_MULTIPLE_TRACKS = 1, + CLAP_MIDI_FILE_FORMAT_MULTIPLE_SONGS = 2, +}; + +static const char * +clap_midi_file_format_name(int fmt) +{ + switch (fmt) { + case CLAP_MIDI_FILE_FORMAT_SINGLE_TRACK: return "single track"; + case CLAP_MIDI_FILE_FORMAT_MULTIPLE_TRACKS: return "multiple tracks"; + case CLAP_MIDI_FILE_FORMAT_MULTIPLE_SONGS: return "multiple songs"; + } +} + struct clap_midi_header { int32_t size; @@ -50,7 +67,6 @@ enum clap_midi_channel_event_type struct clap_midi_channel_event { - int64_t delta_time; unsigned event_type : 4; unsigned channel : 4; uint8_t param1; @@ -81,6 +97,7 @@ struct clap_midi_parser int32_t size; /* result */ + int64_t vtime; struct clap_midi_header header; struct clap_midi_track track; struct clap_midi_channel_event channel; diff --git a/tests/midi-parser/midi-parser.c b/tests/midi-parser/midi-parser.c @@ -34,18 +34,20 @@ void parse_and_dump(struct clap_midi_parser *parser) case CLAP_MIDI_PARSER_HEADER: printf("header\n"); printf(" size: %d\n", parser->header.size); - printf(" format: %d\n", parser->header.format); + printf(" format: %d [%s]\n", parser->header.format, clap_midi_file_format_name(parser->header.format)); printf(" tracks count: %d\n", parser->header.tracks_count); printf(" time division: %d\n", parser->header.time_division); break; case CLAP_MIDI_PARSER_TRACK: puts("track"); + printf(" length: %d\n", parser->track.size); break; case CLAP_MIDI_PARSER_TRACK_MIDI: puts("track-midi"); - printf(" event type: %d\n", parser->channel.event_type); + printf(" time: %d\n", parser->vtime); + printf(" type: %d\n", parser->channel.event_type); printf(" channel: %d\n", parser->channel.channel); printf(" param1: %d\n", parser->channel.param1); printf(" param2: %d\n", parser->channel.param2); @@ -53,12 +55,14 @@ void parse_and_dump(struct clap_midi_parser *parser) case CLAP_MIDI_PARSER_TRACK_META: printf("track-meta\n"); + printf(" time: %d\n", parser->vtime); printf(" type: %d\n", parser->meta.type); printf(" length: %d\n", parser->meta.length); break; case CLAP_MIDI_PARSER_TRACK_SYSEX: puts("track-sysex"); + printf(" time: %d\n", parser->vtime); break; default: