5 #include "cAudioSource.h" 10 #include "cAudioSleep.h" 14 #if CAUDIO_EFX_ENABLED == 1 15 #include "cOpenALDeviceContext.h" 21 ALfloat GetBufferLength(ALuint buffer)
23 ALint size, bits, channels, freq;
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)
32 return (ALfloat)((ALuint)size/channels/(bits/8)) / (ALfloat)freq;
35 ALint GetBufferSize(ALuint buffer)
38 alGetBufferi(buffer, AL_SIZE, &size);
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)
51 cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context)
52 : cAudioSourceBase(context), Decoder(decoder), Loop(false), Valid(false)
55 cAudioMutexBasicLock lock(Mutex);
59 for(
int i=0; i<CAUDIO_SOURCE_NUM_BUFFERS; ++i) {
63 #if CAUDIO_EFX_ENABLED == 1 64 for(
int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
67 for(
int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
68 LastEffectTimeStamp[i] = 0;
74 ALboolean state = alIsSource(Source);
79 alGenBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
80 state = !checkALError();
83 #if CAUDIO_EFX_ENABLED == 1 84 Valid = state && (Decoder != NULL) && (Context != NULL) && (EFX != NULL);
87 ALCdevice* device = alcGetContextsDevice(((cOpenALDeviceContext*)Context)->getOpenALContext());
88 alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &numSlots);
90 EffectSlotsAvailable = (numSlots <= CAUDIO_SOURCE_MAX_EFFECT_SLOTS) ? numSlots : CAUDIO_SOURCE_MAX_EFFECT_SLOTS;
92 Valid = state && (Decoder != NULL) && (Context != NULL);
96 cAudioSource::~cAudioSource()
98 cAudioMutexBasicLock lock(
Mutex);
100 #if CAUDIO_EFX_ENABLED == 1 101 for(
int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
117 alSourcei(
Source, AL_BUFFER, 0);
119 alDeleteBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
128 cAudioSourceBase::cAudioSourceBase(IAudioDeviceContext* context) :
131 alGenSources(1, &Source);
136 cAudioSourceBase::~cAudioSourceBase()
140 alDeleteSources(1, &
Source);
166 alSourcei(
Source, AL_BUFFER, 0);
167 BufferPosition = Decoder->getCurrentPosition();
168 BufferTime = Decoder->getCurrentTime();
170 for(
int u = 0; u < CAUDIO_SOURCE_NUM_BUFFERS; u++)
172 int val = stream(Buffers[u]);
182 alSourceQueueBuffers(
Source, queueSize, Buffers);
185 #if CAUDIO_EFX_ENABLED == 1 187 for(
unsigned int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
194 oldState = AL_PLAYING;
201 alSourcei(
Source, AL_SOURCE_RELATIVE,
true);
211 alSourcei(
Source, AL_SOURCE_RELATIVE,
false);
227 oldState = AL_PAUSED;
237 alGetSourcei(
Source, AL_BUFFERS_QUEUED, &queued);
241 alSourceUnqueueBuffers(
Source, 1, &buffer);
245 Decoder->setPosition(0,
false);
249 oldState = AL_STOPPED;
262 if(Decoder->isSeekingSupported())
264 state = Decoder->seek(seconds, relative);
266 BufferPosition = Decoder->getCurrentPosition();
267 BufferTime = Decoder->getCurrentTime();
270 alGetSourcei(
Source, AL_BUFFERS_QUEUED, &queued);
272 BufferPosition -= queued * GetBufferSize(Buffers[0]);
273 BufferTime -= queued * GetBufferLength(Buffers[0]);
281 return Decoder->getTotalTime();
286 return Decoder->getTotalSize();
291 return Decoder->getCompressedSize();
297 alGetSourcef(
Source, AL_SEC_OFFSET, &time);
298 return BufferTime + time;
304 alGetSourcei(
Source, AL_BYTE_OFFSET, &offset);
305 return BufferPosition + offset;
310 return Decoder->getCurrentCompressedPosition();
321 #if CAUDIO_EFX_ENABLED == 1 323 for(
unsigned int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
328 alGetSourcei(
Source, AL_BUFFERS_PROCESSED, &processed);
335 alSourceUnqueueBuffers(
Source, 1, &buffer);
336 BufferPosition += GetBufferSize(buffer);
337 BufferTime += GetBufferLength(buffer);
346 active = stream(buffer);
351 alSourceQueueBuffers(
Source, 1, &buffer);
366 alGetSourcei(
Source, AL_SOURCE_STATE, &state);
368 if(state == AL_STOPPED && oldState != state)
371 Decoder->setPosition(0,
false);
388 alGetSourcei(
Source, AL_SOURCE_STATE, &state);
390 return (state == AL_PLAYING);
396 alGetSourcei(
Source, AL_SOURCE_STATE, &state);
398 return (state == AL_PAUSED);
404 alGetSourcei(
Source, AL_SOURCE_STATE, &state);
406 return (state == AL_STOPPED);
417 alSource3f(
Source, AL_POSITION, position.x, position.y, position.z);
424 alSource3f(
Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
431 alSource3f(
Source, AL_DIRECTION, direction.x, direction.y, direction.z);
438 alSourcef(
Source, AL_ROLLOFF_FACTOR, rolloff);
444 float inverseStrength = 0.0f;
445 if(soundstrength > 0.0f)
446 inverseStrength = 1.0f / soundstrength;
449 alSourcef(
Source, AL_ROLLOFF_FACTOR, inverseStrength);
456 alSourcef(
Source, AL_REFERENCE_DISTANCE, minDistance);
463 alSourcef(
Source, AL_MAX_DISTANCE, maxDistance);
470 alSourcef (
Source, AL_PITCH, pitch);
485 alSourcef(
Source, AL_MIN_GAIN, minVolume);
492 alSourcef(
Source, AL_MAX_GAIN, maxVolume);
499 alSourcef(
Source, AL_CONE_INNER_ANGLE, innerAngle);
506 alSourcef(
Source, AL_CONE_OUTER_ANGLE, outerAngle);
513 alSourcef(
Source, AL_CONE_OUTER_GAIN, outerVolume);
520 alSourcef(
Source, AL_DOPPLER_FACTOR, dstrength);
527 alSource3f(
Source, AL_DOPPLER_VELOCITY, dvelocity.x, dvelocity.y, dvelocity.z);
535 cVector3 velocity = position - oldPos;
537 alSource3f(
Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
538 alSource3f(
Source, AL_POSITION, position.x, position.y, position.z);
545 alGetSourcefv(
Source, AL_POSITION, &position.x);
553 alGetSourcefv(
Source, AL_VELOCITY, &velocity.x);
560 alGetSourcefv(
Source, AL_DIRECTION, &direction.x);
568 alGetSourcef(
Source, AL_ROLLOFF_FACTOR, &value);
576 alGetSourcef(
Source, AL_ROLLOFF_FACTOR, &value);
579 float inverseStrength = 0.0f;
581 inverseStrength = 1.0f / value;
583 return inverseStrength;
589 alGetSourcef(
Source, AL_REFERENCE_DISTANCE, &value);
597 alGetSourcef(
Source, AL_MAX_DISTANCE, &value);
605 alGetSourcei(
Source, AL_SOURCE_RELATIVE, &relative);
624 dist = std::max(dist, refDist);
633 alGetSourcef(
Source, AL_PITCH, &value);
646 alGetSourcef(
Source, AL_MIN_GAIN, &value);
654 alGetSourcef(
Source, AL_MAX_GAIN, &value);
662 alGetSourcef(
Source, AL_CONE_INNER_ANGLE, &value);
670 alGetSourcef(
Source, AL_CONE_OUTER_ANGLE, &value);
678 alGetSourcef(
Source, AL_CONE_OUTER_GAIN, &value);
686 alGetSourcef(
Source, AL_DOPPLER_FACTOR, &value);
694 alGetSourcefv(
Source, AL_DOPPLER_VELOCITY, &velocity.x);
699 #if CAUDIO_EFX_ENABLED == 1 700 unsigned int cAudioSource::getNumEffectSlotsAvailable()
const 702 return EffectSlotsAvailable;
705 bool cAudioSource::attachEffect(
unsigned int slot, IEffect* effect)
708 if(slot < EffectSlotsAvailable)
710 Effects[slot] = effect;
713 Effects[slot]->grab();
721 void cAudioSource::removeEffect(
unsigned int slot)
724 if(slot < EffectSlotsAvailable)
727 Effects[slot]->drop();
729 Effects[slot] = NULL;
730 LastEffectTimeStamp[slot] = 0;
731 updateEffect(slot,
true);
735 bool cAudioSource::attachFilter(IFilter* filter)
747 void cAudioSource::removeFilter()
753 LastFilterTimeStamp = 0;
758 void cAudioSource::empty()
761 alGetSourcei(
Source, AL_BUFFERS_QUEUED, &queued);
767 alSourceUnqueueBuffers(
Source, 1, &buffer);
772 bool cAudioSource::stream(ALuint buffer)
778 size_t totalread = 0;
779 unsigned int errorcount = 0;
780 char tempbuffer[CAUDIO_SOURCE_BUFFER_SIZE];
781 while( totalread < CAUDIO_SOURCE_BUFFER_SIZE )
783 char tempbuffer2[CAUDIO_SOURCE_BUFFER_SIZE];
785 int actualread = Decoder->readAudioData(tempbuffer2, CAUDIO_SOURCE_BUFFER_SIZE-totalread);
790 memcpy(tempbuffer+totalread,tempbuffer2,actualread);
791 totalread += actualread;
796 getLogger()->
logDebug(
"Audio Source",
"Decoder returned an error: %i (%i of 3)", actualread, errorcount);
808 Decoder->setPosition(0,
false);
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());
827 #if CAUDIO_EFX_ENABLED == 1 828 void cAudioSource::updateFilter(
bool remove)
832 if(Filter && Filter->isValid())
834 if(LastFilterTimeStamp != Filter->getLastUpdated())
836 LastFilterTimeStamp = Filter->getLastUpdated();
837 cFilter* theFilter =
static_cast<cFilter*
>(Filter);
840 alSourcei(
Source, AL_DIRECT_FILTER, theFilter->getOpenALFilter());
848 alSourcei(
Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
852 void cAudioSource::updateEffect(
unsigned int slot,
bool remove)
854 if(slot < EffectSlotsAvailable)
858 if(Effects[slot] && Effects[slot]->
isValid())
860 if(LastEffectTimeStamp[slot] != Effects[slot]->getLastUpdated())
862 LastEffectTimeStamp[slot] = Effects[slot]->getLastUpdated();
863 cEffect* theEffect =
static_cast<cEffect*
>(Effects[slot]);
866 ALuint filterID = AL_FILTER_NULL;
867 cFilter* theFilter =
static_cast<cFilter*
>(theEffect->getFilter());
870 filterID = theFilter->getOpenALFilter();
872 alSource3i(
Source, AL_AUXILIARY_SEND_FILTER, theEffect->getOpenALEffectSlot(), slot, filterID);
880 alSource3i(
Source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, slot, AL_FILTER_NULL);
921 for(
int i=0; i<size; )
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;
virtual int getCurrentAudioPosition()
Returns the current position in the decoded audio stream in bytes. See IAudioDecoder for details...
virtual bool isRelative() const
Return true for 2d sounds, false for 3d sounds.
ALenum convertAudioFormatEnum(AudioFormats format)
Converts our audio format enum to OpenAL's.
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 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 float getOuterConeVolume() const
Returns how much the volume of the source is scaled in the outer cone.
virtual bool isStopped() const
Returns if the source is stopped.
virtual bool play2d(const bool &toLoop=false)
Plays the source in 2D mode.
virtual bool isValid() const =0
Returns if the source is ready to be used.
virtual cVector3 getPosition(void) const =0
Returns the current position of the listener.
virtual void setMinDistance(const float &minDistance)
Sets the distance from the source where attenuation will begin.
virtual float getMinVolume() const
Returns the minimum volume that the source can be attenuated to.
virtual void stop()=0
Stops playback of the sound source.
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 getRolloffFactor() const
Returns the factor used in attenuating the source over distance.
virtual float getOuterConeAngle() const
Returns the angle of the outer sound cone of the source.
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 bool drop()
Decrements the reference count by one. If it hits zero, this object is deleted.
virtual void logDebug(const char *sender, const char *msg,...)=0
Used to log a debug message to the logging system.
cAudioVector< ISourceEventHandler * >::Type eventHandlerList
List of registered event handlers.
virtual int getCurrentCompressedAudioPosition()
Returns the current position in the original audio stream in bytes. See IAudioDecoder for details...
virtual float getDopplerStrength() const
Returns the doppler strength, which enhances or diminishes the doppler effect.
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 cVector3 getDirection() const
Returns the audio objects direction.
virtual int getTotalAudioSize()
Returns the total decoded size of the audio stream. See IAudioDecoder for details.
virtual float getMasterVolume() const =0
Get the master volume.
virtual void setOuterConeVolume(const float &outerVolume)
Sets how much the volume of the source is scaled in the outer cone.
virtual bool isLooping() const =0
Returns if the source is looping.
virtual float getMaxVolume() const
Returns the maximum volume that the source can achieve.
virtual void setDopplerVelocity(const cVector3 &dvelocity)
Overrides the doppler velocity vector. It is usually better to let the engine take care of it automat...
cAudioMutex Mutex
Mutex for thread synchronization.
virtual void setDopplerStrength(const float &dstrength)
Sets the doppler strength, which enhances or diminishes the doppler effect. Can be used to exaggerate...
Interface for event handlers on Audio Sources.
virtual bool drop()
Decrements the reference count by one. If it hits zero, this object is deleted.
virtual float getMinDistance() const
Returns the distance from the source where attenuation will begin.
virtual void onUpdate()
This function is called when a source updates its buffers.
virtual float getPitch() const
Returns the pitch of the source.
IAudioDeviceContext * Context
The context that owns this source.
virtual bool isPlaying() const
Returns if the source is playing.
Class for manipulating vectors in 3D space.
virtual float getInnerConeAngle() const
Returns the angle of the inner sound cone of the source.
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.
virtual bool isValid() const
Returns if the source is ready to be used.
ALuint Source
OpenAL source.
virtual bool isLooping() const
Returns if the source is looping.
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 cVector3 getVelocity() const
Returns the audio objects velocity.
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 bool isPaused() const
Returns if the source is paused.
virtual void setStrength(const float &soundstrength)
Sets how well the source carries over distance.
virtual float getVolume() const
Returns the source volume before attenuation and other effects.
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 cVector3 getDopplerVelocity() const
Returns the override for the doppler velocity vector.
float Volume
Holds the current volume.
virtual int getCompressedAudioSize()
Returns the original size of the audio stream. See IAudioDecoder for details.
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.
float length() const
Returns the length (magnitude) of the vector.
virtual float getStrength() const
Returns the strength of the source.
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.
virtual float getMaxDistance() const
Returns the distance from the source where attenuation will stop.
CAUDIO_API ILogger * getLogger()
Gets the interface to the logger.
virtual cVector3 getPosition() const
Returns the audio objects position.
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.
void signalEvent(Events sevent)
Signals a event to all event handlers.
Main namespace for the entire cAudio library.