mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-28 20:55:19 +00:00
655ce26b3f
svn-id: r34514
212 lines
5.7 KiB
C++
212 lines
5.7 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
* sound functionality
|
|
*/
|
|
|
|
#include "tinsel/sound.h"
|
|
|
|
#include "tinsel/dw.h"
|
|
#include "tinsel/config.h"
|
|
#include "tinsel/music.h"
|
|
#include "tinsel/strres.h"
|
|
#include "tinsel/tinsel.h"
|
|
|
|
#include "common/endian.h"
|
|
#include "common/file.h"
|
|
#include "common/system.h"
|
|
|
|
#include "sound/mixer.h"
|
|
#include "sound/audiocd.h"
|
|
|
|
namespace Tinsel {
|
|
|
|
//--------------------------- General data ----------------------------------
|
|
|
|
SoundManager::SoundManager(TinselEngine *vm) :
|
|
//_vm(vm), // TODO: Enable this once global _vm var is gone
|
|
_sampleIndex(0), _sampleIndexLen(0) {
|
|
}
|
|
|
|
SoundManager::~SoundManager() {
|
|
free(_sampleIndex);
|
|
}
|
|
|
|
/**
|
|
* Plays the specified sample through the sound driver.
|
|
* @param id Identifier of sample to be played
|
|
* @param type type of sound (voice or sfx)
|
|
* @param handle sound handle
|
|
*/
|
|
bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) {
|
|
// Floppy version has no sample file
|
|
if (_vm->getFeatures() & GF_FLOPPY)
|
|
return false;
|
|
|
|
// no sample driver?
|
|
if (!_vm->_mixer->isReady())
|
|
return false;
|
|
|
|
// stop any currently playing sample
|
|
_vm->_mixer->stopHandle(_handle);
|
|
|
|
// make sure id is in range
|
|
assert(id > 0 && id < _sampleIndexLen);
|
|
|
|
// get file offset for this sample
|
|
int32 dwSampleIndex = _sampleIndex[id];
|
|
|
|
// move to correct position in the sample file
|
|
_sampleStream.seek(dwSampleIndex);
|
|
if (_sampleStream.ioFailed() || _sampleStream.pos() != dwSampleIndex)
|
|
error("File %s is corrupt", SAMPLE_FILE);
|
|
|
|
// read the length of the sample
|
|
uint32 sampleLen = _sampleStream.readUint32LE();
|
|
if (_sampleStream.ioFailed())
|
|
error("File %s is corrupt", SAMPLE_FILE);
|
|
|
|
// allocate a buffer
|
|
void *sampleBuf = malloc(sampleLen);
|
|
assert(sampleBuf);
|
|
|
|
// read all of the sample
|
|
if (_sampleStream.read(sampleBuf, sampleLen) != sampleLen)
|
|
error("File %s is corrupt", SAMPLE_FILE);
|
|
|
|
// FIXME: Should set this in a different place ;)
|
|
_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volSound);
|
|
//_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic);
|
|
_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volVoice);
|
|
|
|
|
|
// play it
|
|
_vm->_mixer->playRaw(type, &_handle, sampleBuf, sampleLen, 22050,
|
|
Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED);
|
|
|
|
if (handle)
|
|
*handle = _handle;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns TRUE if there is a sample for the specified sample identifier.
|
|
* @param id Identifier of sample to be checked
|
|
*/
|
|
bool SoundManager::sampleExists(int id) {
|
|
if (_vm->_mixer->isReady()) {
|
|
// make sure id is in range
|
|
if (id > 0 && id < _sampleIndexLen) {
|
|
// check for a sample index
|
|
if (_sampleIndex[id])
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// no sample driver or no sample
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if a sample is currently playing.
|
|
*/
|
|
bool SoundManager::sampleIsPlaying(void) {
|
|
return _vm->_mixer->isSoundHandleActive(_handle);
|
|
}
|
|
|
|
/**
|
|
* Stops any currently playing sample.
|
|
*/
|
|
void SoundManager::stopAllSamples(void) {
|
|
// stop currently playing sample
|
|
_vm->_mixer->stopHandle(_handle);
|
|
}
|
|
|
|
/**
|
|
* Opens and inits all sound sample files.
|
|
*/
|
|
void SoundManager::openSampleFiles(void) {
|
|
// Floppy and demo versions have no sample files
|
|
if (_vm->getFeatures() & GF_FLOPPY || _vm->getFeatures() & GF_DEMO)
|
|
return;
|
|
|
|
Common::File f;
|
|
|
|
if (_sampleIndex)
|
|
// already allocated
|
|
return;
|
|
|
|
// open sample index file in binary mode
|
|
if (f.open(SAMPLE_INDEX)) {
|
|
// get length of index file
|
|
f.seek(0, SEEK_END); // move to end of file
|
|
_sampleIndexLen = f.pos(); // get file pointer
|
|
f.seek(0, SEEK_SET); // back to beginning
|
|
|
|
if (_sampleIndex == NULL) {
|
|
// allocate a buffer for the indices
|
|
_sampleIndex = (int32 *)malloc(_sampleIndexLen);
|
|
|
|
// make sure memory allocated
|
|
if (_sampleIndex == NULL) {
|
|
// disable samples if cannot alloc buffer for indices
|
|
// TODO: Disabled sound if we can't load the sample index?
|
|
return;
|
|
}
|
|
}
|
|
|
|
// load data
|
|
if (f.read(_sampleIndex, _sampleIndexLen) != (uint32)_sampleIndexLen)
|
|
// file must be corrupt if we get to here
|
|
error("File %s is corrupt", SAMPLE_FILE);
|
|
|
|
#ifdef SCUMM_BIG_ENDIAN
|
|
// Convert all ids from LE to native format
|
|
for (uint i = 0; i < _sampleIndexLen / sizeof(uint32); ++i) {
|
|
_sampleIndex[i] = READ_LE_UINT32(_sampleIndex + i);
|
|
}
|
|
#endif
|
|
|
|
// close the file
|
|
f.close();
|
|
|
|
// convert file size to size in DWORDs
|
|
_sampleIndexLen /= sizeof(uint32);
|
|
} else
|
|
error("Cannot find file %s", SAMPLE_INDEX);
|
|
|
|
// open sample file in binary mode
|
|
if (!_sampleStream.open(SAMPLE_FILE))
|
|
error("Cannot find file %s", SAMPLE_FILE);
|
|
|
|
/*
|
|
// gen length of the largest sample
|
|
sampleBuffer.size = _sampleStream.readUint32LE();
|
|
if (_sampleStream.ioFailed())
|
|
error("File %s is corrupt", SAMPLE_FILE);
|
|
*/
|
|
}
|
|
|
|
} // end of namespace Tinsel
|