mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-24 04:29:34 -04:00
speed up midifile.c (#367)
* don't realloc for one event at time * use memio * fix gcc warning
This commit is contained in:
parent
d5bb524f77
commit
97779b39fb
@ -49,6 +49,7 @@ set(WOOF_SOURCES
|
||||
m_misc2.c m_misc2.h
|
||||
m_random.c m_random.h
|
||||
m_swap.h
|
||||
memio.c memio.h
|
||||
midifile.c midifile.h
|
||||
mmus2mid.c mmus2mid.h
|
||||
net_client.c net_client.h
|
||||
|
@ -1625,32 +1625,9 @@ static boolean IsMid(byte *mem, int len)
|
||||
return len > 4 && !memcmp(mem, "MThd", 4);
|
||||
}
|
||||
|
||||
static boolean ConvertMus(byte *musdata, int len, char *filename)
|
||||
{
|
||||
MIDI mididata;
|
||||
UBYTE *mid;
|
||||
int midlen;
|
||||
int result;
|
||||
|
||||
// [FG] remove dependency on memio
|
||||
memset(&mididata, 0, sizeof(MIDI));
|
||||
result = mmus2mid(musdata, &mididata, 89, 0);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
MIDIToMidi(&mididata, &mid, &midlen);
|
||||
|
||||
M_WriteFile(filename, mid, midlen);
|
||||
free(mid);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void *I_OPL_RegisterSong(void *data, int len)
|
||||
{
|
||||
midi_file_t *result;
|
||||
char *filename;
|
||||
|
||||
if (!music_initialized)
|
||||
{
|
||||
@ -1660,32 +1637,38 @@ static void *I_OPL_RegisterSong(void *data, int len)
|
||||
// MUS files begin with "MUS"
|
||||
// Reject anything which doesnt have this signature
|
||||
|
||||
filename = M_TempFile("doom.mid");
|
||||
|
||||
// [crispy] remove MID file size limit
|
||||
if (IsMid(data, len) /* && len < MAXMIDLENGTH */)
|
||||
{
|
||||
M_WriteFile(filename, data, len);
|
||||
result = MIDI_LoadFile(data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume a MUS file and try to convert
|
||||
MIDI mididata;
|
||||
UBYTE *mid;
|
||||
int midlen;
|
||||
int err;
|
||||
|
||||
ConvertMus(data, len, filename);
|
||||
memset(&mididata, 0, sizeof(MIDI));
|
||||
err = mmus2mid(data, &mididata, 89, 0);
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
MIDIToMidi(&mididata, &mid, &midlen);
|
||||
result = MIDI_LoadFile(mid, midlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
result = MIDI_LoadFile(filename);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
fprintf(stderr, "I_OPL_RegisterSong: Failed to load MID.\n");
|
||||
}
|
||||
|
||||
// remove file now
|
||||
|
||||
remove(filename);
|
||||
(free)(filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -463,15 +463,12 @@ void I_WIN_RegisterSong(void *data, int size)
|
||||
{
|
||||
int i;
|
||||
midi_file_t *file;
|
||||
char *filename;
|
||||
|
||||
MIDIPROPTIMEDIV timediv;
|
||||
MIDIPROPTEMPO tempo;
|
||||
MMRESULT mmr;
|
||||
|
||||
filename = M_TempFile("doom.mid");
|
||||
M_WriteFile(filename, data, size);
|
||||
file = MIDI_LoadFile(filename);
|
||||
file = MIDI_LoadFile(data, size);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
@ -515,8 +512,6 @@ void I_WIN_RegisterSong(void *data, int size)
|
||||
|
||||
FillBuffer();
|
||||
StreamOut();
|
||||
|
||||
(free)(filename);
|
||||
}
|
||||
|
||||
void I_WIN_UnRegisterSong(void)
|
||||
|
197
Source/memio.c
Normal file
197
Source/memio.c
Normal file
@ -0,0 +1,197 @@
|
||||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 2005-2014 Simon Howard
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// Emulates the IO functions in C stdio.h reading and writing to
|
||||
// memory.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "memio.h"
|
||||
|
||||
#include "z_zone.h"
|
||||
|
||||
typedef enum {
|
||||
MODE_READ,
|
||||
MODE_WRITE,
|
||||
} memfile_mode_t;
|
||||
|
||||
struct _MEMFILE {
|
||||
unsigned char *buf;
|
||||
size_t buflen;
|
||||
size_t alloced;
|
||||
unsigned int position;
|
||||
memfile_mode_t mode;
|
||||
};
|
||||
|
||||
// Open a memory area for reading
|
||||
|
||||
MEMFILE *mem_fopen_read(void *buf, size_t buflen)
|
||||
{
|
||||
MEMFILE *file;
|
||||
|
||||
file = Z_Malloc(sizeof(MEMFILE), PU_STATIC, 0);
|
||||
|
||||
file->buf = (unsigned char *) buf;
|
||||
file->buflen = buflen;
|
||||
file->position = 0;
|
||||
file->mode = MODE_READ;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
// Read bytes
|
||||
|
||||
size_t mem_fread(void *buf, size_t size, size_t nmemb, MEMFILE *stream)
|
||||
{
|
||||
size_t items;
|
||||
|
||||
if (stream->mode != MODE_READ)
|
||||
{
|
||||
printf("not a read stream\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Trying to read more bytes than we have left?
|
||||
|
||||
items = nmemb;
|
||||
|
||||
if (items * size > stream->buflen - stream->position)
|
||||
{
|
||||
items = (stream->buflen - stream->position) / size;
|
||||
}
|
||||
|
||||
// Copy bytes to buffer
|
||||
|
||||
memcpy(buf, stream->buf + stream->position, items * size);
|
||||
|
||||
// Update position
|
||||
|
||||
stream->position += items * size;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
// Open a memory area for writing
|
||||
|
||||
MEMFILE *mem_fopen_write(void)
|
||||
{
|
||||
MEMFILE *file;
|
||||
|
||||
file = Z_Malloc(sizeof(MEMFILE), PU_STATIC, 0);
|
||||
|
||||
file->alloced = 1024;
|
||||
file->buf = Z_Malloc(file->alloced, PU_STATIC, 0);
|
||||
file->buflen = 0;
|
||||
file->position = 0;
|
||||
file->mode = MODE_WRITE;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
// Write bytes to stream
|
||||
|
||||
size_t mem_fwrite(const void *ptr, size_t size, size_t nmemb, MEMFILE *stream)
|
||||
{
|
||||
size_t bytes;
|
||||
|
||||
if (stream->mode != MODE_WRITE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// More bytes than can fit in the buffer?
|
||||
// If so, reallocate bigger.
|
||||
|
||||
bytes = size * nmemb;
|
||||
|
||||
while (bytes > stream->alloced - stream->position)
|
||||
{
|
||||
unsigned char *newbuf;
|
||||
|
||||
newbuf = Z_Malloc(stream->alloced * 2, PU_STATIC, 0);
|
||||
memcpy(newbuf, stream->buf, stream->alloced);
|
||||
Z_Free(stream->buf);
|
||||
stream->buf = newbuf;
|
||||
stream->alloced *= 2;
|
||||
}
|
||||
|
||||
// Copy into buffer
|
||||
|
||||
memcpy(stream->buf + stream->position, ptr, bytes);
|
||||
stream->position += bytes;
|
||||
|
||||
if (stream->position > stream->buflen)
|
||||
stream->buflen = stream->position;
|
||||
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
void mem_get_buf(MEMFILE *stream, void **buf, size_t *buflen)
|
||||
{
|
||||
*buf = stream->buf;
|
||||
*buflen = stream->buflen;
|
||||
}
|
||||
|
||||
void mem_fclose(MEMFILE *stream)
|
||||
{
|
||||
if (stream->mode == MODE_WRITE)
|
||||
{
|
||||
Z_Free(stream->buf);
|
||||
}
|
||||
|
||||
Z_Free(stream);
|
||||
}
|
||||
|
||||
long mem_ftell(MEMFILE *stream)
|
||||
{
|
||||
return stream->position;
|
||||
}
|
||||
|
||||
int mem_fseek(MEMFILE *stream, signed long position, mem_rel_t whence)
|
||||
{
|
||||
unsigned int newpos;
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case MEM_SEEK_SET:
|
||||
newpos = (int) position;
|
||||
break;
|
||||
|
||||
case MEM_SEEK_CUR:
|
||||
newpos = (int) (stream->position + position);
|
||||
break;
|
||||
|
||||
case MEM_SEEK_END:
|
||||
newpos = (int) (stream->buflen + position);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (newpos < stream->buflen)
|
||||
{
|
||||
stream->position = newpos;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error seeking to %u\n", newpos);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
38
Source/memio.h
Normal file
38
Source/memio.h
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 2005-2014 Simon Howard
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
|
||||
#ifndef MEMIO_H
|
||||
#define MEMIO_H
|
||||
|
||||
typedef struct _MEMFILE MEMFILE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEM_SEEK_SET,
|
||||
MEM_SEEK_CUR,
|
||||
MEM_SEEK_END,
|
||||
} mem_rel_t;
|
||||
|
||||
MEMFILE *mem_fopen_read(void *buf, size_t buflen);
|
||||
size_t mem_fread(void *buf, size_t size, size_t nmemb, MEMFILE *stream);
|
||||
MEMFILE *mem_fopen_write(void);
|
||||
size_t mem_fwrite(const void *ptr, size_t size, size_t nmemb, MEMFILE *stream);
|
||||
void mem_get_buf(MEMFILE *stream, void **buf, size_t *buflen);
|
||||
void mem_fclose(MEMFILE *stream);
|
||||
long mem_ftell(MEMFILE *stream);
|
||||
int mem_fseek(MEMFILE *stream, signed long offset, mem_rel_t whence);
|
||||
|
||||
#endif /* #ifndef MEMIO_H */
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "doomtype.h"
|
||||
#include "m_swap.h"
|
||||
#include "i_system.h"
|
||||
#include "memio.h"
|
||||
#include "midifile.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -67,6 +68,7 @@ typedef struct
|
||||
|
||||
midi_event_t *events;
|
||||
int num_events;
|
||||
int num_events_mem;
|
||||
} midi_track_t;
|
||||
|
||||
struct midi_track_iter_s
|
||||
@ -111,28 +113,26 @@ static boolean CheckChunkHeader(chunk_header_t *chunk,
|
||||
|
||||
// Read a single byte. Returns false on error.
|
||||
|
||||
static boolean ReadByte(byte *result, FILE *stream)
|
||||
static boolean ReadByte(byte *result, MEMFILE *stream)
|
||||
{
|
||||
int c;
|
||||
byte c;
|
||||
|
||||
c = fgetc(stream);
|
||||
|
||||
if (c == EOF)
|
||||
if (mem_fread(&c, sizeof(byte), 1, stream) == 1)
|
||||
{
|
||||
fprintf(stderr, "ReadByte: Unexpected end of file\n");
|
||||
return false;
|
||||
*result = c;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = (byte) c;
|
||||
|
||||
return true;
|
||||
fprintf(stderr, "ReadByte: Unexpected end of file\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Read a variable-length value.
|
||||
|
||||
static boolean ReadVariableLength(unsigned int *result, FILE *stream)
|
||||
static boolean ReadVariableLength(unsigned int *result, MEMFILE *stream)
|
||||
{
|
||||
int i;
|
||||
byte b = 0;
|
||||
@ -168,7 +168,7 @@ static boolean ReadVariableLength(unsigned int *result, FILE *stream)
|
||||
|
||||
// Read a byte sequence into the data buffer.
|
||||
|
||||
static void *ReadByteSequence(unsigned int num_bytes, FILE *stream)
|
||||
static void *ReadByteSequence(unsigned int num_bytes, MEMFILE *stream)
|
||||
{
|
||||
unsigned int i;
|
||||
byte *result;
|
||||
@ -206,7 +206,7 @@ static void *ReadByteSequence(unsigned int num_bytes, FILE *stream)
|
||||
|
||||
static boolean ReadChannelEvent(midi_event_t *event,
|
||||
byte event_type, boolean two_param,
|
||||
FILE *stream)
|
||||
MEMFILE *stream)
|
||||
{
|
||||
byte b = 0;
|
||||
|
||||
@ -246,7 +246,7 @@ static boolean ReadChannelEvent(midi_event_t *event,
|
||||
// Read sysex event:
|
||||
|
||||
static boolean ReadSysExEvent(midi_event_t *event, int event_type,
|
||||
FILE *stream)
|
||||
MEMFILE *stream)
|
||||
{
|
||||
event->event_type = event_type;
|
||||
|
||||
@ -272,7 +272,7 @@ static boolean ReadSysExEvent(midi_event_t *event, int event_type,
|
||||
|
||||
// Read meta event:
|
||||
|
||||
static boolean ReadMetaEvent(midi_event_t *event, FILE *stream)
|
||||
static boolean ReadMetaEvent(midi_event_t *event, MEMFILE *stream)
|
||||
{
|
||||
byte b = 0;
|
||||
|
||||
@ -311,7 +311,7 @@ static boolean ReadMetaEvent(midi_event_t *event, FILE *stream)
|
||||
}
|
||||
|
||||
static boolean ReadEvent(midi_event_t *event, unsigned int *last_event_type,
|
||||
FILE *stream)
|
||||
MEMFILE *stream)
|
||||
{
|
||||
byte event_type = 0;
|
||||
|
||||
@ -336,7 +336,7 @@ static boolean ReadEvent(midi_event_t *event, unsigned int *last_event_type,
|
||||
{
|
||||
event_type = *last_event_type;
|
||||
|
||||
if (fseek(stream, -1, SEEK_CUR) < 0)
|
||||
if (mem_fseek(stream, -1, MEM_SEEK_CUR) < 0)
|
||||
{
|
||||
fprintf(stderr, "ReadEvent: Unable to seek in stream\n");
|
||||
return false;
|
||||
@ -415,12 +415,12 @@ static void FreeEvent(midi_event_t *event)
|
||||
|
||||
// Read and check the track chunk header
|
||||
|
||||
static boolean ReadTrackHeader(midi_track_t *track, FILE *stream)
|
||||
static boolean ReadTrackHeader(midi_track_t *track, MEMFILE *stream)
|
||||
{
|
||||
size_t records_read;
|
||||
chunk_header_t chunk_header;
|
||||
|
||||
records_read = fread(&chunk_header, sizeof(chunk_header_t), 1, stream);
|
||||
records_read = mem_fread(&chunk_header, sizeof(chunk_header_t), 1, stream);
|
||||
|
||||
if (records_read < 1)
|
||||
{
|
||||
@ -437,9 +437,9 @@ static boolean ReadTrackHeader(midi_track_t *track, FILE *stream)
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean ReadTrack(midi_track_t *track, FILE *stream)
|
||||
static boolean ReadTrack(midi_track_t *track, MEMFILE *stream)
|
||||
{
|
||||
midi_event_t *new_events;
|
||||
midi_event_t *new_events = NULL;
|
||||
midi_event_t *event;
|
||||
unsigned int last_event_type;
|
||||
|
||||
@ -461,8 +461,18 @@ static boolean ReadTrack(midi_track_t *track, FILE *stream)
|
||||
{
|
||||
// Resize the track slightly larger to hold another event:
|
||||
|
||||
// new_events = realloc(track->events,
|
||||
// sizeof(midi_event_t) * (track->num_events + 1));
|
||||
|
||||
// Depending on the state of the heap and the malloc implementation,
|
||||
// realloc() one more event at a time can be VERY slow.
|
||||
|
||||
if (track->num_events == track->num_events_mem)
|
||||
{
|
||||
track->num_events_mem += 100;
|
||||
new_events = realloc(track->events,
|
||||
sizeof(midi_event_t) * (track->num_events + 1));
|
||||
sizeof (midi_event_t) * track->num_events_mem);
|
||||
}
|
||||
|
||||
if (new_events == NULL)
|
||||
{
|
||||
@ -507,7 +517,7 @@ static void FreeTrack(midi_track_t *track)
|
||||
free(track->events);
|
||||
}
|
||||
|
||||
static boolean ReadAllTracks(midi_file_t *file, FILE *stream)
|
||||
static boolean ReadAllTracks(midi_file_t *file, MEMFILE *stream)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -537,12 +547,12 @@ static boolean ReadAllTracks(midi_file_t *file, FILE *stream)
|
||||
|
||||
// Read and check the header chunk.
|
||||
|
||||
static boolean ReadFileHeader(midi_file_t *file, FILE *stream)
|
||||
static boolean ReadFileHeader(midi_file_t *file, MEMFILE *stream)
|
||||
{
|
||||
size_t records_read;
|
||||
unsigned int format_type;
|
||||
|
||||
records_read = fread(&file->header, sizeof(midi_header_t), 1, stream);
|
||||
records_read = mem_fread(&file->header, sizeof(midi_header_t), 1, stream);
|
||||
|
||||
if (records_read < 1)
|
||||
{
|
||||
@ -589,10 +599,10 @@ void MIDI_FreeFile(midi_file_t *file)
|
||||
free(file);
|
||||
}
|
||||
|
||||
midi_file_t *MIDI_LoadFile(char *filename)
|
||||
midi_file_t *MIDI_LoadFile(void *buf, size_t buflen)
|
||||
{
|
||||
midi_file_t *file;
|
||||
FILE *stream;
|
||||
MEMFILE *stream;
|
||||
|
||||
file = malloc(sizeof(midi_file_t));
|
||||
|
||||
@ -608,11 +618,11 @@ midi_file_t *MIDI_LoadFile(char *filename)
|
||||
|
||||
// Open file
|
||||
|
||||
stream = fopen(filename, "rb");
|
||||
stream = mem_fopen_read(buf, buflen);
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
fprintf(stderr, "MIDI_LoadFile: Failed to open '%s'\n", filename);
|
||||
fprintf(stderr, "MIDI_LoadFile: Failed to open\n");
|
||||
MIDI_FreeFile(file);
|
||||
return NULL;
|
||||
}
|
||||
@ -621,7 +631,7 @@ midi_file_t *MIDI_LoadFile(char *filename)
|
||||
|
||||
if (!ReadFileHeader(file, stream))
|
||||
{
|
||||
fclose(stream);
|
||||
mem_fclose(stream);
|
||||
MIDI_FreeFile(file);
|
||||
return NULL;
|
||||
}
|
||||
@ -630,12 +640,12 @@ midi_file_t *MIDI_LoadFile(char *filename)
|
||||
|
||||
if (!ReadAllTracks(file, stream))
|
||||
{
|
||||
fclose(stream);
|
||||
mem_fclose(stream);
|
||||
MIDI_FreeFile(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(stream);
|
||||
mem_fclose(stream);
|
||||
|
||||
return file;
|
||||
}
|
||||
@ -738,112 +748,3 @@ void MIDI_RestartIterator(midi_track_iter_t *iter)
|
||||
{
|
||||
iter->position = 0;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
static char *MIDI_EventTypeToString(midi_event_type_t event_type)
|
||||
{
|
||||
switch (event_type)
|
||||
{
|
||||
case MIDI_EVENT_NOTE_OFF:
|
||||
return "MIDI_EVENT_NOTE_OFF";
|
||||
case MIDI_EVENT_NOTE_ON:
|
||||
return "MIDI_EVENT_NOTE_ON";
|
||||
case MIDI_EVENT_AFTERTOUCH:
|
||||
return "MIDI_EVENT_AFTERTOUCH";
|
||||
case MIDI_EVENT_CONTROLLER:
|
||||
return "MIDI_EVENT_CONTROLLER";
|
||||
case MIDI_EVENT_PROGRAM_CHANGE:
|
||||
return "MIDI_EVENT_PROGRAM_CHANGE";
|
||||
case MIDI_EVENT_CHAN_AFTERTOUCH:
|
||||
return "MIDI_EVENT_CHAN_AFTERTOUCH";
|
||||
case MIDI_EVENT_PITCH_BEND:
|
||||
return "MIDI_EVENT_PITCH_BEND";
|
||||
case MIDI_EVENT_SYSEX:
|
||||
return "MIDI_EVENT_SYSEX";
|
||||
case MIDI_EVENT_SYSEX_SPLIT:
|
||||
return "MIDI_EVENT_SYSEX_SPLIT";
|
||||
case MIDI_EVENT_META:
|
||||
return "MIDI_EVENT_META";
|
||||
|
||||
default:
|
||||
return "(unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
void PrintTrack(midi_track_t *track)
|
||||
{
|
||||
midi_event_t *event;
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<track->num_events; ++i)
|
||||
{
|
||||
event = &track->events[i];
|
||||
|
||||
if (event->delta_time > 0)
|
||||
{
|
||||
printf("Delay: %u ticks\n", event->delta_time);
|
||||
}
|
||||
|
||||
printf("Event type: %s (%i)\n",
|
||||
MIDI_EventTypeToString(event->event_type),
|
||||
event->event_type);
|
||||
|
||||
switch(event->event_type)
|
||||
{
|
||||
case MIDI_EVENT_NOTE_OFF:
|
||||
case MIDI_EVENT_NOTE_ON:
|
||||
case MIDI_EVENT_AFTERTOUCH:
|
||||
case MIDI_EVENT_CONTROLLER:
|
||||
case MIDI_EVENT_PROGRAM_CHANGE:
|
||||
case MIDI_EVENT_CHAN_AFTERTOUCH:
|
||||
case MIDI_EVENT_PITCH_BEND:
|
||||
printf("\tChannel: %u\n", event->data.channel.channel);
|
||||
printf("\tParameter 1: %u\n", event->data.channel.param1);
|
||||
printf("\tParameter 2: %u\n", event->data.channel.param2);
|
||||
break;
|
||||
|
||||
case MIDI_EVENT_SYSEX:
|
||||
case MIDI_EVENT_SYSEX_SPLIT:
|
||||
printf("\tLength: %u\n", event->data.sysex.length);
|
||||
break;
|
||||
|
||||
case MIDI_EVENT_META:
|
||||
printf("\tMeta type: %u\n", event->data.meta.type);
|
||||
printf("\tLength: %u\n", event->data.meta.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
midi_file_t *file;
|
||||
unsigned int i;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s <filename>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file = MIDI_LoadFile(argv[1]);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<file->num_tracks; ++i)
|
||||
{
|
||||
printf("\n== Track %u ==\n\n", i);
|
||||
|
||||
PrintTrack(&file->tracks[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -131,7 +131,7 @@ typedef struct
|
||||
|
||||
// Load a MIDI file.
|
||||
|
||||
midi_file_t *MIDI_LoadFile(char *filename);
|
||||
midi_file_t *MIDI_LoadFile(void *buf, size_t buflen);
|
||||
|
||||
// Free a MIDI file.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user