[Scummvm-cvs-logs] CVS: scummvm/simon sound.cpp,NONE,1.1 sound.h,NONE,1.1

Oliver Kiehl olki at users.sourceforge.net
Fri Nov 29 14:10:03 CET 2002


Update of /cvsroot/scummvm/scummvm/simon
In directory sc8-pr-cvs1:/tmp/cvs-serv12574

Added Files:
	sound.cpp sound.h 
Log Message:
renamed simonsound on Fingolfin's request


--- NEW FILE: sound.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001/2002 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

#include "simon/simonsound.h"
#include "common/file.h"
#include "common/engine.h"

SimonSound::SimonSound(const byte game, const GameSpecificSettings *gss, const char *gameDataPath, SoundMixer *mixer)
{
	_game = game;
	_mixer = mixer;
	
	_effects_paused = false;
	_ambient_paused = false;

	_voice_handle = 0;
	_effects_handle = 0;
	_ambient_handle = 0;

	_ambient_playing = 0;

	File *file = new File();
	File *file2 = new File();
	const char *s;

#ifdef USE_MAD
	file->open(gss->mp3_filename, gameDataPath);
	if (file->isOpen() == false) {
#endif
		if (_game & GAME_WIN) {
			s = gss->wav_filename;
			file->open(s, gameDataPath);
			if (file->isOpen() == false) {
				warning("Cannot open voice file %s", s);
			} else	{
				_voice = new WavSound(_mixer, file);
			}
		} else if (_game & GAME_TALKIE) {
			s = gss->voc_filename;
			file->open(s, gameDataPath);
			if (file->isOpen() == false) {
				warning("Cannot open voice file %s", s);
			} else {
				_voice = new VocSound(_mixer, file);
			}
		}
#ifdef USE_MAD
	} else {
		_voice = new MP3Sound(_mixer, file);
	}
#endif

	if (_game == GAME_SIMON1TALKIE) {
#ifdef USE_MAD
		file2->open(gss->mp3_effects_filename, gameDataPath);
		if (file2->isOpen() == false) {
#endif
			s = gss->voc_effects_filename;
			file2->open(s, gameDataPath);
			if (file2->isOpen() == false) {
				warning("Cannot open effects file %s", s);
			} else {
				_effects = new VocSound(_mixer, file2);
			}
#ifdef USE_MAD
		} else {
			_effects = new MP3Sound(_mixer, file2);
		}
#endif
	}
}

void SimonSound::readSfxFile(const char *filename, const char *gameDataPath)
{
	stopAll();

	File *file = new File();
	file->open(filename, gameDataPath);

	if (file->isOpen() == false) {
		warning("readSfxFile: Cannot load sfx file %s", filename);
		return;
	}

	_effects = new WavSound(_mixer, file);
}

void SimonSound::loadSfxTable(File *gameFile, uint32 base) 
{
	stopAll();

	if (_game & GAME_WIN)
		_effects = new WavSound(_mixer, gameFile, base);
	else
		_effects = new VocSound(_mixer, gameFile, base);
}

void SimonSound::playVoice(uint sound)
{
	if (!_voice)
		return;
	
	_voice->playSound(sound, &_voice_handle);
}

void SimonSound::playEffects(uint sound)
{
	if (!_effects)
		return;
	
	if (_effects_paused)
		return;

	_effects->playSound(sound, &_effects_handle);
}

void SimonSound::playAmbient(uint sound)
{
	if (!_effects)
		return;

	if (sound == _ambient_playing)
		return;

	_ambient_playing = sound;

	if (_ambient_paused)
		return;

	if (_ambient_handle)
		_mixer->stop(_ambient_index);

	_ambient_index = _effects->playSound(sound, &_ambient_handle, SoundMixer::FLAG_LOOP);
}

bool SimonSound::hasVoice()
{
	return _voice != NULL;
}

void SimonSound::stopAll()
{
	_mixer->stopAll();
	_ambient_playing = 0;
}

void SimonSound::effectsPause(bool b)
{
	_effects_paused = b;
}

void SimonSound::ambientPause(bool b)
{
	_ambient_paused = b;

	if (_ambient_paused && _ambient_playing) {
		_mixer->stop(_ambient_index);
	} else if (_ambient_playing) {
		uint tmp = _ambient_playing;
		_ambient_playing = 0;
		playAmbient(tmp);
	}
}

/******************************************************************************/

SimonSound::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("Cannot 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();
}

#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 SimonSound::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 SimonSound::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): cannot 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 SimonSound::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): cannot 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): cannot 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);
}


--- NEW FILE: sound.h ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001/2002 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

#include "sound/mixer.h"
#include "simon/intern.h"

class SimonSound {
private:
	class Sound {
	protected:
		File *_file;
		uint32 *_offsets;
		SoundMixer *_mixer;

	public:
		Sound(SoundMixer *mixer, File *file, uint32 base = 0);
		virtual int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0) = 0;
	};

	class WavSound : public Sound {
	public:
		WavSound(SoundMixer *mixer, File *file, uint32 base = 0) : Sound(mixer, file, base) {};
		int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0);
	};

	class VocSound : public Sound {
	public:
		VocSound(SoundMixer *mixer, File *file, uint32 base = 0) : Sound(mixer, file, base) {};
		int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0);
	};

	class MP3Sound : public Sound {
	public:
		MP3Sound(SoundMixer *mixer, File *file, uint32 base = 0) : Sound(mixer, file, base) {};
		int playSound(uint sound, PlayingSoundHandle *handle, byte flags = 0);
	};

	byte _game;
	int _ambient_index;
	SoundMixer *_mixer;

	Sound *_voice;
	Sound *_effects;

	bool _effects_paused;
	bool _ambient_paused;

public:
	PlayingSoundHandle _voice_handle;
	PlayingSoundHandle _effects_handle;
	PlayingSoundHandle _ambient_handle;

	uint _ambient_playing;

	SimonSound(const byte game, const GameSpecificSettings *gss, const char *gameDataPath, SoundMixer *mixer);

	void readSfxFile(const char *filename, const char *gameDataPath);
	void loadSfxTable(File *gameFile, uint32 base);

	void playVoice(uint sound);
	void playEffects(uint sound);
	void playAmbient(uint sound);

	bool hasVoice();
	void stopAll();
	void effectsPause(bool b);
	void ambientPause(bool b);
};






More information about the Scummvm-git-logs mailing list