diff options
| -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  | 
