SoundManager::SoundManager(QString soundDirectory)
{
    QString applicationDirectory;
    QString completeSoundDirectory;
    char cwd[PATH_MAX];

    // Initialize ALUT.
    if (alutInit(NULL, NULL) == false) {
        reportALUTError(alutGetError());
    }

    // Get the complete application directory in which we will load sounds from.
    // We convert to QString since it is more convenient when working with directories.
    getcwd(cwd, PATH_MAX);
    applicationDirectory = QString(cwd);

    // Append the assets directory and the actual sounds directory name.
    completeSoundDirectory = applicationDirectory
                            .append("/app/native/assets/")
                            .append(soundDirectory);

    // Create OpenAL buffers from all files in the sound directory.
    QDir dir(completeSoundDirectory);

    if (!dir.exists()) {
        qDebug() << "Cannot find the sounds directory." << completeSoundDirectory;
    } else {

        // Set a filter for file listing, only files should be listed.
        dir.setFilter(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot);

        // Get a directory listing.
        QFileInfoList list = dir.entryInfoList();

        // Traverse and load all the audio files into buffers.
        for (int i = 0; i < list.size(); ++i) {

            // Create a file info for each audio file.
        	QFileInfo fileInfo = list.at(i);
        	const char* path = fileInfo.absoluteFilePath().toStdString().c_str();
        	ALenum error;

        	// Generate buffers to hold audio data.
			alGenBuffers(1, &mSoundBuffers[fileInfo.fileName()]);

			error = alGetError();
			if (error != AL_NO_ERROR) {
				reportOpenALError(error);
				break;
			}

			// Load sound file.
			FILE* file = fopen(path, "rb");
			if (!file) {
				qDebug() << "Failed to load audio file " << path;
				break;
			}

			// Read the file header
			char header[12];
			ALuint bufferId = mSoundBuffers[fileInfo.fileName()];
			if (fread(header, 1, 12, file) != 12) {
				qDebug() << "Invalid header for audio file " << path;
				alDeleteBuffers(1, &bufferId);
				goto cleanup;
			}

			// Check the file format & load the buffer with audio data.
			if (memcmp(header, "RIFF", 4) == 0) {
				if (!loadWav(file, bufferId)) {
					qDebug() << "Invalid wav file: " << path;
					alDeleteBuffers(1, &bufferId);
					goto cleanup;
				}
			}
			else if (memcmp(header, "OggS", 4) == 0) {
				if (!loadOgg(file, bufferId)) {
					qDebug() << "Invalid ogg file: " << path;
					alDeleteBuffers(1, &bufferId);
					goto cleanup;
				}
			}
			else {
				qDebug() << "Unsupported audio file: " << path;
				goto cleanup;
			}

		cleanup:
			if (file) {
				fclose(file);
			}
        }
    }

    // Generate a number of sources used to attach buffers and play.
    alGenSources(SOUNDMANAGER_MAX_NBR_OF_SOURCES, mSoundSources);
    ALenum error = alGetError();
    if (error != AL_NO_ERROR) {
        reportOpenALError(error);
    }
}
int main (int argc, const char * argv[]) {
	MyLoopPlayer player;
	
	// convert to an OpenAL-friendly format and read into memory
	CheckError(loadLoopIntoBuffer(&player),
			   "Couldn't load loop into buffer") ;
	
	// set up OpenAL buffer
	ALCdevice* alDevice = alcOpenDevice(NULL);
	CheckALError ("Couldn't open AL device"); // default device
	ALCcontext* alContext = alcCreateContext(alDevice, 0);
	CheckALError ("Couldn't open AL context");
	alcMakeContextCurrent (alContext);
	CheckALError ("Couldn't make AL context current");
	ALuint buffers[1];
	alGenBuffers(1, buffers);
	CheckALError ("Couldn't generate buffers");
	alBufferData(*buffers,
				 AL_FORMAT_MONO16,
				 player.sampleBuffer,
				 player.bufferSizeBytes,
				 player.dataFormat.mSampleRate);
	
	// AL copies the samples, so we can free them now
	free(player.sampleBuffer);
	
	// set up OpenAL source
	alGenSources(1, player.sources);
	CheckALError ("Couldn't generate sources");
	alSourcei(player.sources[0], AL_LOOPING, AL_TRUE);
	CheckALError ("Couldn't set source looping property");
	alSourcef(player.sources[0], AL_GAIN, AL_MAX_GAIN);
	CheckALError("Couldn't set source gain");
	updateSourceLocation(player);
	CheckALError ("Couldn't set initial source position");
	
	// connect buffer to source
	alSourcei(player.sources[0], AL_BUFFER, buffers[0]);
	CheckALError ("Couldn't connect buffer to source");
	
	// set up listener
	alListener3f (AL_POSITION, 0.0, 0.0, 0.0);
	CheckALError("Couldn't set listner position");
	
	//	ALfloat listenerOrientation[6]; // 3 vectors: forward x,y,z components, then up x,y,z
	//	listenerOrientation[2] = -1.0;
	//	listenerOrientation[0] = listenerOrientation [1] = 0.0;
	//	listenerOrientation[3] = listenerOrientation [4] =  listenerOrientation[5] = 0.0;
	//	alListenerfv (AL_ORIENTATION, listenerOrientation);
	
	// start playing
	// alSourcePlayv (1, player.sources);
	alSourcePlay(player.sources[0]);
	CheckALError ("Couldn't play");
	
	// and wait
	printf("Playing...\n");
	time_t startTime = time(NULL);
	do
	{
		// get next theta
		updateSourceLocation(player);
		CheckALError ("Couldn't set looping source position");
		CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
	} while (difftime(time(NULL), startTime) < RUN_TIME);
	
	// cleanup:
	alSourceStop(player.sources[0]);
	alDeleteSources(1, player.sources);
	alDeleteBuffers(1, buffers);
	alcDestroyContext(alContext);
	alcCloseDevice(alDevice);
	printf ("Bottom of main\n");
}
Esempio n. 3
0
void SoundStream::Stream()
{
    // Create the buffers
    ALCheck(alGenBuffers(BufferCount, myBuffers));
    for (int i = 0; i < BufferCount; ++i)
        myEndBuffers[i] = false;

    // Fill the queue
    bool requestStop = FillQueue();

    // Play the sound
    ALCheck(alSourcePlay(mySource));

    while (myIsStreaming)
    {
        // The stream has been interrupted!
        if (SoundSource::GetStatus() == Stopped)
        {
            if (!requestStop)
            {
                // Just continue
                ALCheck(alSourcePlay(mySource));
            }
            else
            {
                // End streaming
                myIsStreaming = false;
            }
        }

        // Get the number of buffers that have been processed (ie. ready for reuse)
        ALint nbProcessed = 0;
        ALCheck(alGetSourcei(mySource, AL_BUFFERS_PROCESSED, &nbProcessed));

        while (nbProcessed--)
        {
            // Pop the first unused buffer from the queue
            ALuint buffer;
            ALCheck(alSourceUnqueueBuffers(mySource, 1, &buffer));

            // Find its number
            unsigned int bufferNum = 0;
            for (int i = 0; i < BufferCount; ++i)
                if (myBuffers[i] == buffer)
                {
                    bufferNum = i;
                    break;
                }

            // Retrieve its size and add it to the samples count
            if (myEndBuffers[bufferNum])
            {
                // This was the last buffer: reset the sample count
                mySamplesProcessed = 0;
                myEndBuffers[bufferNum] = false;
            }
            else
            {
                ALint size, bits;
                ALCheck(alGetBufferi(buffer, AL_SIZE, &size));
                ALCheck(alGetBufferi(buffer, AL_BITS, &bits));
                mySamplesProcessed += 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(10);
    }

    // Stop the playback
    ALCheck(alSourceStop(mySource));

    // Unqueue any buffer left in the queue
    ClearQueue();

    // Delete the buffers
    ALCheck(alSourcei(mySource, AL_BUFFER, 0));
    ALCheck(alDeleteBuffers(BufferCount, myBuffers));
}
Esempio n. 4
0
bool ttLibC_AlPlayer_queue(ttLibC_AlPlayer *player, ttLibC_PcmS16 *pcmS16) {
	if(player == NULL) {
		return false;
	}
	if(pcmS16 == NULL) {
		return false;
	}
	ttLibC_AlPlayer_ *player_ = (ttLibC_AlPlayer_ *)player;
	switch(pcmS16->type) {
	case PcmS16Type_bigEndian:
	case PcmS16Type_bigEndian_planar:
	case PcmS16Type_littleEndian_planar:
	default:
		ERR_PRINT("non support pcm type.");
		player_->inherit_super.error = ttLibC_updateError(Target_On_Util, Error_InvalidOperation);
		return false;
	case PcmS16Type_littleEndian:
		break;
	}
	ALenum format = AL_FORMAT_MONO16;
	switch(pcmS16->inherit_super.channel_num) {
	case 1: // monoral
		format = AL_FORMAT_MONO16;
		break;
	case 2: // stereo
		format = AL_FORMAT_STEREO16;
		break;
	default:
		ERR_PRINT("only support monoral or stereo.");
		player_->inherit_super.error = ttLibC_updateError(Target_On_Util, Error_InvalidOperation);
		return false;
	}
	int num;
	ALuint buffer = 0;
	alGetSourcei(player_->source, AL_BUFFERS_PROCESSED, &num);
	if(num != -1 && num != 0) {
		alSourceUnqueueBuffers(player_->source, 1, &buffer);
		ALint frequency, channel, size, bits;
		alGetBufferi(buffer, AL_FREQUENCY, &frequency);
		alGetBufferi(buffer, AL_CHANNELS, &channel);
		alGetBufferi(buffer, AL_SIZE, &size);
		alGetBufferi(buffer, AL_BITS, &bits);
		double val = 1.0 * size / (bits / 8) / frequency / channel;
		player_->pts += val;
	}
	else {
		// check the space.
		int empty_num = -1;
		for(int i = 0;i < player_->total_buffer_num;++ i) {
			if(player_->buffers[i] == 0) {
				empty_num = i;
				break;
			}
		}
		if(empty_num == -1) {
			return false;
		}
		alGenBuffers(1, &buffer);
		player_->buffers[empty_num] = buffer;
	}
	alBufferData(buffer, format, pcmS16->l_data, pcmS16->l_stride, pcmS16->inherit_super.sample_rate);
	alSourceQueueBuffers(player_->source, 1, &buffer);

	int state;
	alGetSourcei(player_->source, AL_SOURCE_STATE, &state);
	if(state != AL_PLAYING) {
		// try to start play.
		alSourcePlay(player_->source);
	}
	return true;
}
StreamSoundSource::StreamSoundSource()
  : file(0), fade_state(NoFading), looping(false)
{
  alGenBuffers(STREAMFRAGMENTS, buffers);
  SoundManager::check_al_error("Couldn't allocate audio buffers: ");
}
Esempio n. 6
0
void Cyanide::audio_thread()
{
    return;
    const char *device_list, *output_device = NULL;
    //void *audio_device = NULL;

    bool call[MAX_CALLS] = {0}, preview = 0;
    bool audio_filtering_enabled;
    // bool groups_audio[MAX_NUM_GROUPS] = {0};

    int perframe = (av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate) / 1000;
    uint8_t buf[perframe * 2 * av_DefaultSettings.audio_channels], dest[perframe * 2 * av_DefaultSettings.audio_channels];
    memset(buf, 0, sizeof(buf));

    uint8_t audio_count = 0;
    bool record_on = 0;
    #ifdef AUDIO_FILTERING
    qDebug() << "Audio Filtering enabled";
    #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
    qDebug() << "Echo cancellation enabled";
    #endif
    #endif

    qDebug() << "frame size:" << perframe;

    device_list = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
    if(device_list) {
        output_device = device_list;
        qDebug() << "Output Device List:";
        while(*device_list) {
            qDebug() << device_list;
            //postmessage(NEW_AUDIO_OUT_DEVICE, 0, 0, (void*)device_list);
            device_list += strlen(device_list) + 1;
        }
    }

    device_out = alcOpenDevice(output_device);
    if(!device_out) {
        qDebug() << "alcOpenDevice() failed";
        return;
    }

    int attrlist[] = {  ALC_FREQUENCY, av_DefaultSettings.audio_sample_rate,
                        ALC_INVALID };

    context = alcCreateContext(device_out, attrlist);
    if(!alcMakeContextCurrent(context)) {
        qDebug() << "alcMakeContextCurrent() failed";
        alcCloseDevice(device_out);
        return;
    }

    alGenSources(countof(source), source);

    static ALuint ringSrc[MAX_CALLS];
    alGenSources(MAX_CALLS, ringSrc);

    /* Create buffer to store samples */
    ALuint RingBuffer;
    alGenBuffers(1, &RingBuffer);

    {
        float frequency1 = 441.f;
        float frequency2 = 882.f;
        int seconds = 4;
        unsigned sample_rate = 22050;
        size_t buf_size = seconds * sample_rate * 2; //16 bit (2 bytes per sample)
        int16_t *samples = (int16_t*)malloc(buf_size * sizeof(int16_t));
        if (!samples)
            return;

        /*Generate an electronic ringer sound that quickly alternates between two frequencies*/
        int index = 0;
        for(index = 0; index < buf_size; ++index) {
            if ((index / (sample_rate)) % 4 < 2 ) {//4 second ring cycle, first 2 secondsring, the rest(2 seconds) is silence
                if((index / 1000) % 2 == 1) {
                    samples[index] = 5000 * sin((2.0 * 3.1415926 * frequency1) / sample_rate * index); //5000=amplitude(volume level). It can be from zero to 32700
                } else {
                    samples[index] = 5000 * sin((2.0 * 3.1415926 * frequency2) / sample_rate * index);
                }
            } else {
                samples[index] = 0;
            }
        }

        alBufferData(RingBuffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
        free(samples);
    }

    {
        unsigned int i;
        for (i = 0; i < MAX_CALLS; ++i) {
            alSourcei(ringSrc[i], AL_LOOPING, AL_TRUE);
            alSourcei(ringSrc[i], AL_BUFFER, RingBuffer);
        }
    }
    #ifdef AUDIO_FILTERING
    Filter_Audio *f_a = NULL;
    #endif

    while(loop == LOOP_RUN || loop == LOOP_SUSPEND) {
        #ifdef AUDIO_FILTERING
        if (!f_a && audio_filtering_enabled) {
            f_a = new_filter_audio(av_DefaultSettings.audio_sample_rate);
            if (!f_a) {
                audio_filtering_enabled = 0;
                qDebug() << "filter audio failed";
            } else {
                qDebug() << "filter audio on";
            }
        } else if (f_a && !audio_filtering_enabled) {
            kill_filter_audio(f_a);
            f_a = NULL;
            qDebug() << "filter audio off";
        }
        #else
        if (audio_filtering_enabled)
            audio_filtering_enabled = 0;
        #endif

        bool sleep = 1;

        if(record_on) {
            ALint samples;
            alcGetIntegerv(device_in, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
            if(samples >= perframe) {
                alcCaptureSamples(device_in, buf, perframe);
                if (samples >= perframe * 2) {
                    sleep = 0;
                }
            }
        }

        #ifdef AUDIO_FILTERING
        #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
        if (f_a && audio_filtering_enabled) {
            ALint samples;
            alcGetIntegerv(device_out, ALC_LOOPBACK_CAPTURE_SAMPLES, sizeof(samples), &samples);
            if(samples >= perframe) {
                int16_t buffer[perframe];
                alcCaptureSamplesLoopback(device_out, buffer, perframe);
                pass_audio_output(f_a, buffer, perframe);
                set_echo_delay_ms(f_a, 5);
                    if (samples >= perframe * 2) {
                    sleep = 0;
                }
            }
        }
        #endif
        #endif

        #ifdef AUDIO_FILTERING
        if (f_a && filter_audio(f_a, (int16_t*)buf, perframe) == -1) {
            qDebug() << "filter audio error";
        }
        #endif
        if(preview) {
            audio_play(0, (int16_t*)buf, perframe, av_DefaultSettings.audio_channels, av_DefaultSettings.audio_sample_rate);
        }

        int i;
        for(i = 0; i < MAX_CALLS; i++) {
            if(call[i]) {
                int r;
                if((r = toxav_prepare_audio_frame(toxav, i, dest, sizeof(dest), (const int16_t*)buf, perframe)) < 0) {
                    qDebug() << "toxav_prepare_audio_frame error" << r;
                    continue;
                }

                if((r = toxav_send_audio(toxav, i, dest, r)) < 0) {
                    qDebug() << "toxav_send_audio error" << r;
                }
            }
        }

        if (sleep) {
            usleep(5000);
        }
    }

    #ifdef AUDIO_FILTERING
    kill_filter_audio(f_a);
    #endif

    //missing some cleanup ?
    alDeleteSources(MAX_CALLS, ringSrc);
    alDeleteSources(countof(source), source);
    alDeleteBuffers(1, &RingBuffer);

    if(device_in) {
        if(record_on) {
            alcCaptureStop(device_in);
        }
        alcCaptureCloseDevice(device_in);
    }

    alcMakeContextCurrent(NULL);
    alcDestroyContext(context);
    alcCloseDevice(device_out);
}
Esempio n. 7
0
static int init(struct ao *ao)
{
    float position[3] = {0, 0, 0};
    float direction[6] = {0, 0, -1, 0, 1, 0};
    ALCdevice *dev = NULL;
    ALCcontext *ctx = NULL;
    ALCint freq = 0;
    ALCint attribs[] = {ALC_FREQUENCY, ao->samplerate, 0, 0};
    int i;
    struct priv *p = ao->priv;
    if (ao_data) {
        MP_FATAL(ao, "Not reentrant!\n");
        return -1;
    }
    ao_data = ao;
    struct mp_chmap_sel sel = {0};
    for (i = 0; speaker_pos[i].id != -1; i++)
        mp_chmap_sel_add_speaker(&sel, speaker_pos[i].id);
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_out;
    struct speaker speakers[MAX_CHANS];
    for (i = 0; i < ao->channels.num; i++) {
        speakers[i].id = -1;
        for (int n = 0; speaker_pos[n].id >= 0; n++) {
            if (speaker_pos[n].id == ao->channels.speaker[i])
                speakers[i] = speaker_pos[n];
        }
        if (speakers[i].id < 0) {
            MP_FATAL(ao, "Unknown channel layout\n");
            goto err_out;
        }
    }
    char *dev_name = ao->device;
    dev = alcOpenDevice(dev_name && dev_name[0] ? dev_name : NULL);
    if (!dev) {
        MP_FATAL(ao, "could not open device\n");
        goto err_out;
    }
    ctx = alcCreateContext(dev, attribs);
    alcMakeContextCurrent(ctx);
    alListenerfv(AL_POSITION, position);
    alListenerfv(AL_ORIENTATION, direction);
    alGenSources(ao->channels.num, sources);
    for (i = 0; i < ao->channels.num; i++) {
        cur_buf[i] = 0;
        unqueue_buf[i] = 0;
        alGenBuffers(NUM_BUF, buffers[i]);
        alSourcefv(sources[i], AL_POSITION, speakers[i].pos);
        alSource3f(sources[i], AL_VELOCITY, 0, 0, 0);
    }
    alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
    if (alcGetError(dev) == ALC_NO_ERROR && freq)
        ao->samplerate = freq;

    p->al_format = AL_FALSE;
    int try_formats[AF_FORMAT_COUNT];
    af_get_best_sample_formats(ao->format, try_formats);
    for (int n = 0; try_formats[n]; n++) {
        p->al_format = get_al_format(try_formats[n]);
        if (p->al_format != AL_FALSE) {
            ao->format = try_formats[n];
            break;
        }
    }

    if (p->al_format == AL_FALSE) {
        MP_FATAL(ao, "Can't find appropriate sample format.\n");
        uninit(ao);
        goto err_out;
    }

    p->chunk_size = CHUNK_SAMPLES * af_fmt_to_bytes(ao->format);
    return 0;

err_out:
    ao_data = NULL;
    return -1;
}
Esempio n. 8
0
//----------------------------------------------------------------------------//
SoundBuffer::SoundBuffer(const Ogre::String& name): mDuration(0), mChannels(0), mFrequency(0), mSize(0), mBits(0)
{
	mBuffers = new ALuint[1];
	alGenBuffers(1, mBuffers);
}
Esempio n. 9
0
/*
========================
idSoundVoice_OpenAL::Create
========================
*/
void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSoundSample* loopingSample_ )
{
	if( IsPlaying() )
	{
		// This should never hit
		Stop();
		return;
	}
	
	triggered = true;
	
	leadinSample = ( idSoundSample_OpenAL* )leadinSample_;
	loopingSample = ( idSoundSample_OpenAL* )loopingSample_;
	
	if( alIsSource( openalSource ) && CompatibleFormat( leadinSample ) )
	{
		sampleRate = leadinSample->format.basic.samplesPerSec;
	}
	else
	{
		DestroyInternal();
		formatTag = leadinSample->format.basic.formatTag;
		numChannels = leadinSample->format.basic.numChannels;
		sampleRate = leadinSample->format.basic.samplesPerSec;
		
		//soundSystemLocal.hardware.pXAudio2->CreateSourceVoice( &pSourceVoice, ( const WAVEFORMATEX* )&leadinSample->format, XAUDIO2_VOICE_USEFILTER, 4.0f, &streamContext );
		
		CheckALErrors();
		
		alGenSources( 1, &openalSource );
		if( CheckALErrors() != AL_NO_ERROR )
			//if( pSourceVoice == NULL )
		{
			// If this hits, then we are most likely passing an invalid sample format, which should have been caught by the loader (and the sample defaulted)
			return;
		}
		
		alSourcef( openalSource, AL_ROLLOFF_FACTOR, 0.0f );
		
		//if( ( loopingSample == NULL && leadinSample->openalBuffer != 0 ) || ( loopingSample != NULL && soundShader->entries[0]->hardwareBuffer ) )
		if( leadinSample->openalBuffer != 0 )
		{
			alSourcei( openalSource, AL_BUFFER, 0 );
			
			// handle uncompressed (non streaming) single shot and looping sounds
			/*
			if( triggered )
			{
				alSourcei( openalSource, AL_BUFFER, looping ? chan->soundShader->entries[0]->openalBuffer : leadinSample->openalBuffer );
			}
			*/
		}
		else
		{
			//if( triggered )
			
			// handle streaming sounds (decode on the fly) both single shot AND looping
			
			alSourcei( openalSource, AL_BUFFER, 0 );
			alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
			lastopenalStreamingBuffer[0] = openalStreamingBuffer[0];
			lastopenalStreamingBuffer[1] = openalStreamingBuffer[1];
			lastopenalStreamingBuffer[2] = openalStreamingBuffer[2];
			
			alGenBuffers( 3, &openalStreamingBuffer[0] );
			/*
			if( soundSystemLocal.alEAXSetBufferMode )
			{
				soundSystemLocal.alEAXSetBufferMode( 3, &chan->openalStreamingBuffer[0], alGetEnumValue( ID_ALCHAR "AL_STORAGE_ACCESSIBLE" ) );
			}
			*/
			openalStreamingBuffer[0];
			openalStreamingBuffer[1];
			openalStreamingBuffer[2];
		}
		
		if( s_debugHardware.GetBool() )
		{
			if( loopingSample == NULL || loopingSample == leadinSample )
			{
				idLib::Printf( "%dms: %i created for %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>" );
			}
			else
			{
				idLib::Printf( "%dms: %i created for %s and %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>", loopingSample ? loopingSample->GetName() : "<null>" );
			}
		}
	}
	
	sourceVoiceRate = sampleRate;
	//pSourceVoice->SetSourceSampleRate( sampleRate );
	//pSourceVoice->SetVolume( 0.0f );
	
	alSourcei( openalSource, AL_SOURCE_RELATIVE, AL_TRUE );
	alSource3f( openalSource, AL_POSITION, 0.0f, 0.0f, 0.0f );
	
	// RB: FIXME 0.0f ?
	alSourcef( openalSource, AL_GAIN, 1.0f );
	
	//OnBufferStart( leadinSample, 0 );
}
Esempio n. 10
0
/*
==============
S_EndLoadSound
==============
*/
qboolean S_EndLoadSound( sfx_t *sfx )
{
    wavinfo_t	info;
    byte*		data;
    ALuint		Buffer;

    assert(sfx->iFlags & SFX_FLAG_LOADING);
    sfx->iFlags &= ~SFX_FLAG_LOADING;

    // was the read successful?
    if (Sys_StreamIsError(sfx->iStreamHandle))
    {
#if defined(FINAL_BUILD)
        /*
        extern void ERR_DiscFail(bool);
        ERR_DiscFail(false);
        */
#endif
        Sys_StreamClose(sfx->iStreamHandle);
        Z_Free(sfx->pSoundData);
        sfx->iFlags |= SFX_FLAG_RESIDENT | SFX_FLAG_DEFAULT;
        return qfalse;
    }

    Sys_StreamClose(sfx->iStreamHandle);
    SND_TouchSFX(sfx);

    sfx->iLastTimeUsed = Com_Milliseconds()+1;	// why +1? Hmmm, leave it for now I guess

    // loading a WAV, presumably...
    data = (byte*)sfx->pSoundData;
    info = GetWavInfo( data );

    if (info.size == 0)
    {
        Z_Free(sfx->pSoundData);
        sfx->iFlags |= SFX_FLAG_RESIDENT | SFX_FLAG_DEFAULT;
        return qfalse;
    }

    sfx->iSoundLength = info.size;

    // make sure we have enough space for the sound
    SND_update(sfx);

    // Clear Open AL Error State
    alGetError();

    // Generate AL Buffer
    alGenBuffers(1, &Buffer);

    // Copy audio data to AL Buffer
    alBufferData(Buffer, info.format, data,
                 sfx->iSoundLength, info.rate);
    if (alGetError() != AL_NO_ERROR)
    {
        Z_Free(sfx->pSoundData);
        sfx->iFlags |= SFX_FLAG_UNLOADED;
        return qfalse;
    }

    sfx->Buffer = Buffer;

#ifdef _GAMECUBE
    Z_Free(sfx->pSoundData);
#endif
    sfx->iFlags |= SFX_FLAG_RESIDENT;

    return qtrue;
}
Esempio n. 11
0
	void Music::MusicThread()
	{
		// Allocation of streaming buffers
		ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
		alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);

		for (unsigned int buffer : buffers)
		{
			if (FillAndQueueBuffer(buffer))
				break; // We have reached the end of the stream, there is no use to add new buffers
		}

		alSourcePlay(m_source);

		// Reading loop (Filling new buffers as playing)
		while (m_impl->streaming)
		{
			// The reading has stopped, we have reached the end of the stream
			SoundStatus status = GetInternalStatus();
			if (status == SoundStatus_Stopped)
			{
				m_impl->streaming = false;
				break;
			}

			Nz::LockGuard lock(m_impl->bufferLock);

			// We treat read buffers
			ALint processedCount = 0;
			alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
			while (processedCount--)
			{
				ALuint buffer;
				alSourceUnqueueBuffers(m_source, 1, &buffer);

				ALint bits, size;
				alGetBufferi(buffer, AL_BITS, &bits);
				alGetBufferi(buffer, AL_SIZE, &size);

				if (bits != 0)
					m_impl->processedSamples += (8 * size) / bits;

				if (FillAndQueueBuffer(buffer))
					break;
			}

			lock.Unlock();

			// We go back to sleep
			Thread::Sleep(50);
		}

		// Stop playing of the sound (in the case where it has not been already done)
		alSourceStop(m_source);

		// We delete buffers from the stream
		ALint queuedBufferCount;
		alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);

		ALuint buffer;
		for (ALint i = 0; i < queuedBufferCount; ++i)
			alSourceUnqueueBuffers(m_source, 1, &buffer);

		alDeleteBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
	}
Esempio n. 12
0
AudioBuffer::AudioBuffer(const String &filename) {
	if (filename.ExtractExt() == "wav") {
		m_alBuffer = 0;
		File * file = new File(filename, FILE_READ);

		int32 chunkId = file->ReadInt();
		int32 riffChunkSize = file->ReadInt();
		int32 format = file->ReadInt();
		int32 subChunkId = file->ReadInt();
		int32 fmtChunkSize = file->ReadInt();
		int16 audioFormat = file->ReadInt16();
		int16 channels = file->ReadInt16();
		int32 sampleRate = file->ReadInt();
		int32 byteRate = file->ReadInt();
		int16 blockAlign = file->ReadInt16();
		int16 bitsPerSample = file->ReadInt16();
		if (fmtChunkSize > 16) {
			int16 extraParamsSize = file->ReadInt16();
			file->Seek(file->Pos() + extraParamsSize);
		}

		char text[5] = "";
		file->ReadBytes(text, 4);
		while (String(text) != "data" && !file->Eof()) {
			file->ReadBytes(text, 4);
			if (String(text) == "data")
				break;
			file->Seek(file->Pos() + 4);
		}

		int32 dataSize = file->ReadInt();
		uint32 * data = (uint32 *)malloc(dataSize);
		file->ReadBytes(data, dataSize);

		ALenum bufferFormat;
		if (bitsPerSample == 8) {
			if (channels == 1)
				bufferFormat = AL_FORMAT_MONO8;
			else
				bufferFormat = AL_FORMAT_STEREO8;
		}
		else {
			if (channels == 1)
				bufferFormat = AL_FORMAT_MONO16;
			else
				bufferFormat = AL_FORMAT_STEREO16;
		}

		alGenBuffers(1, &m_alBuffer);
		alBufferData(m_alBuffer, bufferFormat, data, dataSize, sampleRate);
		delete file;
		free(data);
	} else if (filename.ExtractExt() == "ogg") {
		stb_vorbis * file = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr);

		if (file) {
			stb_vorbis_info info = stb_vorbis_get_info(file);
			uint32 size = stb_vorbis_stream_length_in_samples(file) * info.channels;
			int16 * buffer = (int16 *)malloc(size * sizeof(int16));
			stb_vorbis_get_samples_short_interleaved(file, info.channels, buffer, size);
			alGenBuffers(1, &m_alBuffer);
			ALenum bufferFormat;
			if (info.channels == 1)
				bufferFormat = AL_FORMAT_MONO16;
			else
				bufferFormat = AL_FORMAT_STEREO16;
			alBufferData(m_alBuffer, bufferFormat, buffer, size, info.sample_rate);
			stb_vorbis_close(file);
			free(buffer);
		}
	}
}
Esempio n. 13
0
/** Plays the audio data from the given file
 *  \param fileHandle,volume,onFinished,user_data see sound_PlayStream()
 *  \param streamBufferSize the size to use for the decoded audio buffers
 *  \param buffer_count the amount of audio buffers to use
 *  \see sound_PlayStream() for details about the rest of the function
 *       parameters and other details.
 */
AUDIO_STREAM* sound_PlayStreamWithBuf(PHYSFS_file* fileHandle, float volume, void (*onFinished)(void*), void* user_data, size_t streamBufferSize, unsigned int buffer_count)
{
#if !defined(WZ_NOSOUND)
	AUDIO_STREAM* stream;
	ALuint*       buffers = alloca(sizeof(ALuint) * buffer_count);
	ALint error;
	unsigned int i;

	if ( !openal_initialized )
	{
		debug(LOG_WARNING, "OpenAL isn't initialized, not creating an audio stream");
		return NULL;
	}

	stream = malloc(sizeof(AUDIO_STREAM));
	if (stream == NULL)
	{
		debug(LOG_FATAL, "sound_PlayStream: Out of memory");
		abort();
		return NULL;
	}

	// Clear error codes
	alGetError();

	// Retrieve an OpenAL sound source
	alGenSources(1, &(stream->source));

	error = sound_GetError();
	if (error != AL_NO_ERROR)
	{
		// Failed to create OpenAL sound source, so bail out...
		debug(LOG_SOUND, "alGenSources failed, most likely out of sound sources");
		free(stream);
		return NULL;
	}

	stream->fileHandle = fileHandle;

	stream->decoder = sound_CreateOggVorbisDecoder(stream->fileHandle, false);
	if (stream->decoder == NULL)
	{
		debug(LOG_ERROR, "sound_PlayStream: Failed to open audio file for decoding");
		free(stream);
		return NULL;
	}

	stream->volume = volume;
	stream->bufferSize = streamBufferSize;

	alSourcef(stream->source, AL_GAIN, stream->volume);

	// HACK: this is a workaround for a bug in the 64bit implementation of OpenAL on GNU/Linux
	// The AL_PITCH value really should be 1.0.
	alSourcef(stream->source, AL_PITCH, 1.001f);

	// Create some OpenAL buffers to store the decoded data in
	alGenBuffers(buffer_count, buffers);
	sound_GetError();

	// Fill some buffers with audio data
	for (i = 0; i < buffer_count; ++i)
	{
		// Decode some audio data
		soundDataBuffer* soundBuffer = sound_DecodeOggVorbis(stream->decoder, stream->bufferSize);

		// If we actually decoded some data
		if (soundBuffer && soundBuffer->size > 0)
		{
			// Determine PCM data format
			ALenum format = (soundBuffer->channelCount == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;

			// Copy the audio data into one of OpenAL's own buffers
			alBufferData(buffers[i], format, soundBuffer->data, soundBuffer->size, soundBuffer->frequency);
			sound_GetError();

			// Clean up our memory
			free(soundBuffer);
		}
		else
		{
			// If no data has been decoded we're probably at the end of our
			// stream. So cleanup the excess stuff here.

			// First remove the data buffer itself
			free(soundBuffer);

			// Then remove OpenAL's buffers
			alDeleteBuffers(buffer_count - i, &buffers[i]);
			sound_GetError();

			break;
		}
	}

	// Bail out if we didn't fill any buffers
	if (i == 0)
	{
		debug(LOG_ERROR, "Failed to fill buffers with decoded audio data!");

		// Destroy the decoder
		sound_DestroyOggVorbisDecoder(stream->decoder);

		// Destroy the OpenAL source
		alDeleteSources(1, &stream->source);

		// Free allocated memory
		free(stream);

		return NULL;
	}

	// Attach the OpenAL buffers to our OpenAL source
	// (i = the amount of buffers we worked on in the above for-loop)
	alSourceQueueBuffers(stream->source, i, buffers);
	sound_GetError();

	// Start playing the source
	alSourcePlay(stream->source);

	sound_GetError();

	// Set callback info
	stream->onFinished = onFinished;
	stream->user_data = user_data;

	// Prepend this stream to the linked list
	stream->next = active_streams;
	active_streams = stream;

	return stream;
#else
	return NULL;
#endif
}
Esempio n. 14
0
bool OpenALAudio::StreamContext::stream_data(int new_buffer_count)
{
   const size_t BUFFER_SIZE = 0x4000;

   /*
    * This constant determines how many milliseconds of audio data go into
    * one buffer.  The larger it is, the less probability of skipping, but
    * the longer the delay from calling stop() to the point when it
    * actually stops.
    */
   const size_t MAX_BUFFER_TIME_MS = 50;

   uint8_t data[BUFFER_SIZE];
   size_t frames_read;
   size_t max_frames;
   ALenum format;
   ALuint buf;
   ALint state;

   if (!this->streaming)
      return false;

   format = openal_format(this->stream);
   max_frames = this->stream->frame_rate() * MAX_BUFFER_TIME_MS / 1000;

   for (;;)
   {
      buf = 0;

      if (new_buffer_count > 0)
      {
	 alGenBuffers(1, &buf);
	 if (!check_al())
	    goto err;

	 new_buffer_count--;
      }
      else
      {
	 ALint processed;

	 alGetSourcei(this->source, AL_BUFFERS_PROCESSED, &processed);

	 if (processed == 0)
	    break;

	 alSourceUnqueueBuffers(this->source, 1, &buf);
	 if (!check_al())
	    goto err;
      }

      size_t space_frames = sizeof(data) / this->stream->frame_size();
      space_frames = MIN(space_frames, max_frames);
      frames_read = this->stream->read(data, space_frames);

      if (frames_read == 0)
      {
	 if (this->looping)
	 {
	    this->stream->seek(this->loop_start_frame);
	    frames_read = this->stream->read(data, space_frames);
	    if (frames_read == 0)
	    {
	       this->streaming = false;
	       break;
	    }
	 }
	 else
	 {
	    this->streaming = false;
	    break;
	 }
      }

      if (this->fade_frames != 0)
	 this->apply_fading(data, frames_read);

      alBufferData(buf, format, data,
		   frames_read * this->stream->frame_size(),
		   this->stream->frame_rate());
      if (!check_al())
	 goto err;

      alSourceQueueBuffers(this->source, 1, &buf);
      if (!check_al())
	 goto err;
   }

   if (!this->streaming)
   {
      alDeleteBuffers(1, &buf);
      check_al();
   }

   alGetSourcei(this->source, AL_SOURCE_STATE, &state);

   if (state != AL_PLAYING)
   {
      alSourcePlay(this->source);
      check_al();
   }

   return this->streaming;

err:
   if (buf != 0)
      alDeleteBuffers(1, &buf);

   this->streaming = false;
   return false;
}
Esempio n. 15
0
int main(int argc, char* argv[]) {
    /* initialize OpenAL */
    init_al();

    srand(time(NULL));

    /* Create buffer to store samples */
    ALuint buf;
    alGenBuffers(1, &buf);
    al_check_error();

    /* Fill buffer with Sine-Wave */
    float freq = 400.f;
    int seconds = 4;
    unsigned sample_rate = 8000;
    size_t buf_size = seconds * sample_rate;

    //os vetores de frequencia e amplitude serão recebidos
    //a partir da imagem de profundidade
    //o tamanho de frequencias eh igual ao numero de pixels
    int freq_size = 256;
    float *frequencias;
    frequencias = new float[freq_size];
    float freq_aux;
    for(int i=0; i<256; ++i) {
        if (i == 0)
            frequencias[i] = 100;
        else
            frequencias[i] = frequencias[i-1] + 15;
    }

    //o tamanho de amplitudes eh igual ao numero de pixels
    int amp_size = 256; //igual ao de frequencias
    float *amplitudes;
    amplitudes = new float[amp_size];
    for(int i=0; i<256; ++i) {
        amplitudes[i] = float(rand()%4) / 2;
        //amplitudes[i] = 1;
    }

    short *samples;
    samples = new short[buf_size];

    for(int i=0; i<buf_size; ++i) {
        //samples[i] = 32760 * sin( (2.f*float(M_PI)*freq)/sample_rate * i );
        samples[i] = 0;
        for (int j=0; j<freq_size; ++j){
            samples[i] = samples[i] + 32760 * amplitudes[j] * sin( (2.f*float(M_PI)*frequencias[j])/sample_rate * i );
        }
        //samples[i] = 32760 * sin( (2.f*float(M_PI)*float(rand()%300+100))/sample_rate * i );
    }

    /* Download buffer to OpenAL */
    alBufferData(buf, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
    al_check_error();


    /* Set-up sound source and play buffer */
    ALuint src = 0;
    alGenSources(1, &src);
    alSourcei(src, AL_BUFFER, buf);
    alSourcePlay(src);
    std::cout << "dasdasdas";

    /* While sound is playing, sleep */
    al_check_error();
    //sleep(seconds);
    for(int i = 0; i< 1000000000; i++);
    /* Dealloc OpenAL */
    exit_al();
    al_check_error();
    return 0;
}
Esempio n. 16
0
/*! Initializes the sound device
 *
 *  @returns        ICRESULT        Success/failure of initializing the device
**/
ICRESULT icSoundDeviceAL::Initialize(void)
{
    ICRESULT res = Cleanup();
    if(ICEFAIL(res))
    {
        ALenum err = alGetError();
        icWarningf("icSoundDeviceAL::Initialize failed with error: %i", err);
        return res;
    }

    m_Device = alcOpenDevice(NULL);
    if (NULL == m_Device)
    {
        ALenum err = alGetError();
        icWarningf("icSoundDeviceAL::Initialize failed with error: %i", err);
        return IC_FAIL_GEN;
    }

    m_Context = alcCreateContext(m_Device,NULL);


    if (!alcMakeContextCurrent(m_Context))
    {
        ALenum err = alGetError();
        icWarningf("icSoundDeviceAL::Initialize failed with error: %i", err);
        return IC_FAIL_GEN;
    }

    
    ALenum err = alGetError();

    if (err)
    {
        ALenum err = alGetError();
        icWarningf("icSoundDeviceAL::Initialize failed with error: %i", err);
        return IC_FAIL_GEN;
    }


    ALuint temp_sounds[ICSND_MAX_PLAYING];
    ALuint temp_buffers[ICSND_MAX_SOURCE];
    memset(temp_sounds,0,sizeof(ALuint)*ICSND_MAX_PLAYING);
    memset(temp_buffers,0,sizeof(ALuint)*ICSND_MAX_SOURCE);

    // create the sources
    alGenSources(ICSND_MAX_PLAYING, temp_sounds);

    err = alGetError();
    if (err)
    {
        ALenum err = alGetError();
        icWarningf("icSoundDeviceAL::Initialize failed with error: %i", err);
        return IC_FAIL_GEN;
    }

    // create the buffers
    alGenBuffers(ICSND_MAX_SOURCE, temp_buffers);

    err = alGetError();
    if (err)
    {
        ALenum err = alGetError();
        icWarningf("icSoundDeviceAL::Initialize failed with error: %i", err);
        return IC_FAIL_GEN;
    }

    for (int i=0; i<ICSND_MAX_SOURCE; ++i)
        m_SrcBufs[i].buffID = temp_buffers[i];

    for (int i=0; i<ICSND_MAX_PLAYING; ++i)
    {
        m_Sounds[i] = new icSoundAL();
        m_NumFreeSounds++;
        icSoundAL* temp = (icSoundAL*)m_Sounds[i];
        temp->m_ALsource = temp_sounds[i];
        temp->m_bInitialized = true;
    }

    icMinHeapBuild(m_Sounds,m_NumFreeSounds);

    // TODO 3d stuff
    //alDopplerFactor(ALfloat factor);
    //alDopplerVelocity(ALfloat velocity);

    return IC_OK;
}// END FUNCTION Initialize(void)
Esempio n. 17
0
static int SmpLoad(V3XA_HANDLE *sam)
{
  alGenBuffers(1, (ALuint *)&sam->sampleID);
  alBufferData((ALuint)sam->sampleID, (sam->sampleFormat & V3XA_FMTSTEREO) ?  ((sam->sampleFormat & V3XA_FMT16BIT) ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8) : ((sam->sampleFormat & V3XA_FMT16BIT) ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8), sam->sample, sam->length, sam->samplingRate);
  return 0;
}
Esempio n. 18
0
		Sound::Sound (ALenum format, ALsizei frequency, const Buffer * samples) : _format(format), _frequency(frequency)
		{
			alGenBuffers(1, &_buffer_id);
			alBufferData(_buffer_id, _format, samples->begin(), samples->size(), _frequency);
		}
Esempio n. 19
0
//-----------------------------------------------------------------------------
bool MusicOggStream::load(const std::string& filename)
{
    if (isPlaying()) stopMusic();

    m_error = true;
    m_fileName = filename;
    if(m_fileName=="") return false;

    m_oggFile = fopen(m_fileName.c_str(), "rb");

    if(!m_oggFile)
    {
        Log::error("MusicOgg", "Loading Music: %s failed (fopen returned NULL)\n", m_fileName.c_str());
        return false;
    }

#if defined( WIN32 ) || defined( WIN64 )
    const int result = ov_open_callbacks((void *)m_oggFile, &m_oggStream, NULL, 0, OV_CALLBACKS_DEFAULT);
#else
    const int result = ov_open(m_oggFile, &m_oggStream, NULL, 0);
#endif

    if (result < 0)
    {
        fclose(m_oggFile);


        const char* errorMessage;
        switch (result)
        {
            case OV_EREAD:
                errorMessage = "OV_EREAD";
                break;
            case OV_ENOTVORBIS:
                errorMessage = "OV_ENOTVORBIS";
                break;
            case OV_EVERSION:
                errorMessage = "OV_EVERSION";
                break;
            case OV_EBADHEADER:
                errorMessage = "OV_EBADHEADER";
                break;
            case OV_EFAULT:
                errorMessage = "OV_EFAULT";
                break;
            default:
                errorMessage = "Unknown Error";
        }

        Log::error("MusicOgg", "Loading Music: %s failed : ov_open returned error code %i (%s)\n",
               m_fileName.c_str(), result, errorMessage);
        return false;
    }

    m_vorbisInfo = ov_info(&m_oggStream, -1);

    if (m_vorbisInfo->channels == 1) nb_channels = AL_FORMAT_MONO16;
    else                             nb_channels = AL_FORMAT_STEREO16;

    alGenBuffers(2, m_soundBuffers);
    if (check("alGenBuffers") == false) return false;

    alGenSources(1, &m_soundSource);
    if (check("alGenSources") == false) return false;

    alSource3f(m_soundSource, AL_POSITION,        0.0, 0.0, 0.0);
    alSource3f(m_soundSource, AL_VELOCITY,        0.0, 0.0, 0.0);
    alSource3f(m_soundSource, AL_DIRECTION,       0.0, 0.0, 0.0);
    alSourcef (m_soundSource, AL_ROLLOFF_FACTOR,  0.0          );
    alSourcef (m_soundSource, AL_GAIN,            1.0          );
    alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_TRUE      );

    m_error=false;
    return true;
}   // load
Esempio n. 20
0
int
main() {
    char input[INPUT_BUFFER];
    char *words[MAX_WORDS];
    int count_of_words, signal_index, sleep_usec, count_of_processed, count_of_queued;
    int i;
    ALint state;
    ALshort signals[BUFFER];
    ALCdevice *device;
    ALCcontext *context;
    ALuint buffer, source;

    sleep_usec = (int)(((1.0 / SAMPLING_FREQUENCY) * MAX_WORDS / 2 ) * 1000 * 1000);
    device     = alcOpenDevice(NULL);
    context    = alcCreateContext(device, NULL);
    alcMakeContextCurrent(context);
    alGenSources(1, &source);
    alSourcei(source, AL_SOURCE_TYPE, AL_STREAMING);

    while (fgets(input, INPUT_BUFFER, stdin) != NULL) {
puts("### got input");
        count_of_words = split_string(input, words);
        signal_index   = 0;

        for (i = 0; i < count_of_words; i++) {
            signals[signal_index++] = (ALshort)atoi(words[i]);
        }

        if (alGetSourcei(source, AL_BUFFERS_QUEUED, &count_of_queued), count_of_queued < COUNT_OF_BUFFERS) {
            alGenBuffers(1, &buffer);
        }
        else {
            while (alGetSourcei(source, AL_BUFFERS_PROCESSED, &count_of_processed), count_of_processed == 0) {
                usleep(sleep_usec);
            }

            for (i = 0; i < count_of_processed; i++) {
                alSourceUnqueueBuffers(source, 1, &buffer);
            }
        }

        alBufferData(buffer, AL_FORMAT_MONO16, signals, sizeof(ALshort) * signal_index, SAMPLING_FREQUENCY);
        alSourceQueueBuffers(source, 1, &buffer);

        if (alGetSourcei(source, AL_SOURCE_STATE, &state), state != AL_PLAYING) {
puts("--- start playing");
            alGetSourcei(source, AL_BUFFERS_PROCESSED, &count_of_processed);
            
            for (i = 0; i < count_of_processed - 1; i++) {
printf("--- unqueue: %d\n", i);
                alSourceUnqueueBuffers(source, 1, &buffer);
            }

            alSourcePlay(source);
        }
    }

    alSourceStop(source);
    alDeleteSources(1, &source);
    alDeleteBuffers(1, &buffer);
    alcMakeContextCurrent(NULL);
    alcDestroyContext(context);
    alcCloseDevice(device);

    return 0;
}
Esempio n. 21
0
void Sound::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/)
{
    if (!GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled()))
        return;

    std::string filename = path.string();
    ALuint current_buffer;
    ALenum source_state;
    ALsizei ogg_freq;
    FILE *file = 0;
    int m_i;
    bool found_buffer = true;
    bool found_source = false;

#ifdef FREEORION_WIN32
    ov_callbacks callbacks = {

        (size_t (*)(void *, size_t, size_t, void *))  fread,

        (int (*)(void *, ogg_int64_t, int))           _fseek64_wrap,

        (int (*)(void *))                             fclose,

        (long (*)(void *))                            ftell

    };
#endif

    if (alcGetCurrentContext() != 0)
    {
        /* First check if the sound data of the file we want to play is already buffered somewhere */
        std::map<std::string, ALuint>::iterator it = m_buffers.find(filename);
        if (it != m_buffers.end())
            current_buffer = it->second;
        else {
            if ((file = fopen(filename.c_str(), "rb")) != 0) // make sure we CAN open it
            {
                OggVorbis_File ogg_file;
                vorbis_info *vorbis_info;
                ALenum ogg_format;
#ifdef FREEORION_WIN32
                if (!(ov_test_callbacks(file, &ogg_file, 0, 0, callbacks))) // check if it's a proper ogg
#else
                if (!(ov_test(file, &ogg_file, 0, 0))) // check if it's a proper ogg
#endif
                {
                    ov_test_open(&ogg_file); // it is, now fully open the file
                    /* now we need to take some info we will need later */
                    vorbis_info = ov_info(&ogg_file, -1);
                    if (vorbis_info->channels == 1)
                        ogg_format = AL_FORMAT_MONO16;
                    else
                        ogg_format = AL_FORMAT_STEREO16;
                    ogg_freq = vorbis_info->rate;
                    ogg_int64_t byte_size = ov_pcm_total(&ogg_file, -1) * vorbis_info->channels * 2;
                    if (byte_size <= 1024 * 1024 * 1024) {
                        /* fill up the buffers and queue them up for the first time */
                        ALuint sound_handle;
                        alGenBuffers(1, &sound_handle);

                        int loop = 0;

                        RefillBuffer(&ogg_file, ogg_format, ogg_freq, sound_handle, byte_size, loop);

                        current_buffer = sound_handle;
                        m_buffers.insert(std::make_pair(filename, sound_handle));
                    }
                    else
                    {
                        Logger().errorStream() << "PlaySound: unable to open file " << filename.c_str() << " too big to buffer. Aborting\n";
                    }
                    ov_clear(&ogg_file);
                }
                else
                {
                    Logger().errorStream() << "PlaySound: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n";
                }
            }
        }
        if (found_buffer) {
            /* Now that we have the buffer, we need to find a source to send it to */
            for (m_i = 1; m_i < NUM_SOURCES; ++m_i) {   // as we're playing sounds we start at 1. 0 is reserved for music
                alGetSourcei(m_sources[m_i],AL_SOURCE_STATE,&source_state);
                if ((source_state != AL_PLAYING) && (source_state != AL_PAUSED)) {
                    found_source = true;
                    alSourcei(m_sources[m_i], AL_BUFFER, current_buffer);
                    alSourcePlay(m_sources[m_i]);
                    break; // so that the sound won't block all the sources
                }
            }
            if (!found_source)
                Logger().errorStream() << "PlaySound: Could not find aviable source - playback aborted\n";
        }
        source_state = alGetError();
        if (source_state != AL_NONE)
            Logger().errorStream() << "PlaySound: OpenAL ERROR: " << alGetString(source_state);
        /* it's important to check for errors, as some functions won't work properly if
         * they're called when there is a unchecked previous error. */
    }
}
Esempio n. 22
0
int main(void) 
{ 
/*Отсюда нужно две функции - 
1) получение в виде массива (строки) данных с микрофона за время необработки
2)Проигрвание строки равной значению

*/
const ALCchar *   devices; 
const ALCchar *         ptr; 
ALCdevice *       mainDev; 
ALCcontext *      mainContext; 
ALCdevice *       captureDev; 
ALubyte           captureBuffer[1048576]; 
ALubyte           *captureBufPtr; 
ALint             samplesAvailable; 
ALint             samplesCaptured; 
time_t            currentTime; 
time_t            lastTime; 
ALuint            buffer; 
ALuint            source; 
ALint             playState; 
int               i; 

// Print the list of capture devices 
printf("Available playback devices:\n");

devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER); 
ptr = devices; 
//while (ptr[0] != NULL)
while (*ptr)
{ 
   printf("   %s\n", ptr); 
   ptr += strlen(ptr) + 1; 
} 

// Open a playback device and create a context first 
printf("Opening playback device:\n"); 
mainDev = alcOpenDevice(NULL); 
if (mainDev == NULL) 
{ 
  printf("Unable to open playback device!\n"); 
  exit(1); 
} 
devices = alcGetString(mainDev, ALC_DEVICE_SPECIFIER); 
printf("   opened device '%s'\n", devices); 
mainContext = alcCreateContext(mainDev, NULL); 
if (mainContext == NULL) 
{ 
  printf("Unable to create playback context!\n"); 
  exit(1); 
} 
printf("   created playback context\n"); 

// Make the playback context current 
alcMakeContextCurrent(mainContext); 
alcProcessContext(mainContext); 

// Print the list of capture devices 

printf("Available capture devices:\n"); 
devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); 
ptr = devices; 

//while (ptr[0] != NULL)
while (*ptr)
{ 
   printf("   %s\n", ptr); 
   ptr += strlen(ptr) + 1; 
}

// Open the default device 
printf("Opening capture device:\n"); 
captureDev = alcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO16, 800); 
if (captureDev == NULL) 
{  
  printf("   Unable to open device!\n"); 
  exit(1); 
} 
devices = alcGetString(captureDev, ALC_CAPTURE_DEVICE_SPECIFIER); 
printf("   opened device %s\n", devices); 

// Wait for three seconds to prompt the user 
for (i = 3; i > 0; i--) 
{ 
  printf("Starting capture in %d...\r", i); 
  fflush(stdout); 
  lastTime = time(NULL); 
  currentTime = lastTime; 
  while (currentTime == lastTime) 
  { 
     currentTime = time(NULL); 
     usleep(100000); 
  } 
} 

printf("Starting capture NOW!\n"); 
fflush(stdout); 
lastTime = currentTime; 

// Capture (roughly) five seconds of audio 
alcCaptureStart(captureDev); 
samplesCaptured = 0; 
captureBufPtr = captureBuffer; 
while (currentTime < (lastTime + 5)) 
{ 
  // Get the number of samples available 
  alcGetIntegerv(captureDev, ALC_CAPTURE_SAMPLES, 1, &samplesAvailable); 

  // Copy the samples to our capture buffer 
  if (samplesAvailable > 0) 
  { 
     alcCaptureSamples(captureDev, captureBufPtr, samplesAvailable); 
     samplesCaptured += samplesAvailable; 
     printf("Captured %d samples (adding %d)\r", samplesCaptured, 
        samplesAvailable); 
     fflush(stdout); 

     // Advance the buffer (two bytes per sample * number of samples) 
     captureBufPtr += samplesAvailable * 2; 
  } 

  // Wait for a bit 
  usleep(10000); 

  // Update the clock 
  currentTime = time(NULL); 
} 
printf("\nPausing capture.\n"); 
alcCaptureStop(captureDev); 

// Wait for three seconds to prompt the user 
for (i = 3; i > 0; i--) 
{ 
  printf("Resuming capture in %d...\r", i); 
  fflush(stdout); 
  lastTime = time(NULL); 
  currentTime = lastTime; 
  while (currentTime == lastTime) 
  { 
     currentTime = time(NULL); 
     usleep(100000); 
  } 
} 

printf("Resuming capture NOW!\n"); 
fflush(stdout); 
lastTime = currentTime; 

// Capture (roughly) five seconds of audio 
alcCaptureStart(captureDev); 
while (currentTime < (lastTime + 5)) 
{ 
  // Get the number of samples available 
  alcGetIntegerv(captureDev, ALC_CAPTURE_SAMPLES, 1, &samplesAvailable); 

  // Copy the samples to our capture buffer 
  if (samplesAvailable > 0) 
  { 
     alcCaptureSamples(captureDev, captureBufPtr, samplesAvailable); 
     samplesCaptured += samplesAvailable; 
     printf("Captured %d samples (adding %d)\r", samplesCaptured, 
        samplesAvailable); 
     fflush(stdout); 

     // Advance the buffer (two bytes per sample * number of samples) 
     captureBufPtr += samplesAvailable * 2; 
  } 

  // Wait for a bit 
  usleep(10000); 

  // Update the clock 
  currentTime = time(NULL); 
} 

printf("\nDone capturing.\n"); 
alcCaptureStop(captureDev); 

// Play back the captured data 
printf("Starting playback...\n"); 
fflush(stdout); 

// Generate an OpenAL buffer for the captured data 
alGenBuffers(1, &buffer); 
alGenSources(1, &source); 
alBufferData(buffer, AL_FORMAT_MONO16, captureBuffer,samplesCaptured*2, 8000); 
alSourcei(source, AL_BUFFER, buffer); 
alSourcePlay(source); 

// Wait for the source to stop playing 
playState = AL_PLAYING; 
while (playState == AL_PLAYING) 
{ 
  printf("  source %d is playing...\r", source); 
  fflush(stdout); 
  alGetSourcei(source, AL_SOURCE_STATE, &playState); 
  usleep(100000); 
} 
printf("\nDone with playback.\n"); 
fflush(stdout); 

// Shut down OpenAL 
alDeleteSources(1, &source); 
alDeleteBuffers(1, &buffer); 
alcMakeContextCurrent(NULL); 
alcCloseDevice(mainDev); 
alcCaptureCloseDevice(captureDev); 
}
Esempio n. 23
0
/*
 * queue pcm data.
 * @param device openalDevice object.
 * @param pcms16 pcms16 object.
 */
bool ttLibC_AlDevice_queue(ttLibC_AlDevice *device, ttLibC_PcmS16 *pcms16) {
	if(device == NULL) {
		return false;
	}
	if(pcms16 == NULL) {
		return false;
	}
	switch(pcms16->type) {
	case PcmS16Type_bigEndian:
	case PcmS16Type_bigEndian_planar:
		ERR_PRINT("big endian is not support by openal.");
		return false;
	case PcmS16Type_littleEndian:
		break;
	case PcmS16Type_littleEndian_planar:
		if(pcms16->inherit_super.channel_num != 1) {
			ERR_PRINT("planar data is supported only monoral.");
			return false;
		}
		break;
	default:
		ERR_PRINT("unknown pcms16Type.%d", pcms16->type);
		return false;
	}
	ttLibC_AlDevice_ *device_ = (ttLibC_AlDevice_ *)device;
	ALenum format = AL_FORMAT_MONO16;
	switch(pcms16->inherit_super.channel_num) {
	case 1: // monoral
		format = AL_FORMAT_MONO16;
		break;
	case 2: // stereo
		format = AL_FORMAT_STEREO16;
		break;
	default:
		ERR_PRINT("only monoral or stereo for openal.");
		return false;
	}
	int num;
	ALuint buffer = 0;
	alGetSourcei(device_->source, AL_BUFFERS_PROCESSED, &num);
	if(num != -1 && num != 0) {
		// reuse played buffer.
		alSourceUnqueueBuffers(device_->source, 1, &buffer);
	}
	else {
		// establish new buffer.
		alGetSourcei(device_->source, AL_BUFFERS_QUEUED, &num);
		if(num == device_->inherit_super.buffer_num) {
			ERR_PRINT("buffer is already fulled. cannot queue anymore.");
			return false;
		}
	}
	if(buffer == 0) {
		alGenBuffers(1, &buffer);
		for(uint32_t i = 0;i < device_->inherit_super.buffer_num;++ i) {
			if(device_->buffers[i] == 0) {
				device_->buffers[i] = buffer;
				break;
			}
		}
	}
	alBufferData(buffer, format, pcms16->l_data, pcms16->l_stride, pcms16->inherit_super.sample_rate);
	alSourceQueueBuffers(device_->source, 1, &buffer);
	return true;
}
Esempio n. 24
0
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

	int 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);

	//LL_INFOS("OpenAL") << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers	<<" (" << unprocessed << ":" << processed << ")" << LL_ENDL;

	while(processed--) // unqueue old buffers
	{
		ALuint buffer;
		int error;
		alGetError(); /* clear error */
		alSourceUnqueueBuffers(mWindSource, 1, &buffer);
		error = alGetError();
		if(error != AL_NO_ERROR)
		{
			LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << LL_ENDL;
		}
		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)
		{
			LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << LL_ENDL;
			break;
		}

		alBufferData(buffer,
			     AL_FORMAT_STEREO16,
			     mWindGen->windGenerate(mWindBuf,
						    mWindBufSamples, 2),
			     mWindBufBytes,
			     mWindBufFreq);
		error = alGetError();
		if(error != AL_NO_ERROR)
			LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << LL_ENDL;
		
		alSourceQueueBuffers(mWindSource, 1, &buffer);
		error = alGetError();
		if(error != AL_NO_ERROR)
			LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << LL_ENDL;

		--mNumEmptyWindALBuffers;
	}

	int playing;
	alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
	if(playing != AL_PLAYING)
	{
		alSourcePlay(mWindSource);

		LL_INFOS("OpenAL") << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << LL_ENDL;
	}
}
Esempio n. 25
0
int main(int argc, char* argv[]) {
  //
  // Setup the AL context.
  //
  device = alcOpenDevice(NULL);
  context = alcCreateContext(device, NULL);
  alcMakeContextCurrent(context);

  //
  // Read in the audio sample.
  //
#ifdef EMSCRIPTEN
  FILE* fp = fopen("the_entertainer.wav", "rb");
#else
  FILE* fp = fopen("sounds/the_entertainer.wav", "rb");
#endif
  fseek(fp, 0, SEEK_END);
  size = ftell(fp);
  fseek(fp, 0, SEEK_SET);

  data = (unsigned char*)malloc(size);
  fread(data, size, 1, fp);
  fclose(fp);

  offset = 12; // ignore the RIFF header
  offset += 8; // ignore the fmt header
  offset += 2; // ignore the format type

  channels = data[offset + 1] << 8;
  channels |= data[offset];
  offset += 2;
  printf("Channels: %u\n", channels);

  frequency = data[offset + 3] << 24;
  frequency |= data[offset + 2] << 16;
  frequency |= data[offset + 1] << 8;
  frequency |= data[offset];
  offset += 4;
  printf("Frequency: %u\n", frequency);

  offset += 6; // ignore block size and bps

  bits = data[offset + 1] << 8;
  bits |= data[offset];
  offset += 2;
  printf("Bits: %u\n", bits);

  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

  //
  // Seed the buffers with some initial data.
  //
  ALuint buffers[NUM_BUFFERS];
  alGenBuffers(NUM_BUFFERS, buffers);
  alGenSources(1, &source);

  ALint numBuffers = 0;
  while (numBuffers < NUM_BUFFERS && offset < size) {
    int len = size - offset;
    if (len > BUFFER_SIZE) {
      len = BUFFER_SIZE;
    }

    alBufferData(buffers[numBuffers], format, &data[offset], len, frequency);
    alSourceQueueBuffers(source, 1, &buffers[numBuffers]);
    assert(alGetError() == AL_NO_ERROR);

    offset += len;
    numBuffers++;
  }

  //
  // Start playing the source.
  //
  alSourcePlay(source);

  ALint state;
  alGetSourcei(source, AL_SOURCE_STATE, &state);
  assert(state == AL_PLAYING);

  alGetSourcei(source, AL_BUFFERS_QUEUED, &numBuffers);
  assert(numBuffers == NUM_BUFFERS);

  //
  // Cycle and refill the buffers until we're done.
  //
#if EMSCRIPTEN
  emscripten_set_main_loop(iter, 0, 0);
#else
  while (1) {
    iter(NULL);
    usleep(16);
  }
#endif
}
Esempio n. 26
0
 static ALuint generate_buffer() {
     ALuint buffer;
     alGenBuffers(1, &buffer);
     check_al_error("alGenBuffers");
     return buffer;
 }
Esempio n. 27
0
Audio::Buffer :: Buffer(){
    if(Headless::enabled())
        return;
    auto l = Audio::lock();
    alGenBuffers(1, &id);
}
Esempio n. 28
0
int main(int argc, char *argv[])
{
	ALuint freq;
	ALenum format;
	ALvoid *data;
	ALsizei i, size;
	thread_id thread1, thread2;
	status_t status;
	
	/* listener parameters */
	ALfloat listenerOrientation[] = { 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f };
	ALfloat listenerPosition[] = { 0.0f, 0.0f, 0.0f };
	ALfloat listenerVelocity[] = { 0.0f, 0.0f, 0.0f };

	/* source parameters */
	ALfloat sourcePosition[] = { 0.0f, 0.0f, 1.0f };
	ALfloat sourceVelocity[] = { 0.0f, 0.0f, 0.0f };
	ALfloat sourcePitch = 1.0f;
	ALfloat sourceGain = 1.0f;



	/* initialize */
	print("Main: initialize");
	alInit((ALint *) &argc, (ALubyte **) argv);

	/* create context */
	print("Main: create context");
	context = alcCreateContext(22050, AL_FORMAT_STEREO16, 2048);

	/* lock the context */
	print("Main: make current");
	alcMakeCurrent(context);


	/* create buffers and sources */
	if (alGenBuffers(kNumBuffers, buffer) != kNumBuffers)
		quit("Can't create buffers");

	if (alGenSources(kNumSources, source) != kNumSources)
		quit("Can't create sources");

	/* load buffers with data */
	alutLoadWAV(kWaveFileName, &format, &data, &size, &freq);
	for (i = 0; i < kNumBuffers; i++) {
		alBufferData(buffer[i], format, data, size, freq);
	}
	free(data);


	/* initialize listener */
	alListenerfv(AL_POSITION, listenerPosition);
	alListenerfv(AL_VELOCITY, listenerVelocity);
	alListenerfv(AL_ORIENTATION, listenerOrientation);

	/* initialize sources */
	for (i = 0; i < kNumSources; i++) {
		alSourcefv(source[i], AL_POSITION, sourcePosition);
		alSourcefv(source[i], AL_VELOCITY, sourceVelocity);

		alSourcef(source[i], AL_PITCH, sourcePitch);
		alSourcef(source[i], AL_GAIN, sourceGain);

		alSourcei(source[i], AL_BUFFER, buffer[i % kNumBuffers]);
		alSourcei(source[i], AL_LOOPING, AL_TRUE);
	}

	/* start the sources */
	print("Main: play");
	for (i = 0; i < kNumSources; i++)
		alSourcePlay(source[i]);
	
	/* release the context */
	print("Main: release current");
	alcMakeCurrent(NULL);
	

	/* spawn two threads */
	print("Main: spawn thread 1");
	thread1 = spawn_thread(threadFunc1, "thread 1", B_NORMAL_PRIORITY, NULL);
	print("Main: spawn thread 2");
	thread2 = spawn_thread(threadFunc2, "thread 2", B_NORMAL_PRIORITY, NULL);

	/* resume the threads */	
	print("Main: resume thread 1");
	resume_thread(thread1);
	print("Main: resume thread 2");
	resume_thread(thread2);

	/* acquire context, snooze and release context */
	print("Main: make current");
	alcMakeCurrent(context);
	
	print("Main: snooze...");
	snooze(500000);

	print("Main: release current");
	alcMakeCurrent(NULL);
	

	/* wait until the threads end */
	print("Main: wait thread 1");
	wait_for_thread(thread1, &status);
	if (status != 0)
		print("Main: thread 1 failed?");
	print("Main: wait thread 2");
	wait_for_thread(thread2, &status);
	if (status != 0)
		print("Main: thread 2 failed?");


	/* acquire the context */
	print("Main: make current");
	alcMakeCurrent(context);

	/* delete buffers and sources */
	print("Main: delete sources");
	alDeleteSources(kNumSources, source);
	print("Main: delete buffers");
	alDeleteBuffers(kNumBuffers, buffer);

	/* release the context */
	print("Main: release current");
	alcMakeCurrent(NULL);
	
	
	/* shutdown */
	print("Main: delete context");
	alcDeleteContext(context);

	/* bye */
	print("Main: bye");
	alExit();
	
	return 0;
}
Esempio n. 29
0
void SoundStream::streamData()
{
    bool requestStop = false;

    {
        Lock lock(m_threadMutex);

        // Check if the thread was launched Stopped
        if (m_threadStartState == Stopped)
        {
            m_isStreaming = false;
            return;
        }
    }

    // Create the buffers
    alCheck(alGenBuffers(BufferCount, m_buffers));
    for (int i = 0; i < BufferCount; ++i)
        m_endBuffers[i] = false;

    // Fill the queue
    requestStop = fillQueue();

    // Play the sound
    alCheck(alSourcePlay(m_source));

    {
        Lock lock(m_threadMutex);

        // Check if the thread was launched Paused
        if (m_threadStartState == Paused)
            alCheck(alSourcePause(m_source));
    }

    for (;;)
    {
        {
            Lock lock(m_threadMutex);
            if (!m_isStreaming)
                break;
        }

        // The stream has been interrupted!
        if (SoundSource::getStatus() == Stopped)
        {
            if (!requestStop)
            {
                // Just continue
                alCheck(alSourcePlay(m_source));
            }
            else
            {
                // End streaming
                Lock lock(m_threadMutex);
                m_isStreaming = false;
            }
        }

        // Get the number of buffers that have been processed (i.e. 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));

                // Bits can be 0 if the format or parameters are corrupt, avoid division by zero
                if (bits == 0)
                {
                    err() << "Bits in sound stream are 0: make sure that the audio format is not corrupt "
                          << "and initialize() has been called correctly" << std::endl;

                    // Abort streaming (exit main loop)
                    Lock lock(m_threadMutex);
                    m_isStreaming = false;
                    requestStop = true;
                    break;
                }
                else
                {
                    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));

    // Dequeue any buffer left in the queue
    clearQueue();

    // Delete the buffers
    alCheck(alSourcei(m_source, AL_BUFFER, 0));
    alCheck(alDeleteBuffers(BufferCount, m_buffers));
}
Esempio n. 30
0
const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager,
                              AudioRenderer *audioRenderer)
{
	AudioVorbis *audio = audioRenderer->audio;
	if (!audio) return 0;

	u32 alSourceId = getSourceId(audioManager, audioRenderer);
	if (alIsSource(alSourceId) == AL_FALSE)
	{
		DEBUG_LOG("audio_updateAndPlay(): Update failed on invalid source id");
		return -1;
	}

	ALint audioState;
	alGetSourcei(alSourceId, AL_SOURCE_STATE, &audioState);
	AL_CHECK_ERROR();
	if (audioState == AL_STOPPED || audioState == AL_INITIAL)
	{
		if (audioState == AL_STOPPED)
		{
			if (audioRenderer->numPlays != AUDIO_REPEAT_INFINITE)
				audioRenderer->numPlays--;

			if (audioRenderer->numPlays == AUDIO_REPEAT_INFINITE ||
			    audioRenderer->numPlays > 0)
			{
				// TODO(doyle): Delete and recreate fixes clicking when reusing
				// buffers
				alDeleteBuffers(ARRAY_COUNT(audioRenderer->bufferId),
				                audioRenderer->bufferId);
				AL_CHECK_ERROR();

				alGenBuffers(ARRAY_COUNT(audioRenderer->bufferId),
				             audioRenderer->bufferId);
				AL_CHECK_ERROR();
			}
			else
			{
				i32 result =
				    rendererRelease(arena, audioManager, audioRenderer);
				return result;
			}
		}

		if (audioRenderer->isStreaming)
		{
			stb_vorbis_seek_start(audio->file);
			for (i32 i = 0; i < ARRAY_COUNT(audioRenderer->bufferId); i++)
			{
				i16 audioChunk[AUDIO_CHUNK_SIZE_] = {0};
				stb_vorbis_get_samples_short_interleaved(
				    audio->file, audio->info.channels, audioChunk,
				    AUDIO_CHUNK_SIZE_);

				alBufferData(audioRenderer->bufferId[i], audioRenderer->format,
				             audioChunk, AUDIO_CHUNK_SIZE_ * sizeof(i16),
				             audio->info.sample_rate);
				AL_CHECK_ERROR();
			}

			alSourceQueueBuffers(alSourceId,
			                     ARRAY_COUNT(audioRenderer->bufferId),
			                     audioRenderer->bufferId);
		}
		else
		{
			alSourceQueueBuffers(alSourceId, 1, audioRenderer->bufferId);
		}

		AL_CHECK_ERROR();
		alSourcePlay(alSourceId);
		AL_CHECK_ERROR();
	}
	else if (audioState == AL_PLAYING)
	{
		ALint numProcessedBuffers;
		alGetSourcei(alSourceId, AL_BUFFERS_PROCESSED,
		             &numProcessedBuffers);
		AL_CHECK_ERROR();
		if (numProcessedBuffers > 0)
		{
			// TODO(doyle): Possibly wrong, we should pass in all processed buffers?
			ALint numBuffersToUnqueue = 1;
			ALuint emptyBufferId;
			alSourceUnqueueBuffers(alSourceId, numBuffersToUnqueue,
			                       &emptyBufferId);
			AL_CHECK_ERROR();

			i16 audioChunk[AUDIO_CHUNK_SIZE_] = {0};
			i32 sampleCount = stb_vorbis_get_samples_short_interleaved(
			    audio->file, audio->info.channels, audioChunk,
			    AUDIO_CHUNK_SIZE_);

			/* There are still samples to play */
			if (sampleCount > 0)
			{
				alBufferData(emptyBufferId, audioRenderer->format, audioChunk,
				             sampleCount * audio->info.channels * sizeof(i16),
				             audio->info.sample_rate);
				AL_CHECK_ERROR();
				alSourceQueueBuffers(alSourceId, 1, &emptyBufferId);
				AL_CHECK_ERROR();
			}
		}
	}

	return 0;
}