mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
474 lines
12 KiB
C++
474 lines
12 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifndef TITANIC_SOUND_MANAGER_H
|
|
#define TITANIC_SOUND_MANAGER_H
|
|
|
|
#include "titanic/core/list.h"
|
|
#include "titanic/support/simple_file.h"
|
|
#include "titanic/sound/audio_buffer.h"
|
|
#include "titanic/sound/proximity.h"
|
|
#include "titanic/sound/qmixer.h"
|
|
#include "titanic/sound/wave_file.h"
|
|
#include "titanic/true_talk/dialogue_file.h"
|
|
|
|
namespace Titanic {
|
|
|
|
enum VolumeMode {
|
|
VOL_NORMAL = -1, VOL_QUIET = -2, VOL_VERY_QUIET = -3, VOL_MUTE = -4
|
|
};
|
|
|
|
/**
|
|
* Abstract interface class for a sound manager
|
|
*/
|
|
class CSoundManager {
|
|
protected:
|
|
uint _handleCtr;
|
|
// Old volume levels, deprecated in favor of setting the volumes
|
|
// directly in the ScummVM mixer
|
|
double _musicPercent;
|
|
double _speechPercent;
|
|
double _masterPercent;
|
|
double _parrotPercent;
|
|
public:
|
|
CSoundManager();
|
|
virtual ~CSoundManager() {}
|
|
|
|
/**
|
|
* Loads a sound
|
|
* @param name Name of sound resource
|
|
* @returns Loaded wave file
|
|
*/
|
|
virtual CWaveFile *loadSound(const CString &name) { return nullptr; }
|
|
|
|
/**
|
|
* Loads a speech resource from a dialogue file
|
|
* @param name Name of sound resource
|
|
* @returns Loaded wave file
|
|
*/
|
|
virtual CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId) { return 0; }
|
|
|
|
/**
|
|
* Loads a music file
|
|
* @param name Name of music resource
|
|
* @returns Loaded wave file
|
|
* @remarks The original only classified music as what's produced in the
|
|
* music room puzzle. For ScummVM, we've reclassified some wave files that
|
|
* contain background music as music as well.
|
|
*/
|
|
virtual CWaveFile *loadMusic(const CString &name) { return nullptr; }
|
|
|
|
/**
|
|
* Loads a music file from a streaming audio buffer
|
|
* @param buffer Audio buffer
|
|
* @returns Loaded wave file
|
|
*/
|
|
virtual CWaveFile *loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse) { return nullptr; }
|
|
|
|
/**
|
|
* Start playing a previously loaded wave file
|
|
*/
|
|
virtual int playSound(CWaveFile &waveFile, CProximity &prox) = 0;
|
|
|
|
/**
|
|
* Stop playing the specified sound
|
|
*/
|
|
virtual void stopSound(int handle) = 0;
|
|
|
|
/**
|
|
* Stops a designated range of channels
|
|
*/
|
|
virtual void stopChannel(int channel) = 0;
|
|
|
|
virtual void proc9(int handle) {}
|
|
|
|
/**
|
|
* Stops sounds on all playing channels
|
|
*/
|
|
virtual void stopAllChannels() = 0;
|
|
|
|
/**
|
|
* Sets the volume for a sound
|
|
* @param handle Handle for sound
|
|
* @param volume New volume
|
|
* @param seconds Number of seconds to transition to the new volume
|
|
*/
|
|
virtual void setVolume(int handle, uint volume, uint seconds) = 0;
|
|
|
|
/**
|
|
* Set the position for a sound
|
|
* @param handle Handle for sound
|
|
* @param x x position in metres
|
|
* @param y y position in metres
|
|
* @param z z position in metres
|
|
* @param panRate Rate in milliseconds to transition
|
|
*/
|
|
virtual void setVectorPosition(int handle, double x, double y, double z, uint panRate) {}
|
|
|
|
/**
|
|
* Set the position for a sound
|
|
* @param handle Handle for sound
|
|
* @param range Range value in metres
|
|
* @param azimuth Azimuth value in degrees
|
|
* @param elevation Elevation value in degrees
|
|
* @param panRate Rate in milliseconds to transition
|
|
*/
|
|
virtual void setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) {}
|
|
|
|
/**
|
|
* Returns true if the given sound is currently active
|
|
*/
|
|
virtual bool isActive(int handle) = 0;
|
|
|
|
/**
|
|
* Returns true if the given sound is currently active
|
|
*/
|
|
virtual bool isActive(const CWaveFile *waveFile) { return false; }
|
|
|
|
/**
|
|
* Handles regularly updating the mixer
|
|
*/
|
|
virtual void waveMixPump() = 0;
|
|
|
|
/**
|
|
* Returns the movie latency
|
|
*/
|
|
virtual uint getLatency() const { return 0; }
|
|
|
|
/**
|
|
* Sets the music volume percent
|
|
*/
|
|
virtual void setMusicPercent(double percent) = 0;
|
|
|
|
/**
|
|
* Sets the speech volume percent
|
|
*/
|
|
virtual void setSpeechPercent(double percent) = 0;
|
|
|
|
/**
|
|
* Sets the master volume percent
|
|
*/
|
|
virtual void setMasterPercent(double percent) = 0;
|
|
|
|
/**
|
|
* Sets the Parrot NPC volume percent
|
|
*/
|
|
virtual void setParrotPercent(double percent) = 0;
|
|
|
|
/**
|
|
* Called when a game is about to be loaded
|
|
*/
|
|
virtual void preLoad() { stopAllChannels(); }
|
|
|
|
/**
|
|
* Load the data for the class from file
|
|
*/
|
|
void load(SimpleFile *file) {}
|
|
|
|
/**
|
|
* Called after loading of a game is completed
|
|
*/
|
|
virtual void postLoad() {}
|
|
|
|
/**
|
|
* Called when a game is about to be saved
|
|
*/
|
|
virtual void preSave() {}
|
|
|
|
/**
|
|
* Save the data for the class to file
|
|
*/
|
|
void save(SimpleFile *file) const {}
|
|
|
|
/**
|
|
* Called after saving is complete
|
|
*/
|
|
virtual void postSave() {}
|
|
|
|
/**
|
|
* Sets the position and orientation for the listener (player)
|
|
*/
|
|
virtual void setListenerPosition(double posX, double posY, double posZ,
|
|
double directionX, double directionY, double directionZ, bool stopSounds) {}
|
|
|
|
/**
|
|
* Returns the music volume percent
|
|
*/
|
|
double getMusicVolume() const { return _musicPercent; }
|
|
|
|
/**
|
|
* Returns the speech volume percent
|
|
*/
|
|
double getSpeechVolume() const { return _speechPercent; }
|
|
|
|
/**
|
|
* Returns the parrot volume percent
|
|
*/
|
|
double getParrotVolume() const { return _parrotPercent; }
|
|
|
|
/**
|
|
* Gets the volume for a given mode? value
|
|
*/
|
|
uint getModeVolume(VolumeMode mode);
|
|
};
|
|
|
|
class QSoundManagerSound : public ListItem {
|
|
public:
|
|
CWaveFile *_waveFile;
|
|
int _iChannel;
|
|
CEndTalkerFn _endFn;
|
|
TTtalker *_talker;
|
|
public:
|
|
QSoundManagerSound() : ListItem(), _waveFile(nullptr),
|
|
_iChannel(0), _endFn(nullptr), _talker(nullptr) {}
|
|
QSoundManagerSound(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker) :
|
|
ListItem(), _waveFile(waveFile), _iChannel(iChannel), _endFn(endFn), _talker(talker) {}
|
|
};
|
|
|
|
class QSoundManagerSounds : public List<QSoundManagerSound> {
|
|
public:
|
|
/**
|
|
* Adds a new sound entry to the list
|
|
*/
|
|
void add(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker);
|
|
|
|
/**
|
|
* Flushes a wave file attached to the specified channel
|
|
*/
|
|
void flushChannel(int iChannel);
|
|
|
|
/**
|
|
* Flushes a wave file attached to the specified channel
|
|
*/
|
|
void flushChannel(CWaveFile *waveFile, int iChannel);
|
|
|
|
/**
|
|
* Returns true if the list contains the specified wave file
|
|
*/
|
|
bool contains(const CWaveFile *waveFile) const;
|
|
};
|
|
|
|
/**
|
|
* Concrete sound manager class that handles interfacing with
|
|
* the QMixer sound mixer class
|
|
*/
|
|
class QSoundManager : public CSoundManager, public QMixer {
|
|
struct Slot {
|
|
CWaveFile *_waveFile;
|
|
bool _isTimed;
|
|
uint _ticks;
|
|
int _channel;
|
|
int _handle;
|
|
PositioningMode _positioningMode;
|
|
|
|
Slot() : _waveFile(0), _isTimed(0), _ticks(0), _channel(-1),
|
|
_handle(0), _positioningMode(POSMODE_NONE) {}
|
|
void clear();
|
|
};
|
|
private:
|
|
QSoundManagerSounds _sounds;
|
|
Common::Array<Slot> _slots;
|
|
uint _channelsVolume[16];
|
|
int _channelsMode[16];
|
|
private:
|
|
/**
|
|
* Updates the volume for a channel
|
|
* @param channel Channel to be update
|
|
* @param panRate Time in milliseconds for change to occur
|
|
*/
|
|
void updateVolume(int channel, uint panRate);
|
|
|
|
/**
|
|
* Updates all the volumes
|
|
*/
|
|
void updateVolumes();
|
|
|
|
/**
|
|
* Called by the QMixer when a sound finishes playing
|
|
*/
|
|
static void soundFinished(int iChannel, CWaveFile *waveFile, void *soundManager);
|
|
|
|
/**
|
|
* Finds the first free slot
|
|
*/
|
|
int findFreeSlot();
|
|
|
|
/**
|
|
* Sets a channel volume
|
|
*/
|
|
void setChannelVolume(int iChannel, uint volume, uint mode);
|
|
|
|
/**
|
|
* Resets the specified channel and returns a new free one
|
|
*/
|
|
int resetChannel(int iChannel);
|
|
public:
|
|
int _field18;
|
|
int _field1C;
|
|
|
|
public:
|
|
QSoundManager(Audio::Mixer *mixer);
|
|
~QSoundManager() override;
|
|
|
|
/**
|
|
* Loads a sound
|
|
* @param name Name of sound resource
|
|
* @returns Loaded wave file
|
|
*/
|
|
CWaveFile *loadSound(const CString &name) override;
|
|
|
|
/**
|
|
* Loads a speech resource from a dialogue file
|
|
* @param name Name of sound resource
|
|
* @returns Loaded wave file
|
|
*/
|
|
CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId) override;
|
|
|
|
/**
|
|
* Loads a music file
|
|
* @param name Name of music resource
|
|
* @returns Loaded wave file
|
|
* @remarks The original only classified music as what's produced in the
|
|
* music room puzzle. For ScummVM, we've reclassified some wave files that
|
|
* contain background music as music as well.
|
|
*/
|
|
CWaveFile *loadMusic(const CString &name) override;
|
|
|
|
/**
|
|
* Loads a music file from a streaming audio buffer
|
|
* @param buffer Audio buffer
|
|
* @returns Loaded wave file
|
|
*/
|
|
CWaveFile *loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse) override;
|
|
|
|
/**
|
|
* Start playing a previously loaded sound resource
|
|
*/
|
|
int playSound(CWaveFile &waveFile, CProximity &prox) override;
|
|
|
|
/**
|
|
* Stop playing the specified sound
|
|
*/
|
|
void stopSound(int handle) override;
|
|
|
|
/**
|
|
* Stops a designated range of channels
|
|
*/
|
|
void stopChannel(int channel) override;
|
|
|
|
/**
|
|
* Flags that a sound can be freed if a timeout is set
|
|
*/
|
|
virtual void setCanFree(int handle);
|
|
|
|
/**
|
|
* Stops sounds on all playing channels
|
|
*/
|
|
void stopAllChannels() override;
|
|
|
|
/**
|
|
* Sets the volume for a sound
|
|
* @param handle Handle for sound
|
|
* @param volume New volume
|
|
* @param seconds Number of seconds to transition to the new volume
|
|
*/
|
|
void setVolume(int handle, uint volume, uint seconds) override;
|
|
|
|
/**
|
|
* Set the position for a sound
|
|
* @param handle Handle for sound
|
|
* @param x x position in metres
|
|
* @param y y position in metres
|
|
* @param z z position in metres
|
|
* @param panRate Rate in milliseconds to transition
|
|
*/
|
|
void setVectorPosition(int handle, double x, double y, double z, uint panRate) override;
|
|
|
|
/**
|
|
* Set the position for a sound
|
|
* @param handle Handle for sound
|
|
* @param range Range value in metres
|
|
* @param azimuth Azimuth value in degrees
|
|
* @param elevation Elevation value in degrees
|
|
* @param panRate Rate in milliseconds to transition
|
|
*/
|
|
void setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) override;
|
|
|
|
/**
|
|
* Returns true if the given sound is currently active
|
|
*/
|
|
bool isActive(int handle) override;
|
|
|
|
/**
|
|
* Returns true if the given sound is currently active
|
|
*/
|
|
bool isActive(const CWaveFile *waveFile) override;
|
|
|
|
/**
|
|
* Handles regularly updating the mixer
|
|
*/
|
|
void waveMixPump() override;
|
|
|
|
/**
|
|
* Returns the movie latency
|
|
*/
|
|
uint getLatency() const override;
|
|
|
|
/**
|
|
* Sets the music volume percent
|
|
*/
|
|
void setMusicPercent(double percent) override;
|
|
|
|
/**
|
|
* Sets the speech volume percent
|
|
*/
|
|
void setSpeechPercent(double percent) override;
|
|
|
|
/**
|
|
* Sets the master volume percent
|
|
*/
|
|
void setMasterPercent(double percent) override;
|
|
|
|
/**
|
|
* Sets the Parrot NPC volume percent
|
|
*/
|
|
void setParrotPercent(double percent) override;
|
|
|
|
/**
|
|
* Sets the position and orientation for the listener (player)
|
|
*/
|
|
void setListenerPosition(double posX, double posY, double posZ,
|
|
double directionX, double directionY, double directionZ, bool stopSounds) override;
|
|
|
|
/**
|
|
* Starts a wave file playing
|
|
*/
|
|
virtual int playWave(CWaveFile *waveFile, int iChannel, uint flags, CProximity &prox);
|
|
|
|
/**
|
|
* Called when a wave file is freed
|
|
*/
|
|
void soundFreed(Audio::SoundHandle &handle);
|
|
};
|
|
|
|
} // End of namespace Titanic
|
|
|
|
#endif /* TITANIC_QSOUND_MANAGER_H */
|