aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/midiparser_qt.cpp74
-rw-r--r--audio/midiparser_qt.h10
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