cAudio  2.3.0
3d Audio Engine
cAudioSource.cpp
1 // Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari
2 // This file is part of the "cAudio Engine"
3 // For conditions of distribution and use, see copyright notice in cAudio.h
4 
5 #include "cAudioSource.h"
6 #include "cAudio.h"
7 #include "cLogger.h"
8 #include "cFilter.h"
9 #include "cEffect.h"
10 #include "cAudioSleep.h"
11 #include <string.h>
12 #include <algorithm>
13 
14 #if CAUDIO_EFX_ENABLED == 1
15 #include "cOpenALDeviceContext.h"
16 #endif
17 
18 namespace
19 {
20  // return buffer length in seconds
21  ALfloat GetBufferLength(ALuint buffer)
22  {
23  ALint size, bits, channels, freq;
24 
25  alGetBufferi(buffer, AL_SIZE, &size);
26  alGetBufferi(buffer, AL_BITS, &bits);
27  alGetBufferi(buffer, AL_CHANNELS, &channels);
28  alGetBufferi(buffer, AL_FREQUENCY, &freq);
29  if(alGetError() != AL_NO_ERROR || !bits || !channels || !freq)
30  return -1.0f;
31 
32  return (ALfloat)((ALuint)size/channels/(bits/8)) / (ALfloat)freq;
33  }
34 
35  ALint GetBufferSize(ALuint buffer)
36  {
37  ALint size;
38  alGetBufferi(buffer, AL_SIZE, &size);
39  return size;
40  }
41 }
42 
43 namespace cAudio
44 {
45 
46 #if CAUDIO_EFX_ENABLED == 1
47  cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context, cEFXFunctions* oALFunctions)
48  : cAudioSourceBase(context), Decoder(decoder), Loop(false), Valid(false),
49  EFX(oALFunctions), Filter(NULL), EffectSlotsAvailable(0), LastFilterTimeStamp(0)
50 #else
51  cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context)
52  : cAudioSourceBase(context), Decoder(decoder), Loop(false), Valid(false)
53 #endif
54  {
55  cAudioMutexBasicLock lock(Mutex);
56 
57  BufferPosition = 0;
58  BufferTime = 0;
59  for(int i=0; i<CAUDIO_SOURCE_NUM_BUFFERS; ++i) {
60  Buffers[i] = 0;
61  }
62 
63 #if CAUDIO_EFX_ENABLED == 1
64  for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
65  Effects[i] = NULL;
66 
67  for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
68  LastEffectTimeStamp[i] = 0;
69 #endif
70 
71  if(Decoder)
72  Decoder->grab();
73 
74  ALboolean state = alIsSource(Source);
75 
76  if (state)
77  {
78  //Generates 3 buffers for the ogg file
79  alGenBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
80  state = !checkALError();
81  }
82 
83 #if CAUDIO_EFX_ENABLED == 1
84  Valid = state && (Decoder != NULL) && (Context != NULL) && (EFX != NULL);
85 
86  int numSlots = 0;
87  ALCdevice* device = alcGetContextsDevice(((cOpenALDeviceContext*)Context)->getOpenALContext());
88  alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &numSlots);
89 
90  EffectSlotsAvailable = (numSlots <= CAUDIO_SOURCE_MAX_EFFECT_SLOTS) ? numSlots : CAUDIO_SOURCE_MAX_EFFECT_SLOTS;
91 #else
92  Valid = state && (Decoder != NULL) && (Context != NULL);
93 #endif
94  }
95 
96  cAudioSource::~cAudioSource()
97  {
98  cAudioMutexBasicLock lock(Mutex);
99 
100 #if CAUDIO_EFX_ENABLED == 1
101  for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
102  {
103  if(Effects[i])
104  Effects[i]->drop();
105  Effects[i] = NULL;
106  }
107 
108  if(Filter)
109  Filter->drop();
110  Filter = NULL;
111 #endif
112 
113  //Stops the audio Source
114  alSourceStop(Source);
115  checkALError();
116  empty();
117  alSourcei(Source, AL_BUFFER, 0);
118  //deletes the last filled buffer
119  alDeleteBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
120  checkALError();
121 
122  if(Decoder) {
123  Decoder->drop();
124  Decoder = NULL;
125  }
126  }
127 
128  cAudioSourceBase::cAudioSourceBase(IAudioDeviceContext* context) :
129  Context(context), Volume(1.f), Source(0)
130  {
131  alGenSources(1, &Source);
132  checkALError();
133  setVolume(Volume);
134  }
135 
136  cAudioSourceBase::~cAudioSourceBase()
137  {
138  alSourceStop(Source);
139  checkALError();
140  alDeleteSources(1, &Source);
141  checkALError();
142 
143  getLogger()->logDebug("Audio Source", "Audio source released.");
144  signalEvent(ON_RELEASE);
145  }
146 
147 
149  {
150  --RefCount;
151  if (RefCount == 0)
152  {
153  Context->getAudioManager()->release(this);
154  return true;
155  }
156  return false;
157  }
158 
160  {
162  if (!isPaused())
163  {
164  int queueSize = 0;
165  //Purges all buffers from the source
166  alSourcei(Source, AL_BUFFER, 0);
167  BufferPosition = Decoder->getCurrentPosition();
168  BufferTime = Decoder->getCurrentTime();
169  checkALError();
170  for(int u = 0; u < CAUDIO_SOURCE_NUM_BUFFERS; u++)
171  {
172  int val = stream(Buffers[u]);
173 
174  if(val < 0)
175  {
176  return false;
177  }
178  else if(val > 0)
179  ++queueSize;
180  }
181  //Stores the sources 3 buffers to be used in the queue
182  alSourceQueueBuffers(Source, queueSize, Buffers);
183  checkALError();
184  }
185 #if CAUDIO_EFX_ENABLED == 1
186  updateFilter();
187  for(unsigned int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
188  updateEffect(i);
189 #endif
190  alSourcePlay(Source);
191  checkALError();
192  getLogger()->logDebug("Audio Source", "Source playing.");
193  signalEvent(ON_PLAY);
194  oldState = AL_PLAYING;
195  return true;
196  }
197 
198  bool cAudioSource::play2d(const bool& toLoop)
199  {
201  alSourcei(Source, AL_SOURCE_RELATIVE, true);
202  loop(toLoop);
203  bool state = play();
204  checkALError();
205  return state;
206  }
207 
208  bool cAudioSource::play3d(const cVector3& position, const float& soundstr, const bool& toLoop)
209  {
211  alSourcei(Source, AL_SOURCE_RELATIVE, false);
212  setPosition(position);
213  setStrength(soundstr);
214  loop(toLoop);
215  bool state = play();
216  checkALError();
217  return state;
218  }
219 
221  {
223  alSourcePause(Source);
224  checkALError();
225  getLogger()->logDebug("Audio Source", "Source paused.");
226  signalEvent(ON_PAUSE);
227  oldState = AL_PAUSED;
228  }
229 
231  {
233  alSourceStop(Source);
234 
235  //INFO:FIXED EXTREME SLOWDOWN ON IPHONE
236  int queued = 0;
237  alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued);
238  while ( queued-- )
239  {
240  ALuint buffer;
241  alSourceUnqueueBuffers(Source, 1, &buffer);
242  }
243 
244  //Resets the audio to the beginning
245  Decoder->setPosition(0, false);
246  checkALError();
247  getLogger()->logDebug("Audio Source", "Source stopped.");
248  signalEvent(ON_STOP);
249  oldState = AL_STOPPED;
250  }
251 
252  void cAudioSource::loop(const bool& loop)
253  {
255  Loop = loop;
256  }
257 
258  bool cAudioSource::seek(const float& seconds, bool relative)
259  {
260  bool state = false;
262  if(Decoder->isSeekingSupported())
263  {
264  state = Decoder->seek(seconds, relative);
265 
266  BufferPosition = Decoder->getCurrentPosition();
267  BufferTime = Decoder->getCurrentTime();
268 
269  int queued = 0;
270  alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued);
271  if (queued) {
272  BufferPosition -= queued * GetBufferSize(Buffers[0]);
273  BufferTime -= queued * GetBufferLength(Buffers[0]);
274  }
275  }
276  return state;
277  }
278 
280  {
281  return Decoder->getTotalTime();
282  }
283 
285  {
286  return Decoder->getTotalSize();
287  }
288 
290  {
291  return Decoder->getCompressedSize();
292  }
293 
295  {
296  float time = -1;
297  alGetSourcef(Source, AL_SEC_OFFSET, &time);
298  return BufferTime + time;
299  }
300 
302  {
303  int offset = -1;
304  alGetSourcei(Source, AL_BYTE_OFFSET, &offset);
305  return BufferPosition + offset;
306  }
307 
309  {
310  return Decoder->getCurrentCompressedPosition();
311  }
312 
314  {
316 
317  int processed = 0;
318  bool active = true;
319  if(isValid() || isPlaying())
320  {
321 #if CAUDIO_EFX_ENABLED == 1
322  updateFilter();
323  for(unsigned int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
324  updateEffect(i);
325 #endif
326 
327  //gets the sound source processed buffers
328  alGetSourcei(Source, AL_BUFFERS_PROCESSED, &processed);
329  checkALError();
330 
331  //while there is more data refill buffers with audio data.
332  while (processed--)
333  {
334  ALuint buffer;
335  alSourceUnqueueBuffers(Source, 1, &buffer);
336  BufferPosition += GetBufferSize(buffer);
337  BufferTime += GetBufferLength(buffer);
338 
339  if (checkALError())
340  {
341  processed++;
342  cAudioSleep(1);
343  continue;
344  }
345 
346  active = stream(buffer);
347 
348  //if more in stream continue playing.
349  if(active)
350  {
351  alSourceQueueBuffers(Source, 1, &buffer);
352  }
353 
354  if (checkALError())
355  {
356  processed++;
357  cAudioSleep(1);
358  continue;
359  }
360  }
361 
362  signalEvent(ON_UPDATE);
363  }
364 
365  ALenum state;
366  alGetSourcei(Source, AL_SOURCE_STATE, &state);
367  checkALError();
368  if(state == AL_STOPPED && oldState != state)
369  {
370  //Resets the audio to the beginning
371  Decoder->setPosition(0, false);
372  getLogger()->logDebug("Audio Source", "Source stopped.");
373  signalEvent(ON_STOP);
374  oldState = state;
375  }
376 
377  return active;
378  }
379 
381  {
382  return Valid;
383  }
384 
386  {
387  ALenum state = 0;
388  alGetSourcei(Source, AL_SOURCE_STATE, &state);
389  checkALError();
390  return (state == AL_PLAYING);
391  }
392 
394  {
395  ALenum state = 0;
396  alGetSourcei(Source, AL_SOURCE_STATE, &state);
397  checkALError();
398  return (state == AL_PAUSED);
399  }
400 
402  {
403  ALenum state = 0;
404  alGetSourcei(Source, AL_SOURCE_STATE, &state);
405  checkALError();
406  return (state == AL_STOPPED);
407  }
408 
410  {
411  return Loop;
412  }
413 
415  {
417  alSource3f(Source, AL_POSITION, position.x, position.y, position.z);
418  checkALError();
419  }
420 
422  {
424  alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
425  checkALError();
426  }
427 
429  {
431  alSource3f(Source, AL_DIRECTION, direction.x, direction.y, direction.z);
432  checkALError();
433  }
434 
435  void cAudioSourceBase::setRolloffFactor(const float& rolloff)
436  {
438  alSourcef(Source, AL_ROLLOFF_FACTOR, rolloff);
439  checkALError();
440  }
441 
442  void cAudioSourceBase::setStrength(const float& soundstrength)
443  {
444  float inverseStrength = 0.0f;
445  if(soundstrength > 0.0f)
446  inverseStrength = 1.0f / soundstrength;
447 
449  alSourcef(Source, AL_ROLLOFF_FACTOR, inverseStrength);
450  checkALError();
451  }
452 
453  void cAudioSourceBase::setMinDistance(const float& minDistance)
454  {
456  alSourcef(Source, AL_REFERENCE_DISTANCE, minDistance);
457  checkALError();
458  }
459 
460  void cAudioSourceBase::setMaxAttenuationDistance(const float& maxDistance)
461  {
463  alSourcef(Source, AL_MAX_DISTANCE, maxDistance);
464  checkALError();
465  }
466 
467  void cAudioSourceBase::setPitch(const float& pitch)
468  {
470  alSourcef (Source, AL_PITCH, pitch);
471  checkALError();
472  }
473 
474  void cAudioSourceBase::setVolume(const float& volume)
475  {
477  Volume = volume;
478  alSourcef(Source, AL_GAIN, Volume * Context->getAudioManager()->getMasterVolume());
479  checkALError();
480  }
481 
482  void cAudioSourceBase::setMinVolume(const float& minVolume)
483  {
485  alSourcef(Source, AL_MIN_GAIN, minVolume);
486  checkALError();
487  }
488 
489  void cAudioSourceBase::setMaxVolume(const float& maxVolume)
490  {
492  alSourcef(Source, AL_MAX_GAIN, maxVolume);
493  checkALError();
494  }
495 
496  void cAudioSourceBase::setInnerConeAngle(const float& innerAngle)
497  {
499  alSourcef(Source, AL_CONE_INNER_ANGLE, innerAngle);
500  checkALError();
501  }
502 
503  void cAudioSourceBase::setOuterConeAngle(const float& outerAngle)
504  {
506  alSourcef(Source, AL_CONE_OUTER_ANGLE, outerAngle);
507  checkALError();
508  }
509 
510  void cAudioSourceBase::setOuterConeVolume(const float& outerVolume)
511  {
513  alSourcef(Source, AL_CONE_OUTER_GAIN, outerVolume);
514  checkALError();
515  }
516 
517  void cAudioSourceBase::setDopplerStrength(const float& dstrength)
518  {
520  alSourcef(Source, AL_DOPPLER_FACTOR, dstrength);
521  checkALError();
522  }
523 
525  {
527  alSource3f(Source, AL_DOPPLER_VELOCITY, dvelocity.x, dvelocity.y, dvelocity.z);
528  checkALError();
529  }
530 
531  void cAudioSourceBase::move(const cVector3& position)
532  {
534  cVector3 oldPos = getPosition();
535  cVector3 velocity = position - oldPos;
536 
537  alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
538  alSource3f(Source, AL_POSITION, position.x, position.y, position.z);
539  checkALError();
540  }
541 
543  {
544  cVector3 position;
545  alGetSourcefv(Source, AL_POSITION, &position.x);
546  checkALError();
547  return position;
548  }
549 
551  {
552  cVector3 velocity;
553  alGetSourcefv(Source, AL_VELOCITY, &velocity.x);
554  return velocity;
555  }
556 
558  {
559  cVector3 direction;
560  alGetSourcefv(Source, AL_DIRECTION, &direction.x);
561  checkALError();
562  return direction;
563  }
564 
566  {
567  float value = 0.0f;
568  alGetSourcef(Source, AL_ROLLOFF_FACTOR, &value);
569  checkALError();
570  return value;
571  }
572 
574  {
575  float value = 0.0f;
576  alGetSourcef(Source, AL_ROLLOFF_FACTOR, &value);
577  checkALError();
578 
579  float inverseStrength = 0.0f;
580  if(value > 0.0f)
581  inverseStrength = 1.0f / value;
582 
583  return inverseStrength;
584  }
585 
587  {
588  float value = 0.0f;
589  alGetSourcef(Source, AL_REFERENCE_DISTANCE, &value);
590  checkALError();
591  return value;
592  }
593 
595  {
596  float value = 0.0f;
597  alGetSourcef(Source, AL_MAX_DISTANCE, &value);
598  checkALError();
599  return value;
600  }
601 
603  {
604  int relative = 0;
605  alGetSourcei(Source, AL_SOURCE_RELATIVE, &relative);
606  return relative;
607  }
608 
610  {
611  // OpenAL Inverse Distance Clamped Model
612  // distance = max(distance,AL_REFERENCE_DISTANCE);
613  // distance = min(distance,AL_MAX_DISTANCE);
614  // gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +
615  // AL_ROLLOFF_FACTOR *
616  // (distance – AL_REFERENCE_DISTANCE));
617 
618  cVector3 lpos = Context->getAudioManager()->getListener()->getPosition();
619  cVector3 pos = getPosition();
620 
621  float refDist = getMinDistance();
622  float dist = 0.f;
623  dist = isRelative() ? pos.length() : (pos - lpos).length();
624  dist = std::max(dist, refDist);
625  dist = std::min(dist, getMaxDistance());
626  float gain = refDist / (refDist + getRolloffFactor() * (dist - refDist));
627  return gain * getVolume();
628  }
629 
631  {
632  float value = 0.0f;
633  alGetSourcef(Source, AL_PITCH, &value);
634  checkALError();
635  return value;
636  }
637 
639  {
640  return Volume;
641  }
642 
644  {
645  float value = 0.0f;
646  alGetSourcef(Source, AL_MIN_GAIN, &value);
647  checkALError();
648  return value;
649  }
650 
652  {
653  float value = 0.0f;
654  alGetSourcef(Source, AL_MAX_GAIN, &value);
655  checkALError();
656  return value;
657  }
658 
660  {
661  float value = 0.0f;
662  alGetSourcef(Source, AL_CONE_INNER_ANGLE, &value);
663  checkALError();
664  return value;
665  }
666 
668  {
669  float value = 0.0f;
670  alGetSourcef(Source, AL_CONE_OUTER_ANGLE, &value);
671  checkALError();
672  return value;
673  }
674 
676  {
677  float value = 0.0f;
678  alGetSourcef(Source, AL_CONE_OUTER_GAIN, &value);
679  checkALError();
680  return value;
681  }
682 
684  {
685  float value = 0.0f;
686  alGetSourcef(Source, AL_DOPPLER_FACTOR, &value);
687  checkALError();
688  return value;
689  }
690 
692  {
693  cVector3 velocity;
694  alGetSourcefv(Source, AL_DOPPLER_VELOCITY, &velocity.x);
695  checkALError();
696  return velocity;
697  }
698 
699 #if CAUDIO_EFX_ENABLED == 1
700  unsigned int cAudioSource::getNumEffectSlotsAvailable() const
701  {
702  return EffectSlotsAvailable;
703  }
704 
705  bool cAudioSource::attachEffect(unsigned int slot, IEffect* effect)
706  {
708  if(slot < EffectSlotsAvailable)
709  {
710  Effects[slot] = effect;
711 
712  if(Effects[slot])
713  Effects[slot]->grab();
714 
715  updateEffect(slot);
716  return true;
717  }
718  return false;
719  }
720 
721  void cAudioSource::removeEffect(unsigned int slot)
722  {
724  if(slot < EffectSlotsAvailable)
725  {
726  if(Effects[slot])
727  Effects[slot]->drop();
728 
729  Effects[slot] = NULL;
730  LastEffectTimeStamp[slot] = 0;
731  updateEffect(slot, true);
732  }
733  }
734 
735  bool cAudioSource::attachFilter(IFilter* filter)
736  {
738  Filter = filter;
739 
740  if(Filter)
741  Filter->grab();
742 
743  updateFilter();
744  return true;
745  }
746 
747  void cAudioSource::removeFilter()
748  {
750  if(Filter)
751  Filter->drop();
752  Filter = NULL;
753  LastFilterTimeStamp = 0;
754  updateFilter(true);
755  }
756 #endif
757 
758  void cAudioSource::empty()
759  {
760  int queued = 0;
761  alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued);
762  checkALError();
763 
764  while (queued--)
765  {
766  ALuint buffer;
767  alSourceUnqueueBuffers(Source, 1, &buffer);
768  checkALError();
769  }
770  }
771 
772  bool cAudioSource::stream(ALuint buffer)
773  {
774  if(!Decoder)
775  return false;
776 
777  //stores the calculated data into buffer that is passed to output.
778  size_t totalread = 0;
779  unsigned int errorcount = 0;
780  char tempbuffer[CAUDIO_SOURCE_BUFFER_SIZE];
781  while( totalread < CAUDIO_SOURCE_BUFFER_SIZE )
782  {
783  char tempbuffer2[CAUDIO_SOURCE_BUFFER_SIZE];
784  Mutex.unlock(); // this can take a long time
785  int actualread = Decoder->readAudioData(tempbuffer2, CAUDIO_SOURCE_BUFFER_SIZE-totalread);
786  Mutex.lock();
787 
788  if(actualread > 0)
789  {
790  memcpy(tempbuffer+totalread,tempbuffer2,actualread);
791  totalread += actualread;
792  }
793  if(actualread < 0)
794  {
795  ++errorcount;
796  getLogger()->logDebug("Audio Source", "Decoder returned an error: %i (%i of 3)", actualread, errorcount);
797  if(errorcount >= 3)
798  {
799  stop();
800  break;
801  }
802  }
803  if(actualread == 0)
804  {
805  if(isLooping())
806  {
807  //If we are to loop, set to the beginning and reload from the start
808  Decoder->setPosition(0, false);
809  getLogger()->logDebug("Audio Source", "Buffer looping.");
810  }
811  else
812  break;
813  }
814  }
815 
816  //Second check, in case looping is not enabled, we will return false for end of stream
817  if(totalread == 0)
818  {
819  return false;
820  }
821  getLogger()->logDebug("Audio Source", "Buffered %i bytes of data into buffer %i at %i hz.", totalread, buffer, Decoder->getFrequency());
822  alBufferData(buffer, convertAudioFormatEnum(Decoder->getFormat()), tempbuffer, totalread, Decoder->getFrequency());
823  checkALError();
824  return true;
825  }
826 
827 #if CAUDIO_EFX_ENABLED == 1
828  void cAudioSource::updateFilter(bool remove)
829  {
830  if(!remove)
831  {
832  if(Filter && Filter->isValid())
833  {
834  if(LastFilterTimeStamp != Filter->getLastUpdated())
835  {
836  LastFilterTimeStamp = Filter->getLastUpdated();
837  cFilter* theFilter = static_cast<cFilter*>(Filter);
838  if(theFilter)
839  {
840  alSourcei(Source, AL_DIRECT_FILTER, theFilter->getOpenALFilter());
841  checkALError();
842  return;
843  }
844  }
845  return;
846  }
847  }
848  alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
849  checkALError();
850  }
851 
852  void cAudioSource::updateEffect(unsigned int slot, bool remove)
853  {
854  if(slot < EffectSlotsAvailable)
855  {
856  if(!remove)
857  {
858  if(Effects[slot] && Effects[slot]->isValid())
859  {
860  if(LastEffectTimeStamp[slot] != Effects[slot]->getLastUpdated())
861  {
862  LastEffectTimeStamp[slot] = Effects[slot]->getLastUpdated();
863  cEffect* theEffect = static_cast<cEffect*>(Effects[slot]);
864  if(theEffect)
865  {
866  ALuint filterID = AL_FILTER_NULL;
867  cFilter* theFilter = static_cast<cFilter*>(theEffect->getFilter());
868  if(theFilter)
869  {
870  filterID = theFilter->getOpenALFilter();
871  }
872  alSource3i(Source, AL_AUXILIARY_SEND_FILTER, theEffect->getOpenALEffectSlot(), slot, filterID);
873  checkALError();
874  return;
875  }
876  }
877  return;
878  }
879  }
880  alSource3i(Source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, slot, AL_FILTER_NULL);
881  checkALError();
882  }
883  }
884 #endif
885 
887  {
888  if(handler)
889  {
891  eventHandlerList.push_back(handler);
892  }
893  }
894 
896  {
897  if(handler)
898  {
900  for(int i=0; i<eventHandlerList.size(); i++) {
901  if(eventHandlerList[i] == handler)
902  eventHandlerList.erase(eventHandlerList.begin() + i);
903  }
904  }
905  }
906 
908  {
910  eventHandlerList.clear();
911  }
912 
913  void cAudioSourceBase::signalEvent(Events sevent)
914  {
916  if(eventHandlerList.empty())
917  return;
918 
919  size_t size = eventHandlerList.size();
920 
921  for(int i=0; i<size; )
922  {
924 
925  switch(sevent)
926  {
927  case ON_UPDATE: handler->onUpdate(); break;
928  case ON_RELEASE: handler->onRelease(); break;
929  case ON_PLAY: handler->onPlay(); break;
930  case ON_PAUSE: handler->onPause(); break;
931  case ON_STOP: handler->onStop(); break;
932  }
933 
934  // handler may have unregistered itself
935  if(size == eventHandlerList.size()) {
936  i++;
937  } else {
938  size = eventHandlerList.size();
939  }
940  }
941  }
942 }
virtual int getCurrentAudioPosition()
Returns the current position in the decoded audio stream in bytes. See IAudioDecoder for details...
virtual float getMaxVolume() const
Returns the maximum volume that the source can achieve.
ALenum convertAudioFormatEnum(AudioFormats format)
Converts our audio format enum to OpenAL&#39;s.
Definition: cOpenALUtil.h:48
virtual void unRegisterEventHandler(ISourceEventHandler *handler)
Removes a specified event handler from this source.
virtual void loop(const bool &toLoop)=0
Controls whether the source should loop or not.
virtual bool update()
Normally called every frame by the audio manager to update the internal buffers. Note: For internal u...
virtual float getMaxDistance() const
Returns the distance from the source where attenuation will stop.
virtual float getPitch() const
Returns the pitch of the source.
virtual void setInnerConeAngle(const float &innerAngle)
Sets the angle of the inner sound cone of the source. The cone opens up in the direction of the sourc...
virtual void setPosition(const cVector3 &position)
Sets the position of the source in 3D space.
virtual bool play2d(const bool &toLoop=false)
Plays the source in 2D mode.
virtual cVector3 getVelocity() const
Returns the audio objects velocity.
virtual void setMinDistance(const float &minDistance)
Sets the distance from the source where attenuation will begin.
virtual void stop()=0
Stops playback of the sound source.
virtual float getDopplerStrength() const
Returns the doppler strength, which enhances or diminishes the doppler effect.
virtual void unRegisterAllEventHandlers()
Removes all event handlers attached to this source.
virtual void pause()
Pauses playback of the sound source.
virtual void onStop()
This function is called when a source stopped playback.
virtual void stop()
Stops playback of the sound source.
virtual void setMaxAttenuationDistance(const float &maxDistance)
Sets the distance from the source where attenuation will stop.
virtual bool play3d(const cVector3 &position, const float &soundstr=1.0, const bool &toLoop=false)
Plays the source in 3D mode.
virtual float getOuterConeVolume() const
Returns how much the volume of the source is scaled in the outer cone.
float length() const
Returns the length (magnitude) of the vector.
Definition: cVector3.h:99
virtual void setPitch(const float &pitch)
Sets the pitch of the source.
virtual bool seek(const float &seconds, bool relative=false)
Seeks through the audio stream to a specific spot.
virtual float getRolloffFactor() const
Returns the factor used in attenuating the source over distance.
virtual float getMasterVolume() const =0
Get the master volume.
virtual bool drop()
Decrements the reference count by one. If it hits zero, this object is deleted.
virtual bool isValid() const
Returns if the source is ready to be used.
virtual void logDebug(const char *sender, const char *msg,...)=0
Used to log a debug message to the logging system.
virtual bool isStopped() const
Returns if the source is stopped.
cAudioVector< ISourceEventHandler * >::Type eventHandlerList
List of registered event handlers.
Definition: cAudioSource.h:113
virtual int getCurrentCompressedAudioPosition()
Returns the current position in the original audio stream in bytes. See IAudioDecoder for details...
virtual cVector3 getPosition() const
Returns the audio objects position.
virtual void move(const cVector3 &position)
Convenience function to automatically set the velocity and position for you in a single call...
virtual void setDirection(const cVector3 &direction)
Sets the direction the source is facing.
virtual float getCurrentAudioTime()
Returns the current position in the audio stream in seconds. See IAudioDecoder for details...
virtual int getTotalAudioSize()
Returns the total decoded size of the audio stream. See IAudioDecoder for details.
virtual bool isPaused() const
Returns if the source is paused.
virtual float getStrength() const
Returns the strength of the source.
virtual void setOuterConeVolume(const float &outerVolume)
Sets how much the volume of the source is scaled in the outer cone.
virtual void setDopplerVelocity(const cVector3 &dvelocity)
Overrides the doppler velocity vector. It is usually better to let the engine take care of it automat...
virtual cVector3 getDopplerVelocity() const
Returns the override for the doppler velocity vector.
virtual float getOuterConeAngle() const
Returns the angle of the outer sound cone of the source.
cAudioMutex Mutex
Mutex for thread synchronization.
Definition: cAudioSource.h:96
virtual void setDopplerStrength(const float &dstrength)
Sets the doppler strength, which enhances or diminishes the doppler effect. Can be used to exaggerate...
virtual bool isRelative() const
Return true for 2d sounds, false for 3d sounds.
Interface for event handlers on Audio Sources.
virtual bool drop()
Decrements the reference count by one. If it hits zero, this object is deleted.
Definition: IRefCounted.h:25
virtual bool isLooping() const =0
Returns if the source is looping.
virtual cVector3 getPosition(void) const =0
Returns the current position of the listener.
virtual void onUpdate()
This function is called when a source updates its buffers.
IAudioDeviceContext * Context
The context that owns this source.
Definition: cAudioSource.h:102
virtual float getMinVolume() const
Returns the minimum volume that the source can be attenuated to.
Class for manipulating vectors in 3D space.
Definition: cVector3.h:22
virtual bool isValid() const =0
Returns if the source is ready to be used.
virtual void onPlay()
This function is called when a source starts playing.
virtual void setVelocity(const cVector3 &velocity)
Sets the current velocity of the source for doppler effects.
ALuint Source
OpenAL source.
Definition: cAudioSource.h:108
virtual void onPause()
This function is called when a source is paused.
virtual float calculateGain() const
Return gain, taking into account volume as well as distance attenuation.
virtual bool play()
Plays the source with the last set parameters.
virtual void release(IAudioSource *source)=0
Releases a single Audio Source, removing it from the manager.
virtual float getTotalAudioTime()
Returns the total amount of time in the audio stream. See IAudioDecoder for details.
virtual void setOuterConeAngle(const float &outerAngle)
Sets the angle of the outer sound cone of the source. The cone opens up in the direction of the sourc...
virtual void setMinVolume(const float &minVolume)
Sets the minimum volume that the source can be attenuated to.
virtual void setStrength(const float &soundstrength)
Sets how well the source carries over distance.
virtual void loop(const bool &toLoop)
Controls whether the source should loop or not.
virtual IListener * getListener()=0
Returns the interface for the listener.
virtual void onRelease()
This function is called when a source is released and soon to be deleted.
virtual bool isLooping() const
Returns if the source is looping.
float Volume
Holds the current volume.
Definition: cAudioSource.h:105
virtual int getCompressedAudioSize()
Returns the original size of the audio stream. See IAudioDecoder for details.
virtual float getVolume() const
Returns the source volume before attenuation and other effects.
virtual bool play()=0
Plays the source with the last set parameters.
virtual void setVolume(const float &volume)
Sets the source volume before attenuation and other effects.
virtual cVector3 getDirection() const
Returns the audio objects direction.
virtual void registerEventHandler(ISourceEventHandler *handler)
Registers a new event handler to this source.
virtual void setMaxVolume(const float &maxVolume)
Sets the maximum volume that the source can achieve.
CAUDIO_API ILogger * getLogger()
Gets the interface to the logger.
Definition: cAudio.cpp:45
virtual float getMinDistance() const
Returns the distance from the source where attenuation will begin.
virtual void setRolloffFactor(const float &rolloff)
Sets the factor used in attenuating the source over distance.
CAUDIO_API void cAudioSleep(unsigned int ms)
Causes the current thread to give up control for a certain duration.
Definition: cAudioSleep.cpp:17
virtual float getInnerConeAngle() const
Returns the angle of the inner sound cone of the source.
void signalEvent(Events sevent)
Signals a event to all event handlers.
Main namespace for the entire cAudio library.
Definition: cAudioCapture.h:15
virtual bool isPlaying() const
Returns if the source is playing.