diff options
Diffstat (limited to 'audio/midiparser_qt.cpp')
-rw-r--r-- | audio/midiparser_qt.cpp | 161 |
1 files changed, 92 insertions, 69 deletions
diff --git a/audio/midiparser_qt.cpp b/audio/midiparser_qt.cpp index 0d42e6c1f9..ed4bb22242 100644 --- a/audio/midiparser_qt.cpp +++ b/audio/midiparser_qt.cpp @@ -20,61 +20,76 @@ * */ -#include "audio/midiparser.h" +#include "audio/midiparser_qt.h" #include "common/debug.h" -#include "common/quicktime.h" - -class MidiParser_QT : /* public MidiParser, */ public Common::QuickTimeParser { -public: - MidiParser_QT() {} - ~MidiParser_QT() {} - -protected: - SampleDesc *readSampleDesc(Track *track, uint32 format); - -private: - struct NoteRequestInfo { - byte flags; - byte reserved; - uint16 polyphony; - Common::Rational typicalPolyphony; - }; - - struct ToneDescription { - uint32 synthesizerType; - Common::String synthesizerName; - Common::String instrumentName; - uint32 instrumentNumber; - uint32 gmNumber; - }; - - struct NoteRequest { - uint16 part; - NoteRequestInfo info; - ToneDescription tone; - }; - - typedef Common::Array<NoteRequest> NoteRequestList; - - class MIDISampleDesc : public SampleDesc { - public: - MIDISampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag); - ~MIDISampleDesc() {} - - NoteRequestList _noteRequests; - }; - - Common::String readString31(); - Common::Rational readFixed(); - NoteRequestList readNoteRequestList(); -}; +#include "common/memstream.h" + +bool MidiParser_QT::loadMusic(byte *data, uint32 size) { + // Assume that this is a Tune and not a QuickTime container + Common::SeekableReadStream *stream = new Common::MemoryReadStream(data, size, DisposeAfterUse::NO); + + if (!loadFromTune(stream)) { + delete stream; + return false; + } + + return true; +} + +void MidiParser_QT::unloadMusic() { + MidiParser::unloadMusic(); + close(); + // TODO +} + +bool MidiParser_QT::loadFromTune(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) { + unloadMusic(); + + // a tune starts off with a sample description + stream->readUint32BE(); // header size + + if (stream->readUint32BE() != MKTAG('m', 'u', 's', 'i')) + return false; + + stream->readUint32BE(); // reserved + stream->readUint16BE(); // reserved + stream->readUint16BE(); // index + + // TODO + readNoteRequestList(stream); + return true; +} + +bool MidiParser_QT::loadFromContainerStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) { + unloadMusic(); + + if (!parseStream(stream, disposeAfterUse)) + return false; + + initFromContainerTracks(); + return true; +} + +bool MidiParser_QT::loadFromContainerFile(const Common::String &fileName) { + unloadMusic(); + + if (!parseFile(fileName)) + return false; + + initFromContainerTracks(); + return true; +} + +void MidiParser_QT::parseNextEvent(EventInfo &info) { + // TODO +} Common::QuickTimeParser::SampleDesc *MidiParser_QT::readSampleDesc(Track *track, uint32 format) { if (track->codecType == CODEC_TYPE_MIDI) { debug(0, "MIDI Codec FourCC '%s'", tag2str(format)); MIDISampleDesc *entry = new MIDISampleDesc(track, format); - entry->_noteRequests = readNoteRequestList(); + entry->_noteRequests = readNoteRequestList(_fd); return entry; } @@ -85,31 +100,31 @@ MidiParser_QT::MIDISampleDesc::MIDISampleDesc(Common::QuickTimeParser::Track *pa Common::QuickTimeParser::SampleDesc(parentTrack, codecTag) { } -Common::String MidiParser_QT::readString31() { - byte size = _fd->readByte(); +Common::String MidiParser_QT::readString31(Common::SeekableReadStream *stream) { + byte size = stream->readByte(); assert(size < 32); Common::String string; for (byte i = 0; i < size; i++) - string += (char)_fd->readByte(); + string += (char)stream->readByte(); - _fd->skip(31 - size); + stream->skip(31 - size); return string; } -Common::Rational MidiParser_QT::readFixed() { - int16 integerPart = _fd->readSint16BE(); - uint16 fractionalPart = _fd->readUint16BE(); +Common::Rational MidiParser_QT::readFixed(Common::SeekableReadStream *stream) { + int16 integerPart = stream->readSint16BE(); + uint16 fractionalPart = stream->readUint16BE(); return integerPart + Common::Rational(fractionalPart, 0x10000); } -MidiParser_QT::NoteRequestList MidiParser_QT::readNoteRequestList() { +MidiParser_QT::NoteRequestList MidiParser_QT::readNoteRequestList(Common::SeekableReadStream *stream) { NoteRequestList requests; - /* uint32 flags = */ _fd->readUint32BE(); // always 0 + /* uint32 flags = */ stream->readUint32BE(); // always 0 for (;;) { - uint32 event = _fd->readUint32BE(); + uint32 event = stream->readUint32BE(); if (event == 0x60000000) // marker event break; @@ -118,17 +133,17 @@ MidiParser_QT::NoteRequestList MidiParser_QT::readNoteRequestList() { NoteRequest request; request.part = (event >> 16) & 0xFFF; - request.info.flags = _fd->readByte(); - request.info.reserved = _fd->readByte(); - request.info.polyphony = _fd->readUint16BE(); - request.info.typicalPolyphony = readFixed(); - request.tone.synthesizerType = _fd->readUint32BE(); - request.tone.synthesizerName = readString31(); - request.tone.instrumentName = readString31(); - request.tone.instrumentNumber = _fd->readUint32BE(); - request.tone.gmNumber = _fd->readUint32BE(); - - if (_fd->readUint32BE() != 0xC0010017) // general event note request + request.info.flags = stream->readByte(); + request.info.reserved = stream->readByte(); + request.info.polyphony = stream->readUint16BE(); + request.info.typicalPolyphony = readFixed(stream); + request.tone.synthesizerType = stream->readUint32BE(); + request.tone.synthesizerName = readString31(stream); + request.tone.instrumentName = readString31(stream); + request.tone.instrumentNumber = stream->readUint32BE(); + request.tone.gmNumber = stream->readUint32BE(); + + if (stream->readUint32BE() != 0xC0010017) // general event note request error("Invalid instrument end event"); requests.push_back(request); @@ -136,3 +151,11 @@ MidiParser_QT::NoteRequestList MidiParser_QT::readNoteRequestList() { return requests; } + +void MidiParser_QT::initFromContainerTracks() { + // TODO +} + +MidiParser *MidiParser::createParser_QT() { + return new MidiParser_QT(); +} |