mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-04 16:26:53 +00:00
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:
parent
7f7ce14d5e
commit
9ef0657c5c
362
simon/sound.cpp
362
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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user