Ejemplo n.º 1
0
int main(int argc, char **argv)
{
    ALCdevice *device;
    ALuint source, buffer;
    const char *soundname;
    const char *hrtfname;
    ALCint hrtf_state;
    ALCint num_hrtf;
    ALdouble angle;
    ALenum state;

    /* Print out usage if no file was specified */
    if(argc < 2 || (strcmp(argv[1], "-hrtf") == 0 && argc < 4))
    {
        fprintf(stderr, "Usage: %s [-hrtf <name>] <soundfile>\n", argv[0]);
        return 1;
    }

    /* Initialize OpenAL with the default device, and check for HRTF support. */
    if(InitAL() != 0)
        return 1;

    if(strcmp(argv[1], "-hrtf") == 0)
    {
        hrtfname = argv[2];
        soundname = argv[3];
    }
    else
    {
        hrtfname = NULL;
        soundname = argv[1];
    }

    device = alcGetContextsDevice(alcGetCurrentContext());
    if(!alcIsExtensionPresent(device, "ALC_SOFT_HRTF"))
    {
        fprintf(stderr, "Error: ALC_SOFT_HRTF not supported\n");
        CloseAL();
        return 1;
    }

    /* Define a macro to help load the function pointers. */
#define LOAD_PROC(d, x)  ((x) = alcGetProcAddress((d), #x))
    LOAD_PROC(device, alcGetStringiSOFT);
    LOAD_PROC(device, alcResetDeviceSOFT);
#undef LOAD_PROC

    /* Enumerate available HRTFs, and reset the device using one. */
    alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf);
    if(!num_hrtf)
        printf("No HRTFs found\n");
    else
    {
        ALCint attr[5];
        ALCint index = -1;
        ALCint i;

        printf("Available HRTFs:\n");
        for(i = 0; i < num_hrtf; i++)
        {
            const ALCchar *name = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i);
            printf("    %d: %s\n", i, name);

            /* Check if this is the HRTF the user requested. */
            if(hrtfname && strcmp(name, hrtfname) == 0)
                index = i;
        }

        i = 0;
        attr[i++] = ALC_HRTF_SOFT;
        attr[i++] = ALC_TRUE;
        if(index == -1)
        {
            if(hrtfname)
                printf("HRTF \"%s\" not found\n", hrtfname);
            printf("Using default HRTF...\n");
        }
        else
        {
            printf("Selecting HRTF %d...\n", index);
            attr[i++] = ALC_HRTF_ID_SOFT;
            attr[i++] = index;
        }
        attr[i] = 0;

        if(!alcResetDeviceSOFT(device, attr))
            printf("Failed to reset device: %s\n", alcGetString(device, alcGetError(device)));
    }

    /* Check if HRTF is enabled, and show which is being used. */
    alcGetIntegerv(device, ALC_HRTF_SOFT, 1, &hrtf_state);
    if(!hrtf_state)
        printf("HRTF not enabled!\n");
    else
    {
        const ALchar *name = alcGetString(device, ALC_HRTF_SPECIFIER_SOFT);
        printf("HRTF enabled, using %s\n", name);
    }
    fflush(stdout);

    /* Load the sound into a buffer. */
    buffer = LoadSound(soundname);
    if(!buffer)
    {
        CloseAL();
        return 1;
    }

    /* Create the source to play the sound with. */
    source = 0;
    alGenSources(1, &source);
    alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
    alSource3f(source, AL_POSITION, 0.0f, 0.0f, -1.0f);
    alSourcei(source, AL_BUFFER, buffer);
    assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");

    /* Play the sound until it finishes. */
    angle = 0.0;
    alSourcePlay(source);
    do {
        al_nssleep(10000000);

        /* Rotate the source around the listener by about 1/4 cycle per second.
         * Only affects mono sounds.
         */
        angle += 0.01 * M_PI * 0.5;
        alSource3f(source, AL_POSITION, (ALfloat)sin(angle), 0.0f, -(ALfloat)cos(angle));

        alGetSourcei(source, AL_SOURCE_STATE, &state);
    } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);

    /* All done. Delete resources, and close OpenAL. */
    alDeleteSources(1, &source);
    alDeleteBuffers(1, &buffer);

    CloseAL();

    return 0;
}
Ejemplo n.º 2
0
ChannelHandle SoundManager::playAudioStream(AudioStream *audStream, SoundType type, bool disposeAfterUse) {
	assert((type >= 0) && (type < kSoundTypeMAX));

	checkReady();

	if (!audStream)
		throw Common::Exception("No audio stream");

	Common::StackLock lock(_mutex);

	ChannelHandle handle = newChannel();

	_channels[handle.channel] = new Channel;
	Channel &channel = *_channels[handle.channel];

	channel.id              = handle.id;
	channel.state           = AL_PAUSED;
	channel.stream          = audStream;
	channel.source          = 0;
	channel.disposeAfterUse = disposeAfterUse;
	channel.type            = type;
	channel.typeIt          = _types[channel.type].list.end();
	channel.gain            = 1.0;

	try {

		if (!channel.stream)
			throw Common::Exception("Could not detect stream type");

		ALenum error = AL_NO_ERROR;

		if (_hasSound) {
			// Create the source
			alGenSources(1, &channel.source);
			if ((error = alGetError()) != AL_NO_ERROR)
				throw Common::Exception("OpenAL error while generating sources: %X", error);

			// Create all needed buffers
			for (int i = 0; i < kOpenALBufferCount; i++) {
				ALuint buffer;

				alGenBuffers(1, &buffer);
				if ((error = alGetError()) != AL_NO_ERROR)
					throw Common::Exception("OpenAL error while generating buffers: %X", error);

				if (fillBuffer(channel.source, buffer, channel.stream)) {
					// If we could fill the buffer with data, queue it

					alSourceQueueBuffers(channel.source, 1, &buffer);
					if ((error = alGetError()) != AL_NO_ERROR)
						throw Common::Exception("OpenAL error while queueing buffers: %X", error);

				} else
					// If not, put it into our free list
					channel.freeBuffers.push_back(buffer);

				channel.buffers.push_back(buffer);
			}

			// Set the gain to the current sound type gain
			alSourcef(channel.source, AL_GAIN, _types[channel.type].gain);
		}

		// Add the channel to the correct type list
		_types[channel.type].list.push_back(&channel);
		channel.typeIt = --_types[channel.type].list.end();

	} catch (...) {
		freeChannel(handle);
		throw;
	}

	return handle;
}
//------------------------------------------------------------
bool ofSoundPlayerExtended::load(string fileName, bool is_stream){
    
    string ext = ofToLower(ofFilePath::getFileExt(fileName));
    if(ext != "wav" && ext != "aif" && ext != "aiff" && ext != "mp3"){
        ofLogError("Sound player can only load .wav .aiff or .mp3 files");
        return false;
    }
    
    fileName = ofToDataPath(fileName);
    
    bLoadedOk = false;
    bMultiPlay = false;
    isStreaming = is_stream;
    
    // [1] init sound systems, if necessary
    initialize();
    
    // [2] try to unload any previously loaded sounds
    // & prevent user-created memory leaks
    // if they call "loadSound" repeatedly, for example
    
    unload();
    
    ALenum format=AL_FORMAT_MONO16;
    
    if(!isStreaming || ext == "mp3"){ // mp3s don't stream cause they gotta be decoded
        readFile(fileName, buffer);
    }else{
        stream(fileName, buffer);
    }
    
    if(channels == 0){
        ofLogError("ofSoundPlayerExtended -- File not found");
        return false;
    }
    
    int numFrames = buffer.size()/channels;
    if(isStreaming){
        buffers.resize(channels*2);
    }else{
        buffers.resize(channels);
    }
    alGenBuffers(buffers.size(), &buffers[0]);
    if(channels==1){
        sources.resize(1);
        alGenSources(1, &sources[0]);
        if (alGetError() != AL_NO_ERROR){
            ofLog(OF_LOG_WARNING,"ofSoundPlayerExtended: openAL error reported generating sources for " + fileName);
            return false;
        }
        
        for(int i=0; i<(int)buffers.size(); i++){
            alBufferData(buffers[i],format,&buffer[0],buffer.size()*2,samplerate);
            if (alGetError() != AL_NO_ERROR){
                ofLog(OF_LOG_ERROR,"ofSoundPlayerExtended: error creating buffer");
                return false;
            }
            if(isStreaming){
                stream(fileName,buffer);
            }
        }
        if(isStreaming){
            alSourceQueueBuffers(sources[0],buffers.size(),&buffers[0]);
        }else{
            alSourcei (sources[0], AL_BUFFER,   buffers[0]);
        }
        
        alSourcef (sources[0], AL_PITCH,    1.0f);
        alSourcef (sources[0], AL_GAIN,     1.0f);
        alSourcef (sources[0], AL_ROLLOFF_FACTOR,  0.0);
        alSourcei (sources[0], AL_SOURCE_RELATIVE, AL_TRUE);
    }else{
        vector<vector<short> > multibuffer;
        multibuffer.resize(channels);
        sources.resize(channels);
        alGenSources(channels, &sources[0]);
        if(isStreaming){
            for(int s=0; s<2;s++){
                for(int i=0;i<channels;i++){
                    multibuffer[i].resize(buffer.size()/channels);
                    for(int j=0;j<numFrames;j++){
                        multibuffer[i][j] = buffer[j*channels+i];
                    }
                    alBufferData(buffers[s*2+i],format,&multibuffer[i][0],buffer.size()/channels*2,samplerate);
                    if (alGetError() != AL_NO_ERROR){
                        ofLog(OF_LOG_ERROR,"ofSoundPlayerExtended: error creating stereo buffers for " + fileName);
                        return false;
                    }
                    alSourceQueueBuffers(sources[i],1,&buffers[s*2+i]);
                    stream(fileName,buffer);
                }
            }
        }else{
            for(int i=0;i<channels;i++){
                multibuffer[i].resize(buffer.size()/channels);
                for(int j=0;j<numFrames;j++){
                    multibuffer[i][j] = buffer[j*channels+i];
                }
                alBufferData(buffers[i],format,&multibuffer[i][0],buffer.size()/channels*2,samplerate);
                if (alGetError() != AL_NO_ERROR){
                    ofLog(OF_LOG_ERROR,"ofSoundPlayerExtended: error creating stereo buffers for " + fileName);
                    return false;
                }
                alSourcei (sources[i], AL_BUFFER,   buffers[i]   );
            }
        }
        
        for(int i=0;i<channels;i++){
            if (alGetError() != AL_NO_ERROR){
                ofLog(OF_LOG_ERROR,"ofSoundPlayerExtended: error creating stereo sources for " + fileName);
                return false;
            }
            
            // only stereo panning
            if(i==0){
                float pos[3] = {-1,0,0};
                alSourcefv(sources[i],AL_POSITION,pos);
            }else{
                float pos[3] = {1,0,0};
                alSourcefv(sources[i],AL_POSITION,pos);
            }
            alSourcef (sources[i], AL_ROLLOFF_FACTOR,  0.0);
            alSourcei (sources[i], AL_SOURCE_RELATIVE, AL_TRUE);
        }
    }
    //soundBuffer stuff---------------------
    currentSoundBuffer.setNumChannels(channels);
    currentSoundBuffer.setSampleRate(samplerate);
    currentSoundBuffer.clear();
    channelSoundBuffer.setNumChannels(1);
    channelSoundBuffer.setSampleRate(samplerate);
    channelSoundBuffer.clear();
    //--------------------------------------
    ofLogVerbose("ofSoundPlayerExtended: successfully loaded " + fileName);
    bLoadedOk = true;
    return true;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
Archivo: audio.c Proyecto: kytvi2p/uTox
void audio_thread(void *args){
    ToxAV *av = args;
    const char *device_list, *output_device = NULL;
    void *audio_device = NULL;

    _Bool call[MAX_CALLS] = {0}, preview = 0;
    _Bool groups_audio[MAX_NUM_GROUPS] = {0};

    int perframe = (UTOX_DEFAULT_FRAME_A * UTOX_DEFAULT_SAMPLE_RATE_A) / 1000;
    uint8_t buf[perframe * 2 * UTOX_DEFAULT_AUDIO_CHANNELS]; //, dest[perframe * 2 * UTOX_DEFAULT_AUDIO_CHANNELS];
    memset(buf, 0, sizeof(buf));

    uint8_t audio_count = 0;
    _Bool record_on = 0;
    #ifdef AUDIO_FILTERING
    debug("Audio Filtering");
    #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
    debug(" and Echo cancellation");
    #endif
    debug(" enabled in this build\n");
    #endif

    debug("frame size: %u\n", perframe);

    device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
    if (device_list) {
        audio_device = (void*)device_list;
        debug("uTox audio input device list:\n");
        while(*device_list) {
            debug("\t%s\n", device_list);
            postmessage(AUDIO_IN_DEVICE, UI_STRING_ID_INVALID, 0, (void*)device_list);
            device_list += strlen(device_list) + 1;
        }
    }

    postmessage(AUDIO_IN_DEVICE, STR_AUDIO_IN_NONE, 0, NULL);
    audio_detect();

    if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT")) {
        device_list = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
    } else {
        device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
    }

    if(device_list) {
        output_device = device_list;
        debug("uTox audio output device list:\n");
        while(*device_list) {
            debug("\t%s\n", device_list);
            postmessage(AUDIO_OUT_DEVICE, 0, 0, (void*)device_list);
            device_list += strlen(device_list) + 1;
        }
    }

    device_out = alcOpenDevice(output_device);
    if(!device_out) {
        debug("alcOpenDevice() failed\n");
        return;
    }

    int attrlist[] = {  ALC_FREQUENCY, UTOX_DEFAULT_SAMPLE_RATE_A,
                        ALC_INVALID };

    context = alcCreateContext(device_out, attrlist);
    if(!alcMakeContextCurrent(context)) {
        debug("alcMakeContextCurrent() failed\n");
        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 = 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);
        }
    }
    Filter_Audio *f_a = NULL;

    audio_thread_init = 1;

    int16_t *preview_buffer = NULL;
    unsigned int preview_buffer_index = 0;
    #define PREVIEW_BUFFER_SIZE (UTOX_DEFAULT_SAMPLE_RATE_A / 2)

    while(1) {
        if(audio_thread_msg) {
            TOX_MSG *m = &audio_msg;
            if(!m->msg) {
                break;
            }

            switch(m->msg) {
            case AUDIO_SET_INPUT: {
                audio_device = m->data;

                if(record_on) {
                    alccapturestop(device_in);
                    alccaptureclose(device_in);
                }

                if(audio_count) {
                    device_in = alcopencapture(audio_device);
                    if(!device_in) {
                        record_on = 0;
                    } else {
                        alccapturestart(device_in);
                        record_on = 1;
                    }
                }

                debug("set audio in\n");
                break;
            }

            case AUDIO_SET_OUTPUT: {
                output_device = m->data;

                ALCdevice *device = alcOpenDevice(output_device);
                if(!device) {
                    debug("alcOpenDevice() failed\n");
                    break;
                }

                ALCcontext *con = alcCreateContext(device, NULL);
                if(!alcMakeContextCurrent(con)) {
                    debug("alcMakeContextCurrent() failed\n");
                    alcCloseDevice(device);
                    break;
                }

                alcDestroyContext(context);
                alcCloseDevice(device_out);
                context = con;
                device_out = device;

                alGenSources(countof(source), source);
                alGenSources(MAX_CALLS, ringSrc);

                Tox *tox = toxav_get_tox(av);
                uint32_t num_chats = tox_count_chatlist(tox);

                if (num_chats != 0) {
                    int32_t chats[num_chats];
                    uint32_t max = tox_get_chatlist(tox, chats, num_chats);

                    unsigned int i;
                    for (i = 0; i < max; ++i) {
                        if (tox_group_get_type(tox, chats[i]) == TOX_GROUPCHAT_TYPE_AV) {
                            GROUPCHAT *g = &group[chats[i]];
                            alGenSources(g->peers, g->source);
                        }
                    }
                }

                debug("set audio out\n");
                break;
            }

            case AUDIO_PREVIEW_START: {
                preview = 1;
                audio_count++;
                preview_buffer = calloc(PREVIEW_BUFFER_SIZE, 2);
                preview_buffer_index = 0;
                if(!record_on) {
                    device_in = alcopencapture(audio_device);
                    if(device_in) {
                        alccapturestart(device_in);
                        record_on = 1;
                        debug("Starting Audio Preview\n");
                    }
                }
                break;
            }

            case AUDIO_START: {
                audio_count++;
                if(!record_on) {
                    device_in = alcopencapture(audio_device);
                    if(device_in) {
                        alccapturestart(device_in);
                        record_on = 1;
                        debug("Listening to audio\n");
                        yieldcpu(20);
                    }
                }
                break;
            }

            case GROUP_AUDIO_CALL_START: {
                break; // TODO, new groups API
                audio_count++;
                groups_audio[m->param1] = 1;
                if(!record_on) {
                    device_in = alcopencapture(audio_device);
                    if(device_in) {
                        alccapturestart(device_in);
                        record_on = 1;
                        debug("Starting Audio GroupCall\n");
                    }
                }
                break;
            }

            case AUDIO_PREVIEW_END: {
                preview = 0;
                audio_count--;
                free(preview_buffer);
                preview_buffer = NULL;
                if(!audio_count && record_on) {
                    alccapturestop(device_in);
                    alccaptureclose(device_in);
                    record_on = 0;
                    debug("Audio Preview Stopped\n");
                }
                break;
            }

            case AUDIO_END: {
                if(!call[m->param1]) {
                    break;
                }
                call[m->param1] = 0;
                audio_count--;
                if(!audio_count && record_on) {
                    alccapturestop(device_in);
                    alccaptureclose(device_in);
                    record_on = 0;
                    debug("stop\n");
                }
                break;
            }

            case GROUP_AUDIO_CALL_END: {
                break; // TODO, new groups API
                if(!groups_audio[m->param1]) {
                    break;
                }
                audio_count--;
                groups_audio[m->param1] = 0;
                if(!audio_count && record_on) {
                    alccapturestop(device_in);
                    alccaptureclose(device_in);
                    record_on = 0;
                    debug("stop\n");
                }
                break;
            }

            case AUDIO_PLAY_RINGTONE: {
                if(!audible_notifications_enabled) {
                    break;
                }

                alSourcePlay(ringSrc[m->param1]);
                break;
            }

            case AUDIO_STOP_RINGTONE: {
                ALint state;
                alGetSourcei(ringSrc[m->param1], AL_SOURCE_STATE, &state);
                if(state == AL_PLAYING) {
                    alSourceStop(ringSrc[m->param1]);
                }
                break;
            }
            }

            audio_thread_msg = 0;
        }

        // TODO move this code to filter_audio.c
        #ifdef AUDIO_FILTERING
            if (!f_a && audio_filtering_enabled) {
                f_a = new_filter_audio(UTOX_DEFAULT_SAMPLE_RATE_A);
                if (!f_a) {
                    audio_filtering_enabled = 0;
                    debug("filter audio failed\n");
                } else {
                    debug("filter audio on\n");
                }
            } else if (f_a && !audio_filtering_enabled) {
                kill_filter_audio(f_a);
                f_a = NULL;
                debug("filter audio off\n");
            }
        #else
            if (audio_filtering_enabled) {
                audio_filtering_enabled = 0;
            }
        #endif

        _Bool sleep = 1;

        if(record_on) {
            ALint samples;
            _Bool frame = 0;
            /* If we have a device_in we're on linux so we can just call OpenAL, otherwise we're on something else so
             * we'll need to call audio_frame() to add to the buffer for us. */
            if (device_in == (void*)1) {
                frame = audio_frame((void*)buf);
                if (frame) {
                    /* We have an audio frame to use, continue without sleeping. */
                    sleep = 0;
                }
            } else {
                alcGetIntegerv(device_in, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
                if(samples >= perframe) {
                    alcCaptureSamples(device_in, buf, perframe);
                    frame = 1;
                    if (samples >= perframe * 2) {
                        sleep = 0;
                    }
                }
            }

            #ifdef AUDIO_FILTERING
            #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
            if (f_a && audio_filtering_enabled) {
                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, UTOX_DEFAULT_FRAME_A);
                    if (samples >= perframe * 2) {
                        sleep = 0;
                    }
                }
            }
            #endif
            #endif

            if (frame) {
                _Bool voice = 1;
                #ifdef AUDIO_FILTERING
                if (f_a) {
                    int ret = filter_audio(f_a, (int16_t*)buf, perframe);

                    if (ret == -1) {
                        debug("filter audio error\n");
                    }

                    if (ret == 0) {
                        voice = 0;
                    }
                }
                #endif

                /* If push to talk, we don't have to do anything */
                if (!check_ptt_key()) {
                    voice = 0; //PTT is up, send nothing.
                }

                if (preview) {
                    if (preview_buffer_index + perframe > PREVIEW_BUFFER_SIZE) {
                        preview_buffer_index = 0;
                    }

                    sourceplaybuffer(0, preview_buffer + preview_buffer_index, perframe, UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A);
                    if (voice) {
                        memcpy(preview_buffer + preview_buffer_index, buf, perframe * sizeof(int16_t));
                    } else {
                        memset(preview_buffer + preview_buffer_index, 0, perframe * sizeof(int16_t));
                    }
                    preview_buffer_index += perframe;
                }

                if (voice) {
                    int i, active_call_count = 0;
                    for(i = 0; i < UTOX_MAX_NUM_FRIENDS; i++) {
                        if( UTOX_SEND_AUDIO(i) ) {
                            active_call_count++;
                            TOXAV_ERR_SEND_FRAME error = 0;
                            toxav_audio_send_frame(av, friend[i].number, (const int16_t *)buf, perframe, UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A, &error);
                            if (error) {
                                debug("toxav_send_audio error friend == %i, error ==  %i\n", i, error);
                            } else {
                                // debug("Send a frame to friend %i\n",i);
                                if (i >= UTOX_MAX_CALLS) {
                                    debug("We're calling more peers than allowed by UTOX_MAX_CALLS, This is a bug\n");
                                        break;
                                }
                            }
                        }
                    }

                    // TODO REMOVED until new groups api can be implemented.
                    /*Tox *tox = toxav_get_tox(av);
                    uint32_t num_chats = tox_count_chatlist(tox);

                    if (num_chats != 0) {
                        int32_t chats[num_chats];
                        uint32_t max = tox_get_chatlist(tox, chats, num_chats);
                        for (i = 0; i < max; ++i) {
                            if (groups_audio[chats[i]]) {
                                toxav_group_send_audio(tox, chats[i], (int16_t *)buf, perframe, UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A);
                            }
                        }
                    }*/
                }
            }
        }

        if (sleep) {
            yieldcpu(5);
        }
    }

    utox_filter_audio_kill(f_a);

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

    audio_thread_msg = 0;
    audio_thread_init = 0;
    debug("UTOX AUDIO:\tClean thread exit!\n");
}
Ejemplo n.º 6
0
int SoundSource::LoadFile(const char* file)
{
    //Variables to store info about the WAVE file (all of them is not needed for OpenAL)
    char type[4];
    DWORD size,chunkSize;
    short formatType,channels;
    DWORD sampleRate,avgBytesPerSec;
    short bytesPerSample,bitsPerSample;
    DWORD dataSize;

    //Loading of the WAVE file
    FILE *fp = NULL;                                                            //Create FILE pointer for the WAVE file
    fp=fopen(file,"rb");                                            //Open the WAVE file
    if (!fp) return endWithError("Failed to open file");                        //Could not open file

    //Check that the WAVE file is OK
    fread(type,sizeof(char),4,fp);                                              //Reads the first bytes in the file
    if(type[0]!='R' || type[1]!='I' || type[2]!='F' || type[3]!='F')            //Should be "RIFF"
        return endWithError ("No RIFF");                                            //Not RIFF

    fread(&size, sizeof(DWORD),1,fp);                                           //Continue to read the file
    fread(type, sizeof(char),4,fp);                                             //Continue to read the file
    if (type[0]!='W' || type[1]!='A' || type[2]!='V' || type[3]!='E')           //This part should be "WAVE"
        return endWithError("not WAVE");                                            //Not WAVE

    fread(type,sizeof(char),4,fp);                                              //Continue to read the file
    if (type[0]!='f' || type[1]!='m' || type[2]!='t' || type[3]!=' ')           //This part should be "fmt "
        return endWithError("not fmt ");                                            //Not fmt

    //Now we know that the file is a acceptable WAVE file
    //Info about the WAVE data is now read and stored
    fread(&chunkSize,sizeof(DWORD),1,fp);
    fread(&formatType,sizeof(short),1,fp);
    fread(&channels,sizeof(short),1,fp);
    fread(&sampleRate,sizeof(DWORD),1,fp);
    fread(&avgBytesPerSec,sizeof(DWORD),1,fp);
    fread(&bytesPerSample,sizeof(short),1,fp);
    fread(&bitsPerSample,sizeof(short),1,fp);

    fread(type,sizeof(char),4,fp);
    if (type[0]!='d' || type[1]!='a' || type[2]!='t' || type[3]!='a')           //This part should be "data"
        return endWithError("Missing DATA");                                        //not data

    fread(&dataSize,sizeof(DWORD),1,fp);                                        //The size of the sound data is read

    //Display the info about the WAVE file
    cout << "Chunk Size: " << chunkSize << "\n";
    cout << "Format Type: " << formatType << "\n";
    cout << "Channels: " << channels << "\n";
    cout << "Sample Rate: " << sampleRate << "\n";
    cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n";
    cout << "Bytes Per Sample: " << bytesPerSample << "\n";
    cout << "Bits Per Sample: " << bitsPerSample << "\n";
    cout << "Data Size: " << dataSize << "\n";

    soundData = new unsigned char[dataSize];                            //Allocate memory for the sound data. kalla denna soundData
    cout << fread(soundData,sizeof(BYTE),dataSize,fp) << " bytes loaded\n";           //Read the sound data and display the
    //number of bytes loaded.
    //Should be the same as the Data Size if OK

    ALuint frequency = sampleRate;                                               //The Sample Rate of the WAVE file
    ALenum format=0;                                                            //The audio format (bits per sample, number of channels)

    //Figure out the format of the WAVE file
    if(bitsPerSample == 8)
    {
        if(channels == 1)
            format = AL_FORMAT_MONO8;
        else if(channels == 2)
            format = AL_FORMAT_STEREO8;
    }
    else if(bitsPerSample == 16)
    {
        if(channels == 1)
            format = AL_FORMAT_MONO16;
        else if(channels == 2)
            format = AL_FORMAT_STEREO16;
    }
    if(!format) return endWithError("Wrong BitPerSample");                      //Not valid format

    alGenBuffers(1, &mBuffer);                                                    //Generate one OpenAL Buffer and link to "buffer"
    alGenSources(1, &mSource);                                                   //Generate one OpenAL Source and link to "source"
    if(alGetError() != AL_NO_ERROR) return endWithError("Error GenSource");     //Error during buffer/source generation

    alBufferData(mBuffer, format, soundData, dataSize, frequency);                    //Store the sound data in the OpenAL Buffer
    if(alGetError() != AL_NO_ERROR)
        return endWithError("Error loading ALBuffer");                              //Error during buffer loading

    fclose(fp);
}
Ejemplo n.º 7
0
/*
 * ALboolean LoadALData()
 *
 *	This function will load our sample data from the disk using the alut
 *	utility and send the data into OpenAL as a buffer. A source is then
 *	also created to play that buffer.
 */
int LoadSoundBuffers()
{
    int theerror=0;
	// Variables to load into.
    if (total_loaded_buffers==0) { fprintf(stderr,"No Sounds to load!\n");
                                   return 0; }

	ALenum format;
	ALsizei size;
	ALvoid* data;
	ALsizei freq;
	ALboolean loop;

	// Load wav data into buffers.
	alGenBuffers(total_loaded_buffers, Buffers);
	if(alGetError() != AL_NO_ERROR) { fprintf(stderr,"Error Generating Buffers!\n");
                                      return 0; }

    for (unsigned int i=0; i<total_loaded_buffers; i++)
      {
         alutLoadWAVFile((ALbyte *)filenames[i], &format, &data, &size, &freq, &loop);
         theerror=alGetError();
	     if(theerror != AL_NO_ERROR) { fprintf(stderr,"Error (%u) loading Wav sound Buffer %u %s\n",theerror,i,filenames[i]);   }

         alBufferData(Buffers[i], format, data, size, freq);
	     theerror=alGetError();
	     if(theerror != AL_NO_ERROR) { fprintf(stderr,"Error (%u) loading Wav sound Buffer %u %s\n",theerror,i,filenames[i]);   }

         alutUnloadWAV(format, data, size, freq);
	     theerror=alGetError();
	     if(theerror != AL_NO_ERROR) { fprintf(stderr,"Error (%u) loading Wav sound Buffer %u %s\n",theerror,i,filenames[i]);   }

	     free(filenames[i]); /* Release memory for filename */
      }
	// Bind buffers into audio sources.


	alGenSources(NUM_SOURCES, Sources);
    theerror=alGetError();
	if(theerror != AL_NO_ERROR) { fprintf(stderr,"Error Generating Sources (%u)!\n",theerror);
                                  return 0; }


    for (unsigned int i=0; i<total_loaded_buffers; i++)
      {
         /*alGenSources( 1, &Sources[i] );
         theerror=alGetError();
         if(theerror != AL_NO_ERROR) { cout<<"Error Generating Sources ("<<theerror<<")!\n";
                                       return false; }   */
         alSourcei (Sources[i], AL_BUFFER,   Buffers[i]   );
         alSourcef (Sources[i], AL_PITCH,    1.0f              );
         alSourcef (Sources[i], AL_GAIN,     1.0f              );
	     alSourcefv(Sources[i], AL_POSITION, SourcesPos[i]);
	     alSourcefv(Sources[i], AL_VELOCITY, SourcesVel[i]);
	     alSourcei (Sources[i], AL_LOOPING,  AL_FALSE           );
      }
	// Bind buffers into audio sources.


	// Do another error check and return.
	if(alGetError() != AL_NO_ERROR) return 0;

	SetListenerValues();

    return 1;
}
Ejemplo n.º 8
0
	//------------------------------------------------------------------------------
	bool CGUIMusicData_openal::LoadOggFile( const CGUIString& rFilename ) const
	{
		//open file
		FILE *pFile = fopen( rFilename.c_str(), "rb" );
		if( !pFile)
		{
			return false;
		}

		ov_callbacks sCallbacks;
		sCallbacks.read_func = ov_read_func;
		sCallbacks.seek_func = ov_seek_func;
		sCallbacks.close_func = ov_close_func;
		sCallbacks.tell_func = ov_tell_func;
		if (ov_open_callbacks(pFile, &m_aVorbisFile, NULL, 0, sCallbacks) != 0)
		{
			fclose( pFile );
			return false;
		}

		// Get some information about the file (Channels, Format, and Frequency)
		if( false == GetOggVorbisInfo( &m_aVorbisFile, &m_nFrequency, &m_nFormat, &m_nFormat, &m_nBufferSize ) )
		{
			ov_clear(&m_aVorbisFile);
			return false;
		}

		// Allocate a buffer to be used to store decoded data for all Buffers
		m_pDecodeBuffer = (char*)malloc(m_nBufferSize);
		if ( !m_pDecodeBuffer )
		{
			ov_clear(&m_aVorbisFile);
			return false;
		}

		// Generate a Source to playback the Buffers
		alGenSources(1, &m_nSourceId);
		if (alGetError() != AL_NO_ERROR)
		{
			return false;
		}

		// Generate some AL Buffers for streaming
		alGenBuffers( GUI_MUSIC_NUMBUFFERS, m_nBuffers );
		if (alGetError() != AL_NO_ERROR)
		{
			return false;
		}

		// Fill all the Buffers with decoded audio data from the OggVorbis file
		for (int iLoop = 0; iLoop < GUI_MUSIC_NUMBUFFERS; iLoop++)
		{
			unsigned long ulBytesWritten = DecodeOggVorbis(&m_aVorbisFile, m_pDecodeBuffer, m_nBufferSize, m_nChannels);
			if (ulBytesWritten)
			{
				alBufferData(m_nBuffers[iLoop], m_nFormat, m_pDecodeBuffer, ulBytesWritten, m_nFrequency);
				alSourceQueueBuffers(m_nSourceId, 1, &m_nBuffers[iLoop]);
			}
		}

		return true;
	}
Ejemplo n.º 9
0
ALuint Audio::RegisterSource()
{
	ALuint source;
	alGenSources((ALuint)1, &source);
	return source;
}
Ejemplo n.º 10
0
SoundSource::SoundSource() {
  id.emplace();
  AL(alGenSources(1, &*id));
}
Ejemplo n.º 11
0
void GLApplication::initialize() {
	if (!windowManager
			|| !windowManager->initialize(800, 700, "Window GLFW", false)) {
		this->destroy();
		exit(-1);
	}

	glViewport(0, 0, WindowManager::screenWidth, WindowManager::screenHeight);
	glClearColor(0.2f, 0.2f, 0.2f, 0.0f);

	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);

	shader.initialize("Shaders/lightingSpecularMap.vs",
			"Shaders/lightingSpecularMap.fs");
	sphere.init();
	sphere.load();

	textureDifuse.load();
	textureSpecular.load();

	alutInit(0, NULL);

	alListenerfv(AL_POSITION, listenerPos);
	alListenerfv(AL_VELOCITY, listenerVel);
	alListenerfv(AL_ORIENTATION, listenerOri);

	alGetError(); // clear any error messages

	if (alGetError() != AL_NO_ERROR) {
		printf("- Error creating buffers !!\n");
		exit(1);
	} else {
		printf("init() - No errors yet.");
	}

	// Generate buffers, or else no sound will happen!
	alGenBuffers(NUM_BUFFERS, buffer);

	buffer[0] = alutCreateBufferFromFile("sounds/lawyer1.wav");
	//buffer[0] = alutCreateBufferHelloWorld();

	alGetError(); /* clear error */
	alGenSources(NUM_SOURCES, source);

	if (alGetError() != AL_NO_ERROR) {
		printf("- Error creating sources !!\n");
		exit(2);
	} else {
		printf("init - no errors after alGenSources\n");
	}

	alSourcef(source[0], AL_PITCH, 1.0f);
	alSourcef(source[0], AL_GAIN, 1.0f);
	alSourcefv(source[0], AL_POSITION, source0Pos);
	alSourcefv(source[0], AL_VELOCITY, source0Vel);
	alSourcei(source[0], AL_BUFFER, buffer[0]);
	alSourcei(source[0], AL_LOOPING, AL_TRUE);
	alSourcef(source[0], AL_MAX_DISTANCE, 1200);

	objModel.loadModel("objects/nanosuit/nanosuit.obj");

	/*alSourcef(source[1], AL_PITCH, 1.0f);
	 alSourcef(source[1], AL_GAIN, 1.0f);
	 alSourcefv(source[1], AL_POSITION, source1Pos);
	 alSourcefv(source[1], AL_VELOCITY, source1Vel);
	 alSourcei(source[1], AL_BUFFER, buffer[1]);
	 alSourcei(source[1], AL_LOOPING, AL_TRUE);

	 alSourcef(source[2], AL_PITCH, 1.0f);
	 alSourcef(source[2], AL_GAIN, 1.0f);
	 alSourcefv(source[2], AL_POSITION, source2Pos);
	 alSourcefv(source[2], AL_VELOCITY, source2Vel);
	 alSourcei(source[2], AL_BUFFER, buffer[2]);
	 alSourcei(source[2], AL_LOOPING, AL_TRUE);*/

}
Ejemplo n.º 12
0
    void ChannelStream::Open( int channels, int bits, int samplerate )
    {
        if (started)
            return;
        
        VERBOSE("ChannelStream Open");
        
        if (channels == 1)
        {
            format = AL_FORMAT_MONO16;
            if (bits == 8)
                format = AL_FORMAT_MONO8;
        }
        else if (channels == 2)
        {
            format = AL_FORMAT_STEREO16;
            if (bits == 8)
                format = AL_FORMAT_STEREO8;
        }
        
        Check();
        
        alGenBuffers(NUM_BUFFERS, buffers);
        
        Check("opengenbuf");
        
        alGenSources(1, &source);
        
        Check("opengensource");
        
        alSourcei(source, AL_BUFFER, AL_NONE);
        
        Check("buffer reset");

//        Debug::Log("AUDIO: Opening Audio Channel: " + StringOf(samplerate) + "hz w/ " + StringOf(bits) + "bits w/ " + StringOf(channels) + " channels (ALformat:" + StringOf(format) +") SOURCE ID: " + StringOf(source));
        
        Check("openbufferdata");
        
        alSource3f(source, AL_POSITION, 0.0, 0.0, 0.0);
        /*alSource3f(source, AL_VELOCITY, 0.0, 0.0, 0.0);
         alSource3f(source, AL_DIRECTION, 0.0, 0.0, 0.0);*/
        
        this->lastVol = 1.0;
        alSourcef(source, AL_GAIN, 1.0);
        alSourcef(source, AL_PITCH, 1.0);
        alSourcei(source, AL_LOOPING, AL_FALSE);
        
        Check("opensetsource");
        
        alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
        alSourcei(source, AL_ROLLOFF_FACTOR, 0);
        
        Check("opensetsource2");

        this->samplerate = samplerate;
        this->started = true;
        this->startBuffer = 0;
        this->startedPlaying = false;
        this->pausePos = 0;
        this->playOffset = 0;
        this->playStart = 0;
    }
Ejemplo 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)(const void *), const void *user_data, size_t streamBufferSize, unsigned int buffer_count)
{
	AUDIO_STREAM *stream;
	ALuint       *buffers = (ALuint *)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 nullptr;
	}

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

	// 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 nullptr;
	}

	stream->fileHandle = fileHandle;

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

	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 nullptr;
	}

	// 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;
}
Ejemplo n.º 14
0
//*
// =======================================================================================================================
// =======================================================================================================================
//
bool sound_Play2DSample(TRACK *psTrack, AUDIO_SAMPLE *psSample, bool bQueued)
{
	ALfloat zero[3] = { 0.0, 0.0, 0.0 };
	ALfloat volume;
	ALint error;

	if (sfx_volume == 0.0)
	{
		return false;
	}
	volume = ((float)psTrack->iVol / 100.0f);		// each object can have OWN volume!
	psSample->fVol = volume;						// save computed volume
	volume *= sfx_volume;							// and now take into account the Users sound Prefs.

	// We can't hear it, so don't bother creating it.
	if (volume == 0.0f)
	{
		return false;
	}

	// Clear error codes
	alGetError();

	alGenSources(1, &(psSample->iSample));

	error = sound_GetError();
	if (error != AL_NO_ERROR)
	{
		/* FIXME: We run out of OpenAL sources very quickly, so we
		 * should handle the case where we've ran out of them.
		 * Currently we don't do this, causing some unpleasant side
		 * effects, e.g. crashing...
		 */
	}

	alSourcef(psSample->iSample, AL_PITCH, 1.0f);
	alSourcef(psSample->iSample, AL_GAIN, volume);
	alSourcefv(psSample->iSample, AL_POSITION, zero);
	alSourcefv(psSample->iSample, AL_VELOCITY, zero);
	alSourcei(psSample->iSample, AL_BUFFER, psTrack->iBufferName);
	alSourcei(psSample->iSample, AL_SOURCE_RELATIVE, AL_TRUE);
	alSourcei(psSample->iSample, AL_LOOPING, (sound_SetupChannel(psSample)) ? AL_TRUE : AL_FALSE);

	// NOTE: this is only useful for debugging.
#ifdef DEBUG
	psSample->is3d = false;
	psSample->isLooping = sound_TrackLooped(psSample->iTrack) ? AL_TRUE : AL_FALSE;
	memcpy(psSample->filename, psTrack->fileName, strlen(psTrack->fileName));
	psSample->filename[strlen(psTrack->fileName)] = '\0';
#endif
	// Clear error codes
	alGetError();

	alSourcePlay(psSample->iSample);
	sound_GetError();

	if (bQueued)
	{
		current_queue_sample = psSample->iSample;
	}
	else if (current_queue_sample == psSample->iSample)
	{
		current_queue_sample = -1;
	}

	return true;
}
Ejemplo n.º 15
0
void boot_init(int* argc, char** argv) {

  int error;

  fail_if(glfwInit() == false);

  // OpenGL version 3
  glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
  glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 0);

  // No window resize
  glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, true);
  // 400% gameboy scale, 5 bit rgb with 1 bit alpha, 8 bit z buffer
  fail_if(glfwOpenWindow(160 * 4, 144 * 4, 5, 5, 5, 1, 8, 0, GLFW_WINDOW) == false);

  glfwSetWindowTitle("");

  glfwEnable(GLFW_AUTO_POLL_EVENTS); // Automatically poll input on swap
  glfwSwapInterval(1); // 0: vsync off, 1: vsync on 

  printf("Renderer: %s\n", glGetString(GL_RENDERER));
  printf("GL Version: %s\n", glGetString(GL_VERSION));
  printf("Using GLSL: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));

  error = glewInit();

  if (error != GLEW_OK) {
    fprintf(stderr, "GLEW error: %s\n", glewGetErrorString(error));
  }

  printf("GL Extension Wrangler: %s\n", glewGetString(GLEW_VERSION));

  // Load audio
  fail_if(alutInit(argc, argv) == false);

  glClearColor(206.0/255.0, 230.0/255.0, 165.0/255.0, 1.0f);
  glEnable(GL_SCISSOR_TEST); // For geom culling
  
  // transparency
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  // z-buffer
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  // Set up perspective
  glOrtho(0, 160, 144, 0, -1.0, 1.0);
  glDepthRange(-1.0f, 1.0f);
  glViewport(0, 0, 160 * 4, 144 * 4);

  // This is where Ill put the logo thing
  unsigned logo = bitmap_load("bmp/logo.bmp");
  unsigned logo_vbo;
  float t0, t1, dt;
  float logo_x = 16, logo_y = -80;
  float logo_v[] = {
    0,     0, 0, 1.0 - 0,
    0,   128, 0, 1.0 - 1,
    128, 128, 1, 1.0 - 1,
    128,   0, 1, 1.0 - 0,
  };

  glGenBuffers(1, &logo_vbo);
  glBindBuffer(GL_ARRAY_BUFFER, logo_vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(logo_v)*sizeof(float), logo_v, GL_STATIC_DRAW);
 
  Pipeline* logo_program = pipeline_new(
    shader_new(SHADER_VERTEX, "shader/logo.vert"),
    shader_new(SHADER_FRAGMENT, "shader/logo.frag"));

  pipeline_attribute(logo_program, "coord", 0);
  pipeline_attribute(logo_program, "st", 1);
  pipeline_uniform(logo_program, "pos", 0);
  pipeline_uniform(logo_program, "tex", 1);

  glUseProgram(logo_program->id);

  // Bind the logo to texture 0
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, logo);
  glUniform1i(logo_program->uniform[1], 0);

  // Bind logo vbo
  glBindBuffer(GL_ARRAY_BUFFER, logo_vbo);
  glEnableVertexAttribArray(logo_program->attribute[0]);
  glVertexAttribPointer(logo_program->attribute[0], 2, GL_FLOAT, false, 4*sizeof(float), (void*)0);
  glEnableVertexAttribArray(logo_program->attribute[1]);
  glVertexAttribPointer(logo_program->attribute[1], 2, GL_FLOAT, false, 4*sizeof(float), (void*)(2 * sizeof(float)));

  // load sound
  unsigned sound_source;
  alGenSources(1, &sound_source);
  Sound* ding = sound_load("sound/ding.ogg");

  alSourcei(sound_source, AL_BUFFER, ding->buffer);
  
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  glfwSwapBuffers();

  sleep(1);

  t0 = glfwGetTime();
  while (logo_y < 8) {
    t1 = glfwGetTime();
    dt = t1 - t0;
    t0 = t1;

    logo_y += 50 * dt;

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glUniform2f(logo_program->uniform[0], roundf(logo_x), roundf(logo_y));

    // Render logo
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glfwSwapBuffers();
  }

  alSourcePlay(sound_source);

  glDisableVertexAttribArray(logo_program->attribute[0]);
  glDisableVertexAttribArray(logo_program->attribute[1]);

  sleep(1);
}
Ejemplo n.º 16
0
ALboolean LoadALData()
{
	// Variables to load into.

	ALenum format;
	ALsizei size;
	ALvoid* data;
	ALsizei freq;
	ALboolean loop;

	// Load wav data into buffers.

	alGenBuffers(NUM_BUFFERS, Buffers);

	if(alGetError() != AL_NO_ERROR)
		return AL_FALSE;

	alutLoadWAVFile("sound/hit.wav", &format, &data, &size, &freq, &loop);
	alBufferData(Buffers[hit], format, data, size, freq);
	alutUnloadWAV(format, data, size, freq);

//	alutLoadWAVFile("wavdata/Gun1.wav", &format, &data, &size, &freq, &loop);
//	alBufferData(Buffers[GUN1], format, data, size, freq);
//	alutUnloadWAV(format, data, size, freq);

//	alutLoadWAVFile("wavdata/Gun2.wav", &format, &data, &size, &freq, &loop);
//	alBufferData(Buffers[GUN2], format, data, size, freq);
//	alutUnloadWAV(format, data, size, freq);
	
	//alutLoadWAVFile("sound/dung.wav", &format, &data, &size, &freq, &loop);
	//alBufferData(Buffers[dung], format, data, size, freq);
	//alutUnloadWAV(format, data, size, freq);

	// Bind buffers into audio sources.

	alGenSources(NUM_SOURCES, Sources);

	if(alGetError() != AL_NO_ERROR)
		return AL_FALSE;



	//alSourcei (Sources[dung], AL_BUFFER,   Buffers[dung]   );
	//alSourcef (Sources[dung], AL_PITCH,    1.0f              );
	//alSourcef (Sources[dung], AL_GAIN,     1.0f              );
	//alSourcefv(Sources[dung], AL_POSITION, SourcesPos[dung]);
	//alSourcefv(Sources[dung], AL_VELOCITY, SourcesVel[dung]);
	//alSourcei (Sources[dung], AL_LOOPING,  AL_TRUE           );


	alSourcei (Sources[hit], AL_BUFFER,   Buffers[hit]   );
	alSourcef (Sources[hit], AL_PITCH,    1.0f              );
	alSourcef (Sources[hit], AL_GAIN,     1.0f              );
	alSourcefv(Sources[hit], AL_POSITION, SourcesPos[hit]);
	alSourcefv(Sources[hit], AL_VELOCITY, SourcesVel[hit]);
	alSourcei (Sources[hit], AL_LOOPING,  AL_FALSE           );
/*
	alSourcei (Sources[GUN1], AL_BUFFER,   Buffers[GUN1]   );
	alSourcef (Sources[GUN1], AL_PITCH,    1.0f            );
	alSourcef (Sources[GUN1], AL_GAIN,     1.0f            );
	alSourcefv(Sources[GUN1], AL_POSITION, SourcesPos[GUN1]);
	alSourcefv(Sources[GUN1], AL_VELOCITY, SourcesVel[GUN1]);
	alSourcei (Sources[GUN1], AL_LOOPING,  AL_FALSE        );

	alSourcei (Sources[GUN2], AL_BUFFER,   Buffers[GUN2]   );
	alSourcef (Sources[GUN2], AL_PITCH,    1.0f            );
	alSourcef (Sources[GUN2], AL_GAIN,     1.0f            );
	alSourcefv(Sources[GUN2], AL_POSITION, SourcesPos[GUN2]);
	alSourcefv(Sources[GUN2], AL_VELOCITY, SourcesVel[GUN2]);
	alSourcei (Sources[GUN2], AL_LOOPING,  AL_FALSE        );
*/
	// Do another error check and return.

	if(alGetError() != AL_NO_ERROR)
		return AL_FALSE;

	return AL_TRUE;
}
Ejemplo n.º 17
0
//------------------------------------------------------------
bool ofOpenALSoundPlayer::loadSound(string fileName, bool is_stream){

	fileName = ofToDataPath(fileName);

	bMultiPlay = false;
	isStreaming = is_stream;
	int err = AL_NO_ERROR;

	// [1] init sound systems, if necessary
	initialize();

	// [2] try to unload any previously loaded sounds
	// & prevent user-created memory leaks
	// if they call "loadSound" repeatedly, for example

	unloadSound();
	ALenum format=AL_FORMAT_MONO16;
	bLoadedOk = false;

	if(!isStreaming){
		readFile(fileName, buffer);
	}else{
		stream(fileName, buffer);
	}

	int numFrames = buffer.size()/channels;

	if(isStreaming){
		buffers.resize(channels*2);
	}else{
		buffers.resize(channels);
	}
	alGenBuffers(buffers.size(), &buffers[0]);
	if(channels==1){
		sources.resize(1);
		alGenSources(1, &sources[0]);
		err = alGetError();
		if (err != AL_NO_ERROR){
			ofLogError("ofOpenALSoundPlayer") << "loadSound(): couldn't generate source for \"" << fileName << "\": "
			<< (int) err << " " << getALErrorString(err);
			return false;
		}

		for(int i=0; i<(int)buffers.size(); i++){
			alBufferData(buffers[i],format,&buffer[0],buffer.size()*2,samplerate);
			err = alGetError();
			if (err != AL_NO_ERROR){
				ofLogError("ofOpenALSoundPlayer:") << "loadSound(): couldn't create buffer for \"" << fileName << "\": "
				<< (int) err << " " << getALErrorString(err);
				return false;
			}
			if(isStreaming){
				stream(fileName,buffer);
			}
		}
		if(isStreaming){
			alSourceQueueBuffers(sources[0],buffers.size(),&buffers[0]);
		}else{
			alSourcei (sources[0], AL_BUFFER,   buffers[0]);
		}

		alSourcef (sources[0], AL_PITCH,    1.0f);
		alSourcef (sources[0], AL_GAIN,     1.0f);
	    alSourcef (sources[0], AL_ROLLOFF_FACTOR,  0.0);
	    alSourcei (sources[0], AL_SOURCE_RELATIVE, AL_TRUE);
	}else{
		vector<vector<short> > multibuffer;
		multibuffer.resize(channels);
		sources.resize(channels);
		alGenSources(channels, &sources[0]);
		if(isStreaming){
			for(int s=0; s<2;s++){
				for(int i=0;i<channels;i++){
					multibuffer[i].resize(buffer.size()/channels);
					for(int j=0;j<numFrames;j++){
						multibuffer[i][j] = buffer[j*channels+i];
					}
					alBufferData(buffers[s*2+i],format,&multibuffer[i][0],buffer.size()/channels*2,samplerate);
					err = alGetError();
					if ( err != AL_NO_ERROR){
						ofLogError("ofOpenALSoundPlayer") << "loadSound(): couldn't create stereo buffers for \"" << fileName << "\": " << (int) err << " " << getALErrorString(err);
						return false;
					}
					alSourceQueueBuffers(sources[i],1,&buffers[s*2+i]);
					stream(fileName,buffer);
				}
			}
		}else{
			for(int i=0;i<channels;i++){
				multibuffer[i].resize(buffer.size()/channels);
				for(int j=0;j<numFrames;j++){
					multibuffer[i][j] = buffer[j*channels+i];
				}
				alBufferData(buffers[i],format,&multibuffer[i][0],buffer.size()/channels*2,samplerate);
				err = alGetError();
				if (err != AL_NO_ERROR){
					ofLogError("ofOpenALSoundPlayer") << "loadSound(): couldn't create stereo buffers for \"" << fileName << "\": "
					<< (int) err << " " << getALErrorString(err);
					return false;
				}
				alSourcei (sources[i], AL_BUFFER,   buffers[i]   );
			}
		}

		
		for(int i=0;i<channels;i++){
			err = alGetError();
			if (err != AL_NO_ERROR){
				ofLogError("ofOpenALSoundPlayer") << "loadSound(): couldn't create stereo sources for \"" << fileName << "\": "
				<< (int) err << " " << getALErrorString(err);
				return false;
			}

			// only stereo panning
			if(i==0){
				float pos[3] = {-1,0,0};
				alSourcefv(sources[i],AL_POSITION,pos);
			}else{
				float pos[3] = {1,0,0};
				alSourcefv(sources[i],AL_POSITION,pos);
			}
			alSourcef (sources[i], AL_ROLLOFF_FACTOR,  0.0);
			alSourcei (sources[i], AL_SOURCE_RELATIVE, AL_TRUE);
		}
	}
	
	bLoadedOk = true;
	return bLoadedOk;

}
Ejemplo n.º 18
0
void audio_output::init(int i)
{
    if (!_initialized)
    {
        if (i < 0)
        {
            if (!(_device = alcOpenDevice(NULL)))
            {
                throw exc(_("No OpenAL device available."));
            }
        }
        else if (i >= static_cast<int>(_devices.size()))
        {
            throw exc(str::asprintf(_("OpenAL device '%s' is not available."), _("unknown")));
        }
        else
        {
            if (!(_device = alcOpenDevice(_devices[i].c_str())))
            {
                throw exc(str::asprintf(_("OpenAL device '%s' is not available."),
                            _devices[i].c_str()));
            }
        }
        if (!(_context = alcCreateContext(_device, NULL)))
        {
            alcCloseDevice(_device);
            throw exc(_("No OpenAL context available."));
        }
        alcMakeContextCurrent(_context);
        set_openal_versions();
        _buffers.resize(_num_buffers);
        alGenBuffers(_num_buffers, &(_buffers[0]));
        if (alGetError() != AL_NO_ERROR)
        {
            alcMakeContextCurrent(NULL);
            alcDestroyContext(_context);
            alcCloseDevice(_device);
            throw exc(_("Cannot create OpenAL buffers."));
        }
        alGenSources(1, &_source);
        if (alGetError() != AL_NO_ERROR)
        {
            alDeleteBuffers(_num_buffers, &(_buffers[0]));
            alcMakeContextCurrent(NULL);
            alcDestroyContext(_context);
            alcCloseDevice(_device);
            throw exc(_("Cannot create OpenAL source."));
        }
        /* Comment from alffmpeg.c:
         * "Set parameters so mono sources won't distance attenuate" */
        alSourcei(_source, AL_SOURCE_RELATIVE, AL_TRUE);
        alSourcei(_source, AL_ROLLOFF_FACTOR, 0);
        if (alGetError() != AL_NO_ERROR)
        {
            alDeleteSources(1, &_source);
            alDeleteBuffers(_num_buffers, &(_buffers[0]));
            alcMakeContextCurrent(NULL);
            alcDestroyContext(_context);
            alcCloseDevice(_device);
            throw exc(_("Cannot set OpenAL source parameters."));
        }
        _state = 0;
        _initialized = true;
    }
}
Ejemplo n.º 19
0
OpenalSoundInterface::OpenalSoundInterface(float sampling_rate, int n_channels): SoundInterface (sampling_rate, n_channels)
{
	car_src = NULL;

	ALfloat far_away[] = { 0.0f, 0.0f,  1000.0f };
	ALfloat zeroes[] = { 0.0f, 0.0f,  0.0f };
	ALfloat front[]  = { 0.0f, 0.0f,  1.0f, 0.0f, 1.0f, 0.0f };
	dev = alcOpenDevice( NULL );
	if( dev == NULL ) {
		throw ("Could not open device");
	}
	
	// Last zero is termination of the array, I think the current official beat SDK ignores that.
	// ALCint attr[] = { ALC_MONO_SOURCES, 1024, ALC_STEREO_SOURCES, 0, 0};
	cc = alcCreateContext( dev, NULL);
	if(cc == NULL) {
		alcCloseDevice( dev );
		throw ("Could not create context.");
	}

	alcMakeContextCurrent( cc );
	alcGetError(dev);
	alGetError();

	// Figure out the number of possible sources, watch out for an API update, perhaps
	// one can get that easier later with al(c)GetInteger (I'm sure that there is no way to
	// query this now) or even request a number with the context.
	const int MAX_SOURCES = 1024;
	int sources;
	ALuint sourcelist[MAX_SOURCES];
	for (sources = 0; sources < MAX_SOURCES; sources++) {
		alGenSources(1, &sourcelist[sources]);
		if (alGetError() != AL_NO_ERROR) {
			break;
		}
	}

	int clear;
	for (clear = 0; clear < sources; clear++) {
		if (alIsSource(sourcelist[clear])) {
			alDeleteSources(1, &sourcelist[clear]);
			if (alGetError() != AL_NO_ERROR) {
				printf("Error in probing OpenAL sources.\n");
			}
		} else {
			printf("Error in probing OpenAL sources.\n");
		}
	}

	OSI_MAX_SOURCES = sources;
	OSI_MAX_STATIC_SOURCES = MAX(0, OSI_MAX_SOURCES - OSI_MIN_DYNAMIC_SOURCES);

	// Figure out the number of buffers.
	int buffers;
	ALuint bufferlist[MAX_SOURCES];
	for (buffers = 0; buffers < MAX_SOURCES; buffers++) {
		alGenBuffers(1, &bufferlist[buffers]);
		if (alGetError() != AL_NO_ERROR) {
			break;
		}
	}

	for (clear = 0; clear < buffers; clear++) {
		if (alIsBuffer(bufferlist[clear])) {
			alDeleteBuffers(1, &bufferlist[clear]);
			if (alGetError() != AL_NO_ERROR) {
				printf("Error in probing OpenAL buffers.\n");
			}
		} else {
			printf("Error in probing OpenAL buffers.\n");
		}
	}

	OSI_MAX_BUFFERS = buffers;

	printf("OpenAL backend info:\n  Vendor: %s\n  Renderer: %s\n  Version: %s\n", alGetString(AL_VENDOR), alGetString(AL_RENDERER), alGetString(AL_VERSION));
	printf("  Available sources: %d%s\n", OSI_MAX_SOURCES, (sources >= MAX_SOURCES) ? " or more" : "");
	printf("  Available buffers: %d%s\n", OSI_MAX_BUFFERS, (buffers >= MAX_SOURCES) ? " or more" : "");
	
	alDistanceModel ( AL_INVERSE_DISTANCE );
	int error = alGetError();
	if (error != AL_NO_ERROR) {
		printf("OpenAL Error: %d alDistanceModel\n", error);
	}

	alDopplerFactor (1.0f);
	//alSpeedOfSound (SPEED_OF_SOUND); // not defined in linux yet.
	alDopplerVelocity (SPEED_OF_SOUND);
	error = alGetError();
	if (error != AL_NO_ERROR) {
		printf("OpenAL Error: %d alDopplerX\n", error);
	}


	alListenerfv(AL_POSITION, far_away );
	alListenerfv(AL_VELOCITY, zeroes );
	alListenerfv(AL_ORIENTATION, front );
	error = alGetError();
	if (error != AL_NO_ERROR) {
		printf("OpenAL Error: %d alListenerfv\n", error);
	}
	
	engpri = NULL;
	global_gain = 1.0f;
	
	// initialise mappings
	grass.schar = &CarSoundData::grass;
	grass_skid.schar = &CarSoundData::grass_skid;
	road.schar = &CarSoundData::road;
	metal_skid.schar = &CarSoundData::drag_collision;
	backfire_loop.schar = &CarSoundData::engine_backfire;
	turbo.schar = &CarSoundData::turbo;
	axle.schar = &CarSoundData::axle;

	n_static_sources_in_use = 0;
}
Ejemplo n.º 20
0
Source::Source()
{
  alGenSources(1, &source);ALDEBUG_THROW;
}
Ejemplo n.º 21
0
void cargarSonido (void)
{

	ALsizei tamanyo;
	Uint8  *datos;
	ALfloat velocity[3]= { 0.0, 0.0, 0.0 };
	ALfloat pitch = 1.0, gain = 1.0;
	SDL_AudioSpec wav_spec;

	
	// reservar memoria para los sonidos
	son = (sonidos *) malloc (sizeof (sonidos));

	// generar el buffer del rayo
	alGenBuffers (1, &son->bufferRayo);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("blaster02.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferRayo, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente del rayo
	alGenSources (1, &son->fuenteRayo);

    // inicializar los valores de la fuente
	alSourcef (son->fuenteRayo, AL_PITCH, pitch);
    alSourcef (son->fuenteRayo, AL_GAIN, gain);
    alSourcefv (son->fuenteRayo, AL_VELOCITY, velocity);
    alSourcei (son->fuenteRayo, AL_BUFFER, son->bufferRayo);
    alSourcei (son->fuenteRayo, AL_LOOPING, AL_FALSE);


	// generar el buffer de ganas
	alGenBuffers (1, &son->bufferGanas);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("chewie04.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferGanas, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente de ganas
	alGenSources (1, &son->fuenteGanas);

    // inicializar los valores de la fuente
	alSourcef (son->fuenteGanas, AL_PITCH, pitch);
    alSourcef (son->fuenteGanas, AL_GAIN, gain);
    alSourcefv (son->fuenteGanas, AL_VELOCITY, velocity);
    alSourcei (son->fuenteGanas, AL_BUFFER, son->bufferGanas);
    alSourcei (son->fuenteGanas, AL_LOOPING, AL_FALSE);


	// generar el buffer de pierdes
	alGenBuffers (1, &son->bufferPierdes);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("chewie03.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferPierdes, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente de pierdes
	alGenSources (1, &son->fuentePierdes);

    // inicializar los valores de la fuente
	alSourcef (son->fuentePierdes, AL_PITCH, pitch);
    alSourcef (son->fuentePierdes, AL_GAIN, gain);
    alSourcefv (son->fuentePierdes, AL_VELOCITY, velocity);
    alSourcei (son->fuentePierdes, AL_BUFFER, son->bufferPierdes);
    alSourcei (son->fuentePierdes, AL_LOOPING, AL_FALSE);


	// generar el buffer de acierto
	alGenBuffers (1, &son->bufferAcierto);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("expl02.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferAcierto, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente del acierto
	alGenSources (1, &son->fuenteAcierto);

    // inicializar los valores de la fuente
	alSourcef (son->fuenteAcierto, AL_PITCH, pitch);
    alSourcef (son->fuenteAcierto, AL_GAIN, gain);
    alSourcefv (son->fuenteAcierto, AL_VELOCITY, velocity);
    alSourcei (son->fuenteAcierto, AL_BUFFER, son->bufferAcierto);
    alSourcei (son->fuenteAcierto, AL_LOOPING, AL_FALSE);


	// generar el buffer de indy
	alGenBuffers (1, &son->bufferIndy);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("indy.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferIndy, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente de indy
	alGenSources (1, &son->fuenteIndy);

    // inicializar los valores de la fuente
	alSourcef (son->fuenteIndy, AL_PITCH, pitch);
    alSourcef (son->fuenteIndy, AL_GAIN, gain);
    alSourcefv (son->fuenteIndy, AL_VELOCITY, velocity);
    alSourcei (son->fuenteIndy, AL_BUFFER, son->bufferIndy);
    alSourcei (son->fuenteIndy, AL_LOOPING, AL_FALSE);

	
	// generar el buffer de rebote 1
	alGenBuffers (1, &son->bufferRebote1);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("bounce1.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferRebote1, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente de rebote 1
	alGenSources (1, &son->fuenteRebote1);

    // inicializar los valores de la fuente
	alSourcef (son->fuenteRebote1, AL_PITCH, pitch);
    alSourcef (son->fuenteRebote1, AL_GAIN, gain);
    alSourcefv (son->fuenteRebote1, AL_VELOCITY, velocity);
    alSourcei (son->fuenteRebote1, AL_BUFFER, son->bufferRebote1);
    alSourcei (son->fuenteRebote1, AL_LOOPING, AL_FALSE);


	// generar el buffer de rebote 2
	alGenBuffers (1, &son->bufferRebote2);

	// cargar el sonido de un fichero
	SDL_LoadWAV ("bounce2.wav", &wav_spec, &datos, &tamanyo); 
	
	alBufferData (son->bufferRebote2, AL_FORMAT_STEREO8, datos, tamanyo, wav_spec.freq);
	
	SDL_FreeWAV (datos);

	// generar la fuente de rebote 2
	alGenSources (1, &son->fuenteRebote2);

    // inicializar los valores de la fuente
	alSourcef (son->fuenteRebote2, AL_PITCH, pitch);
    alSourcef (son->fuenteRebote2, AL_GAIN, gain);
    alSourcefv (son->fuenteRebote2, AL_VELOCITY, velocity);
    alSourcei (son->fuenteRebote2, AL_BUFFER, son->bufferRebote2);
    alSourcei (son->fuenteRebote2, AL_LOOPING, AL_FALSE);


	
	// inicializar los valores del oyente
	alListenerfv (AL_VELOCITY, velocity);
	
}
Ejemplo n.º 22
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 );
}
Ejemplo n.º 23
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);
}
Ejemplo n.º 24
0
// 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;
}
Ejemplo n.º 25
0
OASound async_init_wav(const char* _file)
{
    
    OASound sound;
    memset(&sound,0,sizeof(OASound));
    
    ALvoid* l_DataBuffer = NULL;
    unsigned int l_FileSize = 0;
   
    // OpenAL: first 
    if(x_load_wav(_file, (unsigned char**)&l_DataBuffer , l_FileSize,sound))
        //    if((l_DataBuffer != NULL) && (l_FileSize > 0))
    {
        if(l_DataBuffer == NULL)
        {
            printf("*** DataBuffer NULL!!! *** \n");
        }
        // grab a buffer ID from openAL
        alGenBuffers(1, (ALuint*)&sound.m_BufferId);
        
        ALenum l_error = alGetError();
        
        if(l_error != AL_NO_ERROR)
        {
            printf("**** OpenAL ERROR buffer%i\n", l_error);
            return sound;
        }
        else
        {
            printf("**** OpenAL OK buffer %i\n", sound.m_BufferId);
        }
        
        ALuint f;
        if (sound.depth==16)
        {
            if (sound.nbchannel == 1)
                f = AL_FORMAT_MONO16;
            else
                f = AL_FORMAT_STEREO16;
        }
        else
        {
            if (sound.nbchannel == 1)
                f = AL_FORMAT_MONO8;
            else
                f = AL_FORMAT_STEREO8;
            
        }
            
        
        alBufferData(sound.m_BufferId, f, l_DataBuffer, l_FileSize, sound.frequency);
        
        l_error = alGetError();
         if(l_error != AL_NO_ERROR)
        {
            printf("**** OpenAL ERROR format\n");
            return sound;
        }
        
        // create Source
        alGenSources(1, (ALuint*)&sound.m_SourceId);
        l_error = alGetError();
          if(l_error != AL_NO_ERROR)
        {
            printf("**** OpenAL ERROR source\n");
            return sound;
        }
        
        alSourcei(sound.m_SourceId, AL_BUFFER, sound.m_BufferId);
        
        l_error = alGetError();
         if(l_error != AL_NO_ERROR)
        {
            printf("**** OpenAL ERROR source buffer\n");
            return sound;
        }
        
        // if loop:
        //alSourcei(m_SourceId, AL_LOOPING, AL_TRUE);
        
        alSourcef(sound.m_SourceId, AL_PITCH, 1.0f);
        //l_error = alGetError();
        
        //ASSERTC(l_error == AL_NO_ERROR,"**** OpenAL ERROR buffer\n");
        //if(l_error != AL_NO_ERROR)
        //{
        //    CONSOLEMSG("**** OpenAL ERROR properties\n");
        //    return FAILURE;
        //}
        
        alSourcef(sound.m_SourceId, AL_GAIN, 1.0f);     
        
        l_error = alGetError();
        
        if(l_error != AL_NO_ERROR)
        {
            printf("**** OpenAL ERROR properties\n");
            return sound;
        }
           }
    else
    {
        return sound;
    }
    
    if (l_DataBuffer)
    {
        free(l_DataBuffer);
        l_DataBuffer = NULL;
    }
    
    //printf("**** OpenAL Resource load SUCCESS\n");
    sound.successfullyLoaded = 1;
	return sound;
}
Ejemplo n.º 26
0
/**
 * @brief Initializes the sound subsystem.
 *
 *    @return 0 on success.
 */
int sound_al_init (void)
{
   int ret;
   ALuint s;
   ALint freq;
   ALint attribs[4] = { 0, 0, 0, 0 };

   /* Default values. */
   ret = 0;

   /* we'll need a mutex */
   sound_lock = SDL_CreateMutex();
   soundLock();

   /* opening the default device */
   al_device = alcOpenDevice(NULL);
   if (al_device == NULL) {
      WARN(_("Unable to open default sound device"));
      ret = -1;
      goto snderr_dev;
   }

   /* Query EFX extension. */
   if (conf.al_efx) {
      al_info.efx = alcIsExtensionPresent( al_device, "ALC_EXT_EFX" );
      if (al_info.efx == AL_TRUE) {
         attribs[0] = ALC_MAX_AUXILIARY_SENDS;
         attribs[1] = 4;
      }
   }
   else
      al_info.efx = AL_FALSE;

   /* Create the OpenAL context */
   al_context = alcCreateContext( al_device, attribs );
   if (al_context == NULL) {
      WARN(_("Unable to create OpenAL context"));
      ret = -2;
      goto snderr_ctx;
   }

   /* Clear the errors */
   alGetError();

   /* Set active context */
   if (alcMakeContextCurrent( al_context )==AL_FALSE) {
      WARN(_("Failure to set default context"));
      ret = -4;
      goto snderr_act;
   }

   /* Get context information. */
   alcGetIntegerv( al_device, ALC_FREQUENCY, sizeof(freq), &freq );

   /* Try to enable EFX. */
   if (al_info.efx == AL_TRUE)
      al_enableEFX();
   else {
      al_info.efx_reverb = AL_FALSE;
      al_info.efx_echo   = AL_FALSE;
   }

   /* Allocate source for music. */
   alGenSources( 1, &music_source );

   /* Check for errors. */
   al_checkErr();

   /* Start allocating the sources - music has already taken his */
   source_nstack  = 0;
   source_mstack  = 0;
   while (source_nstack < conf.snd_voices) {
      if (source_mstack < source_nstack+1) { /* allocate more memory */
         if (source_mstack == 0)
            source_mstack = conf.snd_voices;
         else
            source_mstack *= 2;
         source_stack = realloc( source_stack, sizeof(ALuint) * source_mstack );
      }
      alGenSources( 1, &s );
      source_stack[source_nstack] = s;

      /* How OpenAL distance model works:
       *
       * Clamped:
       *  gain = distance_function( CLAMP( AL_REFERENCE_DISTANCE, AL_MAX_DISTANCE, distance ) );
       *
       * Distance functions:
       *                                       AL_REFERENCE_DISTANCE
       *  * Inverse = ------------------------------------------------------------------------------
       *              AL_REFERENCE_DISTANCE + AL_ROLLOFF_FACTOR ( distance - AL_REFERENCE_DISTANCE )
       *
       *             1 - AL_ROLLOFF_FACTOR ( distance - AL_REFERENCE_DISTANCE )
       *  * Linear = ----------------------------------------------------------
       *                      AL_MAX_DISTANCE - AL_REFERENCE_DISTANCE
       *
       *                  /       distance        \ -AL_ROLLOFF_FACTOR
       *  * Exponential = | --------------------- |
       *                  \ AL_REFERENCE_DISTANCE /
       *
       *
       * Some values:
       *
       *  model    falloff  reference   100     1000    5000   10000
       *  linear     1        500      1.000   0.947   0.526   0.000
       *  inverse    1        500      1.000   0.500   0.100   0.050
       *  exponent   1        500      1.000   0.500   0.100   0.050
       *  inverse   0.5       500      1.000   0.667   0.182   0.095
       *  exponent  0.5       500      1.000   0.707   0.316   0.223
       *  inverse    2        500      1.000   0.333   0.052   0.026
       *  exponent   2        500      1.000   0.250   0.010   0.003
       */
      alSourcef( s, AL_REFERENCE_DISTANCE, 500. ); /* Close distance to clamp at (doesn't get louder). */
      alSourcef( s, AL_MAX_DISTANCE,       25000. ); /* Max distance to clamp at (doesn't get quieter). */
      alSourcef( s, AL_ROLLOFF_FACTOR,     1. ); /* Determines how it drops off. */

      /* Set the filter. */
      if (al_info.efx == AL_TRUE)
         alSource3i( s, AL_AUXILIARY_SEND_FILTER, efx_directSlot, 0, AL_FILTER_NULL );

      /* Check for error. */
      if (alGetError() == AL_NO_ERROR)
         source_nstack++;
      else
         break;
   }
   /* Reduce ram usage. */
   source_mstack = source_nstack;
   source_stack  = realloc( source_stack, sizeof(ALuint) * source_mstack );
   /* Copy allocated sources to total stack. */
   source_ntotal = source_mstack;
   source_total  = malloc( sizeof(ALuint) * source_mstack );
   memcpy( source_total, source_stack, sizeof(ALuint) * source_mstack );
   /* Copy allocated sources to all stack. */
   source_nall   = source_mstack;
   source_all    = malloc( sizeof(ALuint) * source_mstack );
   memcpy( source_all, source_stack, sizeof(ALuint) * source_mstack );

   /* Set up how sound works. */
   alDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); /* Clamping is fundamental so it doesn't sound like crap. */
   alDopplerFactor( 1. );
   sound_al_env( SOUND_ENV_NORMAL, 0. );

   /* Check for errors. */
   al_checkErr();

   /* we can unlock now */
   soundUnlock();

   /* debug magic */
   DEBUG(_("OpenAL started: %d Hz"), freq);
   DEBUG(_("Renderer: %s"), alGetString(AL_RENDERER));
   if (al_info.efx == AL_FALSE)
      DEBUG(_("Version: %s without EFX"), alGetString(AL_VERSION));
   else
      DEBUG(_("Version: %s with EFX %d.%d"), alGetString(AL_VERSION),
            al_info.efx_major, al_info.efx_minor);
   DEBUG("");

   return ret;

   /*
    * error handling
    */
snderr_act:
   alcDestroyContext( al_context );
snderr_ctx:
   al_context = NULL;
   alcCloseDevice( al_device );
snderr_dev:
   al_device = NULL;
   soundUnlock();
   SDL_DestroyMutex( sound_lock );
   sound_lock = NULL;
   return ret;
}
Ejemplo n.º 27
0
void OpenALStream::SoundLoop()
{
  Common::SetCurrentThreadName("Audio thread - openal");

  bool surround_capable = SConfig::GetInstance().bDPL2Decoder;
  bool float32_capable = false;
  bool fixed32_capable = false;

#if defined(__APPLE__)
  surround_capable = false;
#endif

  u32 ulFrequency = m_mixer->GetSampleRate();
  numBuffers = SConfig::GetInstance().iLatency + 2;  // OpenAL requires a minimum of two buffers

  memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
  uiSource = 0;

  if (alIsExtensionPresent("AL_EXT_float32"))
    float32_capable = true;

  // As there is no extension to check for 32-bit fixed point support
  // and we know that only a X-Fi with hardware OpenAL supports it,
  // we just check if one is being used.
  if (strstr(alGetString(AL_RENDERER), "X-Fi"))
    fixed32_capable = true;

  // Clear error state before querying or else we get false positives.
  ALenum err = alGetError();

  // Generate some AL Buffers for streaming
  alGenBuffers(numBuffers, (ALuint*)uiBuffers);
  err = CheckALError("generating buffers");

  // Generate a Source to playback the Buffers
  alGenSources(1, &uiSource);
  err = CheckALError("generating sources");

  // Set the default sound volume as saved in the config file.
  alSourcef(uiSource, AL_GAIN, fVolume);

  // TODO: Error handling
  // ALenum err = alGetError();

  unsigned int nextBuffer = 0;
  unsigned int numBuffersQueued = 0;
  ALint iState = 0;

  soundTouch.setChannels(2);
  soundTouch.setSampleRate(ulFrequency);
  soundTouch.setTempo(1.0);
  soundTouch.setSetting(SETTING_USE_QUICKSEEK, 0);
  soundTouch.setSetting(SETTING_USE_AA_FILTER, 0);
  soundTouch.setSetting(SETTING_SEQUENCE_MS, 1);
  soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
  soundTouch.setSetting(SETTING_OVERLAP_MS, 12);

  while (m_run_thread.IsSet())
  {
    // Block until we have a free buffer
    int numBuffersProcessed;
    alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &numBuffersProcessed);
    if (numBuffers == numBuffersQueued && !numBuffersProcessed)
    {
      soundSyncEvent.Wait();
      continue;
    }

    // Remove the Buffer from the Queue.
    if (numBuffersProcessed)
    {
      ALuint unqueuedBufferIds[OAL_MAX_BUFFERS];
      alSourceUnqueueBuffers(uiSource, numBuffersProcessed, unqueuedBufferIds);
      err = CheckALError("unqueuing buffers");

      numBuffersQueued -= numBuffersProcessed;
    }

    // num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
    const u32 stereo_16_bit_size = 4;
    const u32 dma_length = 32;
    const u64 ais_samples_per_second = 48000 * stereo_16_bit_size;
    u64 audio_dma_period = SystemTimers::GetTicksPerSecond() /
                           (AudioInterface::GetAIDSampleRate() * stereo_16_bit_size / dma_length);
    u64 num_samples_to_render =
        (audio_dma_period * ais_samples_per_second) / SystemTimers::GetTicksPerSecond();

    unsigned int numSamples = (unsigned int)num_samples_to_render;
    unsigned int minSamples =
        surround_capable ? 240 : 0;  // DPL2 accepts 240 samples minimum (FWRDURATION)

    numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples;
    numSamples = m_mixer->Mix(realtimeBuffer, numSamples, false);

    // Convert the samples from short to float
    float dest[OAL_MAX_SAMPLES * STEREO_CHANNELS];
    for (u32 i = 0; i < numSamples * STEREO_CHANNELS; ++i)
      dest[i] = (float)realtimeBuffer[i] / (1 << 15);

    soundTouch.putSamples(dest, numSamples);

    double rate = (double)m_mixer->GetCurrentSpeed();
    if (rate <= 0)
    {
      Core::RequestRefreshInfo();
      rate = (double)m_mixer->GetCurrentSpeed();
    }

    // Place a lower limit of 10% speed.  When a game boots up, there will be
    // many silence samples.  These do not need to be timestretched.
    if (rate > 0.10)
    {
      soundTouch.setTempo(rate);
      if (rate > 10)
      {
        soundTouch.clear();
      }
    }

    unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * numBuffers);

    if (nSamples <= minSamples)
      continue;

    if (surround_capable)
    {
      float dpl2[OAL_MAX_SAMPLES * OAL_MAX_BUFFERS * SURROUND_CHANNELS];
      DPL2Decode(sampleBuffer, nSamples, dpl2);

      // zero-out the subwoofer channel - DPL2Decode generates a pretty
      // good 5.0 but not a good 5.1 output.  Sadly there is not a 5.0
      // AL_FORMAT_50CHN32 to make this super-explicit.
      // DPL2Decode output: LEFTFRONT, RIGHTFRONT, CENTREFRONT, (sub), LEFTREAR, RIGHTREAR
      for (u32 i = 0; i < nSamples; ++i)
      {
        dpl2[i * SURROUND_CHANNELS + 3 /*sub/lfe*/] = 0.0f;
      }

      if (float32_capable)
      {
        alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, dpl2,
                     nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
      }
      else if (fixed32_capable)
      {
        int surround_int32[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];

        for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i)
        {
          // For some reason the ffdshow's DPL2 decoder outputs samples bigger than 1.
          // Most are close to 2.5 and some go up to 8. Hard clamping here, we need to
          // fix the decoder or implement a limiter.
          dpl2[i] = dpl2[i] * (INT64_C(1) << 31);
          if (dpl2[i] > INT_MAX)
            surround_int32[i] = INT_MAX;
          else if (dpl2[i] < INT_MIN)
            surround_int32[i] = INT_MIN;
          else
            surround_int32[i] = (int)dpl2[i];
        }

        alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, surround_int32,
                     nSamples * FRAME_SURROUND_INT32, ulFrequency);
      }
      else
      {
        short surround_short[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];

        for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i)
        {
          dpl2[i] = dpl2[i] * (1 << 15);
          if (dpl2[i] > SHRT_MAX)
            surround_short[i] = SHRT_MAX;
          else if (dpl2[i] < SHRT_MIN)
            surround_short[i] = SHRT_MIN;
          else
            surround_short[i] = (int)dpl2[i];
        }

        alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN16, surround_short,
                     nSamples * FRAME_SURROUND_SHORT, ulFrequency);
      }

      err = CheckALError("buffering data");
      if (err == AL_INVALID_ENUM)
      {
        // 5.1 is not supported by the host, fallback to stereo
        WARN_LOG(AUDIO,
                 "Unable to set 5.1 surround mode.  Updating OpenAL Soft might fix this issue.");
        surround_capable = false;
      }
    }
    else
    {
      if (float32_capable)
      {
        alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO_FLOAT32, sampleBuffer,
                     nSamples * FRAME_STEREO_FLOAT, ulFrequency);

        err = CheckALError("buffering float32 data");
        if (err == AL_INVALID_ENUM)
        {
          float32_capable = false;
        }
      }
      else if (fixed32_capable)
      {
        // Clamping is not necessary here, samples are always between (-1,1)
        int stereo_int32[OAL_MAX_SAMPLES * STEREO_CHANNELS * OAL_MAX_BUFFERS];
        for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
          stereo_int32[i] = (int)((float)sampleBuffer[i] * (INT64_C(1) << 31));

        alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO32, stereo_int32,
                     nSamples * FRAME_STEREO_INT32, ulFrequency);
      }
      else
      {
        // Convert the samples from float to short
        short stereo[OAL_MAX_SAMPLES * STEREO_CHANNELS * OAL_MAX_BUFFERS];
        for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
          stereo[i] = (short)((float)sampleBuffer[i] * (1 << 15));

        alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO16, stereo,
                     nSamples * FRAME_STEREO_SHORT, ulFrequency);
      }
    }

    alSourceQueueBuffers(uiSource, 1, &uiBuffers[nextBuffer]);
    err = CheckALError("queuing buffers");

    numBuffersQueued++;
    nextBuffer = (nextBuffer + 1) % numBuffers;

    alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
    if (iState != AL_PLAYING)
    {
      // Buffer underrun occurred, resume playback
      alSourcePlay(uiSource);
      err = CheckALError("occurred resuming playback");
    }
  }
}
Ejemplo n.º 28
0
bool AudioEngine::SingletonInitialize()
{
    if(!AUDIO_ENABLE)
        return true;

    const ALCchar *best_device = 0; // Will store the name of the 'best' device for audio playback
    ALCint highest_version = 0; // The highest version number found
    CheckALError(); // Clears errors
    CheckALCError(); // Clears errors

    // Find the highest-version device available, if the extension for device enumeration is present
    if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) {
        const ALCchar *device_list = 0;
        device_list = alcGetString(0, ALC_DEVICE_SPECIFIER); // Get list of all devices (terminated with two '0')
        if(CheckALCError() == true) {
            IF_PRINT_WARNING(AUDIO_DEBUG) << "failed to retrieve the list of available audio devices: " << CreateALCErrorString() << std::endl;
        }


        while(*device_list != 0) {  // Check all the detected devices
            ALCint major_v = 0, minor_v = 0;

            // Open a temporary device for reading in its version number
            ALCdevice *temp_device = alcOpenDevice(device_list);
            if(CheckALCError() || temp_device == NULL) {  // If we couldn't open the device, just move on to the next
                IF_PRINT_WARNING(AUDIO_DEBUG) << "couldn't open device for version checking: " << device_list << std::endl;
                device_list += strlen(device_list) + 1;
                continue;
            }

            // Create a temporary context for the device
            ALCcontext *temp_context = alcCreateContext(temp_device, 0);
            if(CheckALCError() || temp_context == NULL) {  // If we couldn't create the context, move on to the next device
                IF_PRINT_WARNING(AUDIO_DEBUG) << "couldn't create a temporary context for device: " << device_list << std::endl;
                alcCloseDevice(temp_device);
                device_list += strlen(device_list) + 1;
                continue;
            }

            // Retrieve the version number for the device
            alcMakeContextCurrent(temp_context);

            alcGetIntegerv(temp_device, ALC_MAJOR_VERSION, sizeof(ALCint), &major_v);
            alcGetIntegerv(temp_device, ALC_MINOR_VERSION, sizeof(ALCint), &minor_v);
            alcMakeContextCurrent(0); // Disable the temporary context
            alcDestroyContext(temp_context); // Destroy the temporary context
            alcCloseDevice(temp_device); // Close the temporary device

            // Check if a higher version device was found
            if(highest_version < (major_v * 10 + minor_v)) {
                highest_version = (major_v * 10 + minor_v);
                best_device = device_list;
            }
            device_list += strlen(device_list) + 1; // Go to the next device name in the list
        } // while (*device_name != 0)
    } // if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)

    // Open the 'best' device we found above. If no devices were previously found,
    // it will try opening the default device (= 0)
    _device = alcOpenDevice(best_device);
    if(CheckALCError() || _device == NULL) {
        PRINT_ERROR << "failed to open an OpenAL audio device: " << CreateALCErrorString() << std::endl;
        return false;
    }

    // Create an OpenAL context
    _context = alcCreateContext(_device, NULL);
    if(CheckALCError() || _context == NULL) {
        PRINT_ERROR << "failed to create an OpenAL context: " << CreateALCErrorString() << std::endl;
        alcCloseDevice(_device);
        return false;
    }

    alcMakeContextCurrent(_context);
    CheckALError(); // Clear errors
    CheckALCError(); // Clear errors

    // Create as many sources as possible (we fix an upper bound of MAX_DEFAULT_AUDIO_SOURCES)
    ALuint source;
    for(uint16 i = 0; i < _max_sources; ++i) {
        alGenSources(1, &source);
        if(CheckALError() == true) {
            _max_sources = i;
            _max_cache_size = i / 4;
            break;
        }
        _audio_sources.push_back(new private_audio::AudioSource(source));
    }

    if(_max_sources == 0) {
        PRINT_ERROR << "failed to create at least one OpenAL audio source" << std::endl;
        return false;
    }

    return true;
} // bool AudioEngine::SingletonInitialize()
Ejemplo n.º 29
0
    void AudioWorld::initializeMusic()
    {
        std::string datPath = "/_work/data/Scripts/_compiled/MUSIC.DAT";
        std::string datFile = Utils::getCaseSensitivePath(datPath, m_Engine.getEngineArgs().gameBaseDirectory);

        if (!Utils::fileExists(datFile)) {
            LogError() << "Failed to find MUSIC.DAT at: " << datFile;
            return;
        }

        m_MusicVM = new Daedalus::DaedalusVM(datFile);
        Daedalus::registerGothicEngineClasses(*m_MusicVM);

        m_MusicVM->getDATFile().iterateSymbolsOfClass("C_MUSICTHEME", [&](size_t i, Daedalus::PARSymbol& s) {
            Daedalus::GameState::MusicThemeHandle h = m_MusicVM->getGameState().createMusicTheme();
            Daedalus::GEngineClasses::C_MusicTheme& mt = m_MusicVM->getGameState().getMusicTheme(h);
            m_MusicVM->initializeInstance(ZMemory::toBigHandle(h), i, Daedalus::IC_MusicTheme);

            m_musicThemeSegments[s.name] = mt.file;
        });

        // DirectMusic initialization
        std::string baseDir = m_Engine.getEngineArgs().gameBaseDirectory;
        std::string musicPath = Utils::getCaseSensitivePath("/_work/data/Music", baseDir);
        try {
            const auto sfFactory = DirectMusic::DlsPlayer::createFactory();
            m_musicContext = std::make_unique<DirectMusic::PlayingContext>(44100, 2, sfFactory);

            auto loader = [musicPath, baseDir](const std::string& name) {
                const auto search = Utils::lowered(Utils::stripFilePath(name));
                for (const auto& file : Utils::getFilesInDirectory(musicPath)) {
                    const auto lowercaseName = Utils::lowered(Utils::stripFilePath(file));
                    if (lowercaseName == search) {
                        return Utils::readBinaryFileContents(file);
                    }
                }
                return std::vector<std::uint8_t>();
            };

            m_musicContext->provideLoader(loader);

            for (const auto& segment : Utils::getFilesInDirectory(musicPath, "sgt")) {
                const auto lowercaseName = Utils::lowered(Utils::stripFilePath(segment));
                const auto segm = m_musicContext->loadSegment(segment);
                LogInfo() << "Loading " + segment;
                m_Segments[lowercaseName] = m_musicContext->prepareSegment(*segm);
            }
            LogInfo() << "All segments loaded.";

            alGenBuffers(RE_NUM_MUSIC_BUFFERS, m_musicBuffers);
            alGenSources(1, &m_musicSource);

            // Set the default volume
            alSourcef(m_musicSource, AL_GAIN, 1);

            // Set the default position of the sound
            alSource3f(m_musicSource, AL_POSITION, 0, 0, 0);

            m_musicRenderThread = std::thread(&AudioWorld::musicRenderFunction, this);
        } catch (const std::exception& exc) {
            LogError() << "Couldn't initialize music system: " << exc.what();
        }
    }
Ejemplo n.º 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;
}