Beispiel #1
0
int32 Sound::playCompSpeech(uint32 speechId, uint8 vol, int8 pan) {
	if (_speechMuted)
		return RD_OK;

	if (getSpeechStatus() == RDERR_SPEECHPLAYING)
		return RDERR_SPEECHPLAYING;

	int cd = _vm->_resman->getCD();
	SoundFileHandle *fh = (cd == 1) ? &_speechFile[0] : &_speechFile[1];

	Audio::AudioStream *input = getAudioStream(fh, "speech", cd, speechId, NULL);

	if (!input)
		return RDERR_INVALIDID;

	// Modify the volume according to the master volume

	byte volume = _speechMuted ? 0 : vol * Audio::Mixer::kMaxChannelVolume / 16;
	int8 p = (pan * 127) / 16;

	if (isReverseStereo())
		p = -p;

	// Start the speech playing
	_vm->_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandleSpeech, input, -1, volume, p);
	return RD_OK;
}
Beispiel #2
0
void Sound::playMovieSound(int32 res, int type) {
	Audio::SoundHandle *handle;

	if (type == kLeadInSound)
		handle = &_leadInHandle;
	else
		handle = &_leadOutHandle;

	if (_vm->_mixer->isSoundHandleActive(*handle)) {
		_vm->_mixer->stopHandle(*handle);
	}

	byte *data = _vm->_resman->openResource(res);
	uint32 len = _vm->_resman->fetchLen(res);

	assert(_vm->_resman->fetchType(data) == WAV_FILE);

	// We want to close the resource right away, so to be safe we make a
	// private copy of the sound;
	byte *soundData = (byte *)malloc(len);

	if (soundData) {
		memcpy(soundData, data, len);

		Common::MemoryReadStream *stream = new Common::MemoryReadStream(soundData, len, DisposeAfterUse::YES);

		// In PSX version we have nothing to skip here, as data starts
		// right away.
		if (!Sword2Engine::isPsx()) {
			stream->seek(ResHeader::size());
		}

		Audio::RewindableAudioStream *input = 0;

		if (Sword2Engine::isPsx()) {
			input = Audio::makeVagStream(stream);
		} else {
			input = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
		}

		_vm->_mixer->playStream(
			Audio::Mixer::kMusicSoundType, handle, input,
			-1, Audio::Mixer::kMaxChannelVolume, 0,
			DisposeAfterUse::YES, false, isReverseStereo());
	} else {
		warning("Sound::playMovieSound: Could not allocate %d bytes\n", len);
	}

	_vm->_resman->closeResource(res);
}
Beispiel #3
0
int32 Sound::setFxIdVolumePan(int32 id, int vol, int pan) {
	if (!_fxQueue[id].resource)
		return RDERR_FXNOTOPEN;

	if (vol > 16)
		vol = 16;

	_fxQueue[id].volume = (vol * Audio::Mixer::kMaxChannelVolume) / 16;

	if (pan != 255) {
		if (isReverseStereo())
			pan = -pan;
		_fxQueue[id].pan = (pan * 127) / 16;
	}

	if (!_fxMuted && _vm->_mixer->isSoundHandleActive(_fxQueue[id].handle)) {
		_vm->_mixer->setChannelVolume(_fxQueue[id].handle, _fxQueue[id].volume);
		if (pan != -1)
			_vm->_mixer->setChannelBalance(_fxQueue[id].handle, _fxQueue[id].pan);
	}

	return RD_OK;
}
Beispiel #4
0
int32 Sound::playFx(Audio::SoundHandle *handle, byte *data, uint32 len, uint8 vol, int8 pan, bool loop, Audio::Mixer::SoundType soundType) {
	if (_fxMuted)
		return RD_OK;

	if (_vm->_mixer->isSoundHandleActive(*handle))
		return RDERR_FXALREADYOPEN;

	Common::MemoryReadStream *stream = new Common::MemoryReadStream(data, len);
	Audio::RewindableAudioStream *input = 0;

	if (Sword2Engine::isPsx())
		input = Audio::makeVagStream(stream);
	else
		input = Audio::makeWAVStream(stream, DisposeAfterUse::YES);

	assert(input);

	_vm->_mixer->playStream(soundType, handle,
	                             Audio::makeLoopingAudioStream(input, loop ? 0 : 1),
	                             -1, vol, pan, DisposeAfterUse::YES, false, isReverseStereo());

	return RD_OK;
}
Beispiel #5
0
void Sound::queueFx(int32 res, int32 type, int32 delay, int32 volume, int32 pan) {
	if (_vm->_wantSfxDebug) {
		const char *typeStr;

		switch (type) {
		case FX_SPOT:
			typeStr = "SPOT";
			break;
		case FX_LOOP:
			typeStr = "LOOPED";
			break;
		case FX_RANDOM:
			typeStr = "RANDOM";
			break;
		default:
			typeStr = "INVALID";
			break;
		}

		debug(0, "SFX (sample=\"%s\", vol=%d, pan=%d, delay=%d, type=%s)", _vm->_resman->fetchName(res), volume, pan, delay, typeStr);
	}

	for (int i = 0; i < FXQ_LENGTH; i++) {
		if (!_fxQueue[i].resource) {
			byte *data = _vm->_resman->openResource(res);

			// Check that we really have a WAV file here, alas this
			// check is useless with psx demo game, because psx audio files
			// are headerless and there is no way to check the type
			if (!(Sword2Engine::isPsx() && (_vm->_features & GF_DEMO)))
				assert(_vm->_resman->fetchType(data) == WAV_FILE);

			uint32 len = _vm->_resman->fetchLen(res);

			// Skip the header if using PC version
			if (!Sword2Engine::isPsx())
				len -= ResHeader::size();

			if (type == FX_RANDOM) {
				// For spot effects and loops the delay is the
				// number of frames to wait. For random
				// effects, however, it's the average number of
				// seconds between playing the sound, so we
				// have to multiply by the frame rate.
				delay *= FRAMES_PER_SECOND;
			}

			volume = (volume * Audio::Mixer::kMaxChannelVolume) / 16;
			pan = (pan * 127) / 16;

			if (isReverseStereo())
				pan = -pan;

			_fxQueue[i].resource = res;

			if (Sword2Engine::isPsx())
				_fxQueue[i].data = data;
			else
				_fxQueue[i].data = data + ResHeader::size();

			_fxQueue[i].len = len;
			_fxQueue[i].delay = delay;
			_fxQueue[i].volume = volume;
			_fxQueue[i].pan = pan;
			_fxQueue[i].type = type;

			// Keep track of the index in the loop so that
			// fnStopFx() can be used later to kill this sound.
			// Mainly for FX_LOOP and FX_RANDOM.

			_vm->_logic->writeVar(RESULT, i);
			return;
		}
	}

	warning("No free slot in FX queue");
}