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:
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user