void SoundSystem::Suspend() { Deque<SoundChannel*>::iterator it; Deque<SoundChannel*>::iterator itEnd = channelsPool.end(); for(it = channelsPool.begin(); it != itEnd; ++it) { SoundChannel * ch = *it; if(SoundChannel::STATE_PLAYING == ch->GetState()) { ch->Pause(true); } } #ifdef __DAVASOUND_AL__ alcSuspendContext(context); #endif }
ALAPI ALvoid ALAPIENTRY alDopplerFactor(ALfloat value) { ALCcontext *Context; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (value>=0.0f) { Context->DopplerFactor=value; Context->Listener.update1 = LDOPPLERFACTOR; alcUpdateContext(Context, ALLISTENER, 0); } else alSetError(AL_INVALID_VALUE); alcProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alDopplerVelocity(ALfloat value) { ALCcontext *Context; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (value>0.0f) { Context->DopplerVelocity=value; Context->Listener.update1 = LDOPPLERVELOCITY; alcUpdateContext(Context, 0, 0); } else alSetError(AL_INVALID_VALUE); alcProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alGetIntegerv(ALenum pname,ALint *data) { ALCcontext *Context; Context=alcGetCurrentContext(); alcSuspendContext(Context); switch (pname) { case AL_DISTANCE_MODEL: *data=Context->DistanceModel; break; default: alSetError(AL_INVALID_ENUM); break; } alcProcessContext(Context); }
AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep) { AUD_Specs specs = reader->getSpecs(); // check format if(specs.channels == AUD_CHANNELS_INVALID) return AUD_Reference<AUD_IHandle>(); if(m_specs.format != AUD_FORMAT_FLOAT32) reader = new AUD_ConverterReader(reader, m_specs); ALenum format; if(!getFormat(format, specs)) return AUD_Reference<AUD_IHandle>(); lock(); alcSuspendContext(m_context); AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound; try { // create the handle sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep); } catch(AUD_Exception&) { alcProcessContext(m_context); unlock(); throw; } alcProcessContext(m_context); // play sound m_playingSounds.push_back(sound); start(); unlock(); return AUD_Reference<AUD_IHandle>(sound); }
ALAPI ALint ALAPIENTRY alGetInteger(ALenum pname) { ALCcontext *Context; ALint value=0; Context=alcGetCurrentContext(); alcSuspendContext(Context); switch (pname) { case AL_DISTANCE_MODEL: value=Context->DistanceModel; break; default: alSetError(AL_INVALID_ENUM); break; } alcProcessContext(Context); return value; }
std::shared_ptr<IHandle> OpenALDevice::play(std::shared_ptr<IReader> reader, bool keep) { Specs specs = reader->getSpecs(); // check format if(specs.channels == CHANNELS_INVALID) return std::shared_ptr<IHandle>(); if(m_specs.format != FORMAT_FLOAT32) reader = std::shared_ptr<IReader>(new ConverterReader(reader, m_specs)); ALenum format; if(!getFormat(format, specs)) return std::shared_ptr<IHandle>(); std::lock_guard<std::recursive_mutex> lock(m_mutex); alcSuspendContext(m_context); std::shared_ptr<OpenALDevice::OpenALHandle> sound; try { // create the handle sound = std::shared_ptr<OpenALDevice::OpenALHandle>(new OpenALDevice::OpenALHandle(this, format, reader, keep)); } catch(Exception&) { alcProcessContext(m_context); throw; } alcProcessContext(m_context); // play sound m_playingSounds.push_back(sound); start(); return std::shared_ptr<IHandle>(sound); }
ALAPI ALboolean ALAPIENTRY alIsSource(ALuint source) { ALboolean result=AL_FALSE; ALCcontext *Context; ALsource *Source; Context=alcGetCurrentContext(); alcSuspendContext(Context); Source=((ALsource *)source); if (Source) { if ((Source->previous==NULL)||(Source->previous->next==Source)) { if ((Source->next==NULL)||(Source->next->previous==Source)) result=Source->valid; } } alcProcessContext(Context); return result; }
ALAPI ALvoid ALAPIENTRY alGetFloatv(ALenum pname,ALfloat *data) { ALCcontext *Context; Context=alcGetCurrentContext(); alcSuspendContext(Context); switch (pname) { case AL_DOPPLER_FACTOR: *data=Context->DopplerFactor; break; case AL_DOPPLER_VELOCITY: *data=Context->DopplerVelocity; break; default: alSetError(AL_INVALID_ENUM); break; } alcProcessContext(Context); }
CSoundEngine::~CSoundEngine() { // unload subclasses UNLOAD_SUBCLASS(SoundManager); if(m_extensions) delete m_extensions; if(m_context) { alcSuspendContext(m_context); alcMakeContextCurrent(NULL); alcDestroyContext(m_context); } if(m_device) alcCloseDevice(m_device); m_context = NULL; m_device = NULL; m_extensions = NULL; }
void SoundSystemOAL::pause() { log::messageln("SoundSystemOAL::pause"); /* for (channels::iterator i = _channels.begin(); i != _channels.end(); ++i) { ChannelOAL& channel = *i; channel.pause(); } */ #if defined(__ANDROID__) //android needs special workaround alcSuspend(); #endif #if defined(__S3E__) alcSuspendContext(_context); alcMakeContextCurrent(0); #endif }
ALAPI ALvoid ALAPIENTRY alSourcePause(ALuint source) { ALCcontext *Context; ALsource *Source; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (alIsSource(source)) { Source=((ALsource *)source); if (Source->state==AL_PLAYING) { Source->state=AL_PAUSED; Source->inuse=AL_FALSE; } Source->update1 = STATE; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_OPERATION); alcProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alDistanceModel(ALenum value) { ALCcontext *Context; Context=alcGetCurrentContext(); alcSuspendContext(Context); switch (value) { case AL_NONE: case AL_INVERSE_DISTANCE: case AL_INVERSE_DISTANCE_CLAMPED: Context->DistanceModel=value; Context->Listener.update1 = LROLLOFFFACTOR; alcUpdateContext(Context, ALLISTENER, 0); break; default: alSetError(AL_INVALID_VALUE); break; } alcProcessContext(Context); }
void audio_update (const Vector3& position, const Vector3& velocity, const Quaternion& rotation) { ALfloat pos[] = { position.x, position.y, position.z }; ALfloat vel[] = { velocity.x, velocity.y, velocity.z }; ALfloat zeros[] = { 0.0f, 0.0f, 0.0f }; Vector3 at = rotation * Vector3(0.0f, 1.0f, 0.0f); Vector3 up = rotation * Vector3(0.0f, 0.0f, 1.0f); ALfloat ori[] = { at.x, at.y, at.z, up.x, up.y, up.z }; alcSuspendContext(alContext); alListenerfv(AL_POSITION, pos); alListenerfv(AL_VELOCITY, audio_option(AUDIO_DOPPLER_ENABLED) ? vel : zeros); alListenerfv(AL_ORIENTATION, ori); float volume = audio_option(AUDIO_MUTE) ? 0 : audio_option(AUDIO_MASTER_VOLUME); alListenerfv(AL_GAIN, &volume); alcProcessContext(alContext); // destroy any one-shot sounds that finished playing // NOTE: this won't account for cases where there's still a sound playing when the game exits for (unsigned i=0 ; i<one_shot_sounds.size() ; ++i) { OneShotSound &oss = one_shot_sounds[i]; ALuint &src = oss.sound; ALint playing; alGetSourcei(src, AL_SOURCE_STATE, &playing); if (playing != AL_PLAYING) { alDeleteSources(1, &src); one_shot_sounds[i] = one_shot_sounds[one_shot_sounds.size()-1]; one_shot_sounds.pop_back(); i--; // re-examine index i again, next iteration } } }
ALAPI ALfloat ALAPIENTRY alGetFloat(ALenum pname) { ALCcontext *Context; ALfloat value=0.0f; Context=alcGetCurrentContext(); alcSuspendContext(Context); switch (pname) { case AL_DOPPLER_FACTOR: value=Context->DopplerFactor; break; case AL_DOPPLER_VELOCITY: value=Context->DopplerVelocity; break; default: alSetError(AL_INVALID_ENUM); break; } alcProcessContext(Context); return value; }
void Sound::Suspend() { //Always check if openal is initialized if (!OpenALInit()) return; OpenALChannel* channel = 0; for (int i = 0; i < sgOpenChannels.size(); i++) { channel = (OpenALChannel*)(sgOpenChannels[i]); if (channel) { channel->suspend(); } } alcMakeContextCurrent(0); alcSuspendContext(sgContext); #ifdef ANDROID alcSuspend(); #endif }
OpenALDevice::~OpenALDevice() { lock(); alcSuspendContext(m_context); while(!m_playingSounds.empty()) m_playingSounds.front()->stop(); while(!m_pausedSounds.empty()) m_pausedSounds.front()->stop(); alcProcessContext(m_context); // wait for the thread to stop unlock(); if(m_thread.joinable()) m_thread.join(); // quit OpenAL alcMakeContextCurrent(nullptr); alcDestroyContext(m_context); alcCloseDevice(m_device); }
ALAPI ALvoid ALAPIENTRY alSource3f(ALuint source,ALenum pname,ALfloat v1,ALfloat v2,ALfloat v3) { ALCcontext *Context; ALsource *Source; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (alIsSource(source)) { Source=((ALsource *)source); switch(pname) { case AL_POSITION: case AL_VELOCITY: case AL_DIRECTION: Source->param[pname-AL_CONE_INNER_ANGLE].data.fv3[0]=v1; Source->param[pname-AL_CONE_INNER_ANGLE].data.fv3[1]=v2; Source->param[pname-AL_CONE_INNER_ANGLE].data.fv3[2]=v3; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; if (pname == AL_POSITION) Source->update1 |= POSITION; else if (pname == AL_VELOCITY) Source->update1 |= VELOCITY; else if (pname == AL_DIRECTION) Source->update1 |= ORIENTATION; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); alcProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alSourcePlayv(ALsizei n,ALuint *sources) { ALCcontext *Context; ALsource *Source; ALsizei i; Context=alcGetCurrentContext(); alcSuspendContext(Context); for (i=0;i<n;i++) { if (alIsSource(sources[i])) { Source=((ALsource *)sources[i]); if (Source->state!=AL_PAUSED) { Source->state=AL_PLAYING; Source->inuse=AL_TRUE; Source->play=AL_TRUE; Source->position=0; Source->position_fraction=0; Source->BuffersProcessed = 0; Source->BuffersAddedToDSBuffer = 0; } else { Source->state=AL_PLAYING; Source->inuse=AL_TRUE; Source->play=AL_TRUE; } Source->update1 |= STATE; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_OPERATION); } alcProcessContext(Context); }
void Contexte::pauseContexte() { alcSuspendContext(alcGetCurrentContext()); }
ALvoid CDECL wine_alcSuspendContext(ALCcontext *context) { alcSuspendContext(context); }
void AUD_OpenALDevice::updateStreams() { AUD_Reference<AUD_OpenALHandle> sound; int length; ALint info; AUD_DeviceSpecs specs = m_specs; ALCenum cerr; std::list<AUD_Reference<AUD_OpenALHandle> > stopSounds; std::list<AUD_Reference<AUD_OpenALHandle> > pauseSounds; AUD_HandleIterator it; while(1) { lock(); alcSuspendContext(m_context); cerr = alcGetError(m_device); if(cerr == ALC_NO_ERROR) { // for all sounds for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++) { sound = *it; // is it a streamed sound? if(!sound->m_isBuffered) { // check for buffer refilling alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info); if(info) { specs.specs = sound->m_reader->getSpecs(); m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs)); // for all empty buffers while(info--) { // if there's still data to play back if(!sound->m_eos) { // read data length = m_buffersize; sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer()); // looping necessary? if(length == 0 && sound->m_loopcount) { if(sound->m_loopcount > 0) sound->m_loopcount--; sound->m_reader->seek(0); length = m_buffersize; sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer()); } if(sound->m_loopcount != 0) sound->m_eos = false; // read nothing? if(length == 0) { break; } // unqueue buffer alSourceUnqueueBuffers(sound->m_source, 1, &sound->m_buffers[sound->m_current]); ALenum err; if((err = alGetError()) != AL_NO_ERROR) { sound->m_eos = true; break; } // fill with new data alBufferData(sound->m_buffers[sound->m_current], sound->m_format, m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate); if((err = alGetError()) != AL_NO_ERROR) { sound->m_eos = true; break; } // and queue again alSourceQueueBuffers(sound->m_source, 1, &sound->m_buffers[sound->m_current]); if(alGetError() != AL_NO_ERROR) { sound->m_eos = true; break; } sound->m_current = (sound->m_current+1) % AUD_OpenALHandle::CYCLE_BUFFERS; } else break; } } } // check if the sound has been stopped alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info); if(info != AL_PLAYING) { // if it really stopped if(sound->m_eos) { if(sound->m_stop) sound->m_stop(sound->m_stop_data); // pause or if(sound->m_keep) pauseSounds.push_back(sound); // stop else stopSounds.push_back(sound); } // continue playing else alSourcePlay(sound->m_source); } } for(it = pauseSounds.begin(); it != pauseSounds.end(); it++) (*it)->pause(); for(it = stopSounds.begin(); it != stopSounds.end(); it++) (*it)->stop(); pauseSounds.clear(); stopSounds.clear(); alcProcessContext(m_context); } // stop thread if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR)) { m_playing = false; unlock(); pthread_exit(NULL); } unlock(); #ifdef WIN32 Sleep(20); #else usleep(20000); #endif } }
static void Stop(void) { ALCcontext *ctxt; ctxt = alcGetCurrentContext(); alcSuspendContext(ctxt); }
ALAPI ALvoid ALAPIENTRY alSourceQueueBuffers( ALuint source, ALsizei n, ALuint* buffers ) { ALCcontext *Context; ALsource *ALSource; ALsizei i; ALbufferlistitem *ALBufferList; ALbufferlistitem *ALBufferListStart; ALuint DataSize; ALuint BufferSize; Context=alcGetCurrentContext(); alcSuspendContext(Context); ALSource = (ALsource*)source; DataSize = 0; BufferSize = 0; // Check that all buffers are valid or zero and that the source is valid // Check that this is a valid source if (!alIsSource(source)) { alSetError(AL_INVALID_NAME); alcProcessContext(Context); return; } for (i = 0; i < n; i++) { if ((!alIsBuffer(buffers[i])) && (buffers[i] != 0)) { alSetError(AL_INVALID_NAME); alcProcessContext(Context); return; } } // All buffers are valid - so add them to the list ALBufferListStart = malloc(sizeof(ALbufferlistitem)); ALBufferListStart->buffer = buffers[0]; ALBufferListStart->bufferstate = PENDING; ALBufferListStart->flag = 0; ALBufferListStart->next = NULL; alGetBufferi(buffers[0], AL_SIZE, &BufferSize); DataSize += BufferSize; // Increment reference counter for buffer if (buffers[0] != 0) ((ALbuffer*)(buffers[0]))->refcount++; ALBufferList = ALBufferListStart; for (i = 1; i < n; i++) { ALBufferList->next = malloc(sizeof(ALbufferlistitem)); ALBufferList->next->buffer = buffers[i]; ALBufferList->next->bufferstate = PENDING; ALBufferList->next->flag = 0; ALBufferList->next->next = NULL; alGetBufferi(buffers[i], AL_SIZE, &BufferSize); DataSize += BufferSize; // Increment reference counter for buffer if (buffers[i] != 0) ((ALbuffer*)(buffers[i]))->refcount++; ALBufferList = ALBufferList->next; } if (ALSource->queue == NULL) { ALSource->queue = ALBufferListStart; // Update Current Buffer ALSource->param[AL_BUFFER-AL_CONE_INNER_ANGLE].data.i = ALBufferListStart->buffer; } else { // Find end of queue ALBufferList = ALSource->queue; while (ALBufferList->next != NULL) { ALBufferList = ALBufferList->next; } ALBufferList->next = ALBufferListStart; } // Update number of buffers in queue ALSource->BuffersInQueue += n; // Record the amount of data added to the queue ALSource->SizeOfBufferDataAddedToQueue = DataSize; ALSource->NumBuffersAddedToQueue = n; ALSource->update1 |= SQUEUE; alcUpdateContext(Context, ALSOURCE, source); alcProcessContext(Context); }
void Mixer::suspend_processing () { alcSuspendContext(_audio_context); }
void lime_alc_suspend_context (value context) { ALCcontext* alcContext = (ALCcontext*)val_data (context); alcSuspendContext (alcContext); }
ALAPI ALvoid ALAPIENTRY alSourcei(ALuint source,ALenum pname,ALint value) { ALCcontext *Context; ALsource *Source; ALbufferlistitem *ALBufferListItem; ALint Counter = 0; ALint DataSize = 0; ALint BufferSize; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (alIsSource(source)) { Source=((ALsource *)source); switch(pname) { case AL_SOURCE_RELATIVE: if ((value==AL_FALSE)||(value==AL_TRUE)) { Source->relative=value; Source->update1 |= MODE; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_VALUE); break; case AL_CONE_INNER_ANGLE: case AL_CONE_OUTER_ANGLE: if ((value>=0)&&(value<=360)) { Source->param[pname-AL_CONE_INNER_ANGLE].data.f=(float)value; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; Source->update1 |= CONEANGLES; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_VALUE); break; case AL_LOOPING: if ((value==AL_FALSE)||(value==AL_TRUE)) { Source->param[pname-AL_CONE_INNER_ANGLE].data.i=value; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; Source->update1 |= LOOPED; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_VALUE); break; case AL_BUFFER: if ((Source->state == AL_STOPPED) || (Source->state == AL_INITIAL)) { if (alIsBuffer(value) || (value == 0)) { // Remove all elements in the queue while (Source->queue != NULL) { ALBufferListItem = Source->queue; Source->queue = ALBufferListItem->next; // Decrement reference counter for buffer if (ALBufferListItem->buffer) ((ALbuffer*)(ALBufferListItem->buffer))->refcount--; // Record size of buffer alGetBufferi(ALBufferListItem->buffer, AL_SIZE, &BufferSize); DataSize += BufferSize; // Increment the number of buffers removed from queue Counter++; // Release memory for buffer list item free(ALBufferListItem); // Decrement the number of buffers in the queue Source->BuffersInQueue--; } // Update variables required by the SUNQUEUE routine in UpdateContext Source->NumBuffersRemovedFromQueue = Counter; Source->SizeOfBufferDataRemovedFromQueue = DataSize; Source->update1 |= SUNQUEUE; alcUpdateContext(Context, ALSOURCE, source); // Add the buffer to the queue (as long as it is NOT the NULL buffer) if (value != 0) { // Add the selected buffer to the queue ALBufferListItem = malloc(sizeof(ALbufferlistitem)); ALBufferListItem->buffer = value; ALBufferListItem->bufferstate = PENDING; ALBufferListItem->flag = 0; ALBufferListItem->next = NULL; Source->queue = ALBufferListItem; Source->BuffersInQueue = 1; alGetBufferi(value, AL_SIZE, &DataSize); // Increment reference counter for buffer ((ALbuffer*)(value))->refcount++; Source->SizeOfBufferDataAddedToQueue = DataSize; Source->NumBuffersAddedToQueue = 1; Source->update1 |= SQUEUE; alcUpdateContext(Context, ALSOURCE, source); } // Set Buffers Processed Source->BuffersProcessed = 0; // Update AL_BUFFER parameter Source->param[pname-AL_CONE_INNER_ANGLE].data.i=value; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; } else alSetError(AL_INVALID_VALUE); } else alSetError(AL_INVALID_OPERATION); break; case AL_SOURCE_STATE: Source->state=value; Source->update1 |= STATE; alcUpdateContext(Context, ALSOURCE, (ALuint)Source); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); alcProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alSourceUnqueueBuffers( ALuint source, ALsizei n, ALuint* buffers ) { ALCcontext *Context; ALsource *ALSource; ALsizei i; ALbufferlistitem *ALBufferList; ALbufferlistitem *ALBufferListTemp; ALuint DataSize; ALuint BufferSize; ALuint BufferID; DataSize = 0; BufferSize = 0; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (alIsSource(source)) { ALSource = (ALsource*)source; // Check that each of the requested buffers to be unqueued have been processed for (i = 0; i < n; i++) { ALBufferList = ALSource->queue; // Find buffer[i] in the queue and check that it has been processed while (ALBufferList != NULL) { // Check if this is the buffer to be removed. If it is, mark it so that we won't try // and remove it multiple times (this can happen if the application queues the same buffer // multiple times, and then removes the incorrect amount) if ((ALBufferList->buffer == buffers[i]) && (ALBufferList->flag != READYTOREMOVE)) { // Set flag to indicate that this buffer is marked for removal ALBufferList->flag = READYTOREMOVE; break; } else ALBufferList = ALBufferList->next; } if ((ALBufferList == NULL) || (ALBufferList->bufferstate != PROCESSED)) { // Buffer not found - or not ready for unqueuing alSetError(AL_INVALID_VALUE); alcProcessContext(Context); return; } } // OK to proceed with removal of buffers from queue for (i = 0; i < n; i++) { // Find each buffer to unqueue and remove it from the list ALBufferList = ALSource->queue; if (ALBufferList->buffer == buffers[i]) { ALSource->queue = ALBufferList->next; // Decrement buffer reference counter if (ALBufferList->buffer) ((ALbuffer*)(ALBufferList->buffer))->refcount--; // Record size of buffer alGetBufferi(ALBufferList->buffer, AL_SIZE, &BufferSize); DataSize += BufferSize; // Release memory for buffer list item free(ALBufferList); ALSource->BuffersInQueue--; ALSource->BuffersProcessed--; } else { while (ALBufferList->next != NULL) { if (ALBufferList->next->buffer == buffers[i]) { ALBufferListTemp = ALBufferList->next; ALBufferList->next = ALBufferList->next->next; // Decrement buffer reference counter if (ALBufferListTemp->buffer) ((ALbuffer*)(ALBufferListTemp->buffer))->refcount--; // Record size of buffer alGetBufferi(ALBufferListTemp->buffer, AL_SIZE, &BufferSize); DataSize += BufferSize; // Release memory for buffer list item free(ALBufferListTemp); ALSource->BuffersInQueue--; ALSource->BuffersProcessed--; break; } ALBufferList = ALBufferList->next; } } } if (ALSource->state != AL_PLAYING) { if (ALSource->queue) BufferID = ALSource->queue->buffer; else BufferID = 0; ALSource->param[AL_BUFFER-AL_CONE_INNER_ANGLE].data.i = BufferID; } ALSource->NumBuffersRemovedFromQueue = n; ALSource->SizeOfBufferDataRemovedFromQueue = DataSize; ALSource->BuffersAddedToDSBuffer -= ALSource->NumBuffersRemovedFromQueue; ALSource->update1 |= SUNQUEUE; alcUpdateContext(Context, ALSOURCE, source); } else { // Invalid source name alSetError(AL_INVALID_NAME); } alcProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alGenSources(ALsizei n,ALuint *sources) { ALCcontext *Context; ALsource *Source; ALsizei i=0; Context=alcGetCurrentContext(); alcSuspendContext(Context); // Check that the requested number of sources can be generated if ((Context->SourceCount + n) > Context->Device->MaxNoOfSources) { alSetError(AL_INVALID_VALUE); alcProcessContext(Context); return; } if (!Context->Source) { // First Source to be created ! Context->Source=malloc(sizeof(ALsource)); if (Context->Source) { memset(Context->Source,0,sizeof(ALsource)); sources[i]=(ALuint)Context->Source; Context->Source->valid=AL_TRUE; Context->Source->update1 |= SGENERATESOURCE; Context->Source->param[AL_CONE_INNER_ANGLE-AL_CONE_INNER_ANGLE].data.f=360.0; Context->Source->param[AL_CONE_INNER_ANGLE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_CONE_OUTER_ANGLE-AL_CONE_INNER_ANGLE].data.f=360.0; Context->Source->param[AL_CONE_OUTER_ANGLE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_PITCH-AL_CONE_INNER_ANGLE].data.f= 1.0; Context->Source->param[AL_PITCH-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_POSITION-AL_CONE_INNER_ANGLE].data.fv3[0]=0.0; Context->Source->param[AL_POSITION-AL_CONE_INNER_ANGLE].data.fv3[1]=0.0; Context->Source->param[AL_POSITION-AL_CONE_INNER_ANGLE].data.fv3[2]=0.0; Context->Source->param[AL_POSITION-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].data.fv3[0]=0.0; Context->Source->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].data.fv3[1]=0.0; Context->Source->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].data.fv3[2]=0.0; Context->Source->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].data.fv3[0]=0.0; Context->Source->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].data.fv3[1]=0.0; Context->Source->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].data.fv3[2]=0.0; Context->Source->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_REFERENCE_DISTANCE-AL_CONE_INNER_ANGLE].data.f= 1.0; Context->Source->param[AL_REFERENCE_DISTANCE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_MAX_DISTANCE-AL_CONE_INNER_ANGLE].data.f= 1000000.0; Context->Source->param[AL_MAX_DISTANCE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_ROLLOFF_FACTOR-AL_CONE_INNER_ANGLE].data.f= 1.0; Context->Source->param[AL_ROLLOFF_FACTOR-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_LOOPING-AL_CONE_INNER_ANGLE].data.i= AL_FALSE; Context->Source->param[AL_LOOPING-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_GAIN-AL_CONE_INNER_ANGLE].data.f= 1.0f; Context->Source->param[AL_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_MIN_GAIN-AL_CONE_INNER_ANGLE].data.f= 0.0f; Context->Source->param[AL_MIN_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_MAX_GAIN-AL_CONE_INNER_ANGLE].data.f= 1.0f; Context->Source->param[AL_MAX_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->param[AL_CONE_OUTER_GAIN-AL_CONE_INNER_ANGLE].data.f= 1.0f; Context->Source->param[AL_CONE_OUTER_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->state = AL_INITIAL; Context->Source->param[AL_BUFFER-AL_CONE_INNER_ANGLE].data.i= 0; Context->Source->param[AL_BUFFER-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Context->Source->update1 |= CONEANGLES | FREQUENCY | POSITION | VELOCITY | ORIENTATION | MINDIST | MAXDIST | LOOPED | VOLUME | CONEOUTSIDEVOLUME | STATE; Context->Source->eaxBP.lDirect = EAXBUFFER_DEFAULTDIRECT; Context->Source->eaxBP.lDirectHF = EAXBUFFER_DEFAULTDIRECTHF; Context->Source->eaxBP.lRoom = EAXBUFFER_DEFAULTROOM; Context->Source->eaxBP.lRoomHF = EAXBUFFER_DEFAULTROOMHF; Context->Source->eaxBP.flRoomRolloffFactor = EAXBUFFER_DEFAULTROOMROLLOFFFACTOR; Context->Source->eaxBP.lObstruction = EAXBUFFER_DEFAULTOBSTRUCTION; Context->Source->eaxBP.flObstructionLFRatio = EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO; Context->Source->eaxBP.lOcclusion = EAXBUFFER_DEFAULTOCCLUSION; Context->Source->eaxBP.flOcclusionLFRatio = EAXBUFFER_DEFAULTOCCLUSIONLFRATIO; Context->Source->eaxBP.flOcclusionRoomRatio = EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO; Context->Source->eaxBP.lOutsideVolumeHF = EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF; Context->Source->eaxBP.flAirAbsorptionFactor = EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR; Context->Source->eaxBP.dwFlags = EAXBUFFER_DEFAULTFLAGS; Context->Source->update2 |= SALLPARAMS; Context->SourceCount++; i++; } alcUpdateContext(Context, ALSOURCE, (ALuint)Context->Source); // Some Listener Settings (e.g EAX 2.0 Reverb) can only be initialized once a Source has been // created, so call alcUpdateContext again to update Listener parameters alcUpdateContext(Context, ALLISTENER, 0); Source=Context->Source; } else { // Some number of sources have already been created - move to the end of the list Source=Context->Source; while (Source->next) Source=Source->next; } // Add additional sources to the list (Source->next points to the location for the next Source structure) while ((Source)&&(i<n)) { Source->next=malloc(sizeof(ALsource)); if (Source->next) { memset(Source->next,0,sizeof(ALsource)); sources[i]=(ALuint)Source->next; Source->next->previous=Source; Source->next->valid=AL_TRUE; Source->next->update1 |= SGENERATESOURCE; Source->next->param[AL_CONE_INNER_ANGLE-AL_CONE_INNER_ANGLE].data.f=360.0; Source->next->param[AL_CONE_INNER_ANGLE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_CONE_OUTER_ANGLE-AL_CONE_INNER_ANGLE].data.f=360.0; Source->next->param[AL_CONE_OUTER_ANGLE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_PITCH-AL_CONE_INNER_ANGLE].data.f= 1.0; Source->next->param[AL_PITCH-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_POSITION-AL_CONE_INNER_ANGLE].data.fv3[0]=0.0; Source->next->param[AL_POSITION-AL_CONE_INNER_ANGLE].data.fv3[1]=0.0; Source->next->param[AL_POSITION-AL_CONE_INNER_ANGLE].data.fv3[2]=0.0; Source->next->param[AL_POSITION-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].data.fv3[0]=0.0; Source->next->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].data.fv3[1]=0.0; Source->next->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].data.fv3[2]=0.0; Source->next->param[AL_DIRECTION-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].data.fv3[0]=0.0; Source->next->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].data.fv3[1]=0.0; Source->next->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].data.fv3[2]=0.0; Source->next->param[AL_VELOCITY-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_REFERENCE_DISTANCE-AL_CONE_INNER_ANGLE].data.f= 1.0; Source->next->param[AL_REFERENCE_DISTANCE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_MAX_DISTANCE-AL_CONE_INNER_ANGLE].data.f= 1000000.0; Source->next->param[AL_MAX_DISTANCE-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_ROLLOFF_FACTOR-AL_CONE_INNER_ANGLE].data.f= 1.0; Source->next->param[AL_ROLLOFF_FACTOR-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_LOOPING-AL_CONE_INNER_ANGLE].data.i= AL_FALSE; Source->next->param[AL_LOOPING-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_GAIN-AL_CONE_INNER_ANGLE].data.f= 1.0f; Source->next->param[AL_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_MIN_GAIN-AL_CONE_INNER_ANGLE].data.f= 0.0f; Source->next->param[AL_MIN_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_MAX_GAIN-AL_CONE_INNER_ANGLE].data.f= 1.0f; Source->next->param[AL_MAX_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->param[AL_CONE_OUTER_GAIN-AL_CONE_INNER_ANGLE].data.f= 1.0f; Source->next->param[AL_CONE_OUTER_GAIN-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->state = AL_INITIAL; Source->next->param[AL_BUFFER-AL_CONE_INNER_ANGLE].data.i= 0; Source->next->param[AL_BUFFER-AL_CONE_INNER_ANGLE].valid = AL_TRUE; Source->next->update1 |= CONEANGLES | FREQUENCY | POSITION | VELOCITY | ORIENTATION | MINDIST | MAXDIST | LOOPED | VOLUME | CONEOUTSIDEVOLUME | STATE; Source->next->eaxBP.lDirect = EAXBUFFER_DEFAULTDIRECT; Source->next->eaxBP.lDirectHF = EAXBUFFER_DEFAULTDIRECTHF; Source->next->eaxBP.lRoom = EAXBUFFER_DEFAULTROOM; Source->next->eaxBP.lRoomHF = EAXBUFFER_DEFAULTROOMHF; Source->next->eaxBP.flRoomRolloffFactor = EAXBUFFER_DEFAULTROOMROLLOFFFACTOR; Source->next->eaxBP.lObstruction = EAXBUFFER_DEFAULTOBSTRUCTION; Source->next->eaxBP.flObstructionLFRatio = EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO; Source->next->eaxBP.lOcclusion = EAXBUFFER_DEFAULTOCCLUSION; Source->next->eaxBP.flOcclusionLFRatio = EAXBUFFER_DEFAULTOCCLUSIONLFRATIO; Source->next->eaxBP.flOcclusionRoomRatio = EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO; Source->next->eaxBP.lOutsideVolumeHF = EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF; Source->next->eaxBP.flAirAbsorptionFactor = EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR; Source->next->eaxBP.dwFlags = EAXBUFFER_DEFAULTFLAGS; Source->next->update2 |= SALLPARAMS; Context->SourceCount++; i++; } alcUpdateContext(Context, ALSOURCE, (ALuint)Source->next); Source=Source->next; } alcProcessContext(Context); if (i!=n) alSetError(AL_OUT_OF_MEMORY); }
ALAPI ALvoid ALAPIENTRY alSourcef(ALuint source,ALenum pname,ALfloat value) { ALCcontext *Context; ALsource *Source; Context=alcGetCurrentContext(); alcSuspendContext(Context); if (alIsSource(source)) { Source=((ALsource *)source); switch(pname) { case AL_PITCH: if ((value>=0.0f)&&(value<=2.0f)) { Source->param[pname-AL_CONE_INNER_ANGLE].data.f=value; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; Source->update1 |= FREQUENCY; // Property to update alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_VALUE); break; case AL_GAIN: case AL_MAX_DISTANCE: case AL_ROLLOFF_FACTOR: case AL_REFERENCE_DISTANCE: if (value>=0.0f) { Source->param[pname-AL_CONE_INNER_ANGLE].data.f=value; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; if (pname == AL_GAIN) Source->update1 |= VOLUME; else if (pname == AL_MAX_DISTANCE) Source->update1 |= MAXDIST; else if (pname == AL_REFERENCE_DISTANCE) Source->update1 |= MINDIST; // ROLLOFF_FACTOR ignored at this time ! alcUpdateContext(Context,ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_VALUE); break; case AL_MIN_GAIN: case AL_MAX_GAIN: case AL_CONE_OUTER_GAIN: if ((value>=0.0f)&&(value<=1.0f)) { Source->param[pname-AL_CONE_INNER_ANGLE].data.f=value; Source->param[pname-AL_CONE_INNER_ANGLE].valid=AL_TRUE; Source->update1 |= CONEOUTSIDEVOLUME; // Property to update alcUpdateContext(Context, ALSOURCE, (ALuint)Source); } else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); alcProcessContext(Context); }