Partial re-implementation of Paul and Jerome's

MIDI file import; see the website for details.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1823 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
mahlzeit
2002-11-01 20:08:23 +00:00
parent 7c27cd32b5
commit 2576750920
2 changed files with 127 additions and 3 deletions
+15 -1
View File
@@ -9,6 +9,7 @@ struct entry_ref;
class BMidiEvent;
class BList;
class BFile;
class BMidiStore : public BMidi
{
@@ -78,13 +79,26 @@ private:
static int CompareEvents(const void* event1, const void* event2);
void ReadFileHeader();
void ReadTrackHeader();
void ReadTrack();
int32 Read32Bit();
int16 Read16Bit();
void ReadData(uint8* data, size_t size);
BList* events;
uint32 tempo;
uint32 curEvent;
uint32 startTime;
uint32 ticksPerBeat;
uint32 _reserved[21];
BFile* file;
int32 numTracks;
int32 trackSize;
int16 division;
uint16 _reserved1;
uint32 _reserved2[17];
};
#endif // _MIDI_STORE_H
+112 -2
View File
@@ -11,8 +11,9 @@
#include <string.h>
#include <Entry.h>
#include <Path.h>
#include <File.h>
#include <List.h>
#include <Path.h>
#include "debug.h"
#include "MidiEvent.h"
@@ -198,9 +199,37 @@ void BMidiStore::AllNotesOff(bool justChannel, uint32 time)
status_t BMidiStore::Import(const entry_ref* ref)
{
return B_OK;
status_t status = B_OK;
try
{
file = new BFile(ref, B_READ_ONLY);
status = file->InitCheck();
if (status != B_OK) { throw status; }
ReadFileHeader();
for (int32 t = 0; t < numTracks; ++t)
{
TRACE(("[midi] Reading track %d\n", t))
ReadTrackHeader();
ReadTrack();
}
SortEvents(true);
}
catch (status_t err)
{
status = err;
}
delete file;
return status;
}
//------------------------------------------------------------------------------
status_t BMidiStore::Export(const entry_ref* ref, int32 format)
@@ -336,3 +365,84 @@ int BMidiStore::CompareEvents(const void* event1, const void* event2)
//------------------------------------------------------------------------------
void BMidiStore::ReadFileHeader()
{
uint8 header[4];
ReadData(header, 4);
if (strncmp((char*) header, "MThd", 4) != 0)
{
throw B_BAD_MIDI_DATA;
}
int32 length = Read32Bit();
if (length != 6) { throw B_BAD_MIDI_DATA; }
Read16Bit(); // skip format
numTracks = Read16Bit();
division = Read16Bit();
if (numTracks == 0) { throw B_BAD_MIDI_DATA; }
if (division == 0) { throw B_BAD_MIDI_DATA; }
TRACE(("[midi] numTracks = %d, division = %d\n", numTracks, division))
}
//------------------------------------------------------------------------------
void BMidiStore::ReadTrackHeader()
{
uint8 header[4];
ReadData(header, 4);
if (strncmp((char*) header, "MTrk", 4) != 0)
{
throw B_BAD_MIDI_DATA;
}
trackSize = Read32Bit();
TRACE(("[midi] trackSize = %d\n", trackSize))
}
//------------------------------------------------------------------------------
void BMidiStore::ReadTrack()
{
/* See <http://home.concepts.nl/~hollies/midi/midi1todo.html> */
}
//------------------------------------------------------------------------------
int32 BMidiStore::Read32Bit()
{
uint8 buf[4];
ReadData(buf, 4);
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
//------------------------------------------------------------------------------
int16 BMidiStore::Read16Bit()
{
uint8 buf[2];
ReadData(buf, 2);
return (buf[0] << 8) | buf[1];
}
//------------------------------------------------------------------------------
void BMidiStore::ReadData(uint8* data, size_t size)
{
ssize_t res = file->Read(data, size);
if (res != size)
{
throw (status_t) res;
}
}
//------------------------------------------------------------------------------