diff options
Diffstat (limited to 'simon')
-rw-r--r-- | simon/sound.cpp | 362 | ||||
-rw-r--r-- | simon/sound.h | 6 |
2 files changed, 184 insertions, 184 deletions
diff --git a/simon/sound.cpp b/simon/sound.cpp index 69dbde3aa9..f9c7785d50 100644 --- a/simon/sound.cpp +++ b/simon/sound.cpp @@ -22,38 +22,208 @@ #include "common/file.h" #include "common/engine.h" -class Sound { +class BaseSound { protected: File *_file; uint32 *_offsets; SoundMixer *_mixer; public: - Sound(SoundMixer *mixer, File *file, uint32 base = 0); - Sound(SoundMixer *mixer, File *file, uint32 *offsets); - virtual ~Sound() { delete _file; } + BaseSound(SoundMixer *mixer, File *file, uint32 base = 0); + BaseSound(SoundMixer *mixer, File *file, uint32 *offsets); + virtual ~BaseSound() { delete _file; } virtual int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0) = 0; }; -class WavSound : public Sound { +class WavSound : public BaseSound { public: - WavSound(SoundMixer *mixer, File *file, uint32 base = 0) : Sound(mixer, file, base) {}; - WavSound(SoundMixer *mixer, File *file, uint32 *offsets) : Sound(mixer, file, offsets) {}; + WavSound(SoundMixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}; + WavSound(SoundMixer *mixer, File *file, uint32 *offsets) : BaseSound(mixer, file, offsets) {}; int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0); }; -class VocSound : public Sound { +class VocSound : public BaseSound { public: - VocSound(SoundMixer *mixer, File *file, uint32 base = 0) : Sound(mixer, file, base) {}; + VocSound(SoundMixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}; int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0); }; -class MP3Sound : public Sound { +class MP3Sound : public BaseSound { public: - MP3Sound(SoundMixer *mixer, File *file, uint32 base = 0) : Sound(mixer, file, base) {}; + MP3Sound(SoundMixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}; int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0); }; +BaseSound::BaseSound(SoundMixer *mixer, File *file, uint32 base) { + _mixer = mixer; + _file = file; + + uint res = 0; + uint32 size; + + _file->seek(base + sizeof(uint32), SEEK_SET); + size = _file->readUint32LE(); + + res = size / sizeof(uint32); + + _offsets = (uint32 *)malloc(size + sizeof(uint32)); + + _file->seek(base, SEEK_SET); + + if (_file->read(_offsets, size) != size) + error("Can't read offsets"); + + for (uint i = 0; i < res; i++) { +#if defined(SCUMM_BIG_ENDIAN) + _offsets[i] = FROM_LE_32(_offsets[i]); +#endif + _offsets[i] += base; + } + + // only needed for mp3 + _file->seek(0, SEEK_END); + _offsets[res] = _file->pos(); +} + +BaseSound::BaseSound(SoundMixer *mixer, File *file, uint32 *offsets) { + _mixer = mixer; + _file = file; + _offsets = offsets; +} + +#if !defined(__GNUC__) +#pragma START_PACK_STRUCTS +#endif + +struct WaveHeader { + uint32 riff; + uint32 unk; + uint32 wave; + uint32 fmt; + + uint32 size; + + uint16 format_tag; + uint16 channels; + uint32 samples_per_sec; + uint32 avg_bytes; + + uint16 block_align; + uint16 bits_per_sample; +} GCC_PACK; + +struct VocHeader { + uint8 desc[20]; + uint16 datablock_offset; + uint16 version; + uint16 id; +} GCC_PACK; + +struct VocBlockHeader { + uint8 blocktype; + uint8 size[3]; + uint8 sr; + uint8 pack; +} GCC_PACK; + +#if !defined(__GNUC__) +#pragma END_PACK_STRUCTS +#endif + +int WavSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) { + if (_offsets == NULL) + return 0; + + WaveHeader wave_hdr; + uint32 data[2]; + + flags |= SoundMixer::FLAG_UNSIGNED|SoundMixer::FLAG_AUTOFREE; + + _file->seek(_offsets[sound], SEEK_SET); + + if (_file->read(&wave_hdr, sizeof(wave_hdr)) != sizeof(wave_hdr) || + wave_hdr.riff != MKID('RIFF') || wave_hdr.wave != MKID('WAVE') + || wave_hdr.fmt != MKID('fmt ') || READ_LE_UINT16(&wave_hdr.format_tag) != 1 + || READ_LE_UINT16(&wave_hdr.channels) != 1 + || READ_LE_UINT16(&wave_hdr.bits_per_sample) != 8) { + error("playWav(%d): can't read RIFF header", sound); + } + + _file->seek(FROM_LE_32(wave_hdr.size) - sizeof(wave_hdr) + 20, SEEK_CUR); + + data[0] = _file->readUint32LE(); + data[1] = _file->readUint32LE(); + if (//fread(data, sizeof(data), 1, sound_file) != 1 || + data[0] != 'atad') { + error("playWav(%d): can't read data header", sound); + } + + byte *buffer = (byte *)malloc(data[1]); + _file->read(buffer, data[1]); + + return _mixer->playRaw(handle, buffer, data[1], FROM_LE_32(wave_hdr.samples_per_sec), flags); +} + +int VocSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) { + if (_offsets == NULL) + return 0; + + VocHeader voc_hdr; + VocBlockHeader voc_block_hdr; + uint32 size; + + flags |= SoundMixer::FLAG_UNSIGNED|SoundMixer::FLAG_AUTOFREE; + + _file->seek(_offsets[sound], SEEK_SET); + + if (_file->read(&voc_hdr, sizeof(voc_hdr)) != sizeof(voc_hdr) || + strncmp((char *)voc_hdr.desc, "Creative Voice File\x1A", 10) != 0) { + error("playVoc(%d): can't read voc header", sound); + } + + _file->read(&voc_block_hdr, sizeof(voc_block_hdr)); + + size = voc_block_hdr.size[0] + (voc_block_hdr.size[1] << 8) + (voc_block_hdr.size[2] << 16) - 2; + uint32 samples_per_sec; + + /* workaround for voc weakness */ + if (voc_block_hdr.sr == 0xa6) { + samples_per_sec = 11025; + } else if (voc_block_hdr.sr == 0xd2) { + samples_per_sec = 22050; + } else { + samples_per_sec = 1000000L / (256L - (long)voc_block_hdr.sr); + warning("inexact sample rate used: %i", samples_per_sec); + } + + byte *buffer = (byte *)malloc(size); + _file->read(buffer, size); + + return _mixer->playRaw(handle, buffer, size, samples_per_sec, flags); +} + +#ifdef USE_MAD +int MP3Sound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) +{ + if (_offsets == NULL) + return 0; + + flags |= SoundMixer::FLAG_AUTOFREE; + + _file->seek(_offsets[sound], SEEK_SET); + + uint32 size = _offsets[sound+1] - _offsets[sound]; + + byte *buffer = (byte *)malloc(size); + _file->read(buffer, size); + + return _mixer->playMP3(handle, buffer, size, flags); +} +#endif + + +/******************************************************************************/ + SimonSound::SimonSound(const byte game, const GameSpecificSettings *gss, const char *gameDataPath, SoundMixer *mixer) { _game = game; @@ -260,173 +430,3 @@ void SimonSound::ambientPause(bool b) { playAmbient(tmp); } } - -/******************************************************************************/ - -Sound::Sound(SoundMixer *mixer, File *file, uint32 base) { - _mixer = mixer; - _file = file; - - uint res = 0; - uint32 size; - - _file->seek(base + sizeof(uint32), SEEK_SET); - size = _file->readUint32LE(); - - res = size / sizeof(uint32); - - _offsets = (uint32 *)malloc(size + sizeof(uint32)); - - _file->seek(base, SEEK_SET); - - if (_file->read(_offsets, size) != size) - error("Can't read offsets"); - - for (uint i = 0; i < res; i++) { -#if defined(SCUMM_BIG_ENDIAN) - _offsets[i] = FROM_LE_32(_offsets[i]); -#endif - _offsets[i] += base; - } - - /* only needed for mp3 */ - _file->seek(0, SEEK_END); - _offsets[res] = _file->pos(); -} - -Sound::Sound(SoundMixer *mixer, File *file, uint32 *offsets) { - _mixer = mixer; - _file = file; - _offsets = offsets; -} - -#if !defined(__GNUC__) -#pragma START_PACK_STRUCTS -#endif - -struct WaveHeader { - uint32 riff; - uint32 unk; - uint32 wave; - uint32 fmt; - - uint32 size; - - uint16 format_tag; - uint16 channels; - uint32 samples_per_sec; - uint32 avg_bytes; - - uint16 block_align; - uint16 bits_per_sample; -} GCC_PACK; - -struct VocHeader { - uint8 desc[20]; - uint16 datablock_offset; - uint16 version; - uint16 id; -} GCC_PACK; - -struct VocBlockHeader { - uint8 blocktype; - uint8 size[3]; - uint8 sr; - uint8 pack; -} GCC_PACK; - -#if !defined(__GNUC__) -#pragma END_PACK_STRUCTS -#endif - -#ifdef USE_MAD -int MP3Sound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) -{ - if (_offsets == NULL) - return 0; - - flags |= SoundMixer::FLAG_AUTOFREE; - - _file->seek(_offsets[sound], SEEK_SET); - - uint32 size = _offsets[sound+1] - _offsets[sound]; - - byte *buffer = (byte *)malloc(size); - _file->read(buffer, size); - - return _mixer->playMP3(handle, buffer, size, flags); -} -#endif - -int VocSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) { - if (_offsets == NULL) - return 0; - - VocHeader voc_hdr; - VocBlockHeader voc_block_hdr; - uint32 size; - - flags |= SoundMixer::FLAG_UNSIGNED|SoundMixer::FLAG_AUTOFREE; - - _file->seek(_offsets[sound], SEEK_SET); - - if (_file->read(&voc_hdr, sizeof(voc_hdr)) != sizeof(voc_hdr) || - strncmp((char *)voc_hdr.desc, "Creative Voice File\x1A", 10) != 0) { - error("playVoc(%d): can't read voc header", sound); - } - - _file->read(&voc_block_hdr, sizeof(voc_block_hdr)); - - size = voc_block_hdr.size[0] + (voc_block_hdr.size[1] << 8) + (voc_block_hdr.size[2] << 16) - 2; - uint32 samples_per_sec; - - /* workaround for voc weakness */ - if (voc_block_hdr.sr == 0xa6) { - samples_per_sec = 11025; - } else if (voc_block_hdr.sr == 0xd2) { - samples_per_sec = 22050; - } else { - samples_per_sec = 1000000L / (256L - (long)voc_block_hdr.sr); - warning("inexact sample rate used: %i", samples_per_sec); - } - - byte *buffer = (byte *)malloc(size); - _file->read(buffer, size); - - return _mixer->playRaw(handle, buffer, size, samples_per_sec, flags); -} - -int WavSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) { - if (_offsets == NULL) - return 0; - - WaveHeader wave_hdr; - uint32 data[2]; - - flags |= SoundMixer::FLAG_UNSIGNED|SoundMixer::FLAG_AUTOFREE; - - _file->seek(_offsets[sound], SEEK_SET); - - if (_file->read(&wave_hdr, sizeof(wave_hdr)) != sizeof(wave_hdr) || - wave_hdr.riff != MKID('RIFF') || wave_hdr.wave != MKID('WAVE') - || wave_hdr.fmt != MKID('fmt ') || READ_LE_UINT16(&wave_hdr.format_tag) != 1 - || READ_LE_UINT16(&wave_hdr.channels) != 1 - || READ_LE_UINT16(&wave_hdr.bits_per_sample) != 8) { - error("playWav(%d): can't read RIFF header", sound); - } - - _file->seek(FROM_LE_32(wave_hdr.size) - sizeof(wave_hdr) + 20, SEEK_CUR); - - data[0] = _file->readUint32LE(); - data[1] = _file->readUint32LE(); - if (//fread(data, sizeof(data), 1, sound_file) != 1 || - data[0] != 'atad') { - error("playWav(%d): can't read data header", sound); - } - - byte *buffer = (byte *)malloc(data[1]); - _file->read(buffer, data[1]); - - return _mixer->playRaw(handle, buffer, data[1], FROM_LE_32(wave_hdr.samples_per_sec), flags); -} - diff --git a/simon/sound.h b/simon/sound.h index e17a331c14..8a510a4e66 100644 --- a/simon/sound.h +++ b/simon/sound.h @@ -20,7 +20,7 @@ #include "sound/mixer.h" #include "simon/intern.h" -class Sound; +class BaseSound; class SimonSound { private: @@ -32,8 +32,8 @@ private: int _voice_index; int _ambient_index; - Sound *_voice; - Sound *_effects; + BaseSound *_voice; + BaseSound *_effects; bool _effects_paused; bool _ambient_paused; |