示例#1
0
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;
}
示例#3
0
CVoid COpenALSoundSource::SetLooping( CBool enable )
{
	alSourcei( m_soundSource, AL_LOOPING, enable );
}
示例#4
0
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]);
}
示例#5
0
文件: Sound.cpp 项目: AdamFlores/SFML
void Sound::setLoop(bool Loop)
{
    alCheck(alSourcei(m_source, AL_LOOPING, Loop));
}
示例#6
0
 void seti(ALenum key, int val) {
     alSourcei(name_, key, val);
     check_error("alSourcei (source::seti)");
 }
示例#7
0
 void setb(ALenum key, bool val) {
     alSourcei(name_, key, val ? AL_TRUE : AL_FALSE);
     check_error("alSourcei (source::setb)");
 }
示例#8
0
void SoundSource::setRelativeToListener(bool relative)
{
    alCheck(alSourcei(m_source, AL_SOURCE_RELATIVE, relative));
}
示例#9
0
文件: sound_openal.c 项目: naev/naev
/**
 * @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;
}
示例#10
0
文件: xldemo.c 项目: Aye1/RVProject
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;
}
示例#11
0
SoundSource::SoundSource()
{
    alCheck(alGenSources(1, &m_source));
    alCheck(alSourcei(m_source, AL_BUFFER, 0));
}
示例#12
0
文件: device.c 项目: fars/toxic
// 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;
}
示例#13
0
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 );
}
示例#14
0
文件: device.c 项目: selukov/toxic
// 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;
}
示例#15
0
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);
}
示例#16
0
void OpenALSound::uninitializeImpl()
{
    alSourcei(mSourceId, AL_BUFFER, -1);//katoun TODO see if it works!!!
}
示例#17
0
文件: openal.cpp 项目: initramfs/qTox
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;
	}
}
示例#19
0
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, &current);
	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;
}
示例#20
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;
}
示例#21
0
文件: Audio.cpp 项目: Robien/acharn
void Audio::updateSourceLoop(ALuint Source, ALboolean loop)
{
    // Définition du mode de lecture de la source
    alSourcei(Source, AL_LOOPING, loop);
}
示例#22
0
/* 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);
}
示例#23
0
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));
}
示例#24
0
CVoid COpenALSoundSource::SetSeekTime( CInt second )
{
	alSourcei( m_soundSource, AL_SEC_OFFSET, second );
}
示例#25
0
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);
}
示例#26
0
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_ );
}
示例#27
0
SoundSource::~SoundSource()
{
    alCheck(alSourcei(m_source, AL_BUFFER, 0));
    alCheck(alDeleteSources(1, &m_source));
}
示例#28
0
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;
}
示例#29
0
CVoid COpenALSoundSource::SetType( CInt type )
{
	alSourcei( m_soundSource, AL_SOURCE_TYPE, type );
}
示例#30
-23
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;
}