renamed Sound -> BaseSound to avoid conflicts with the scumm class of the same name (we really should start to put all the Scumm/Simon/Sky code into namespaces

svn-id: r8508
This commit is contained in:
Max Horn 2003-06-15 12:22:19 +00:00
parent 7f7ce14d5e
commit 9ef0657c5c
2 changed files with 184 additions and 184 deletions

View File

@ -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);
}

View File

@ -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;