From 96005c7da9229f4801ac73b4200c54e38dcd7e32 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sat, 4 Jul 2015 12:55:49 +0200 Subject: AUDIO: Miles Audio AdLib instrument stream support - not using byte pointer + size and instead now a SeekableReadStream for factory - adjusted ACCESS + AGOS engines accordingly --- audio/miles.h | 3 ++- audio/miles_adlib.cpp | 68 ++++++++++++++++++++++++------------------------ engines/access/sound.cpp | 6 ++--- engines/agos/midi.cpp | 29 ++++++--------------- engines/agos/midi.h | 2 +- 5 files changed, 48 insertions(+), 60 deletions(-) diff --git a/audio/miles.h b/audio/miles.h index fde91e6227..584460952e 100644 --- a/audio/miles.h +++ b/audio/miles.h @@ -25,6 +25,7 @@ #include "audio/mididrv.h" #include "common/error.h" +#include "common/stream.h" namespace Audio { @@ -71,7 +72,7 @@ namespace Audio { // Miles Audio actually used 0x4000, because they didn't shift the 2 bytes properly #define MILES_PITCHBENDER_DEFAULT 0x2000 -extern MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFilename, const Common::String &instrumentDataFilenameOPL3, const byte *instrumentDataPtr = NULL, uint32 instrumentDataSize = 0); +extern MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFilename, const Common::String &instrumentDataFilenameOPL3, Common::SeekableReadStream *instrumentStream = nullptr); extern MidiDriver *MidiDriver_Miles_MT32_create(const Common::String &instrumentDataFilename); diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp index a68c252f4b..c85348cdd5 100644 --- a/audio/miles_adlib.cpp +++ b/audio/miles_adlib.cpp @@ -1060,15 +1060,16 @@ uint32 MidiDriver_Miles_AdLib::property(int prop, uint32 param) { return 0; } -MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFilename, const Common::String &instrumentDataFilenameOPL3, const byte *instrumentRawDataPtr, uint32 instrumentRawDataSize) { +MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFilename, const Common::String &instrumentDataFilenameOPL3, Common::SeekableReadStream *instrumentStream) { // Load adlib instrument data from file SAMPLE.AD (OPL3: SAMPLE.OPL) Common::File *fileStream = NULL; uint32 fileSize = 0; - byte *fileDataReadPtr = nullptr; - const byte *fileDataPtr = nullptr; uint32 fileDataOffset = 0; uint32 fileDataLeft = 0; + uint32 streamSize = 0; + byte *streamDataPtr = nullptr; + byte curBankId = 0; byte curPatchId = 0; @@ -1085,21 +1086,22 @@ MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFi if (!fileStream->open(instrumentDataFilename)) error("MILES-ADLIB: could not open instrument file"); - fileSize = fileStream->size(); + streamSize = fileStream->size(); - fileDataReadPtr = new byte[fileSize]; + streamDataPtr = new byte[streamSize]; - if (fileStream->read(fileDataReadPtr, fileSize) != fileSize) + if (fileStream->read(streamDataPtr, streamSize) != streamSize) error("MILES-ADLIB: error while reading instrument file"); fileStream->close(); delete fileStream; - fileDataPtr = fileDataReadPtr; + } else if (instrumentStream) { + // instrument data was passed directly (currently used by Amazon Guardians of Eden + Simon 2) + streamSize = instrumentStream->size(); + streamDataPtr = new byte[streamSize]; - } else if (instrumentRawDataPtr) { - // instrument data was passed directly (currently used by Amazon Guardians of Eden - fileDataPtr = instrumentRawDataPtr; - fileSize = instrumentRawDataSize; + if (instrumentStream->read(streamDataPtr, streamSize) != streamSize) + error("MILES-ADLIB: error while reading instrument stream"); } // File is like this: @@ -1109,13 +1111,13 @@ MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFi // First we check how many entries there are fileDataOffset = 0; - fileDataLeft = fileSize; + fileDataLeft = streamSize; while (1) { if (fileDataLeft < 6) error("MILES-ADLIB: unexpected EOF in instrument file"); - curPatchId = fileDataPtr[fileDataOffset++]; - curBankId = fileDataPtr[fileDataOffset++]; + curPatchId = streamDataPtr[fileDataOffset++]; + curBankId = streamDataPtr[fileDataOffset++]; if ((curBankId == 0xFF) && (curPatchId == 0xFF)) break; @@ -1136,43 +1138,41 @@ MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &instrumentDataFi fileDataOffset = 0; fileDataLeft = fileSize; while (1) { - curPatchId = fileDataPtr[fileDataOffset++]; - curBankId = fileDataPtr[fileDataOffset++]; + curPatchId = streamDataPtr[fileDataOffset++]; + curBankId = streamDataPtr[fileDataOffset++]; if ((curBankId == 0xFF) && (curPatchId == 0xFF)) break; - instrumentOffset = READ_LE_UINT32(fileDataPtr + fileDataOffset); + instrumentOffset = READ_LE_UINT32(streamDataPtr + fileDataOffset); fileDataOffset += 4; instrumentPtr->bankId = curBankId; instrumentPtr->patchId = curPatchId; - instrumentDataSize = READ_LE_UINT16(fileDataPtr + instrumentOffset); + instrumentDataSize = READ_LE_UINT16(streamDataPtr + instrumentOffset); if (instrumentDataSize != 14) error("MILES-ADLIB: unsupported instrument size"); - instrumentPtr->transposition = (signed char)fileDataPtr[instrumentOffset + 2]; - instrumentPtr->reg20op1 = fileDataPtr[instrumentOffset + 3]; - instrumentPtr->reg40op1 = fileDataPtr[instrumentOffset + 4]; - instrumentPtr->reg60op1 = fileDataPtr[instrumentOffset + 5]; - instrumentPtr->reg80op1 = fileDataPtr[instrumentOffset + 6]; - instrumentPtr->regE0op1 = fileDataPtr[instrumentOffset + 7]; - instrumentPtr->regC0 = fileDataPtr[instrumentOffset + 8]; - instrumentPtr->reg20op2 = fileDataPtr[instrumentOffset + 9]; - instrumentPtr->reg40op2 = fileDataPtr[instrumentOffset + 10]; - instrumentPtr->reg60op2 = fileDataPtr[instrumentOffset + 11]; - instrumentPtr->reg80op2 = fileDataPtr[instrumentOffset + 12]; - instrumentPtr->regE0op2 = fileDataPtr[instrumentOffset + 13]; + instrumentPtr->transposition = (signed char)streamDataPtr[instrumentOffset + 2]; + instrumentPtr->reg20op1 = streamDataPtr[instrumentOffset + 3]; + instrumentPtr->reg40op1 = streamDataPtr[instrumentOffset + 4]; + instrumentPtr->reg60op1 = streamDataPtr[instrumentOffset + 5]; + instrumentPtr->reg80op1 = streamDataPtr[instrumentOffset + 6]; + instrumentPtr->regE0op1 = streamDataPtr[instrumentOffset + 7]; + instrumentPtr->regC0 = streamDataPtr[instrumentOffset + 8]; + instrumentPtr->reg20op2 = streamDataPtr[instrumentOffset + 9]; + instrumentPtr->reg40op2 = streamDataPtr[instrumentOffset + 10]; + instrumentPtr->reg60op2 = streamDataPtr[instrumentOffset + 11]; + instrumentPtr->reg80op2 = streamDataPtr[instrumentOffset + 12]; + instrumentPtr->regE0op2 = streamDataPtr[instrumentOffset + 13]; // Instrument read, next instrument please instrumentPtr++; } - if (fileDataReadPtr) { - // Free instrument file data in case it was read by us - delete[] fileDataReadPtr; - } + // Free instrument file/stream data + delete[] streamDataPtr; return new MidiDriver_Miles_AdLib(g_system->getMixer(), instrumentTablePtr, instrumentTableCount); } diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp index e1ed65a240..61191aac25 100644 --- a/engines/access/sound.cpp +++ b/engines/access/sound.cpp @@ -211,12 +211,12 @@ MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) { switch (musicType) { case MT_ADLIB: { Resource *midiDrvResource = _vm->_files->loadFile(92, 1); - const byte *adLibInstrumentData = midiDrvResource->data(); - uint32 adLibInstrumentDataSize = midiDrvResource->_size; + Common::MemoryReadStream *adLibInstrumentStream = new Common::MemoryReadStream(midiDrvResource->data(), midiDrvResource->_size); - _driver = Audio::MidiDriver_Miles_AdLib_create("", "", adLibInstrumentData, adLibInstrumentDataSize); + _driver = Audio::MidiDriver_Miles_AdLib_create("", "", adLibInstrumentStream); delete midiDrvResource; + delete adLibInstrumentStream; break; } case MT_MT32: diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp index f81721297d..9563d7d329 100644 --- a/engines/agos/midi.cpp +++ b/engines/agos/midi.cpp @@ -191,16 +191,15 @@ int MidiPlayer::open(int gameType, bool isDemo) { // if there is no file called MIDPAK.AD, try to extract it from the file SETUP.SHR // if we didn't do this, the user would be forced to "install" the game instead of simply // copying all files from CD-ROM. - const byte *instrumentRawData = NULL; - uint32 instrumentRawDataSize = 0; - instrumentRawData = simon2SetupExtractFile("MIDPAK.AD", instrumentRawDataSize); - if (!instrumentRawData) + Common::SeekableReadStream *midpakAdLibStream; + midpakAdLibStream = simon2SetupExtractFile("MIDPAK.AD"); + if (!midpakAdLibStream) error("MidiPlayer: could not extract MIDPAK.AD from SETUP.SHR"); // Pass this extracted data to the driver warning("SIMON 2: using MIDPAK.AD extracted from SETUP.SHR"); - _driver = Audio::MidiDriver_Miles_AdLib_create("", "", instrumentRawData, instrumentRawDataSize); - delete[] instrumentRawData; + _driver = Audio::MidiDriver_Miles_AdLib_create("", "", midpakAdLibStream); + delete midpakAdLibStream; } // TODO: not sure what's going wrong with AdLib // it doesn't seem to matter if we use the regular XMIDI tracks or the 2nd set meant for MT32 @@ -818,7 +817,7 @@ void MidiPlayer::loadS1D(Common::File *in, bool sfx) { // [bundle file header] // [compressed file header] [compressed file data] // * compressed file count -const byte *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFileName, uint32 &extractedDataSize) { +Common::SeekableReadStream *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFileName) { Common::File *setupBundleStream = new Common::File(); uint32 bundleSize = 0; uint32 bundleBytesLeft = 0; @@ -830,9 +829,8 @@ const byte *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFi Common::String fileName; uint32 fileCompressedSize = 0; byte *fileCompressedDataPtr = nullptr; - byte *extractedDataPtr = nullptr; - extractedDataSize = 0; + Common::SeekableReadStream *extractedStream = nullptr; if (!setupBundleStream->open("setup.shr")) error("MidiPlayer: could not open setup.shr"); @@ -885,22 +883,11 @@ const byte *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFi error("MidiPlayer: setup.shr read error"); Common::MemoryReadStream *compressedStream = nullptr; - Common::SeekableReadStream *extractedStream = nullptr; compressedStream = new Common::MemoryReadStream(fileCompressedDataPtr, fileCompressedSize); // we don't know the unpacked size, let decompressor figure it out extractedStream = Common::decompressDCL(compressedStream); delete compressedStream; - - if (extractedStream) { - // Successfully extracted the data - // TODO: clean up required, but this also requires Miles Audio drivers to use streams - extractedDataPtr = new byte[extractedStream->size()]; - extractedStream->seek(0); - extractedStream->read(extractedDataPtr, extractedStream->size()); - extractedDataSize = extractedStream->size(); - delete extractedStream; - } break; } @@ -913,7 +900,7 @@ const byte *MidiPlayer::simon2SetupExtractFile(const Common::String &requestedFi setupBundleStream->close(); delete setupBundleStream; - return extractedDataPtr; + return extractedStream; } } // End of namespace AGOS diff --git a/engines/agos/midi.h b/engines/agos/midi.h index fff87e63c6..d0a7d77971 100644 --- a/engines/agos/midi.h +++ b/engines/agos/midi.h @@ -129,7 +129,7 @@ private: kMusicMode _musicMode; private: - const byte *simon2SetupExtractFile(const Common::String &requestedFileName, uint32 &extractedDataSize); + Common::SeekableReadStream *simon2SetupExtractFile(const Common::String &requestedFileName); }; } // End of namespace AGOS -- cgit v1.2.3