Subject: bin/20388: Let midiplay(1) play MIDI files
To: None <gnats-bugs@gnats.netbsd.org>
From: None <cube@cubidou.net>
List: netbsd-bugs
Date: 02/17/2003 14:32:08
>Number: 20388
>Category: bin
>Synopsis: midiplay(1) doesn't play RMID files, fix included
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Feb 17 05:33:01 PST 2003
>Closed-Date:
>Last-Modified:
>Originator: Quentin Garnier
>Release: NetBSD 1.6M
>Organization:
>Environment:
System: NetBSD chewie 1.6M NetBSD 1.6M (CHEWIE) #1: Thu Jan 23 14:37:25 CET 2003 cube@chewie:/home/cube/sys/src/NetBSD/src/sys/arch/i386/compile/CHEWIE i386
Architecture: i386
Machine: i386
>Description:
RMID files are Standard MIDI Files embedded in a RIFF container.
They're usually found in Windows. Some additionnal information can
be found in other chunks of data, but included patch doesn't parse
them.
midiplay(1) doesn't play such files.
>How-To-Repeat:
>Fix:
All that's needed is a simple parsing of RIFF headers.
Index: midiplay.1
===================================================================
RCS file: /cvsroot/src/usr.bin/midiplay/midiplay.1,v
retrieving revision 1.12
diff -r1.12 midiplay.1
40c40
< .Nd play MIDI files
---
> .Nd play MIDI and RMID files
56c56
< command plays MIDI files using the sequencer device.
---
> command plays MIDI and RMID files using the sequencer device.
58a59,64
> .Pp
> RMID files are Standard MIDI Files embedded in a RIFF container and
> can usually be found with the 'rmi' extension. They contain some
> additionnal information in other chunks which are not parsed by
> .Nm
> yet.
Index: midiplay.c
===================================================================
RCS file: /cvsroot/src/usr.bin/midiplay/midiplay.c,v
retrieving revision 1.17
diff -r1.17 midiplay.c
118a119,122
> #define RMID_SIG "RIFF"
> #define RMID_MIDI_ID "RMID"
> #define RMID_DATA_ID "data"
>
125a130
> #define GET32_LE(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0])
292a298,342
> if (tot < (MARK_LEN + 4)) {
> warnx("Not a MIDI file, too short");
> return;
> }
>
> if (memcmp(buf, RMID_SIG, MARK_LEN) == 0) {
> u_char *eod;
> /* Detected a RMID file, let's just check if it's
> * a MIDI file */
> if (GET32_LE(buf + MARK_LEN) != (tot - 8)) {
> warnx("Not a RMID file, bad header");
> return;
> }
>
> buf += MARK_LEN + 4;
> if (memcmp(buf, RMID_MIDI_ID, MARK_LEN) != 0) {
> warnx("Not a RMID file, bad ID");
> return;
> }
>
> /* Now look for the 'data' chunk, which contains
> * MIDI data */
> buf += MARK_LEN;
>
> /* Test against end-8 since we must have at least 8 bytes
> * left to read */
> while(buf < (end-8) && memcmp(buf, RMID_DATA_ID, MARK_LEN))
> buf += GET32_LE(buf+4) + 8; /* MARK_LEN + 4 */
>
> if (buf >= (end-8)) {
> warnx("Not a valid RMID file, no data chunk");
> return;
> }
>
> buf += MARK_LEN; /* "data" */
> eod = buf + 4 + GET32_LE(buf);
> if (eod >= end) {
> warnx("Not a valid RMID file, bad data chunk size");
> return;
> }
>
> end = eod;
> buf += 4;
> }
>
296a347
>
>Release-Note:
>Audit-Trail:
>Unformatted: