diff options
author | Kari Salminen | 2008-04-08 14:45:42 +0000 |
---|---|---|
committer | Kari Salminen | 2008-04-08 14:45:42 +0000 |
commit | 4cc4bd0f41812e226f7809904d8d50e26c71d0e1 (patch) | |
tree | b19a27002fc3f3136aa2c72096c557a540fbcf75 /engines/agi | |
parent | 9f94a2fa8c492b83e837621890b053633bc35532 (diff) | |
download | scummvm-rg350-4cc4bd0f41812e226f7809904d8d50e26c71d0e1.tar.gz scummvm-rg350-4cc4bd0f41812e226f7809904d8d50e26c71d0e1.tar.bz2 scummvm-rg350-4cc4bd0f41812e226f7809904d8d50e26c71d0e1.zip |
Implement the full range of Apple IIGS MIDI program number to instrument mapping. Switch to using 8-bit signed sample data with Apple IIGS (In preparation for mixing multiple channels). Make Apple IIGS wavefile handling use SharedPtr and Array.
svn-id: r31451
Diffstat (limited to 'engines/agi')
-rw-r--r-- | engines/agi/sound.cpp | 55 | ||||
-rw-r--r-- | engines/agi/sound.h | 19 |
2 files changed, 39 insertions, 35 deletions
diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index a7101aa8b6..e8f285a116 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -107,9 +107,9 @@ IIgsSample::IIgsSample(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : // Finalize the header info using the 8-bit unsigned sample data _header.finalize(stream); - // Convert sample data from 8-bit unsigned to 16-bit signed format + // Convert sample data from 8-bit unsigned to 8-bit signed format stream.seek(sampleStartPos); - _sample = new int16[_header.sampleSize]; + _sample = new int8[_header.sampleSize]; if (_sample != NULL) _isValid = _manager.convertWave(stream, _sample, _header.sampleSize); } @@ -236,7 +236,8 @@ static const instrumentSetInfo instSetV1 = { 6, 7, 10, 9, 11, 9, 15, 8, 5, 5, 17, 16, 18, 12, 14, 5, 5, 5, 5, 5, 0, 1, 2, 9, 3, 4, 15, 2, 2, 2, - 25, 13, 13, 25, 5, 5, 5, 5, 5, 5} + 25, 13, 13, 25}, + 5 }; /** Newer Apple IIGS AGI instrument set (AGI v1.003+). Used by all others than Space Quest I. */ @@ -246,7 +247,8 @@ static const instrumentSetInfo instSetV2 = { 7, 9, 12, 8, 13, 11, 17, 10, 6, 6, 19, 18, 20, 14, 16, 6, 6, 6, 6, 6, 0, 1, 2, 4, 3, 5, 17, 2, 2, 2, - 27, 15, 15, 27, 6, 6, 6, 6, 6, 6} + 27, 15, 15, 27}, + 6 }; /** Information about different Apple IIGS AGI executables. */ @@ -268,7 +270,6 @@ static const IIgsExeInfo IIgsExeInfos[] = { static IIgsInstrumentHeader g_instruments[MAX_INSTRUMENTS]; static uint g_numInstruments = 0; -static int16 g_wave[SIERRASTANDARD_SIZE]; // FIXME? Should this be allocated from the heap? (Size is 128KiB) // Time (In milliseconds) in Apple IIGS mixing buffer time granularity // (i.e. in IIGS_BUFFER_SIZE / getRate() seconds granularity) static uint32 g_IIgsBufGranMillis = 0; @@ -771,7 +772,7 @@ uint32 SoundMgr::mixSound(void) { for (i = 0; i < IIGS_BUFFER_SIZE; i++) { b = _IIgsChannel.sample[fracToInt(_IIgsChannel.pos)]; // DOESN'T DO MIXING YET! ONLY ONE SAMPLE PER PLAYING! - _sndBuffer[i] = (int16) (b * tempVol); + _sndBuffer[i] = (int16) (b * tempVol * 256); _IIgsChannel.pos += _IIgsChannel.posAdd; if (_IIgsChannel.pos >= intToFrac(_IIgsChannel.size)) { @@ -950,28 +951,28 @@ bool SoundMgr::loadInstrumentHeaders(const Common::String &exePath, const IIgsEx } /** - * Convert sample from 8-bit unsigned to 16-bit signed format. + * Convert sample from 8-bit unsigned to 8-bit signed format. * @param source Source stream containing the 8-bit unsigned sample data. - * @param dest Destination buffer for the 16-bit signed sample data. + * @param dest Destination buffer for the 8-bit signed sample data. * @param length Length of the sample data to be converted. */ -bool SoundMgr::convertWave(Common::SeekableReadStream &source, int16 *dest, uint length) { - // Convert the wave from 8-bit unsigned to 16-bit signed format +bool SoundMgr::convertWave(Common::SeekableReadStream &source, int8 *dest, uint length) { + // Convert the wave from 8-bit unsigned to 8-bit signed format for (uint i = 0; i < length; i++) - dest[i] = (int16) ((source.readByte() - 128) * 256); + dest[i] = (int8) ((int) source.readByte() - 128); return !source.ioFailed(); } -Common::MemoryReadStream *SoundMgr::loadWaveFile(const Common::String &wavePath, const IIgsExeInfo &exeInfo) { +Common::SharedPtr<Common::MemoryReadStream> SoundMgr::loadWaveFile(const Common::String &wavePath, const IIgsExeInfo &exeInfo) { Common::File file; // Open the wave file and read it into memory file.open(wavePath); - Common::MemoryReadStream *uint8Wave = file.readStream(file.size()); + Common::SharedPtr<Common::MemoryReadStream> uint8Wave(file.readStream(file.size())); file.close(); // Check that we got the whole wave file - if (uint8Wave != NULL && uint8Wave->size() == SIERRASTANDARD_SIZE) { + if (uint8Wave && uint8Wave->size() == SIERRASTANDARD_SIZE) { // Check wave file's md5sum char md5str[32+1]; Common::md5_file_string(*uint8Wave, md5str, SIERRASTANDARD_SIZE); @@ -984,8 +985,7 @@ Common::MemoryReadStream *SoundMgr::loadWaveFile(const Common::String &wavePath, return uint8Wave; } else { // Couldn't read the wave file or it had incorrect size warning("Error loading Apple IIGS wave file (%s), not loading instruments", wavePath.c_str()); - delete uint8Wave; // Free the memory buffer allocated for reading the wave file - return NULL; + return Common::SharedPtr<Common::MemoryReadStream>(); // Return a NULL shared pointer } } @@ -1057,19 +1057,16 @@ bool SoundMgr::loadInstruments() { } // First load the wave file and then load the instrument headers. - // Finally fix the instruments' lengths using the wave file data - // (A zero in the wave file data can end the sample prematurely) - // and convert the wave file from 8-bit unsigned to 16-bit signed format. - Common::MemoryReadStream *uint8Wave = loadWaveFile(waveFsnode->getPath(), *exeInfo); - // Seek the wave to its - if (uint8Wave != NULL) - uint8Wave->seek(0); - - bool result = uint8Wave != NULL && loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo) && - finalizeInstruments(*uint8Wave) && convertWave(*uint8Wave, g_wave, uint8Wave->size()); - - delete uint8Wave; // Free the 8-bit unsigned wave file buffer - return result; + // Finally convert the wave file from 8-bit unsigned to 8-bit signed format. + // As none of the tested SIERRASTANDARD-files have zeroes in them there's + // no need to check for true sample size (A zero in the sample data would + // end the sample prematurely). + Common::SharedPtr<Common::MemoryReadStream> uint8Wave = loadWaveFile(waveFsnode->getPath(), *exeInfo); + if (uint8Wave && loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo)) { + _gsWave.resize(uint8Wave->size()); // Allocate space for the 8-bit signed version of the SIERRASTANDARD-file + return convertWave(*uint8Wave, _gsWave.begin(), uint8Wave->size()); + } else // Error loading the wave file or the instrument headers + return false; } static void fillAudio(void *udata, int16 *stream, uint len) { diff --git a/engines/agi/sound.h b/engines/agi/sound.h index bfe4b52886..1537866f14 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -30,6 +30,8 @@ #include "sound/audiostream.h" #include "sound/mixer.h" #include "common/frac.h" +#include "common/array.h" +#include "common/ptr.h" namespace Agi { @@ -195,7 +197,7 @@ struct AgiNote { struct IIgsChannelInfo { IIgsInstrumentHeader ins; ///< Instrument info - const int16 *sample; ///< Source sample data (16-bit signed format) + const int8 *sample; ///< Source sample data (8-bit signed format) frac_t pos; ///< Current sample position frac_t posAdd; ///< Current sample position adder (Calculated using note, vibrato etc) frac_t note; ///< Note @@ -311,10 +313,10 @@ public: ~IIgsSample() { delete[] _sample; } virtual uint16 type() { return _header.type; } const IIgsSampleHeader &getHeader() const { return _header; } - const int16 *getSample() const { return _sample; } + const int8 *getSample() const { return _sample; } protected: IIgsSampleHeader _header; ///< Apple IIGS AGI sample header - int16 *_sample; ///< Sample data (16-bit signed format) + int8 *_sample; ///< Sample data (8-bit signed format) }; /** Apple IIGS AGI instrument set information. */ @@ -323,7 +325,11 @@ struct instrumentSetInfo { uint instCount; ///< Amount of instrument in the set const char *md5; ///< MD5 hex digest of the whole instrument set const char *waveFileMd5; ///< MD5 hex digest of the wave file (i.e. the sample data used by the instruments) - const uint midiProgToInst[50]; ///< Lookup table for the MIDI program number to instrument number mapping + const byte midiProgToInst[44]; ///< Lookup table for the MIDI program number to instrument number mapping + const byte undefinedInst; ///< The undefined instrument number + + // Maps the MIDI program number to an instrument number + byte mapMidiProgToInst(uint midiProg) { return midiProg < ARRAYSIZE(midiProgToInst) ? midiProgToInst[midiProg] : undefinedInst; } }; /** Apple IIGS AGI executable file information. */ @@ -380,6 +386,7 @@ private: int16 *_sndBuffer; const int16 *_waveform; + Common::Array<int8> _gsWave; void premixerCall(int16 *buf, uint len); @@ -401,8 +408,8 @@ public: Audio::AudioStream *makeIIgsSampleStream(Common::SeekableReadStream &stream, int resnum = -1); const IIgsExeInfo *getIIgsExeInfo(enum AgiGameID gameid) const; bool loadInstrumentHeaders(const Common::String &exePath, const IIgsExeInfo &exeInfo); - bool convertWave(Common::SeekableReadStream &source, int16 *dest, uint length); - Common::MemoryReadStream *loadWaveFile(const Common::String &wavePath, const IIgsExeInfo &exeInfo); + bool convertWave(Common::SeekableReadStream &source, int8 *dest, uint length); + Common::SharedPtr<Common::MemoryReadStream> loadWaveFile(const Common::String &wavePath, const IIgsExeInfo &exeInfo); }; } // End of namespace Agi |