void Sound::SetLoop(bool Loop) { ALCheck(alSourcei(mySource, AL_LOOPING, Loop)); }
int main() { ALCdevice* device = alcOpenDevice(NULL); ALCcontext* context = alcCreateContext(device, NULL); alcMakeContextCurrent(context); ALfloat listenerPos[] = {0.0, 0.0, 0.0}; ALfloat listenerVel[] = {0.0, 0.0, 0.0}; ALfloat listenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0}; alListenerfv(AL_POSITION, listenerPos); alListenerfv(AL_VELOCITY, listenerVel); alListenerfv(AL_ORIENTATION, listenerOri); ALuint buffers[1]; alGenBuffers(1, buffers); FILE* source = fopen("audio.wav", "rb"); fseek(source, 0, SEEK_END); int size = ftell(source); fseek(source, 0, SEEK_SET); unsigned char* buffer = (unsigned char*) malloc(size); fread(buffer, size, 1, source); unsigned offset = 12; // ignore the RIFF header offset += 8; // ignore the fmt header offset += 2; // ignore the format type unsigned channels = buffer[offset + 1] << 8; channels |= buffer[offset]; offset += 2; printf("Channels: %u\n", channels); unsigned frequency = buffer[offset + 3] << 24; frequency |= buffer[offset + 2] << 16; frequency |= buffer[offset + 1] << 8; frequency |= buffer[offset]; offset += 4; printf("Frequency: %u\n", frequency); offset += 6; // ignore block size and bps unsigned bits = buffer[offset + 1] << 8; bits |= buffer[offset]; offset += 2; printf("Bits: %u\n", bits); ALenum format = 0; if(bits == 8) { if(channels == 1) format = AL_FORMAT_MONO8; else if(channels == 2) format = AL_FORMAT_STEREO8; } else if(bits == 16) { if(channels == 1) format = AL_FORMAT_MONO16; else if(channels == 2) format = AL_FORMAT_STEREO16; } offset += 8; // ignore the data chunk printf("Start offset: %d\n", offset); alBufferData(buffers[0], format, &buffer[offset], size - offset, frequency); ALuint sources[1]; alGenSources(1, sources); alSourcei(sources[0], AL_BUFFER, buffers[0]); ALint state; alGetSourcei(sources[0], AL_SOURCE_STATE, &state); assert(state == AL_INITIAL); alSourcePlay(sources[0]); alGetSourcei(sources[0], AL_SOURCE_STATE, &state); assert(state == AL_PLAYING); emscripten_async_call(playSource, reinterpret_cast<void*>(sources[0]), 700); return 0; }
CVoid COpenALSoundSource::SetLooping( CBool enable ) { alSourcei( m_soundSource, AL_LOOPING, enable ); }
void ALBuffer(void) { alListenerfv(AL_POSITION, ListenerPos); alListenerfv(AL_VELOCITY, ListenerVel); alListenerfv(AL_ORIENTATION, ListenerOri); alSourcefv(Sources[0], AL_POSITION, SourceFront); alSourcei(Sources[0], AL_SOURCE_RELATIVE, AL_TRUE); alSourcefv(Sources[2], AL_POSITION, SourceBack); alSourcei(Sources[2], AL_SOURCE_RELATIVE, AL_TRUE); alSourcefv(Sources[3], AL_POSITION, SourceRight); alSourcei(Sources[3], AL_SOURCE_RELATIVE, AL_TRUE); alSourcefv(Sources[1], AL_POSITION, SourceLeft); alSourcei(Sources[1], AL_SOURCE_RELATIVE, AL_TRUE); alSourceStop(Sources[0]); alSourceStop(Sources[1]); alSourceStop(Sources[2]); alSourceStop(Sources[3]); alBufferData(buffer, format, buf, dataSize, frequency); alSourcei(Sources[2], AL_BUFFER, buffer); alSourcef(Sources[2], AL_PITCH, 1.0f); alSourcef(Sources[2], AL_GAIN, 0.f); alSourcefv(Sources[2], AL_VELOCITY, SourceVel); alSourcei(Sources[2], AL_LOOPING, AL_TRUE); alSourcefv(Sources[2], AL_POSITION, SourceBack); alSourcei(Sources[0], AL_BUFFER, buffer); alSourcef(Sources[0], AL_PITCH, 1.0f); alSourcef(Sources[0], AL_GAIN, 0.f); alSourcefv(Sources[0], AL_VELOCITY, SourceVel); alSourcei(Sources[0], AL_LOOPING, AL_TRUE); alSourcefv(Sources[0], AL_POSITION, SourceFront); alSourcei(Sources[1], AL_BUFFER, buffer); alSourcef(Sources[1], AL_PITCH, 1.0f); alSourcef(Sources[1], AL_GAIN, 0.f); alSourcefv(Sources[1], AL_VELOCITY, SourceVel); alSourcei(Sources[1], AL_LOOPING, AL_TRUE); alSourcefv(Sources[1], AL_POSITION, SourceLeft); alSourcei(Sources[3], AL_BUFFER, buffer); alSourcef(Sources[3], AL_PITCH, 1.0f); alSourcef(Sources[3], AL_GAIN, 0.f); alSourcefv(Sources[3], AL_VELOCITY, SourceVel); alSourcei(Sources[3], AL_LOOPING, AL_TRUE); alSourcefv(Sources[3], AL_POSITION, SourceRight); alSourcePlay(Sources[2]); alSourcePlay(Sources[0]); alSourcePlay(Sources[1]); alSourcePlay(Sources[3]); }
void Sound::setLoop(bool Loop) { alCheck(alSourcei(m_source, AL_LOOPING, Loop)); }
void seti(ALenum key, int val) { alSourcei(name_, key, val); check_error("alSourcei (source::seti)"); }
void setb(ALenum key, bool val) { alSourcei(name_, key, val ? AL_TRUE : AL_FALSE); check_error("alSourcei (source::setb)"); }
void SoundSource::setRelativeToListener(bool relative) { alCheck(alSourcei(m_source, AL_SOURCE_RELATIVE, relative)); }
/** * @brief Plays a sound in a group. */ int sound_al_playGroup( int group, alSound *s, int once ) { int i, j; alGroup_t *g; ALint state; double v; for (i=0; i<al_ngroups; i++) { /* Find group. */ if (al_groups[i].id != group) continue; g = &al_groups[i]; g->state = VOICE_PLAYING; soundLock(); for (j=0; j<g->nsources; j++) { alGetSourcei( g->sources[j], AL_SOURCE_STATE, &state ); /* No free ones, just smash the last one. */ if (j == g->nsources-1) { if (state != AL_STOPPED) alSourceStop( g->sources[j] ); } /* Ignore playing/paused. */ else if ((state == AL_PLAYING) || (state == AL_PAUSED)) continue; /* Attach buffer. */ alSourcei( g->sources[j], AL_BUFFER, s->u.al.buf ); /* Do not do positional sound. */ alSourcei( g->sources[j], AL_SOURCE_RELATIVE, AL_TRUE ); /* See if should loop. */ alSourcei( g->sources[j], AL_LOOPING, (once) ? AL_FALSE : AL_TRUE ); /* Set volume. */ v = svolume * g->volume; if (g->speed) v *= svolume_speed; alSourcef( g->sources[j], AL_GAIN, v ); /* Start playing. */ alSourcePlay( g->sources[j] ); /* Check for errors. */ al_checkErr(); soundUnlock(); return 0; } soundUnlock(); WARN(_("Group '%d' has no free sounds."), group ); /* Group matched but not found. */ break; } if (i>=al_ngroups) WARN(_("Group '%d' not found."), group); return -1; }
int main(int argc, char *argv[]) { ALenum format; ALsizei size, freq; ALvoid *data; /* setup camera position and orientation */ cameraAngle = 0.0f; cameraPosition[0] = 0.0f; cameraPosition[1] = 0.8f; cameraPosition[2] = 0.0f; cameraOrientation[0] = cos(2.0 * M_PI * cameraAngle / 360.0); cameraOrientation[1] = 0.0f; cameraOrientation[2] = sin(2.0 * M_PI * cameraAngle / 360.0); cameraOrientation[3] = 0.0f; cameraOrientation[4] = 1.0f; cameraOrientation[5] = 0.0f; /* setup radar and phase position */ radarPosition[0] = 5.0f; radarPosition[1] = 0.0f; radarPosition[2] = 0.0f; phaserPosition[0] = 2.0f; phaserPosition[1] = 0.0f; phaserPosition[2] = 0.0f; radarLightAngle = 0.0f; phaserPlaying = AL_FALSE; /* initialize GLUT */ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(200, 100); glutInitWindowSize(320, 240); glutCreateWindow("XL Demo"); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutReshapeFunc(reshape); glutIdleFunc(idle); glEnable(GL_CULL_FACE); /* initialize ALUT */ alutInit(&argc, argv); /* set up the buffers */ alGenBuffers(1, &radarBuffer); alGenBuffers(1, &phaserBuffer); alutLoadWAV(kRadarFileName, &format, &data, &size, &freq); alBufferData(radarBuffer, format, data, size, freq); free(data); alutLoadWAV(kPhaserFileName, &format, &data, &size, &freq); alBufferData(phaserBuffer, format, data, size, freq); free(data); /* set up the sources */ alGenSources(1, &radarSource); alGenSources(1, &phaserSource); alSourcefv(radarSource, AL_POSITION, radarPosition); alSourcef(radarSource, AL_GAIN, 1.0f); alSourcef(radarSource, AL_PITCH, 1.0f); alSourcei(radarSource, AL_BUFFER, radarBuffer); alSourcei(radarSource, AL_LOOPING, AL_TRUE); alSourcefv(phaserSource, AL_POSITION, phaserPosition); alSourcef(phaserSource, AL_GAIN, 1.0f); alSourcef(phaserSource, AL_PITCH, 1.0f); alSourcei(phaserSource, AL_BUFFER, phaserBuffer); alSourcei(phaserSource, AL_LOOPING, AL_FALSE); /* start the radar */ alSourcePlay(radarSource); /* GLUT event loop */ glutMainLoop(); /* shutdown alut */ alutExit(); return 0; }
SoundSource::SoundSource() { alCheck(alGenSources(1, &m_source)); alCheck(alSourcei(m_source, AL_BUFFER, 0)); }
// TODO: generate buffers separately DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx) { if (size[type] <= selection || selection < 0) return de_InvalidSelection; lock; uint32_t i; for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; i ++); if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; } else *device_idx = i; Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));; device->selection = selection; for (i = 0; i < *device_idx; i ++) { /* Check if any previous has the same selection */ if ( running[type][i]->selection == selection ) { device->dhndl = running[type][i]->dhndl; if (type == output) { device->ctx = running[type][i]->ctx; memcpy(device->buffers, running[type][i]->buffers, sizeof(running[type][i]->buffers)); device->source = running[type][i]->source; } device->ref_count++; pthread_mutex_init(device->mutex, NULL); unlock; return de_None; } } if (type == input) { device->dhndl = alcCaptureOpenDevice(devices_names[type][selection], av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, frame_size * 2); device->VAD_treshold = VAD_THRESHOLD_DEFAULT; } else { device->dhndl = alcOpenDevice(devices_names[type][selection]); if ( !device->dhndl ) { free(device); running[type][*device_idx] = NULL; unlock; return de_FailedStart; } device->ctx = alcCreateContext(device->dhndl, NULL); alcMakeContextCurrent(device->ctx); alGenBuffers(openal_bufs, device->buffers); alGenSources((uint32_t)1, &device->source); alSourcei(device->source, AL_LOOPING, AL_FALSE); uint16_t zeros[frame_size]; memset(zeros, 0, frame_size*2); for ( i =0; i < openal_bufs; ++i) { alBufferData(device->buffers[i], AL_FORMAT_MONO16, zeros, frame_size*2, sample_rate); } alSourceQueueBuffers(device->source, openal_bufs, device->buffers); alSourcePlay(device->source); } if (alcGetError(device->dhndl) != AL_NO_ERROR) { free(device); running[type][*device_idx] = NULL; unlock; return de_FailedStart; } if (type == input) { alcCaptureStart(device->dhndl); thread_paused = _False; } pthread_mutex_init(device->mutex, NULL); unlock; return de_None; }
void *decode_audio_thread(void *arg) { INFO("Started decode audio thread!"); av_session_t *_phone = arg; _phone->running_decaud = 1; //int recved_size; //uint8_t dest [RTP_PAYLOAD_SIZE]; int frame_size = AUDIO_FRAME_SIZE; //int data_size; ALCdevice *dev; ALCcontext *ctx; ALuint source, *buffers; dev = alcOpenDevice(NULL); ctx = alcCreateContext(dev, NULL); alcMakeContextCurrent(ctx); int openal_buffers = 5; buffers = calloc(sizeof(ALuint) * openal_buffers, 1); alGenBuffers(openal_buffers, buffers); alGenSources((ALuint)1, &source); alSourcei(source, AL_LOOPING, AL_FALSE); ALuint buffer; ALint ready; uint16_t zeros[frame_size]; memset(zeros, 0, frame_size); int16_t PCM[frame_size]; int i; for (i = 0; i < openal_buffers; ++i) { alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000); } alSourceQueueBuffers(source, openal_buffers, buffers); alSourcePlay(source); if (alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error starting audio\n"); goto ending; } int dec_frame_len = 0; while (_phone->running_decaud) { alGetSourcei(source, AL_BUFFERS_PROCESSED, &ready); if (ready <= 0) continue; dec_frame_len = toxav_recv_audio(_phone->av, frame_size, PCM); /* Play the packet */ if (dec_frame_len > 0) { alSourceUnqueueBuffers(source, 1, &buffer); alBufferData(buffer, AL_FORMAT_MONO16, PCM, dec_frame_len * 2 * 1, 48000); int error = alGetError(); if (error != AL_NO_ERROR) { fprintf(stderr, "Error setting buffer %d\n", error); break; } alSourceQueueBuffers(source, 1, &buffer); if (alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error: could not buffer audio\n"); break; } alGetSourcei(source, AL_SOURCE_STATE, &ready); if (ready != AL_PLAYING) alSourcePlay(source); } usleep(1000); } ending: /* clean up codecs */ //pthread_mutex_lock(&cs->ctrl_mutex); /* alDeleteSources(1, &source); alDeleteBuffers(openal_buffers, buffers); alcMakeContextCurrent(NULL); alcDestroyContext(ctx); alcCloseDevice(dev); */ //pthread_mutex_unlock(&cs->ctrl_mutex); _phone->running_decaud = -1; pthread_exit ( NULL ); }
// TODO: generate buffers separately DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration, uint8_t channels) { if (size[type] <= selection || selection < 0) return de_InvalidSelection; if (channels != 1 && channels != 2) return de_UnsupportedMode; lock; const uint32_t frame_size = (sample_rate * frame_duration / 1000); uint32_t i; for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; ++i); if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; } else *device_idx = i; for (i = 0; i < MAX_DEVICES; i ++) { /* Check if any device has the same selection */ if ( running[type][i] && running[type][i]->selection == selection ) { // printf("a%d-%d:%p ", selection, i, running[type][i]->dhndl); running[type][*device_idx] = running[type][i]; running[type][i]->ref_count ++; unlock; return de_None; } } Device* device = running[type][*device_idx] = calloc(1, sizeof(Device)); device->selection = selection; device->sample_rate = sample_rate; device->frame_duration = frame_duration; device->sound_mode = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; if (pthread_mutex_init(device->mutex, NULL) != 0) { free(device); unlock; return de_InternalError; } if (type == input) { device->dhndl = alcCaptureOpenDevice(devices_names[type][selection], sample_rate, device->sound_mode, frame_size * 2); #ifdef AUDIO device->VAD_treshold = user_settings->VAD_treshold; #endif } else { device->dhndl = alcOpenDevice(devices_names[type][selection]); if ( !device->dhndl ) { free(device); running[type][*device_idx] = NULL; unlock; return de_FailedStart; } device->ctx = alcCreateContext(device->dhndl, NULL); alcMakeContextCurrent(device->ctx); alGenBuffers(OPENAL_BUFS, device->buffers); alGenSources((uint32_t)1, &device->source); alSourcei(device->source, AL_LOOPING, AL_FALSE); uint16_t zeros[frame_size]; memset(zeros, 0, frame_size*2); for ( i = 0; i < OPENAL_BUFS; ++i ) { alBufferData(device->buffers[i], device->sound_mode, zeros, frame_size*2, sample_rate); } alSourceQueueBuffers(device->source, OPENAL_BUFS, device->buffers); alSourcePlay(device->source); } if (alcGetError(device->dhndl) != AL_NO_ERROR) { free(device); running[type][*device_idx] = NULL; unlock; return de_FailedStart; } if (type == input) { alcCaptureStart(device->dhndl); thread_paused = false; } unlock; return de_None; }
Sound::SoundManager::SoundManager() : m_pDevice(alcOpenDevice(nullptr)) { if(!m_pDevice) LogError() << "Could not open audio device"; //m_Enumeration = alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"); ALCenum error; error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; m_pContext = alcCreateContext(m_pDevice, NULL); if (!alcMakeContextCurrent(m_pContext)) LogError() << "Could not make current context"; ALfloat listenerOri[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }; alListener3f(AL_POSITION, 0, 0, 1.0f); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alListener3f(AL_VELOCITY, 0, 0, 0); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alListenerfv(AL_ORIENTATION, listenerOri); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; ALuint source; alGenSources((ALuint)1, &source); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alSourcef(source, AL_PITCH, 1); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alSourcef(source, AL_GAIN, 1); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alSource3f(source, AL_POSITION, 0, 0, 0); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alSource3f(source, AL_VELOCITY, 0, 0, 0); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alSourcei(source, AL_LOOPING, AL_FALSE); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; ALuint buffer; alGenBuffers((ALuint)1, &buffer); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; ALsizei size, freq; ALenum format; ALvoid *data; ALboolean loop = AL_FALSE; alutLoadWAVFile(reinterpret_cast<ALbyte *>(const_cast<char *>("test.wav")), &format, &data, &size, &freq, &loop); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; alBufferData(buffer, format, data, size, freq); alSourcei(source, AL_BUFFER, buffer);alSourcePlay(source); alSourcePlay(source); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; ALint source_state; alGetSourcei(source, AL_SOURCE_STATE, &source_state); LogInfo() << "Play sound..."; while (source_state == AL_PLAYING) { alGetSourcei(source, AL_SOURCE_STATE, &source_state); error = alGetError(); if (error != AL_NO_ERROR) LogError() << error; LogInfo() << "Play sound..."; } // cleanup context alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); m_pDevice = alcGetContextsDevice(m_pContext); alcMakeContextCurrent(NULL); alcDestroyContext(m_pContext); }
void OpenALSound::uninitializeImpl() { alSourcei(mSourceId, AL_BUFFER, -1);//katoun TODO see if it works!!! }
void OpenAL::startLoop() { QMutexLocker locker(&audioLock); alSourcei(alMainSource, AL_LOOPING, AL_TRUE); }
void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) { LLVector3 wind_pos; F64 pitch; F64 center_freq; ALenum error; if (!mEnableWind) return; if (!mWindBuf) return; if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) { // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) // need to convert this to the conventional orientation DS3D and OpenAL use // where +X = right, +Y = up, +Z = backwards wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); pitch = 1.0 + mapWindVecToPitch(wind_vec); center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); mWindGen->mTargetFreq = (F32)center_freq; mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); alSourcei(mWindSource, AL_LOOPING, AL_FALSE); alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0); alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0); alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0); alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE); } // ok lets make a wind buffer now ALint processed, queued, unprocessed; alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued); unprocessed = queued - processed; // ensure that there are always at least 3x as many filled buffers // queued as we managed to empty since last time. mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed); mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0); //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl; while (processed--) // unqueue old buffers { ALuint buffer; ALenum error; alGetError(); /* clear error */ alSourceUnqueueBuffers(mWindSource, 1, &buffer); error = alGetError(); if (error != AL_NO_ERROR) { llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; } else { alDeleteBuffers(1, &buffer); } } unprocessed += mNumEmptyWindALBuffers; while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers { ALuint buffer; alGetError(); /* clear error */ alGenBuffers(1,&buffer); if ((error=alGetError()) != AL_NO_ERROR) { llwarns << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << convertALErrorToString(error) << llendl; break; } alBufferData(buffer, AL_FORMAT_STEREO16, mWindGen->windGenerate(mWindBuf, mWindBufSamples), mWindBufBytes, mWindBufFreq); error = alGetError(); if (error != AL_NO_ERROR) { llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; } alSourceQueueBuffers(mWindSource, 1, &buffer); error = alGetError(); if (error != AL_NO_ERROR) { llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; } --mNumEmptyWindALBuffers; } ALint playing; alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing); if (playing != AL_PLAYING) { alSourcePlay(mWindSource); lldebugs << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << llendl; } }
int main(int, char**) { // Setup SDL if (SDL_Init(SDL_INIT_EVERYTHING) != 0) return -1; // Setup window SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_DisplayMode current; SDL_GetCurrentDisplayMode(0, ¤t); SDL_Window *sdl_window = SDL_CreateWindow("testbed", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); SDL_GLContext glcontext = SDL_GL_CreateContext(sdl_window); // Setup ImGui binding ImGui_ImplSdl_Init(sdl_window); // OpenAL: Open and initialize a device with default settings // and set current context, making the program ready to call OpenAL functions. ALCdevice* alc_device = NULL; ALCcontext* alc_ctx = NULL; const char* alc_device_spec = NULL; const char* alc_ext = NULL; const char* al_vendor = NULL; const char* al_renderer = NULL; const char* al_version = NULL; const char* al_ext = NULL; { alc_device = alcOpenDevice(NULL); if(!alc_device) { ERR("Could not open a device!\n"); return 1; } alc_ctx = alcCreateContext(alc_device, NULL); if(alc_ctx == NULL || alcMakeContextCurrent(alc_ctx) == ALC_FALSE) { if(alc_ctx != NULL) alcDestroyContext(alc_ctx); alcCloseDevice(alc_device); ERR("Could not set a context!\n"); return 1; } alc_device_spec = alcGetString(alc_device, ALC_DEVICE_SPECIFIER); alc_ext = alcGetString(alc_device, ALC_EXTENSIONS); //alcGetIntegerv(alc_device, ALC_MAJOR_VERSION, 1, &alc_major); //alcGetIntegerv(alc_device, ALC_MINOR_VERSION, 1, &alc_minor); al_vendor = alGetString(AL_VENDOR); al_renderer = alGetString(AL_RENDERER); al_version = alGetString(AL_VERSION); al_ext = alGetString(AL_EXTENSIONS); } // Load resource SResources Resources; { bool ok = LoadResources(Resources); if (!ok) { ERR("Could not load all program resource.\n"); return 1; } } // openal sources SMgrState MgrState; SEmitter* SpatialEmit; SEmitter* AmbiantLoop; { Mgr_Init(MgrState); SpatialEmit = &MgrState.Emitters[0]; AmbiantLoop = &MgrState.Emitters[1]; alSourcei(SpatialEmit->Source, AL_BUFFER, Resources.albuf_monoloop); alSourcei(SpatialEmit->Source, AL_LOOPING, AL_TRUE); alSourcei(SpatialEmit->Source, AL_DIRECT_CHANNELS_SOFT, AL_FALSE); SpatialEmit->active = false; SpatialEmit->dB = 0.f; SpatialEmit->pos[0] = .5f; SpatialEmit->pos[1] = .75f; SpatialEmit->pos[2] = -3; SpatialEmit->radius = 0.01f; alSourcei(AmbiantLoop->Source, AL_BUFFER, Resources.albuf_stereoloop); alSourcei(AmbiantLoop->Source, AL_LOOPING, AL_TRUE); alSourcei(AmbiantLoop->Source, AL_DIRECT_CHANNELS_SOFT, AL_TRUE); AmbiantLoop->active = false; AmbiantLoop->dB = -9.f; } // Main loop bool done = false; while (!done) { SDL_Event event; while (SDL_PollEvent(&event)) { ImGui_ImplSdl_ProcessEvent(&event); if (event.type == SDL_QUIT) done = true; } uint CurTimeMs = SDL_GetTicks(); int ActiveSources = Mgr_Update(MgrState); ImGui_ImplSdl_NewFrame(sdl_window); ImGui::SetNextWindowPos(ImVec2(10, 10)); ImGui::SetNextWindowSize(ImVec2(500, 700)); ImGui::Begin("main", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove); // top bar. { if (ImGui::Button("Quit")) break; ImGui::SameLine(); static bool ShowImguiHelp = false; ImGui::Checkbox("show imgui help", &ShowImguiHelp); if (ShowImguiHelp) ImGui::ShowTestWindow(); // documentation shortcut } ImGui::Spacing(); // ----------------- // Openal info: if (ImGui::CollapsingHeader("OpenAL info")) { ImGui::Columns(2, "OpenAL_info"); ImGui::Text("device"); ImGui::NextColumn(); ImGui::TextWrapped(alc_device_spec); ImGui::NextColumn(); ImGui::Text("vendor"); ImGui::NextColumn(); ImGui::TextWrapped(al_vendor); ImGui::NextColumn(); ImGui::Text("renderer"); ImGui::NextColumn(); ImGui::TextWrapped(al_renderer); ImGui::NextColumn(); ImGui::Text("version"); ImGui::NextColumn(); ImGui::TextWrapped(al_version); ImGui::NextColumn(); ImGui::Separator(); ImGui::Text("ALC extensions"); ImGui::NextColumn(); ImGui::TextWrapped(alc_ext); ImGui::NextColumn(); ImGui::Separator(); ImGui::Text("AL extensions"); ImGui::NextColumn(); ImGui::TextWrapped(al_ext); ImGui::NextColumn(); ImGui::Columns(1); } ImGui::Spacing(); // ----------------- // basic test if (ImGui::CollapsingHeader("Basic", NULL, true, true)) { static float mono_gaindB = -3.f; static float stereo_gaindB = -3.f; if (ImGui::Button("Play mono")) { Mgr_Play(MgrState, Resources.albuf_mono, mono_gaindB); } ImGui::SameLine(); ImGui::SliderFloat("##vol1", &mono_gaindB, -60, 6, "%.1fdB"); if (ImGui::Button("Play stereo")) { Mgr_Play(MgrState, Resources.albuf_stereo, stereo_gaindB); } ImGui::SameLine(); ImGui::SliderFloat("##vol2", &stereo_gaindB, -60, 6, "%.1fdB"); } ImGui::Spacing(); // ----------------- // Direct if (ImGui::CollapsingHeader("Direct", NULL, true, true)) { ImGui::Checkbox("Ambiance", &AmbiantLoop->active); ImGui::SameLine(); ImGui::SliderFloat("##vol0", &AmbiantLoop->dB, -60, 6, "%.1fdB"); } ImGui::Spacing(); // ----------------- // Spatialized if (ImGui::CollapsingHeader("Spatialized", NULL, true, true)) { ImGui::Checkbox("Mosquito", &SpatialEmit->active); ImGui::SameLine(); ImGui::SliderFloat("##vol4", &SpatialEmit->dB, -60, 6, "%.1fdB"); ImGui::SliderFloat("radius", &SpatialEmit->radius, 0, 5); static uint PrevTime = 0; static float PrevPos[3]; static bool automove = false; ImGui::Checkbox("Auto move", &automove); if (automove) { struct SLocal { static void anim(float t, float v[3]) { float w = (t*2*PI); v[0] = 5*sinf(w*2+1) + 3*sinf(w*6+2) + 2*sinf(w*6+3) + 1*sinf(w*9+4); v[1] = 5*sinf(w*3+5) + 3*sinf(w*4+6) + 2*sinf(w*7+7) + 1*sinf(w*8+8); v[2] = 5*sinf(w*4+9) + 3*sinf(w*5+1) + 2*sinf(w*8+2) + 1*sinf(w*7+3); } }; float t = (CurTimeMs % 60000) / 60000.f; SLocal::anim(t, SpatialEmit->pos); } ImGui::InputFloat3("pos", SpatialEmit->pos); ImGui::InputFloat3("vel", SpatialEmit->vel); ImGuiPointOnMap("top", &SpatialEmit->pos[0], &SpatialEmit->pos[2], SpatialEmit->radius, 10, 0.25f); ImGui::SameLine(); ImGuiPointOnMap("front", &SpatialEmit->pos[0], &SpatialEmit->pos[1], SpatialEmit->radius, 10, 0.25f); if (PrevTime != 0 && CurTimeMs > PrevTime) { float dt = 0.001f*(CurTimeMs-PrevTime); float k = 1.f; SpatialEmit->vel[0] = k * ((SpatialEmit->pos[0] - PrevPos[0]) / dt); SpatialEmit->vel[1] = k * ((SpatialEmit->pos[1] - PrevPos[1]) / dt); SpatialEmit->vel[2] = k * ((SpatialEmit->pos[2] - PrevPos[2]) / dt); } PrevTime = CurTimeMs; memcpy(PrevPos, SpatialEmit->pos, sizeof(PrevPos)); } ImGui::Spacing(); // ----------------- // basic test if (ImGui::CollapsingHeader("Tests", NULL, true, true)) { static const float Front[3] = {0,0,-1}; if (ImGui::Button("stereo base")) { Mgr_Play(MgrState, Resources.albuf_stereo, -3, false); } ImGui::SameLine(); if (ImGui::Button("stereo direct")) { Mgr_Play(MgrState, Resources.albuf_stereo, -3, true); } if (ImGui::Button("mono base")) { Mgr_Play(MgrState, Resources.albuf_mono, -3, false); } ImGui::SameLine(); if (ImGui::Button("mono direct")) { Mgr_Play(MgrState, Resources.albuf_mono, -3, true); } ImGui::SameLine(); if (ImGui::Button("mono 3d narrow")) { Mgr_Play(MgrState, Resources.albuf_mono, -3, Front, 0.01f); } ImGui::SameLine(); if (ImGui::Button("mono 3d wide")) { Mgr_Play(MgrState, Resources.albuf_mono, -3, Front, 1.f); } ImGui::SameLine(); if (ImGui::Button("mono 3d omni")) { Mgr_Play(MgrState, Resources.albuf_mono, -3, Front, 10.f); } } ImGui::Spacing(); // ----------------- // status { ImGui::Separator(); ImGui::Text("Active Sources: %d / %d\n", ActiveSources, MGR_MAX_SOURCES); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } ImGui::End(); // Rendering ImVec4 clear_color = ImColor(114, 144, 154); glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); SDL_GL_SwapWindow(sdl_window); } Mgr_Destroy(MgrState); FreeResources(Resources); // OpenAL: cleanup { alcMakeContextCurrent(NULL); alcDestroyContext(alc_ctx); alcCloseDevice(alc_device); } // Cleanup ImGui_ImplSdl_Shutdown(); SDL_GL_DeleteContext(glcontext); SDL_DestroyWindow(sdl_window); SDL_Quit(); return 0; }
/* Function: alurePlaySourceStream * * Starts playing a stream, using the specified source ID. A stream can only be * played if it is not already playing. You must call <alureUpdate> at regular * intervals to keep the stream playing, or else the stream will underrun and * cause a break in the playback until an update call can restart it. It is * also important that the current context is kept for <alureUpdate> calls if * ALC_EXT_thread_local_context is not supported, otherwise the method may * start calling OpenAL with invalid IDs. Note that checking the state of the * specified source is not a good method to determine if a stream is playing. * If an underrun occurs, the source will enter a stopped state until it is * automatically restarted. Instead, set a flag using the callback to indicate * the stream being stopped. * * Parameters: * source - The source ID to play the stream with. Any buffers on the source * will be unqueued. It is valid to set source properties not related * to the buffer queue or playback state (ie. you may change the * source's position, pitch, gain, etc, but you must not stop the * source or queue/unqueue buffers on it). To pause the source, call * <alurePauseSource>. * stream - The stream to play. Any valid stream will work, although looping * will only work if the stream can be rewound (eg. streams made with * <alureCreateStreamFromCallback> cannot loop, but will play for as * long as the callback provides data). * numBufs - The number of buffers used to queue with the OpenAL source. Each * buffer will be filled with the chunk length specified when the * stream was created. This value must be at least 2. More buffers at * a larger size will increase the time needed between updates, but * at the cost of more memory usage. * loopcount - The number of times to loop the stream. When the stream reaches * the end of processing, it will be rewound to continue buffering * data. A value of -1 will cause the stream to loop indefinitely * (or until <alureStopSource> is called). * eos_callback - This callback will be called when the stream reaches the end, * no more loops are pending, and the source reaches a stopped * state. It will also be called if an error occured and * playback terminated. * userdata - An opaque user pointer passed to the callback. * * Returns: * AL_FALSE on error. * * *Version Added*: 1.1 * * See Also: * <alureStopSource>, <alurePauseSource>, <alureUpdate> */ ALURE_API ALboolean ALURE_APIENTRY alurePlaySourceStream(ALuint source, alureStream *stream, ALsizei numBufs, ALsizei loopcount, void (*eos_callback)(void *userdata, ALuint source), void *userdata) { PROTECT_CONTEXT(); ALCcontext *current_ctx = alcGetCurrentContext(); if(alGetError() != AL_NO_ERROR) { SetError("Existing OpenAL error"); return AL_FALSE; } if(!alureStream::Verify(stream)) { SetError("Invalid stream pointer"); return AL_FALSE; } if(numBufs < 2) { SetError("Invalid buffer count"); return AL_FALSE; } if(!alIsSource(source)) { SetError("Invalid source ID"); return AL_FALSE; } EnterCriticalSection(&cs_StreamPlay); std::list<AsyncPlayEntry>::iterator i = AsyncPlayList.begin(), end = AsyncPlayList.end(); while(i != end) { if(i->stream == stream) { SetError("Stream is already playing"); LeaveCriticalSection(&cs_StreamPlay); return AL_FALSE; } if(i->source == source && i->ctx == current_ctx) { SetError("Source is already playing"); LeaveCriticalSection(&cs_StreamPlay); return AL_FALSE; } i++; } AsyncPlayEntry ent; ent.stream = stream; ent.source = source; ent.maxloops = loopcount; ent.eos_callback = eos_callback; ent.user_data = userdata; ent.ctx = current_ctx; ent.buffers.resize(numBufs); alGenBuffers(ent.buffers.size(), &ent.buffers[0]); if(alGetError() != AL_NO_ERROR) { LeaveCriticalSection(&cs_StreamPlay); SetError("Error generating buffers"); return AL_FALSE; } numBufs = 0; if(ent.stream->GetFormat(&ent.stream_format, &ent.stream_freq, &ent.stream_align)) { for(size_t i = 0;i < ent.buffers.size();i++) { ALuint got = ent.stream->GetData(&ent.stream->dataChunk[0], ent.stream->dataChunk.size()); got -= got%ent.stream_align; if(got <= 0) { if(ent.loopcount == ent.maxloops || i == 0) ent.finished = true; else { if(ent.maxloops != -1) ent.loopcount++; ent.finished = !ent.stream->Rewind(); } if(ent.finished) break; i--; continue; } ALuint buf = ent.buffers[i]; alBufferData(buf, ent.stream_format, &ent.stream->dataChunk[0], got, ent.stream_freq); numBufs++; } } if(numBufs == 0) { alDeleteBuffers(ent.buffers.size(), &ent.buffers[0]); alGetError(); LeaveCriticalSection(&cs_StreamPlay); SetError("Error buffering from stream"); return AL_FALSE; } if((alSourcei(source, AL_LOOPING, AL_FALSE), alSourcei(source, AL_BUFFER, 0),alGetError()) != AL_NO_ERROR || (alSourceQueueBuffers(source, numBufs, &ent.buffers[0]), alSourcePlay(source),alGetError()) != AL_NO_ERROR) { alSourcei(source, AL_BUFFER, 0); alDeleteBuffers(ent.buffers.size(), &ent.buffers[0]); alGetError(); LeaveCriticalSection(&cs_StreamPlay); SetError("Error starting source"); return AL_FALSE; } AsyncPlayList.push_front(ent); LeaveCriticalSection(&cs_StreamPlay); return AL_TRUE; }
void Audio::updateSourceLoop(ALuint Source, ALboolean loop) { // Définition du mode de lecture de la source alSourcei(Source, AL_LOOPING, loop); }
/* Function: alureUpdate * * Updates the running list of streams, and checks for stopped sources. This * makes sure that sources played with <alurePlaySourceStream> are kept fed * from their associated stream, and sources played with <alurePlaySource> are * still playing. It will call their callbacks as needed. * * *Version Added*: 1.1 * * See Also: * <alurePlaySourceStream>, <alurePlaySource> */ ALURE_API void ALURE_APIENTRY alureUpdate(void) { PROTECT_CONTEXT(); EnterCriticalSection(&cs_StreamPlay); restart: std::list<AsyncPlayEntry>::iterator i = AsyncPlayList.begin(), end = AsyncPlayList.end(); for(;i != end;i++) { if(alcSetThreadContext) { if(alcSetThreadContext(i->ctx) == ALC_FALSE) { AsyncPlayEntry ent(*i); AsyncPlayList.erase(i); if(ent.eos_callback) { DO_UNPROTECT(); ent.eos_callback(ent.user_data, ent.source); DO_PROTECT(); } goto restart; } } if(i->stream == NULL) { ALint state; alGetSourcei(i->source, AL_SOURCE_STATE, &state); if(state == AL_STOPPED || state == AL_INITIAL) { AsyncPlayEntry ent(*i); AsyncPlayList.erase(i); DO_UNPROTECT(); ent.eos_callback(ent.user_data, ent.source); DO_PROTECT(); goto restart; } continue; } ALint queued; if(i->Update(&queued) != AL_PLAYING) { if(queued == 0) { AsyncPlayEntry ent(*i); AsyncPlayList.erase(i); alSourcei(ent.source, AL_BUFFER, 0); alDeleteBuffers(ent.buffers.size(), &ent.buffers[0]); if(ent.eos_callback) { DO_UNPROTECT(); ent.eos_callback(ent.user_data, ent.source); DO_PROTECT(); } goto restart; } if(!i->paused) alSourcePlay(i->source); } } LeaveCriticalSection(&cs_StreamPlay); }
void SoundStream::streamData() { // Create the buffers alCheck(alGenBuffers(BufferCount, m_buffers)); for (int i = 0; i < BufferCount; ++i) m_endBuffers[i] = false; // Fill the queue bool requestStop = fillQueue(); // Play the sound alCheck(alSourcePlay(m_source)); while (m_isStreaming) { // The stream has been interrupted! if (SoundSource::getStatus() == Stopped) { if (!requestStop) { // Just continue alCheck(alSourcePlay(m_source)); } else { // End streaming m_isStreaming = false; } } // Get the number of buffers that have been processed (ie. ready for reuse) ALint nbProcessed = 0; alCheck(alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &nbProcessed)); while (nbProcessed--) { // Pop the first unused buffer from the queue ALuint buffer; alCheck(alSourceUnqueueBuffers(m_source, 1, &buffer)); // Find its number unsigned int bufferNum = 0; for (int i = 0; i < BufferCount; ++i) if (m_buffers[i] == buffer) { bufferNum = i; break; } // Retrieve its size and add it to the samples count if (m_endBuffers[bufferNum]) { // This was the last buffer: reset the sample count m_samplesProcessed = 0; m_endBuffers[bufferNum] = false; } else { ALint size, bits; alCheck(alGetBufferi(buffer, AL_SIZE, &size)); alCheck(alGetBufferi(buffer, AL_BITS, &bits)); m_samplesProcessed += size / (bits / 8); } // Fill it and push it back into the playing queue if (!requestStop) { if (fillAndPushBuffer(bufferNum)) requestStop = true; } } // Leave some time for the other threads if the stream is still playing if (SoundSource::getStatus() != Stopped) sleep(milliseconds(10)); } // Stop the playback alCheck(alSourceStop(m_source)); // Unqueue any buffer left in the queue clearQueue(); // Delete the buffers alCheck(alSourcei(m_source, AL_BUFFER, 0)); alCheck(alDeleteBuffers(BufferCount, m_buffers)); }
CVoid COpenALSoundSource::SetSeekTime( CInt second ) { alSourcei( m_soundSource, AL_SEC_OFFSET, second ); }
void S_PlayClip(Clip* c, AudioSource* source, bool repeating) { alSourcei(source->sourceID, AL_BUFFER, c->bufferID); alSourcei(source->sourceID, AL_LOOPING, repeating ? AL_TRUE : AL_FALSE); alSourcePlay(source->sourceID); }
void SonicDog::alertObstacles( const CoordinateVect &obstacles, bool diff ) { int size = obstacles.size(); // checkError( "alGenSources", AL ); pthread_mutex_lock( &q_lock_ ); if ( play_q_.size() > 0 ) { pthread_mutex_unlock( &q_lock_ ); return; } for ( int i = 0; i < size; i++ ) { SoundSrc *src = new SoundSrc; src->once = true; src->x = obstacles[i].first; src->z = obstacles[i].second; src->pause = 1.5; alGetError(); alGenSources( 1, &(src->source) ); checkError( "alGenSources", AL ); alutGetError(); if ( diff ) { // src->buffer = alutCreateBufferWaveform( ALUT_WAVEFORM_IMPULSE, i*100.0f+200.0f, 0.0f, 0.5f ); src->buffer = alutCreateBufferFromFile( "./ding.wav" ); alSourcef( src->source, AL_PITCH, .2*i+1 ); } else { // src->buffer = alutCreateBufferWaveform( ALUT_WAVEFORM_IMPULSE, 400.0f, 0.0f, 0.5f ); src->buffer = alutCreateBufferFromFile( "./ding.wav" ); alSourcef( src->source, AL_PITCH, 1 ); } if ( src->buffer == AL_NONE ) { checkError( "alutCreateBufferWaveform", ALUT ); } bool front = true; if ( regions_ ) { // move the location of the source in the OpenAL world to one of our discrete zones ALfloat pos[] = { 0.0, 0.0, 0.0 }; front = placeInRegion( src->x, src->z, pos ); alSourcefv( src->source, AL_POSITION, pos ); } else if ( cutoff_ ) { ALfloat pos[] = { 0.0, 0.0, 0.0 }; front = placeInCutoff( src->x, src->z, pos ); alSourcefv( src->source, AL_POSITION, pos ); } else { alSource3f( src->source, AL_POSITION, src->x, 0.0f, src->z ); } alSourcef( src->source, AL_GAIN, 10.0f ); alSource3f( src->source, AL_VELOCITY, 0.0f, 0.0f, 0.0f ); alSourcei( src->source, AL_LOOPING, AL_FALSE ); alSourcei( src->source, AL_BUFFER, src->buffer ); if ( front ) { play_q_.push( src ); } else if ( !front_only_ ) { play_q_.push( src ); } else { alDeleteSources( 1, &(src->source) ); alDeleteBuffers( 1, &(src->buffer) ); delete src; } } pthread_mutex_unlock( &q_lock_ ); pthread_cond_broadcast( &empty_q_lock_ ); }
SoundSource::~SoundSource() { alCheck(alSourcei(m_source, AL_BUFFER, 0)); alCheck(alDeleteSources(1, &m_source)); }
size_t SonicDog::addObject( float x, float z, obj_t type ) { // instantiate the source and buffer for this sound source SoundSrc *src = new SoundSrc; src->id = object_id_; src->once = false; src->x = x; src->z = z; src->pause = 1.5; alGetError(); alGenSources( 1, &(src->source) ); checkError( "alGenSources", AL ); switch ( type ) { case BEAC: { // src->buffer = alutCreateBufferWaveform( ALUT_WAVEFORM_WHITENOISE, 500.0f, 0.0f, 0.5f ); alutGetError(); src->buffer = alutCreateBufferFromFile( "./beeps.wav" ); checkError( "alutCreateBufferFromFile", ALUT ); alSourcef( src->source, AL_GAIN, 10.0f ); break; } case OBS: { alutGetError(); src->buffer = alutCreateBufferWaveform( ALUT_WAVEFORM_SQUARE, object_id_*100.0f + 100.0f, 0.0f, 0.7f ); checkError( "alutCreateBufferWaveform", ALUT ); alSourcef( src->source, AL_GAIN, 0.1f ); break; } default: break; } alSourcef( src->source, AL_PITCH, 1 ); alSource3f( src->source, AL_VELOCITY, 0.0f, 0.0f, 0.0f ); alSourcei( src->source, AL_LOOPING, AL_FALSE ); alSourcei( src->source, AL_BUFFER, src->buffer ); if ( regions_ ) { // move the location of the source in the OpenAL world to one of our discrete zones ALfloat pos[] = { 0.0, 0.0, 0.0 }; placeInRegion( x, z, pos ); alSourcefv( src->source, AL_POSITION, pos ); } else if ( cutoff_ ) { ALfloat pos[] = { 0.0, 0.0, 0.0 }; placeInCutoff( x, z, pos ); alSourcefv( src->source, AL_POSITION, pos ); } else { alSource3f( src->source, AL_POSITION, x, 0.0f, z ); } // insert the src into our map pthread_mutex_lock( &sources_lock_ ); sources_.insert( SoundMap::value_type( src->id, src ) ); pthread_mutex_unlock( &sources_lock_ ); // insert an entry for this source to our removed map pthread_mutex_lock( &remove_lock_ ); removed_.insert( BoolMap::value_type( src->id, false ) ); pthread_mutex_unlock( &remove_lock_ ); // insert an entry for this source to our paused map pthread_mutex_lock( &pause_lock_ ); paused_.insert( BoolMap::value_type( src->id, false ) ); pthread_mutex_unlock( &pause_lock_ ); // alSourcePlay( src->source ); // then insert it into the play queue pthread_mutex_lock( &q_lock_ ); play_q_.push( src ); pthread_mutex_unlock( &q_lock_ ); // alert the threads that a new object has been added pthread_cond_broadcast( &empty_q_lock_ ); // increment the id counter object_id_++; return src->id; }
CVoid COpenALSoundSource::SetType( CInt type ) { alSourcei( m_soundSource, AL_SOURCE_TYPE, type ); }
int main(int argc, char **argv) { ALboolean enumeration; const ALCchar *devices; const ALCchar *defaultDeviceName = argv[1]; int ret; #ifdef LIBAUDIO WaveInfo *wave; #endif char *bufferData; ALCdevice *device; ALvoid *data; ALCcontext *context; ALsizei size, freq; ALenum format; ALuint buffer, source; ALfloat listenerOri[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }; ALboolean loop = AL_FALSE; ALCenum error; ALint source_state; enumeration = alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"); if (enumeration == AL_FALSE) fprintf(stderr, "enumeration extension not available\n"); list_audio_devices(alcGetString(NULL, ALC_DEVICE_SPECIFIER)); if (!defaultDeviceName) defaultDeviceName = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); device = alcOpenDevice(defaultDeviceName); if (!device) { fprintf(stderr, "unable to open default device\n"); return -1; } fprintf(stdout, "Device: %s\n", alcGetString(device, ALC_DEVICE_SPECIFIER)); alGetError(); context = alcCreateContext(device, NULL); if (!alcMakeContextCurrent(context)) { fprintf(stderr, "failed to make default context\n"); return -1; } TEST_ERROR("make default context"); /* set orientation */ alListener3f(AL_POSITION, 0, 0, 1.0f); TEST_ERROR("listener position"); alListener3f(AL_VELOCITY, 0, 0, 0); TEST_ERROR("listener velocity"); alListenerfv(AL_ORIENTATION, listenerOri); TEST_ERROR("listener orientation"); alGenSources((ALuint)1, &source); TEST_ERROR("source generation"); alSourcef(source, AL_PITCH, 1); TEST_ERROR("source pitch"); alSourcef(source, AL_GAIN, 1); TEST_ERROR("source gain"); alSource3f(source, AL_POSITION, 0, 0, 0); TEST_ERROR("source position"); alSource3f(source, AL_VELOCITY, 0, 0, 0); TEST_ERROR("source velocity"); alSourcei(source, AL_LOOPING, AL_FALSE); TEST_ERROR("source looping"); alGenBuffers(1, &buffer); TEST_ERROR("buffer generation"); #ifdef LIBAUDIO /* load data */ wave = WaveOpenFileForReading("test.wav"); if (!wave) { fprintf(stderr, "failed to read wave file\n"); return -1; } ret = WaveSeekFile(0, wave); if (ret) { fprintf(stderr, "failed to seek wave file\n"); return -1; } bufferData = malloc(wave->dataSize); if (!bufferData) { perror("malloc"); return -1; } ret = WaveReadFile(bufferData, wave->dataSize, wave); if (ret != wave->dataSize) { fprintf(stderr, "short read: %d, want: %d\n", ret, wave->dataSize); return -1; } alBufferData(buffer, to_al_format(wave->channels, wave->bitsPerSample), bufferData, wave->dataSize, wave->sampleRate); TEST_ERROR("failed to load buffer data"); #else alutLoadWAVFile("test.wav", &format, &data, &size, &freq, &loop); TEST_ERROR("loading wav file"); alBufferData(buffer, format, data, size, freq); TEST_ERROR("buffer copy"); #endif alSourcei(source, AL_BUFFER, buffer); TEST_ERROR("buffer binding"); alSourcePlay(source); TEST_ERROR("source playing"); alGetSourcei(source, AL_SOURCE_STATE, &source_state); TEST_ERROR("source state get"); while (source_state == AL_PLAYING) { alGetSourcei(source, AL_SOURCE_STATE, &source_state); TEST_ERROR("source state get"); } /* exit context */ alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); device = alcGetContextsDevice(context); alcMakeContextCurrent(NULL); alcDestroyContext(context); alcCloseDevice(device); return 0; }