OpenClonk
C4SoundInstance Class Reference

#include <C4SoundInstance.h>

Collaboration diagram for C4SoundInstance:
[legend]

Public Member Functions

 ~C4SoundInstance ()
 
C4ObjectgetObj () const
 
bool isStarted () const
 
void Clear ()
 
bool Create (C4SoundEffect *pEffect, bool fLoop=false, int32_t iVolume=100, C4Object *pObj=nullptr, int32_t iNearInstanceMax=0, int32_t iFalloffDistance=0, int32_t inPitch=0, C4SoundModifier *modifier=nullptr)
 
bool CheckStart ()
 
bool Start ()
 
bool Stop ()
 
bool Playing ()
 
void Execute ()
 
void SetVolume (int32_t inVolume)
 
void SetPan (int32_t inPan)
 
void SetPitch (int32_t inPitch)
 
void SetVolumeByPos (int32_t x, int32_t y, int32_t relative_volume=100)
 
void SetObj (C4Object *pnObj)
 
void ClearPointers (C4Object *pObj)
 
bool Inside (int32_t iX, int32_t iY, int32_t iRad)
 
C4SoundModifierGetModifier () const
 
void SetModifier (C4SoundModifier *new_modifier, bool is_global)
 
void SetPlayer (int32_t new_player)
 

Protected Member Functions

 C4SoundInstance ()
 

Protected Attributes

C4SoundEffectpEffect {nullptr}
 
int32_t iVolume {0}
 
int32_t iPan {0}
 
int32_t iPitch {0}
 
int32_t iChannel {-1}
 
bool pitch_dirty {false}
 
C4TimeMilliseconds tStarted
 
int32_t iNearInstanceMax
 
bool fLooping
 
C4ObjectpObj
 
int32_t iFalloffDistance
 
C4SoundModifiermodifier {nullptr}
 
bool has_local_modifier {false}
 
C4SoundInstancepNext {nullptr}
 
int32_t player
 

Friends

class C4SoundEffect
 
class C4SoundSystem
 
class C4SoundModifier
 

Detailed Description

Definition at line 55 of file C4SoundInstance.h.

Constructor & Destructor Documentation

◆ C4SoundInstance()

C4SoundInstance::C4SoundInstance ( )
protected

Definition at line 196 of file C4SoundInstance.cpp.

196  :
198 {
199 }
const int NO_OWNER
Definition: C4Constants.h:137

◆ ~C4SoundInstance()

C4SoundInstance::~C4SoundInstance ( )

Definition at line 201 of file C4SoundInstance.cpp.

References Clear().

202 {
203  Clear();
204 }
Here is the call graph for this function:

Member Function Documentation

◆ CheckStart()

bool C4SoundInstance::CheckStart ( )

Definition at line 252 of file C4SoundInstance.cpp.

References C4NearSoundRadius, fLooping, C4SoundEffect::GetStartedInstanceCount(), C4Object::GetX(), C4Object::GetY(), iNearInstanceMax, isStarted(), C4SoundEffect::Length, C4TimeMilliseconds::Now(), pEffect, pObj, Start(), and tStarted.

Referenced by Execute().

253 {
254  // already started?
255  if (isStarted()) return true;
256  // don't bother if half the time is up and the sound is not looping
258  return false;
259  // do near-instances check
260  int32_t iNearInstances = pObj ? pEffect->GetStartedInstanceCount(pObj->GetX(), pObj->GetY(), C4NearSoundRadius)
262  // over maximum?
263  if (iNearInstances > iNearInstanceMax) return false;
264  // Start
265  return Start();
266 }
int32_t GetX() const
Definition: C4Object.h:287
const int32_t C4NearSoundRadius
Definition: C4SoundSystem.h:29
bool isStarted() const
int32_t GetStartedInstanceCount(int32_t iX, int32_t iY, int32_t iRad)
int32_t GetY() const
Definition: C4Object.h:288
C4SoundEffect * pEffect
int32_t iNearInstanceMax
static C4TimeMilliseconds Now()
C4TimeMilliseconds tStarted
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Clear()

void C4SoundInstance::Clear ( )

Definition at line 206 of file C4SoundInstance.cpp.

References C4SoundModifier::DelRef(), has_local_modifier, iChannel, modifier, and Stop().

Referenced by ~C4SoundInstance().

207 {
208  Stop();
209  iChannel = -1;
210  if (modifier)
211  {
212  modifier->DelRef();
213  modifier = nullptr;
214  has_local_modifier = false;
215  }
216 }
C4SoundModifier * modifier
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearPointers()

void C4SoundInstance::ClearPointers ( C4Object pObj)

Definition at line 397 of file C4SoundInstance.cpp.

References fLooping, C4Object::GetX(), C4Object::GetY(), Playing(), pObj, SetVolumeByPos(), and Stop().

Referenced by Execute().

398 {
399  if (!Playing()) { Stop(); return; }
400  if (pObj == pDelete)
401  {
402  // stop if looping (would most likely loop forever)
403  if (fLooping)
404  Stop();
405  // otherwise: set volume by last position
406  else
407  SetVolumeByPos(pObj->GetX(), pObj->GetY());
408  pObj = nullptr;
409  }
410 }
int32_t GetX() const
Definition: C4Object.h:287
int32_t GetY() const
Definition: C4Object.h:288
void SetVolumeByPos(int32_t x, int32_t y, int32_t relative_volume=100)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Create()

bool C4SoundInstance::Create ( C4SoundEffect pEffect,
bool  fLoop = false,
int32_t  iVolume = 100,
C4Object pObj = nullptr,
int32_t  iNearInstanceMax = 0,
int32_t  iFalloffDistance = 0,
int32_t  inPitch = 0,
C4SoundModifier modifier = nullptr 
)

Definition at line 218 of file C4SoundInstance.cpp.

References C4SoundModifier::AddRef(), Config, Execute(), fLooping, has_local_modifier, iChannel, iFalloffDistance, iNearInstanceMax, iPan, iPitch, iVolume, NO_OWNER, C4TimeMilliseconds::Now(), pEffect, pitch_dirty, Playing(), pObj, C4ConfigSound::RXSound, SetPlayer(), C4Config::Sound, Stop(), and tStarted.

Referenced by C4SoundEffect::New().

219 {
220  // Sound check
221  if (!Config.Sound.RXSound || !pnEffect) return false;
222  // Already playing? Stop
223  if (Playing()) { Stop(); return false; }
224  // Set effect
225  pEffect = pnEffect;
226  // Set
228  iVolume = inVolume; iPan = 0; iChannel = -1;
229  iPitch = inPitch; pitch_dirty = (iPitch != 0);
230  iNearInstanceMax = inNearInstanceMax;
232  pObj = pnObj;
233  fLooping = fLoop;
234  if ((this->modifier = modifier))
235  {
236  modifier->AddRef();
237  has_local_modifier = true;
238  }
239  SetPlayer(NO_OWNER); // may be updated on first execution
240  // Start
241  Execute();
242  return true;
243 }
C4Config Config
Definition: C4Config.cpp:833
int32_t RXSound
Definition: C4Config.h:126
void SetPlayer(int32_t new_player)
int32_t iFalloffDistance
const int NO_OWNER
Definition: C4Constants.h:137
int32_t iNearInstanceMax
C4ConfigSound Sound
Definition: C4Config.h:254
static C4TimeMilliseconds Now()
C4TimeMilliseconds tStarted
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Execute()

void C4SoundInstance::Execute ( )

Definition at line 334 of file C4SoundInstance.cpp.

References C4Object::Audible, C4Object::AudiblePan, C4Object::AudiblePlayer, C4AudibilityRadius, CheckStart(), Clamp(), ClearPointers(), Config, iChannel, iFalloffDistance, iPan, iPitch, isStarted(), iVolume, pitch_dirty, player, pObj, SetPlayer(), C4Config::Sound, C4ConfigSound::SoundVolume, and C4PropList::Status.

Referenced by Create(), C4SoundEffect::Execute(), SoundLevel(), SoundPan(), SoundPitch(), SoundUpdate(), and Start().

335 {
336  // Object deleted?
337  if (pObj && !pObj->Status) ClearPointers(pObj);
338  // initial values
339  int32_t iVol = iVolume * 256 * Config.Sound.SoundVolume / 100, iPan = C4SoundInstance::iPan;
340  // bound to an object?
341  if (pObj)
342  {
343  int iAudibility = pObj->Audible;
345  // apply custom falloff distance
346  if (iFalloffDistance)
347  {
348  iAudibility = Clamp<int32_t>(100 + (iAudibility - 100) * C4AudibilityRadius / iFalloffDistance, 0,100);
349  }
350  iVol = iVol * iAudibility / 100;
351  iPan += pObj->AudiblePan;
352  }
353  // sound off?
354  if (!iVol)
355  {
356  // stop, if started
357  if (isStarted())
358  {
359 #if AUDIO_TK == AUDIO_TK_SDL_MIXER
360  Mix_HaltChannel(iChannel);
361 #elif AUDIO_TK == AUDIO_TK_OPENAL
362  alDeleteSources(1, (ALuint*)&iChannel);
363 #endif
364  iChannel = -1;
365  }
366  }
367  else
368  {
369  // start
370  if (!isStarted())
371  if (!CheckStart())
372  return;
373  // set volume & panning
374 #if AUDIO_TK == AUDIO_TK_SDL_MIXER
375  Mix_Volume(iChannel, (iVol * MIX_MAX_VOLUME) / (100 * 256));
376  Mix_SetPanning(iChannel, Clamp((100 - iPan) * 256 / 100, 0, 255), Clamp((100 + iPan) * 256 / 100, 0, 255));
377 #elif AUDIO_TK == AUDIO_TK_OPENAL
378  alSource3f(iChannel, AL_POSITION, Clamp<float>(float(iPan)/100.0f, -1.0f, +1.0f), 0, -0.7f);
379  alSourcef(iChannel, AL_GAIN, float(iVol) / (100.0f*256.0f));
380  if (pitch_dirty)
381  {
382  // set pitch; map -90..+100 range to 0.1f..2.0f
383  alSourcef(iChannel, AL_PITCH, std::max(float(iPitch + 100) / 100.0f, 0.1f));
384  pitch_dirty = false;
385  }
386 #endif
387  }
388 }
C4Config Config
Definition: C4Config.cpp:833
void ClearPointers(C4Object *pObj)
void SetPlayer(int32_t new_player)
bool isStarted() const
int32_t iFalloffDistance
int32_t SoundVolume
Definition: C4Config.h:132
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
int32_t AudiblePlayer
Definition: C4Object.h:121
int32_t AudiblePan
Definition: C4Object.h:121
int32_t Status
Definition: C4PropList.h:168
const int32_t C4AudibilityRadius
Definition: C4SoundSystem.h:30
int32_t Audible
Definition: C4Object.h:121
C4ConfigSound Sound
Definition: C4Config.h:254
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetModifier()

C4SoundModifier* C4SoundInstance::GetModifier ( ) const
inline

Definition at line 99 of file C4SoundInstance.h.

99 { return modifier; }
C4SoundModifier * modifier

◆ getObj()

C4Object* C4SoundInstance::getObj ( ) const
inline

Definition at line 83 of file C4SoundInstance.h.

83 { return pObj; }

◆ Inside()

bool C4SoundInstance::Inside ( int32_t  iX,
int32_t  iY,
int32_t  iRad 
)

Definition at line 412 of file C4SoundInstance.cpp.

References C4Object::GetX(), C4Object::GetY(), and pObj.

413 {
414  return pObj &&
415  (pObj->GetX() - iX) * (pObj->GetX() - iX) + (pObj->GetY() - iY) * (pObj->GetY() - iY) <= iRad * iRad;
416 }
int32_t GetX() const
Definition: C4Object.h:287
int32_t GetY() const
Definition: C4Object.h:288
Here is the call graph for this function:

◆ isStarted()

bool C4SoundInstance::isStarted ( ) const
inline

Definition at line 84 of file C4SoundInstance.h.

References C4SoundEffect::Clear(), and C4SoundEffect::Execute().

Referenced by CheckStart(), Execute(), SetModifier(), and Start().

84 { return iChannel != -1; }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Playing()

bool C4SoundInstance::Playing ( )

Definition at line 315 of file C4SoundInstance.cpp.

References Application, fLooping, iChannel, C4MusicSystem::MODInitialized, C4Application::MusicSystem, and pEffect.

Referenced by ClearPointers(), Create(), and Stop().

316 {
317  if (!pEffect) return false;
318  if (fLooping) return true;
319 #if AUDIO_TK == AUDIO_TK_SDL_MIXER
320  return Application.MusicSystem.MODInitialized && (iChannel != -1) && Mix_Playing(iChannel);
321 #elif AUDIO_TK == AUDIO_TK_OPENAL
322  if (iChannel == -1)
323  return false;
324  else
325  {
326  ALint state;
327  alGetSourcei(iChannel, AL_SOURCE_STATE, &state);
328  return state == AL_PLAYING;
329  }
330 #endif
331  return false;
332 }
C4SoundEffect * pEffect
C4Application Application
Definition: C4Globals.cpp:44
C4MusicSystem MusicSystem
Definition: C4Application.h:41
Here is the caller graph for this function:

◆ SetModifier()

void C4SoundInstance::SetModifier ( C4SoundModifier new_modifier,
bool  is_global 
)

Definition at line 418 of file C4SoundInstance.cpp.

References C4SoundModifier::AddRef(), C4SoundModifier::ApplyTo(), C4SoundModifier::DelRef(), has_local_modifier, iChannel, isStarted(), and modifier.

Referenced by SetPlayer().

419 {
420  // do not overwrite local modifier with global one
421  if (is_global)
422  {
423  if (has_local_modifier) return;
424  }
425  else
426  {
427  // this sound has its own modifier now and doesn't care for global ones
428  has_local_modifier = (new_modifier != nullptr);
429  }
430  if (new_modifier != modifier)
431  {
432  // update modifier and ref-count
433  C4SoundModifier *old_modifier = modifier;
434  modifier = new_modifier;
435  if (modifier) modifier->AddRef();
436  if (old_modifier) old_modifier->DelRef();
437  // Apply new modifier
438  if (isStarted())
439  {
440  if (modifier)
441  {
442 #if AUDIO_TK == AUDIO_TK_OPENAL
444 #endif
445  }
446  else
447  {
448 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
449  alSource3i(iChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
450 #endif
451  }
452  }
453  }
454 }
C4SoundModifier * modifier
bool isStarted() const
void ApplyTo(ALuint source)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetObj()

void C4SoundInstance::SetObj ( C4Object pnObj)
inline

Definition at line 96 of file C4SoundInstance.h.

References C4SoundEffect::ClearPointers(), and Inside().

96 { pObj = pnObj; }
Here is the call graph for this function:

◆ SetPan()

void C4SoundInstance::SetPan ( int32_t  inPan)
inline

Definition at line 93 of file C4SoundInstance.h.

Referenced by SoundPan().

93 { iPan = inPan; }
Here is the caller graph for this function:

◆ SetPitch()

void C4SoundInstance::SetPitch ( int32_t  inPitch)

Definition at line 245 of file C4SoundInstance.cpp.

References iPitch, and pitch_dirty.

Referenced by SoundPitch(), and SoundUpdate().

246 {
247  // set pitch and update on next call to Execute
248  iPitch = inPitch;
249  pitch_dirty = true;
250 }
Here is the caller graph for this function:

◆ SetPlayer()

void C4SoundInstance::SetPlayer ( int32_t  new_player)

Definition at line 456 of file C4SoundInstance.cpp.

References Application, C4SoundModifierList::GetGlobalModifier(), C4SoundSystem::Modifiers, player, SetModifier(), and C4Application::SoundSystem.

Referenced by Create(), Execute(), and SetVolumeByPos().

457 {
458  // update player and associated sound modifier
459  player = new_player;
461 }
C4SoundSystem SoundSystem
Definition: C4Application.h:42
C4SoundModifierList Modifiers
Definition: C4SoundSystem.h:54
C4SoundModifier * GetGlobalModifier(int32_t player_index) const
C4Application Application
Definition: C4Globals.cpp:44
void SetModifier(C4SoundModifier *new_modifier, bool is_global)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetVolume()

void C4SoundInstance::SetVolume ( int32_t  inVolume)
inline

Definition at line 92 of file C4SoundInstance.h.

Referenced by SoundLevel(), and SoundUpdate().

92 { iVolume = inVolume; }
Here is the caller graph for this function:

◆ SetVolumeByPos()

void C4SoundInstance::SetVolumeByPos ( int32_t  x,
int32_t  y,
int32_t  relative_volume = 100 
)

Definition at line 390 of file C4SoundInstance.cpp.

References C4ViewportList::GetAudibility(), iPan, iVolume, NO_OWNER, player, SetPlayer(), and Viewports.

Referenced by ClearPointers(), and StartSoundEffectAt().

391 {
392  int32_t vol_player = NO_OWNER;
393  iVolume = ::Viewports.GetAudibility(x, y, &iPan, 0, &vol_player) * relative_vol / 100.0f;
394  if (vol_player != player) SetPlayer(vol_player);
395 }
void SetPlayer(int32_t new_player)
int32_t GetAudibility(int32_t iX, int32_t iY, int32_t *iPan, int32_t iAudibilityRadius=0, int32_t *outPlayer=nullptr)
const int NO_OWNER
Definition: C4Constants.h:137
C4ViewportList Viewports
Definition: C4Viewport.cpp:841
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Start()

bool C4SoundInstance::Start ( )

Definition at line 268 of file C4SoundInstance.cpp.

References Application, C4SoundModifier::ApplyTo(), Execute(), fLooping, iChannel, isStarted(), modifier, C4MusicSystem::MODInitialized, C4Application::MusicSystem, pEffect, C4SoundEffect::pSample, and C4MusicSystem::SelectContext().

Referenced by CheckStart().

269 {
270 #if AUDIO_TK == AUDIO_TK_SDL_MIXER
271  // Be paranoid about SDL_Mixer initialisation
272  if (!Application.MusicSystem.MODInitialized) return false;
273  if ((iChannel = Mix_PlayChannel(-1, pEffect->pSample, fLooping? -1 : 0)) == -1)
274  return false;
275 #elif AUDIO_TK == AUDIO_TK_OPENAL
277  alGenSources(1, (ALuint*)&iChannel);
278  alSourcei(iChannel, AL_BUFFER, pEffect->pSample);
279  alSourcei(iChannel, AL_LOOPING, fLooping ? AL_TRUE : AL_FALSE);
281  alSourcePlay(iChannel);
282 #else
283  return false;
284 #endif
285  // Safety: Don't execute if start failed, or Execute() would try to start again
286  if (!isStarted()) return false;
287  // Update volume
288  Execute();
289  return true;
290 }
C4SoundModifier * modifier
C4SoundHandle pSample
void SelectContext()
bool isStarted() const
void ApplyTo(ALuint source)
C4SoundEffect * pEffect
C4Application Application
Definition: C4Globals.cpp:44
C4MusicSystem MusicSystem
Definition: C4Application.h:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Stop()

bool C4SoundInstance::Stop ( )

Definition at line 292 of file C4SoundInstance.cpp.

References fLooping, iChannel, pEffect, Playing(), and tStarted.

Referenced by Clear(), ClearPointers(), Create(), and StopSoundEffect().

293 {
294  if (!pEffect) return false;
295  // Stop sound
296  bool fRet = true;
297 #if AUDIO_TK == AUDIO_TK_SDL_MIXER
298  // iChannel == -1 will halt all channels. Is that right?
299  if (Playing())
300  Mix_HaltChannel(iChannel);
301 #elif AUDIO_TK == AUDIO_TK_OPENAL
302  if (iChannel != -1)
303  {
304  if (Playing()) alSourceStop(iChannel);
305  ALuint c = iChannel;
306  alDeleteSources(1, &c);
307  }
308 #endif
309  iChannel = -1;
310  tStarted = 0;
311  fLooping = false;
312  return fRet;
313 }
C4SoundEffect * pEffect
C4TimeMilliseconds tStarted
Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ C4SoundEffect

friend class C4SoundEffect
friend

Definition at line 57 of file C4SoundInstance.h.

◆ C4SoundModifier

friend class C4SoundModifier
friend

Definition at line 59 of file C4SoundInstance.h.

◆ C4SoundSystem

friend class C4SoundSystem
friend

Definition at line 58 of file C4SoundInstance.h.

Member Data Documentation

◆ fLooping

bool C4SoundInstance::fLooping
protected

Definition at line 70 of file C4SoundInstance.h.

Referenced by CheckStart(), ClearPointers(), Create(), Playing(), Start(), and Stop().

◆ has_local_modifier

bool C4SoundInstance::has_local_modifier {false}
protected

Definition at line 74 of file C4SoundInstance.h.

Referenced by Clear(), Create(), and SetModifier().

◆ iChannel

int32_t C4SoundInstance::iChannel {-1}
protected

Definition at line 66 of file C4SoundInstance.h.

Referenced by Clear(), Create(), Execute(), Playing(), SetModifier(), Start(), and Stop().

◆ iFalloffDistance

int32_t C4SoundInstance::iFalloffDistance
protected

Definition at line 72 of file C4SoundInstance.h.

Referenced by Create(), and Execute().

◆ iNearInstanceMax

int32_t C4SoundInstance::iNearInstanceMax
protected

Definition at line 69 of file C4SoundInstance.h.

Referenced by CheckStart(), and Create().

◆ iPan

int32_t C4SoundInstance::iPan {0}
protected

Definition at line 66 of file C4SoundInstance.h.

Referenced by Create(), Execute(), and SetVolumeByPos().

◆ iPitch

int32_t C4SoundInstance::iPitch {0}
protected

Definition at line 66 of file C4SoundInstance.h.

Referenced by Create(), Execute(), and SetPitch().

◆ iVolume

int32_t C4SoundInstance::iVolume {0}
protected

Definition at line 66 of file C4SoundInstance.h.

Referenced by Create(), Execute(), and SetVolumeByPos().

◆ modifier

C4SoundModifier* C4SoundInstance::modifier {nullptr}
protected

Definition at line 73 of file C4SoundInstance.h.

Referenced by Clear(), SetModifier(), and Start().

◆ pEffect

C4SoundEffect* C4SoundInstance::pEffect {nullptr}
protected

◆ pitch_dirty

bool C4SoundInstance::pitch_dirty {false}
protected

Definition at line 67 of file C4SoundInstance.h.

Referenced by Create(), Execute(), and SetPitch().

◆ player

int32_t C4SoundInstance::player
protected

Definition at line 81 of file C4SoundInstance.h.

Referenced by Execute(), SetPlayer(), and SetVolumeByPos().

◆ pNext

◆ pObj

C4Object* C4SoundInstance::pObj
protected

Definition at line 71 of file C4SoundInstance.h.

Referenced by CheckStart(), ClearPointers(), Create(), Execute(), and Inside().

◆ tStarted

C4TimeMilliseconds C4SoundInstance::tStarted
protected

Definition at line 68 of file C4SoundInstance.h.

Referenced by CheckStart(), Create(), and Stop().


The documentation for this class was generated from the following files: