diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/midiparser_qt.cpp | 74 | ||||
-rw-r--r-- | audio/midiparser_qt.h | 10 |
2 files changed, 81 insertions, 3 deletions
diff --git a/audio/midiparser_qt.cpp b/audio/midiparser_qt.cpp index ed4bb22242..0701f7e919 100644 --- a/audio/midiparser_qt.cpp +++ b/audio/midiparser_qt.cpp @@ -39,7 +39,12 @@ bool MidiParser_QT::loadMusic(byte *data, uint32 size) { void MidiParser_QT::unloadMusic() { MidiParser::unloadMusic(); close(); - // TODO + + // Unlike those lesser formats, we *do* hold track data + for (uint i = 0; i < _trackInfo.size(); i++) + free(_trackInfo[i].data); + + _trackInfo.clear(); } bool MidiParser_QT::loadFromTune(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) { @@ -55,8 +60,18 @@ bool MidiParser_QT::loadFromTune(Common::SeekableReadStream *stream, DisposeAfte stream->readUint16BE(); // reserved stream->readUint16BE(); // index - // TODO - readNoteRequestList(stream); + MIDITrackInfo trackInfo; + trackInfo.noteRequests = readNoteRequestList(stream); + + uint32 trackSize = stream->size() - stream->pos(); + assert(trackSize > 0); + + trackInfo.data = (byte *)malloc(trackSize); + stream->read(trackInfo.data, trackSize); + + _trackInfo.push_back(trackInfo); + + initCommon(); return true; } @@ -153,9 +168,62 @@ MidiParser_QT::NoteRequestList MidiParser_QT::readNoteRequestList(Common::Seekab } void MidiParser_QT::initFromContainerTracks() { + const Common::Array<Common::QuickTimeParser::Track *> &tracks = Common::QuickTimeParser::_tracks; + + for (uint32 i = 0; i < tracks.size(); i++) { + if (tracks[i]->codecType == CODEC_TYPE_MIDI) { + assert(tracks[i]->sampleDescs.size() == 1); + + if (tracks[i]->editCount != 1) + warning("Unhandled QuickTime MIDI edit lists, things may go awry"); + + MIDISampleDesc *entry = (MIDISampleDesc *)tracks[i]->sampleDescs[0]; + + MIDITrackInfo trackInfo; + trackInfo.noteRequests = entry->_noteRequests; + trackInfo.data = readWholeTrack(tracks[i]); + _trackInfo.push_back(trackInfo); + } + } + + initCommon(); +} + +void MidiParser_QT::initCommon() { + // Now we have all our info needed in _trackInfo from whatever container + // form, we can fill in the MidiParser tracks. + // TODO } +byte *MidiParser_QT::readWholeTrack(Common::QuickTimeParser::Track *track) { + // This just goes through all chunks and + + Common::MemoryWriteStreamDynamic output; + uint32 curSample = 0; + + for (uint i = 0; i < track->chunkCount; i++) { + _fd->seek(track->chunkOffsets[i]); + + uint32 sampleCount = 0; + + for (uint32 j = 0; j < track->sampleToChunkCount; j++) + if (i >= track->sampleToChunk[j].first) + sampleCount = track->sampleToChunk[j].count; + + for (uint32 j = 0; j < sampleCount; j++, curSample++) { + uint32 size = (track->sampleSize != 0) ? track->sampleSize : track->sampleSizes[curSample]; + + byte *data = new byte[size]; + _fd->read(data, size); + output.write(data, size); + delete[] data; + } + } + + return output.getData(); +} + MidiParser *MidiParser::createParser_QT() { return new MidiParser_QT(); } diff --git a/audio/midiparser_qt.h b/audio/midiparser_qt.h index 34abe4ced7..0047803fc4 100644 --- a/audio/midiparser_qt.h +++ b/audio/midiparser_qt.h @@ -72,6 +72,11 @@ private: typedef Common::Array<NoteRequest> NoteRequestList; + struct MIDITrackInfo { + NoteRequestList noteRequests; + byte *data; + }; + class MIDISampleDesc : public SampleDesc { public: MIDISampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag); @@ -84,7 +89,12 @@ private: Common::Rational readFixed(Common::SeekableReadStream *stream); NoteRequestList readNoteRequestList(Common::SeekableReadStream *stream); + byte *readWholeTrack(Common::QuickTimeParser::Track *track); + + Common::Array<MIDITrackInfo> _trackInfo; + void initFromContainerTracks(); + void initCommon(); }; #endif |