XPMP2
X-Plane multiplayer library 2 - using instancing
Sound.h
Go to the documentation of this file.
1 
22 #pragma once
23 
24 namespace XPMP2 {
25 
26 //
27 // MARK: FMOD Error Handling
28 //
29 
31 class FmodError : public std::runtime_error
32 {
33 public:
34  FMOD_RESULT fmodRes;
35  std::string sFile;
36  int ln;
37  std::string sFunc;
38 public:
40  FmodError (const std::string& _what, FMOD_RESULT _r,
41  const std::string& _file,
42  int _ln, const std::string& _sFunc) :
43  std::runtime_error(leftOf(_what,"( ")), // takes over the name of the function called, but not all the parameter string
44  fmodRes(_r), sFile(_file), ln(_ln), sFunc(_sFunc)
45  {}
46 
48  void LogErr () const {
49  LogMsg(sFile.c_str(), ln, sFunc.c_str(), logERR,
50 #if INCLUDE_FMOD_SOUND + 0 >= 1
51  "FMOD Error %d - '%s' in %s", fmodRes,
52  FMOD_ErrorString(fmodRes),
53 #else
54  "FMOD Error %d in %s", fmodRes,
55 #endif
56  what());
57  }
58 };
59 
61 extern FMOD_RESULT gFmodRes;
62 
64 #define FMOD_TEST(fmodCall) { \
65  if ((gFmodRes = (fmodCall)) != FMOD_OK) \
66  throw FmodError(#fmodCall, gFmodRes, __FILE__, __LINE__, __func__); \
67 }
68 
70 #define FMOD_CATCH catch (const FmodError& e) { e.LogErr(); }
71 
73 #define FMOD_LOG(fmodCall) { \
74  if ((XPMP2::gFmodRes = (fmodCall)) != FMOD_OK) \
75  XPMP2::FmodError(#fmodCall, XPMP2::gFmodRes, __FILE__, __LINE__, __func__).LogErr(); \
76 }
77 
78 //
79 // MARK: Sound Files
80 //
81 
82 class SoundSystem;
83 
87 FMOD_VECTOR FmodHeadPitch2Vec (const float head, const float pitch);
88 
92 void FmodHeadPitchRoll2Normal(const float head, const float pitch, const float roll,
93  FMOD_VECTOR& vecDir, FMOD_VECTOR& vecNorm);
94 
97 void FmodNormalizeHeadingPitch(float& head, float& pitch);
98 
101 class SoundFile {
102 public:
103  SoundSystem* pSndSys = nullptr;
104  std::string filePath;
105  bool bLoop = true;
106 
107  // 3D Cone information, to be applied to the channel later when playing the sound
108  float coneDir = NAN;
109  float conePitch = NAN;
110  float coneInAngle = NAN;
111  float coneOutAngle = NAN;
112  float coneOutVol = NAN;
113 
114 public:
117  SoundFile (SoundSystem* _pSndSys,
118  const std::string& _filePath, bool _bLoop,
119  float _coneDir, float _conePitch,
120  float _coneInAngle, float _coneOutAngle, float _coneOutVol);
121 
123  virtual ~SoundFile () {}
124 
126  SoundFile (const SoundFile& o) = delete;
127 
129  bool hasConeInfo () const
130  {
131  return
132  !std::isnan(coneDir) &&
133  !std::isnan(conePitch) &&
134  !std::isnan(coneInAngle) &&
135  !std::isnan(coneOutAngle) &&
136  !std::isnan(coneOutVol);
137  }
138 
140  virtual bool isReady () = 0;
141 };
142 
144 typedef std::unique_ptr<SoundFile> SoundFilePtr;
146 typedef std::map<std::string,SoundFilePtr> mapSoundPtrTy;
147 
149 class SoundWAV : public SoundFile {
150 public:
151  int16_t* pBuf = nullptr;
152  uint32_t bufferSize = 0;
153  int freqHz = 0;
154  int numChannels = 0;
155 
156 public:
158  SoundWAV (SoundSystem* _pSndSys,
159  const std::string& _filePath, bool _bLoop,
160  float _coneDir, float _conePitch,
161  float _coneInAngle, float _coneOutAngle, float _coneOutVol);
162 
164  ~SoundWAV() override;
165 
167  bool isReady () override { return true; }
168 
169 protected:
171  void WavRead ();
172 };
173 
174 //
175 // MARK: Sound System
176 //
177 
180 public:
181  FMOD_CHANNEL* pChn = nullptr;
182  SoundFile* pSnd = nullptr;
183  float vol = 1.0f;
184  bool bMuted = false;
185  int nPauseCountdown = 2;
186 public:
190  SoundChannel (FMOD_CHANNEL* c, SoundFile* s, float v) : pChn(c), pSnd(s), vol(v) {}
192  operator bool () const { return pChn && pSnd; }
194  bool ShallUnpause () { return nPauseCountdown > 0 ? (--nPauseCountdown == 0) : false; }
195 };
196 
198 class SoundSystem {
199 protected:
203  std::map<uint64_t,SoundChannel> mapChn;
204 private:
206  uint64_t uNxtId = 0;
208  uint64_t cacheSndId = 0;
209  SoundChannel* pCacheChn = nullptr;
210 
211 public:
215  virtual ~SoundSystem() {}
216 
218  virtual bool LoadSoundFile (const std::string& _sndName,
219  const std::string& _filePath, bool _bLoop,
220  float _coneDir, float _conePitch,
221  float _coneInAngle, float _coneOutAngle, float _coneOutVol) = 0;
223  const char* EnumerateSounds (const char* prevName, const char** ppFilePath);
224 
226  virtual uint64_t Play (const std::string& sndName, float vol, const Aircraft& ac) = 0;
228  virtual void Unpause (uint64_t sndId) = 0;
230  virtual void Stop (uint64_t sndId) = 0;
232  virtual void SetPosOrientation (uint64_t sndId, const Aircraft& ac, bool bDoOrientation) = 0;
234  virtual void SetVolume (uint64_t sndId, float vol) = 0;
236  virtual void SetMute (uint64_t sndId, bool bMute) = 0;
237 
239  virtual void Update () = 0;
240 
242  virtual void SetMasterVolume (float volMaster) = 0;
244  virtual void SetAllMute (bool bMute) = 0;
245 
247  virtual bool IsValid (uint64_t sndId);
248 
249 protected:
251  std::pair<uint64_t,SoundChannel*> AddChn (SoundFile* pSnd, float vol, FMOD_CHANNEL* pChn = nullptr);
253  SoundChannel* GetChn (uint64_t sndId);
255  void RemoveChn (uint64_t sndId);
256 };
257 
259 extern SoundSystem* gpSndSys;
260 
261 
266 class SoundSystemXP : public SoundSystem {
267 protected:
268  float volMaster = 1.0f;
269  bool bAllMuted = false;
270 public:
272  SoundSystemXP();
274  ~SoundSystemXP() override {}
275 
278  bool LoadSoundFile (const std::string& _sndName,
279  const std::string& _filePath, bool _bLoop,
280  float _coneDir, float _conePitch,
281  float _coneInAngle, float _coneOutAngle, float _coneOutVol) override;
282 
284  uint64_t Play (const std::string& sndName, float vol, const Aircraft& ac) override;
286  void Unpause (uint64_t sndId) override;
288  void Stop (uint64_t sndId) override;
290  void SetPosOrientation (uint64_t sndId, const Aircraft& ac, bool bDoOrientation) override;
292  void SetVolume (uint64_t sndId, float vol) override;
294  void SetMute (uint64_t sndId, bool bMute) override;
295 
297  void Update () override {}
298 
300  void SetMasterVolume (float volMaster) override;
302  void SetAllMute (bool bMute) override;
303 
304 protected:
306  static void PlayCallback (void* inRefcon,
307  FMOD_RESULT status);
309  void ChnSetVol (const SoundChannel& chn);
311  void AllChnSetVol ();
312 };
313 
314 //
315 // MARK: Global Functions
316 //
317 
319 void SoundInit ();
320 
322 void SoundUpdatesBegin();
323 
325 void SoundUpdatesDone ();
326 
328 void SoundCleanup ();
329 
330 }
Actual representation of all aircraft in XPMP2.
Definition: XPMPAircraft.h:178
Exception class to pass on error information.
Definition: Sound.h:32
int ln
line number here in the code
Definition: Sound.h:36
void LogErr() const
Log myself to Log.txt as an error.
Definition: Sound.h:48
FMOD_RESULT fmodRes
the actual FMOD result code
Definition: Sound.h:34
FmodError(const std::string &_what, FMOD_RESULT _r, const std::string &_file, int _ln, const std::string &_sFunc)
Constructor taking on a descriptive string and the FMOD_RESULT
Definition: Sound.h:40
std::string sFunc
name of the function the error occurred in
Definition: Sound.h:37
std::string sFile
file path of code file
Definition: Sound.h:35
A sound object being played, called channel.
Definition: Sound.h:179
SoundChannel()
Default Constructor creates an invalid object.
Definition: Sound.h:188
FMOD_CHANNEL * pChn
the actual sound channel
Definition: Sound.h:181
bool bMuted
currently muted?
Definition: Sound.h:184
SoundFile * pSnd
the sound file the sound was created from
Definition: Sound.h:182
int nPauseCountdown
frame till unpause this sound (starts paused to avoid crackling)
Definition: Sound.h:185
SoundChannel(FMOD_CHANNEL *c, SoundFile *s, float v)
Constructor.
Definition: Sound.h:190
bool ShallUnpause()
Need to unpause now? (returns true only once when countdown reaches zero)
Definition: Sound.h:194
float vol
volume (if not muted)
Definition: Sound.h:183
Represents a sound file.
Definition: Sound.h:101
SoundFile(SoundSystem *_pSndSys, const std::string &_filePath, bool _bLoop, float _coneDir, float _conePitch, float _coneInAngle, float _coneOutAngle, float _coneOutVol)
Construct a sound object from a file name and have it loaded asynchonously.
Definition: Sound.cpp:130
float coneOutVol
Cone outside volume.
Definition: Sound.h:112
float conePitch
Which pitch does the cone point to (up/down)? (0 would be typical, ie. level with the plane)
Definition: Sound.h:109
SoundSystem * pSndSys
Sound system for which this object was created.
Definition: Sound.h:103
std::string filePath
File path to sound file.
Definition: Sound.h:104
SoundFile(const SoundFile &o)=delete
Copying is not permitted.
bool hasConeInfo() const
Has full cone information?
Definition: Sound.h:129
virtual ~SoundFile()
Make sure destructor is virtual.
Definition: Sound.h:123
bool bLoop
sound to be played in a loop?
Definition: Sound.h:105
float coneDir
Which direction relative to plane's heading does the cone point to? (180 would be typical for jet eng...
Definition: Sound.h:108
float coneOutAngle
Outside cone angle. This is the angle spread outside of which the sound is attenuated to its SoundFil...
Definition: Sound.h:111
float coneInAngle
Inside cone angle. This is the angle spread within which the sound is unattenuated.
Definition: Sound.h:110
virtual bool isReady()=0
Ready to play?
Encapsulates the XP12 Sound System.
Definition: Sound.h:266
uint64_t Play(const std::string &sndName, float vol, const Aircraft &ac) override
Play a new sound, returns an id for that sound.
Definition: Sound.cpp:465
bool LoadSoundFile(const std::string &_sndName, const std::string &_filePath, bool _bLoop, float _coneDir, float _conePitch, float _coneInAngle, float _coneOutAngle, float _coneOutVol) override
Loads a sound file so it becomes ready to play.
Definition: Sound.cpp:434
void SetMute(uint64_t sndId, bool bMute) override
Mute the sound (temporarily)
Definition: Sound.cpp:615
void SetAllMute(bool bMute) override
Mute all sounds (temporarily)
Definition: Sound.cpp:633
~SoundSystemXP() override
Destructor.
Definition: Sound.h:274
void Unpause(uint64_t sndId) override
Unpause a sound, which got started in a paused state to avoid crackling.
Definition: Sound.cpp:544
SoundSystemXP()
Construtor, throws exception if XP sound system unavailable (prior to XP12.04)
Definition: Sound.cpp:426
void SetVolume(uint64_t sndId, float vol) override
Set sound's volume.
Definition: Sound.cpp:605
void SetMasterVolume(float volMaster) override
Set Master Volume, effectively a multiplicator to SetVolume()
Definition: Sound.cpp:625
void ChnSetVol(const SoundChannel &chn)
Update an individual channel's volume.
Definition: Sound.cpp:640
void AllChnSetVol()
Update all channels' volume.
Definition: Sound.cpp:648
void Update() override
Any updates to be done at the end of the frame (not for XP system)
Definition: Sound.h:297
static void PlayCallback(void *inRefcon, FMOD_RESULT status)
Callback required by XPLMPlayPCMOnBus.
Definition: Sound.cpp:518
float volMaster
Master volume, effectively a multiplicator for individual volume.
Definition: Sound.h:268
void SetPosOrientation(uint64_t sndId, const Aircraft &ac, bool bDoOrientation) override
Update sound's position and orientation.
Definition: Sound.cpp:573
bool bAllMuted
All sounds (temporarily) muted?
Definition: Sound.h:269
void Stop(uint64_t sndId) override
Stop the sound.
Definition: Sound.cpp:558
Base class for sound systems, practically empty.
Definition: Sound.h:198
virtual bool IsValid(uint64_t sndId)
Is the sound id available?
Definition: Sound.cpp:382
virtual void SetMasterVolume(float volMaster)=0
Set Master Volume, effectively a multiplicator to SetVolume()
virtual bool LoadSoundFile(const std::string &_sndName, const std::string &_filePath, bool _bLoop, float _coneDir, float _conePitch, float _coneInAngle, float _coneOutAngle, float _coneOutVol)=0
Loads a sound file so it becomes ready to play.
virtual ~SoundSystem()
Destructor.
Definition: Sound.h:215
std::map< uint64_t, SoundChannel > mapChn
Keeps track of currently playing sounds, their key serving as id.
Definition: Sound.h:203
mapSoundPtrTy mapSounds
Map of all sounds, indexed by a sound name (type)
Definition: Sound.h:201
virtual void Unpause(uint64_t sndId)=0
Unpause a sound, which got started in a paused state to avoid crackling.
void RemoveChn(uint64_t sndId)
Remove a channel from out tracking.
Definition: Sound.cpp:414
SoundSystem()
Construtor.
Definition: Sound.h:213
virtual void SetAllMute(bool bMute)=0
Mute all sounds (temporarily)
std::pair< uint64_t, SoundChannel * > AddChn(SoundFile *pSnd, float vol, FMOD_CHANNEL *pChn=nullptr)
Add one more channel, returning the newly created id.
Definition: Sound.cpp:388
const char * EnumerateSounds(const char *prevName, const char **ppFilePath)
Enumerate all loaded sounds.
Definition: Sound.cpp:351
SoundChannel * GetChn(uint64_t sndId)
Return the SoundChannel object for a given id, or nullptr if not found.
Definition: Sound.cpp:398
virtual void SetVolume(uint64_t sndId, float vol)=0
Set sound's volume.
virtual void Update()=0
Any updates to be done at the end of the frame.
virtual void Stop(uint64_t sndId)=0
Stop the sound.
virtual void SetMute(uint64_t sndId, bool bMute)=0
Mute the sound (temporarily)
virtual void SetPosOrientation(uint64_t sndId, const Aircraft &ac, bool bDoOrientation)=0
Update sound's position and orientation.
virtual uint64_t Play(const std::string &sndName, float vol, const Aircraft &ac)=0
Play a new sound, returns an id for that sound.
Represents a WAV file, read into memory, played by XP's Sound API.
Definition: Sound.h:149
void WavRead()
Reads a WAV file into a PCM16 memory buffer, throws exceptions in case of errors.
Definition: Sound.cpp:161
uint32_t bufferSize
buffer size in bytes
Definition: Sound.h:152
SoundWAV(SoundSystem *_pSndSys, const std::string &_filePath, bool _bLoop, float _coneDir, float _conePitch, float _coneInAngle, float _coneOutAngle, float _coneOutVol)
Constructor, will load immediately and throw an exception if loading is unsuccessful.
Definition: Sound.cpp:140
int numChannels
number of channels in the sound sample
Definition: Sound.h:154
~SoundWAV() override
Destructor.
Definition: Sound.cpp:152
int16_t * pBuf
audio buffer of PCM16 data
Definition: Sound.h:151
bool isReady() override
Ready to play? As we load right away in the constructor we're always ready.
Definition: Sound.h:167
int freqHz
sound frequency in Hz
Definition: Sound.h:153
Definition: XPMPAircraft.h:70
FMOD_RESULT gFmodRes
last FMOD result code, needed by the following macro, better don't rely on anywhere else
Definition: Sound.cpp:42
@ logERR
errors mean, aircraft can potentially not be displayed
Definition: Utilities.h:253
std::string leftOf(const std::string &s, const std::string &terminators)
Returns everything left of any of terminators.
Definition: Utilities.h:118
std::map< std::string, SoundFilePtr > mapSoundPtrTy
Map of all sounds, indexed by a sound name (type)
Definition: Sound.h:146
void LogMsg(const char *szPath, int ln, const char *szFunc, logLevelTy lvl, const char *szMsg,...)
Log Text to log file.
Definition: Utilities.cpp:866
SoundSystem * gpSndSys
The sound system in use.
Definition: Sound.cpp:39
void SoundInit()
Initialize the sound module and load the sounds.
Definition: Sound.cpp:973
void FmodHeadPitchRoll2Normal(const float head, const float pitch, const float roll, FMOD_VECTOR &vecDir, FMOD_VECTOR &vecNorm)
Convert heading/pitch to normal x/y/z vector.
Definition: Sound.cpp:682
void FmodNormalizeHeadingPitch(float &head, float &pitch)
Normalize Pitch/Heading.
Definition: Sound.cpp:696
void SoundUpdatesBegin()
Prepare for this frame's updates, which are about to start.
Definition: Sound.cpp:1020
std::unique_ptr< SoundFile > SoundFilePtr
Smart pointer to a SoundFile object.
Definition: Sound.h:144
FMOD_VECTOR FmodHeadPitch2Vec(const float head, const float pitch)
Convert heading/pitch to normalized x/y/z vector.
Definition: Sound.cpp:674
void SoundUpdatesDone()
Tell FMOD that all updates are done.
Definition: Sound.cpp:1026
void SoundCleanup()
Graceful shoutdown.
Definition: Sound.cpp:1050