Esempio n. 1
0
int main(int argc, char *argv[]) {

    if(alcIsExtensionPresent(NULL, "ALC_SOFT_loopback") == ALC_FALSE) {
        fputs("Your OpenAL implementation doesn't support the "
              "\"ALC_SOFT_loopback\" extension, required for this test. "
              "Sorry.\n", stderr);
        exit(EXIT_FAILURE);
    }
    ALCint alc_major, alc_minor;
    alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &alc_major);
    alcGetIntegerv(NULL, ALC_MINOR_VERSION, 1, &alc_minor);
    if(alc_major<1 || (alc_major==1 && alc_minor<1))
        fputs("Warning : ALC_SOFT_loopback has been written against "
              "the OpenAL 1.1 specification.\n", stderr);

#define HELPER(X) X = alcGetProcAddress(NULL, #X)
    HELPER(alcLoopbackOpenDeviceSOFT);
    HELPER(alcIsRenderFormatSupportedSOFT);
    HELPER(alcRenderSamplesSOFT);
#undef  HELPER
#define HELPER(X) X = alcGetEnumValue(NULL, #X)
    HELPER(ALC_BYTE_SOFT);
    HELPER(ALC_UNSIGNED_BYTE_SOFT);
    HELPER(ALC_SHORT_SOFT);
    HELPER(ALC_UNSIGNED_SHORT_SOFT);
    HELPER(ALC_INT_SOFT);
    HELPER(ALC_UNSIGNED_INT_SOFT);
    HELPER(ALC_FLOAT_SOFT);
    HELPER(ALC_MONO_SOFT);
    HELPER(ALC_STEREO_SOFT);
    HELPER(ALC_QUAD_SOFT);
    HELPER(ALC_5POINT1_SOFT);
    HELPER(ALC_6POINT1_SOFT);
    HELPER(ALC_7POINT1_SOFT);
    HELPER(ALC_FORMAT_CHANNELS_SOFT);
    HELPER(ALC_FORMAT_TYPE_SOFT);
#undef  HELPER

    ALCdevice *loopback_device = alcLoopbackOpenDeviceSOFT(NULL);
    if(!loopback_device) {
        fputs("Could not open loopback device.\n", stderr);
        exit(EXIT_FAILURE);
    }
    if(alcIsRenderFormatSupportedSOFT(loopback_device, 
            22050, ALC_STEREO_SOFT, ALC_SHORT_SOFT) == ALC_FALSE) 
    {
        fputs("The loopback device does not support the "
              "required render format.\n", stderr);
        alcCloseDevice(loopback_device);
        exit(EXIT_FAILURE);
    }

    ALCint attrlist[11] = {
        ALC_MONO_SOURCES, 0,
        ALC_STEREO_SOURCES, 255,
        ALC_FREQUENCY, 22050,
        ALC_FORMAT_CHANNELS_SOFT, ALC_STEREO_SOFT,
        ALC_FORMAT_TYPE_SOFT, ALC_SHORT_SOFT,
        0
    };
    ALCcontext *ctx = alcCreateContext(loopback_device, attrlist);
    alcMakeContextCurrent(ctx);
    alGetError(); /* Clear the error state */

    if(argc<=1) {
        fprintf(stderr, "Usage : %s <small_oggfile>\n", argv[0]);
        alcCloseDevice(loopback_device);
        exit(EXIT_FAILURE);
    }

    SF_INFO sndinfo;
    SNDFILE *snd = sf_open(argv[1], SFM_READ, &sndinfo);
    if(!snd) {
        fprintf(stderr, "Failed to open \"%s\" : %s\n", 
                argv[1], sf_strerror(snd));
        alcCloseDevice(loopback_device);
        exit(EXIT_FAILURE);
    }
    if(sndinfo.channels != 2) {
        fprintf(stderr, "The source sound file has %d channels "
                "(exactly 2 are required).\n", sndinfo.channels);
        alcCloseDevice(loopback_device);
        exit(EXIT_FAILURE);
    }
    short *data = malloc(sndinfo.frames*2*sizeof(short));
    printf("Reading from '%s'...\n", argv[1]);
    sf_readf_short(snd, data, sndinfo.frames);
    sf_close(snd);

    ALuint audio_buffer;
    alGenBuffers(1, &audio_buffer);
    alBufferData(audio_buffer, AL_FORMAT_STEREO16, data,
            sndinfo.frames*2*sizeof(short), sndinfo.samplerate);
    free(data);

    ALuint audio_source;
    alGenSources(1, &audio_source);
    alSourcei(audio_source, AL_BUFFER, audio_buffer);

    unsigned num_frames = sndinfo.frames;
    ALCshort *rendered_samples = malloc(num_frames*2*sizeof(ALCshort));
    sndinfo.samplerate = 22050;
    sndinfo.channels = 2;
    sndinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS | SF_ENDIAN_FILE;
    snd = sf_open("rendered.ogg", SFM_WRITE, &sndinfo);

    alSourcePlay(audio_source);

    puts("Rendering frames...");
    unsigned chunk_size = 4096, off;
    for(off=0 ; off<(num_frames-chunk_size)*2 ; off+=2*chunk_size)
        alcRenderSamplesSOFT(loopback_device, rendered_samples+off, chunk_size);

    puts("Writing to 'rendered.ogg'...");
    sf_write_short(snd, rendered_samples, off-s);
    sf_close(snd);
    free(rendered_samples);

    alDeleteSources(1, &audio_source);
    alDeleteBuffers(1, &audio_buffer);
    alcCloseDevice(loopback_device);
    alcMakeContextCurrent(NULL);
    alcDestroyContext(ctx);

    exit(EXIT_SUCCESS);
}
Esempio n. 2
0
bool cOAL_Device::Init( cOAL_Init_Params& acParams )
{
	DEF_FUNC_NAME(cOAL_Device::Init);
	FUNC_USES_ALC;
	FUNC_USES_AL;

	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Command, "Initializing device: %s...\n", (acParams.msDeviceName == "")? "\"preferred\"":acParams.msDeviceName.c_str() );

	LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "Configuring streaming options:\n");

	cOAL_Stream::SetBufferSize(acParams.mlStreamingBufferSize);
	LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\tSetting buffer size to %d bytes\n",cOAL_Stream::GetBufferSize());
	cOAL_Stream::SetBufferCount(acParams.mlStreamingBufferCount);
	LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\tSetting queue length to %d buffers\n",cOAL_Stream::GetBufferCount());

	
	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Attempting to open device...\n" );
	// Open the device, if fails return false
	if(acParams.msDeviceName.empty())
		mpDevice = alcOpenDevice(NULL);
	else
        mpDevice = alcOpenDevice( acParams.msDeviceName.c_str() );
	
	if(mpDevice == NULL)
	{
		LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Error, "Error opening device\n" );
		return false;
	}
	
	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Success.\n" );
	
	// Get ALC extensions ( ie EFX )
	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Checking present ALC extensions\n" );
	for (int i = 0; i < NUM_ALC_EXTENSIONS; ++i)
	{
		mvbExtensions[i] = RUN_ALC_FUNC((alcIsExtensionPresent(mpDevice,sExtensionNames[i].c_str()) == ALC_TRUE));
		if (mvbExtensions[i])
		{
			LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\t%s\n",sExtensionNames[i].c_str() );
		}
	}

	ALCint lAttrList[] = 
	{
		ALC_FREQUENCY,		acParams.mlOutputFreq,
#ifdef __APPLE__
#else
		ALC_MONO_SOURCES,	acParams.mbVoiceManagement ? 256 : acParams.mlMinMonoSourcesHint,
		ALC_STEREO_SOURCES,	acParams.mbVoiceManagement ? 0 : acParams.mlMinStereoSourcesHint,
#endif
		ALC_MAX_AUXILIARY_SENDS, acParams.mlNumSendsHint,
		0,
	};

	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Creating context\n");
	// Create and set a context
	mpContext = RUN_ALC_FUNC(alcCreateContext ( mpDevice, lAttrList ));

	RUN_ALC_FUNC(alcMakeContextCurrent ( mpContext ));

	if (ALC_ERROR_OCCURED)
	{
		LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Error, "Error creating context\n");
		return false;
	}

	/////////////////////////////////////////////////
	//Retrieve device info, such as extensions
	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Checking present AL extensions\n" );
	for (int i = NUM_ALC_EXTENSIONS; i < NUM_EXTENSIONS; ++i)
	{
		mvbExtensions[i] = RUN_AL_FUNC((alIsExtensionPresent(sExtensionNames[i].c_str()) == AL_TRUE));
		if (mvbExtensions[i])
			LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\t%s\n",sExtensionNames[i].c_str() );
	}

	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Retrieving Output Devices\n");
	vector<string> llDevices = GetOutputDevices();
	vector<string>::iterator it;
	for (it = llDevices.begin(); it != llDevices.end(); ++it) {
		LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "\t%s\n", (*it).c_str());
	}

	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Retrieving info\n" );

	// Get device name
	msDeviceName = RUN_ALC_FUNC(alcGetString(mpDevice, ALC_DEVICE_SPECIFIER));

	// Get vendor name (just fancy stuff,not very useful)
	msVendorName = RUN_ALC_FUNC(alGetString( AL_VENDOR ));

	//Get renderer info
	msRenderer = RUN_ALC_FUNC(alGetString ( AL_RENDERER ));

	// Get the OpenAL impl. version
	RUN_ALC_FUNC(alcGetIntegerv ( mpDevice, ALC_MAJOR_VERSION, sizeof(ALCint), &mlMajorVersion ));
	RUN_ALC_FUNC(alcGetIntegerv ( mpDevice, ALC_MINOR_VERSION, sizeof(ALCint), &mlMinorVersion ));

	RUN_ALC_FUNC(alcGetIntegerv ( mpDevice, ALC_MAX_AUXILIARY_SENDS, sizeof(ALCint), &mlEFXSends));

	LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "Device name: %s\n", msDeviceName.c_str() );
	LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "OpenAL version: %d.%d\n", mlMajorVersion, mlMinorVersion );

	// Check device version
	if ( (mlMajorVersion < acParams.mlMajorVersionReq) ||
			((mlMajorVersion == acParams.mlMajorVersionReq) && (mlMinorVersion < acParams.mlMinorVersionReq)) )
	{
		LogMsg("",eOAL_LogVerbose_None, eOAL_LogMsg_Error, "Version required: %d.%d\n",acParams.mlMajorVersionReq,acParams.mlMinorVersionReq);
		return false;
	}

	//	If alSourceNumHint == -1, create as many sources as possible
	if (acParams.mlNumSourcesHint == -1)
		acParams.mlNumSourcesHint = 4096;

	/////////////////////////////////////////////////
	//Start EFX if requested
    if (acParams.mbUseEFX && IsExtensionAvailable (OAL_ALC_EXT_EFX))
	{
		LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Starting EFX on request\n" );
		mpEFXManager = new cOAL_EFXManager;
		mbEFXActive = mpEFXManager->Initialize( acParams.mlNumSlotsHint, mlEFXSends, acParams.mbUseThread, acParams.mlSlotUpdateFreq );
		if (!mbEFXActive)
		{
			mpEFXManager->Destroy();
			delete mpEFXManager;
		}
	}

	LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Creating Source Manager\n" );
	//Create The source manager
	mpSourceManager = new cOAL_SourceManager;
	if ( mpSourceManager->Initialize( acParams.mbVoiceManagement, acParams.mlNumSourcesHint, acParams.mbUseThread, acParams.mlUpdateFreq, mlEFXSends ) == false)
	{
		LogMsg("",eOAL_LogVerbose_None, eOAL_LogMsg_Error, "Error creating Source Manager\n");
		return false;
	}
	
	return true;
}
Esempio n. 3
0
static void printEFXInfo(ALCdevice *device)
{
    ALCint major, minor, sends;
    static const ALchar filters[][32] = {
        "AL_FILTER_LOWPASS", "AL_FILTER_HIGHPASS", "AL_FILTER_BANDPASS", ""
    };
    char filterNames[] = "Low-pass,High-pass,Band-pass,";
    static const ALchar effects[][32] = {
        "AL_EFFECT_EAXREVERB", "AL_EFFECT_REVERB", "AL_EFFECT_CHORUS",
        "AL_EFFECT_DISTORTION", "AL_EFFECT_ECHO", "AL_EFFECT_FLANGER",
        "AL_EFFECT_FREQUENCY_SHIFTER", "AL_EFFECT_VOCAL_MORPHER",
        "AL_EFFECT_PITCH_SHIFTER", "AL_EFFECT_RING_MODULATOR",
        "AL_EFFECT_AUTOWAH", "AL_EFFECT_COMPRESSOR", "AL_EFFECT_EQUALIZER", ""
    };
    static const ALchar dedeffects[][64] = {
        "AL_EFFECT_DEDICATED_DIALOGUE",
        "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", ""
    };
    char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
                         "Frequency Shifter,Vocal Morpher,Pitch Shifter,"
                         "Ring Modulator,Autowah,Compressor,Equalizer,"
                         "Dedicated Dialog,Dedicated LFE,";
    char *current;
    int i;

    if(alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
    {
        printf("EFX not available\n");
        return;
    }

    alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
    alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
    if(checkALCErrors(device) == ALC_NO_ERROR)
        printf("EFX version: %d.%d\n", major, minor);
    alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
    if(checkALCErrors(device) == ALC_NO_ERROR)
        printf("Max auxiliary sends: %d\n", sends);

    current = filterNames;
    for(i = 0;filters[i][0];i++)
    {
        char *next = strchr(current, ',');
        ALenum val;

        val = alGetEnumValue(filters[i]);
        if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
            memmove(current, next+1, strlen(next));
        else
            current = next+1;
    }
    printf("Supported filters:");
    printList(filterNames, ',');

    current = effectNames;
    for(i = 0;effects[i][0];i++)
    {
        char *next = strchr(current, ',');
        ALenum val;

        val = alGetEnumValue(effects[i]);
        if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
            memmove(current, next+1, strlen(next));
        else
            current = next+1;
    }
    if(alcIsExtensionPresent(device, "ALC_EXT_DEDICATED"))
    {
        for(i = 0;dedeffects[i][0];i++)
        {
            char *next = strchr(current, ',');
            ALenum val;

            val = alGetEnumValue(dedeffects[i]);
            if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
                memmove(current, next+1, strlen(next));
            else
                current = next+1;
        }
    }
    else
    {
        for(i = 0;dedeffects[i][0];i++)
        {
            char *next = strchr(current, ',');
            memmove(current, next+1, strlen(next));
        }
    }
    printf("Supported effects:");
    printList(effectNames, ',');
}
void plVoiceRecorder::Update(double time)
{   
    if(!fRecording)
        return;

    int EncoderFrameSize = plSpeex::GetInstance()->GetFrameSize();
    if(EncoderFrameSize == -1) 
        return;

    ALCdevice *captureDevice = plgAudioSys::GetCaptureDevice();
    if(!captureDevice)
        return;

    unsigned minSamples = EncoderFrameSize * 10;

    ALCint samples;
    alcGetIntegerv(captureDevice, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples );
    
    if (samples > 0)
    {
        if (samples >= minSamples)
        {
            int numFrames = (int)(samples / EncoderFrameSize);      // the number of frames that have been captured
            int totalSamples = numFrames * EncoderFrameSize;

            // cap uncompressed data
            if(totalSamples > MAX_DATA_SIZE)
                totalSamples = MAX_DATA_SIZE;

            // convert to correct units:
            short *buffer = new short[totalSamples];

            alcCaptureSamples(captureDevice, buffer, totalSamples);

            if (!CompressionEnabled())
            {
                plNetMsgVoice pMsg;
                pMsg.SetNetProtocol(kNetProtocolCli2Game);
                pMsg.SetVoiceData((char *)buffer, totalSamples * sizeof(short));
                // set frame size here;
                pMsg.SetPlayerID(plNetClientApp::GetInstance()->GetPlayerID());
                //if (false) //plNetClientApp::GetInstance()->GetFlagsBit(plNetClientApp::kEchoVoice))
                //  pMsg.SetBit(plNetMessage::kEchoBackToSender);
                plNetClientApp::GetInstance()->SendMsg(&pMsg);
            
            }
            else  // use the speex voice compression lib
            {
                uint8_t *packet = new uint8_t[totalSamples];      // packet to send encoded data in
                int packedLength = 0;                                     // the size of the packet that will be sent
                hsRAMStream ram;                                          // ram stream to hold output data from speex
                uint8_t numFrames = totalSamples / EncoderFrameSize;        // number of frames to be encoded
                
                // encode the data using speex
                plSpeex::GetInstance()->Encode(buffer, numFrames, &packedLength, &ram);

                if (packedLength)
                {
                    // extract data from ram stream into packet
                    ram.Rewind();
                    ram.Read(packedLength, packet);
                    plNetMsgVoice pMsg;
                    pMsg.SetNetProtocol(kNetProtocolCli2Game);

                    pMsg.SetVoiceData((char *)packet, packedLength);
                    pMsg.SetPlayerID(plNetClientApp::GetInstance()->GetPlayerID());
                    pMsg.SetFlag(VOICE_ENCODED);    // Set encoded flag
                    pMsg.SetNumFrames(numFrames);
                    if (plNetClientApp::GetInstance()->GetFlagsBit(plNetClientApp::kEchoVoice))
                        pMsg.SetBit(plNetMessage::kEchoBackToSender);

                    plNetClientApp::GetInstance()->SendMsg(&pMsg);
                }
                delete[] packet;
            }
            delete[] buffer;
        }
        else if(!fMikeOpen)
        {
            short *buffer = new short[samples];
            // the mike has since closed, and there isn't enough data to meet our minimum, so throw this data out
            alcCaptureSamples(captureDevice, buffer, samples);      
            delete[] buffer;
        }
    }
}
Esempio n. 5
0
	bool COALExtProvider::Create(ALCdevice* device, ALCcontext*& context)
	{
		ALint attribs[4] = { 0 };
		bool efx = false;

		//Try to load effect extension
		if(ExtPresent(device, ALC_EXT_EFX_NAME))
		{
			attribs[0] = ALC_MAX_AUXILIARY_SENDS;
			attribs[1] = 4;
			context = alcCreateContext(device, attribs);
			efx = true;
			CON(MSG_INFO, _W(" Device supports Effect Extension"));
		}
		else
		{
			CON(MSG_INFO, _W(" Device doesn't support Effect Extension"));
			context = alcCreateContext(device, NULL);
		}

		if(context == NULL)
			return false;

		alcMakeContextCurrent(context);

		alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &m_maxAux);
		CON(MSG_INFO, _W(" Device supports %d Aux Sends per Source"), m_maxAux);

		if(efx)
		{
			alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects");
			alDeleteEffects = (LPALDELETEEFFECTS )alGetProcAddress("alDeleteEffects");
			alIsEffect = (LPALISEFFECT )alGetProcAddress("alIsEffect");
			alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti");
			alEffectiv = (LPALEFFECTIV)alGetProcAddress("alEffectiv");
			alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf");
			alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv");
			alGetEffecti = (LPALGETEFFECTI)alGetProcAddress("alGetEffecti");
			alGetEffectiv = (LPALGETEFFECTIV)alGetProcAddress("alGetEffectiv");
			alGetEffectf = (LPALGETEFFECTF)alGetProcAddress("alGetEffectf");
			alGetEffectfv = (LPALGETEFFECTFV)alGetProcAddress("alGetEffectfv");
			alGenFilters = (LPALGENFILTERS)alGetProcAddress("alGenFilters");
			alDeleteFilters = (LPALDELETEFILTERS)alGetProcAddress("alDeleteFilters");
			alIsFilter = (LPALISFILTER)alGetProcAddress("alIsFilter");
			alFilteri = (LPALFILTERI)alGetProcAddress("alFilteri");
			alFilteriv = (LPALFILTERIV)alGetProcAddress("alFilteriv");
			alFilterf = (LPALFILTERF)alGetProcAddress("alFilterf");
			alFilterfv = (LPALFILTERFV)alGetProcAddress("alFilterfv");
			alGetFilteri = (LPALGETFILTERI )alGetProcAddress("alGetFilteri");
			alGetFilteriv= (LPALGETFILTERIV )alGetProcAddress("alGetFilteriv");
			alGetFilterf = (LPALGETFILTERF )alGetProcAddress("alGetFilterf");
			alGetFilterfv= (LPALGETFILTERFV )alGetProcAddress("alGetFilterfv");
			alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots");
			alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots");
			alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)alGetProcAddress("alIsAuxiliaryEffectSlot");
			alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti");
			alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)alGetProcAddress("alAuxiliaryEffectSlotiv");
			alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)alGetProcAddress("alAuxiliaryEffectSlotf");
			alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)alGetProcAddress("alAuxiliaryEffectSlotfv");
			alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)alGetProcAddress("alGetAuxiliaryEffectSloti");
			alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)alGetProcAddress("alGetAuxiliaryEffectSlotiv");
			alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)alGetProcAddress("alGetAuxiliaryEffectSlotf");
			alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)alGetProcAddress("alGetAuxiliaryEffectSlotfv");
				
			if(!(alGenEffects && alDeleteEffects && alIsEffect && alEffecti && alEffectiv &&	alEffectf &&
			alEffectfv && alGetEffecti && alGetEffectiv && alGetEffectf && alGetEffectfv &&	alGenFilters &&
			alDeleteFilters && alIsFilter && alFilteri && alFilteriv &&	alFilterf && alFilterfv &&
			alGetFilteri &&	alGetFilteriv && alGetFilterf && alGetFilterfv && alGenAuxiliaryEffectSlots &&
			alDeleteAuxiliaryEffectSlots &&	alIsAuxiliaryEffectSlot && alAuxiliaryEffectSloti &&
			alAuxiliaryEffectSlotiv && alAuxiliaryEffectSlotf && alAuxiliaryEffectSlotfv &&
			alGetAuxiliaryEffectSloti && alGetAuxiliaryEffectSlotiv && alGetAuxiliaryEffectSlotf &&
			alGetAuxiliaryEffectSlotfv))
			{
				CON(MSG_INFO, _W(" Can't load EFX functions!"));
				efx = false;
			}
		}

		m_initialized = efx;
		return efx;
	}
Esempio n. 6
0
void Audio::init()
{
#ifdef WIN32
	EFXEAXREVERBPROPERTIES efxReverb;
	int attrib[] = {ALC_MAX_AUXILIARY_SENDS, 4};
	int sends;
	ALenum al_err;
#endif

	debugf("Using default audio device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
	device = alcOpenDevice(NULL);
	if (device == NULL)
	{
		debugf("No sound device/driver has been found.\n");
		return;
	}

#ifdef WIN32
    context = alcCreateContext(device, attrib);
#else
    context = alcCreateContext(device, NULL);
#endif
	if (context == NULL)
	{
		debugf("alcCreateContext failed.\n");
	}

	if ( alcMakeContextCurrent(context) == ALC_FALSE )
	{
		ALCenum error = alcGetError(device);

		switch (error)
		{
		case ALC_NO_ERROR:
			debugf("alcMakeContextCurrent failed: No error.\n");
			break;
		case ALC_INVALID_DEVICE:
			debugf("alcMakeContextCurrent failed: Invalid device.\n");
			break;
		case ALC_INVALID_CONTEXT:
			debugf("alcMakeContextCurrent failed: Invalid context.\n");
			break;
		case ALC_INVALID_ENUM:
			debugf("alcMakeContextCurrent failed: Invalid enum.\n");
			break;
		case ALC_INVALID_VALUE:
			debugf("alcMakeContextCurrent failed: Invalid value.\n");
			break;
		case ALC_OUT_OF_MEMORY:
			debugf("alcMakeContextCurrent failed: Out of memory.\n");
			break;
		}
		return;
	}
#ifdef WIN32
	alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
	debugf("%d sends per audio source\n", sends);
#endif
	alListenerf(AL_REFERENCE_DISTANCE, 100.0f);

	//gain = 	(distance / AL_REFERENCE_DISTANCE) ^ (-AL_ROLLOFF_FACTOR
	alDistanceModel(AL_EXPONENT_DISTANCE);
	alListenerf(AL_ROLLOFF_FACTOR, 0.000001f);
//	alListenerf(AL_MAX_DISTANCE, 10000.0f);

	alDopplerFactor(1.0f);
//	alDopplerVelocity(8.0f);
//	alSpeedOfSound(343.3f * UNITS_TO_METERS);
#ifdef WIN32
	alListenerf(AL_METERS_PER_UNIT, 0.3f);

	ALFWIsEFXSupported();
	alGenAuxiliaryEffectSlots(1, &slot);
	al_err = alGetError();
	if (al_err != AL_NO_ERROR)
	{
		debugf("Unable to generate slot: %s\n", GetALErrorString(al_err));
		return;
	}

	alGenEffects(1, &effect);
	al_err = alGetError();
	if (al_err != AL_NO_ERROR)
	{
		debugf("Unable to generate effect: %s\n", GetALErrorString(al_err));
		return;
	}
	alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
	al_err = alGetError();
	if (al_err != AL_NO_ERROR)
	{
		debugf("Unable to set effect: %s\n", GetALErrorString(al_err));
		return;
	}
	ConvertReverbParameters(&eaxBathroom, &efxReverb);
	SetEFXEAXReverbProperties(&efxReverb, effect);

//	alEffectf(effect, AL_REVERB_GAIN, 1.0f);
//	alEffectf(effect, AL_REVERB_DECAY_TIME, 20.0f);
//	alEffectf(effect, AL_REVERB_DENSITY, 0.25f);

	alGenFilters(1, &filter);
	al_err = alGetError();
	if (al_err != AL_NO_ERROR)
	{
		debugf("Unable to generate filter: %s\n", GetALErrorString(al_err));
		return;
	}

	alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
	alFilterf(filter, AL_LOWPASS_GAIN, 0.5f);
	alFilterf(filter, AL_LOWPASS_GAINHF, 0.5f);
#endif
}
Esempio n. 7
0
/*
 * iComponent interface
 */
bool csSndSysRendererOpenAL::Initialize (iObjectRegistry *obj_reg)
{
  if (!libopenal_is_present)
  {
    Report (CS_REPORTER_SEVERITY_WARNING, "OpenAL is not available (libopenal is missing)");
    return false;
  }
  
  // Save the object registry for later use
  m_ObjectRegistry = obj_reg;

  Report (CS_REPORTER_SEVERITY_DEBUG, "Initializing OpenAL sound system");

  // Read the config file
  m_Config.AddConfig (obj_reg, "/config/sound.cfg");

  // Get a list of OpenAL devices:
  // The spec says it's an ALCchar, but my headers include no such type.
  // The format is a series of strings separatrd by nulls, teminated by a
  // double null.
  Report (CS_REPORTER_SEVERITY_DEBUG, "Retrieving available devices.");
  const ALCchar *devices = alcGetString (0, ALC_DEVICE_SPECIFIER);
  // Loop while there is no second null
  while (*devices != 0) {
    Report (CS_REPORTER_SEVERITY_DEBUG, "Available OpenAL device: %s", devices);
    // Seek until the null
    while (*devices != 0)
      devices++;
    // Skip the null
    devices++;
  }

  // Report the default device.
  Report (CS_REPORTER_SEVERITY_DEBUG, "Default OpenAL device: %s", alcGetString (0, ALC_DEFAULT_DEVICE_SPECIFIER));

  // Check if a specific device is specified
  const ALCchar *device = m_Config->GetStr ("SndSys.OpenALDevice", 0);
  if (device == 0) {
    // The config did not contain a device to use
    Report (CS_REPORTER_SEVERITY_DEBUG, "No device specified");
  } else {
    // Attempt to open the spcified device
    m_Device = alcOpenDevice (device);
    if (m_Device == 0) {
      // Failed to open the device
      Report (CS_REPORTER_SEVERITY_WARNING, "Unable to open device %s", device);
    }
  }

  // If we still don't have a device, try the default:
  if (m_Device == 0) {
    Report (CS_REPORTER_SEVERITY_DEBUG, "Falling back on default device");
    m_Device = alcOpenDevice (0);
    if (m_Device == 0) {
      // Even that failed, give up.
      Report (CS_REPORTER_SEVERITY_ERROR, "Unable to open device");
      return false;
    }
  }

  // Check some OpenAL context attributes/capabilities
  // http://opensource.creative.com/pipermail/openal/2006-February/009337.html
  ALCenum err;
  ALCint attrSize = 0;
  ALCint *attributes;
  ALCint *data;
  alcGetIntegerv(m_Device, ALC_ATTRIBUTES_SIZE, sizeof(ALCint), &attrSize);
  err = alcGetError (m_Device);
  if (err == ALC_NO_ERROR)
  {
    attributes = (ALCint *)cs_malloc(attrSize * sizeof(ALCint));
    alcGetIntegerv(m_Device, ALC_ALL_ATTRIBUTES, attrSize, attributes);
    err = alcGetError (m_Device);
    if (err == ALC_NO_ERROR)
    {
      data = attributes;
      while (data < attributes + attrSize)
      {
	switch (*data)
	{
	  case ALC_FREQUENCY:
	    data += 1;
	    Report (CS_REPORTER_SEVERITY_DEBUG, "OpenAL context frequency: %d Hz",
	      *data);
	    break;
	  case ALC_REFRESH:
	    data += 1;
	    Report (CS_REPORTER_SEVERITY_DEBUG, "OpenAL context refresh: %d Hz",
	      *data);
	    break;
	  case ALC_SYNC:
	    data += 1;
	    Report (CS_REPORTER_SEVERITY_DEBUG,
	      "OpenAL context uses %s (%sthreaded) context",
	      *data ? "synchronous": "asynchronous", *data ? "non " : "");
	    break;
	  case ALC_MONO_SOURCES:
	    data += 1;
	    Report (CS_REPORTER_SEVERITY_DEBUG,
	      "OpenAL context should support %d mono sources", *data);
	    break;
	  case ALC_STEREO_SOURCES:
	    data += 1;
	    Report (CS_REPORTER_SEVERITY_DEBUG,
	      "OpenAL context should support %d stereo sources", *data);
	    break;
	  default:
	    break;
	}
	data += 1;
      }
    }
    else
      Report (CS_REPORTER_SEVERITY_DEBUG,
	"Can't retrieve attributes: OpenAL error %s",
	ALCErrors.StringForIdent (err));
    cs_free(attributes);
  }
  else
    Report (CS_REPORTER_SEVERITY_DEBUG,
      "Can't retrieve attributes size: OpenAL error %s",
      ALCErrors.StringForIdent (err));

  // Configure sound sources
  SndSysSourceOpenAL2D::Configure( m_Config );

  // Register for event callbacks.
  csRef<iEventQueue> q (csQueryRegistry<iEventQueue> (m_ObjectRegistry));
  evSystemOpen = csevSystemOpen(m_ObjectRegistry);
  evSystemClose = csevSystemClose(m_ObjectRegistry);
  evFrame = csevFrame(m_ObjectRegistry);
  if (q != 0) {
    csEventID subEvents[] = { evSystemOpen, evSystemClose, evFrame, CS_EVENTLIST_END };
    q->RegisterListener(this, subEvents);
  }

  return true;
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
	ALCcontext *default_context = 0, *custom_context = 0;
	ALCdevice *dev;
	int attrlist[] = { ALC_FREQUENCY, 44100, ALC_SYNC, AL_TRUE, 0 };

	dev = alcOpenDevice( (const ALubyte *) "'((sampling-rate 44100))" );
	if( dev == NULL )
	{
		return 1;
	}

	/* Initialize ALUT. */
	default_context = alcCreateContext(dev, NULL);
	if(default_context == NULL)
	{
		alcCloseDevice( dev );

		return 1;
	}

	free(malloc(4));

	alcMakeContextCurrent(default_context);

	{
		ALint NumFlags = 0;
		ALint *Flags = 0;
		int i;

		printf("default context\n");

		alcGetIntegerv(dev, ALC_ATTRIBUTES_SIZE,
			       sizeof NumFlags, &NumFlags );

		printf("NumFlags %d\n", NumFlags);

		if(NumFlags)
		{
			Flags = malloc(sizeof NumFlags * sizeof *Flags);
			assert(Flags);

			alcGetIntegerv(dev, ALC_ALL_ATTRIBUTES,
				       sizeof NumFlags * sizeof *Flags,
				       Flags );
		}

		for(i = 0; i < NumFlags-1; i += 2)
		{
			printf("key 0x%x : value %d\n",
			       Flags[i], Flags[i+1]);
		}

		/* must be 0 terminated */
		assert(Flags[NumFlags-1] == 0);
	}

	custom_context  = alcCreateContext(dev, attrlist);
	if(custom_context == NULL)
	{
		alcCloseDevice( dev );

		return 1;
	}
	alcMakeContextCurrent(custom_context);

	{
		ALint NumFlags = 0;
		ALint *Flags = 0;
		int i;

		printf("custom context\n");

		alcGetIntegerv(dev, ALC_ATTRIBUTES_SIZE,
			       sizeof NumFlags, &NumFlags );

		printf("NumFlags %d\n", NumFlags);

		if(NumFlags)
		{
			Flags = malloc(sizeof NumFlags * sizeof *Flags);
			assert(Flags);

			alcGetIntegerv(dev, ALC_ALL_ATTRIBUTES,
				       sizeof NumFlags * sizeof *Flags,
				       Flags );
		}

		for(i = 0; i < NumFlags-1; i += 2)
		{
			printf("key 0x%x : value %d\n",
			       Flags[i], Flags[i+1]);
		}

		/* must be 0 terminated */
		assert(Flags[NumFlags-1] == 0);
	}




	fixup_function_pointers();

	alcDestroyContext(default_context);
	alcDestroyContext(custom_context);

	return 0;
}
Esempio n. 9
0
bool AudioEngine::SingletonInitialize() {
	if (AUDIO_ENABLE == false)
		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() << 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 << 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 << 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() << endl;
		return false;
	}

	// Create an OpenAL context
	_context = alcCreateContext(_device, NULL);
	if (CheckALCError() || _context == NULL) {
		PRINT_ERROR << "failed to create an OpenAL context: " << CreateALCErrorString()<< 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" << endl;
		return false;
	}

	return true;
} // bool AudioEngine::SingletonInitialize()
Esempio n. 10
0
////////////////////////////////////////////////////////////
/// Point d'entr�e du programme
///
/// \return Code d'erreur de l'application
///
////////////////////////////////////////////////////////////
int main_capture()
{
    int time_left = 0;

    // Initialisation d'OpenAL avec le device par d�faut
    if (!InitOpenAL_capture(NULL))
        return EXIT_FAILURE;

    // Initialisation de la capture
    if (!InitCapture(NULL))
        return EXIT_FAILURE;

    // Lancement de la capture
    alcCaptureStart(CaptureDevice);

    // On va stocker les �chantillons captur�s dans un tableau d'entiers sign�s 16 bits
    std::vector<ALshort> Samples;

    // ...Et c'est parti pour 5 secondes de capture
    time_t Start = time(NULL);

    while ((time_left = time(NULL) - Start) <= 5) // si x passe � 1, on stop la capture
    {
	std::cout << "\rSpeech capture in progress... " << std::fixed << std::setprecision(2) << 5-time_left << " sec left";
        // On r�cup�re le nombre d'�chantillons disponibles
        ALCint SamplesAvailable;
        alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);

        // On lit les �chantillons et on les ajoute au tableau
        if (SamplesAvailable > 0)
        {
            std::size_t Start = Samples.size();
            Samples.resize(Start + SamplesAvailable);
            alcCaptureSamples(CaptureDevice, &Samples[Start], SamplesAvailable);
        }
    }

    // On stoppe la capture
    alcCaptureStop(CaptureDevice);

    // On n'oublie pas les �ventuels �chantillons qu'il reste � r�cup�rer
    ALCint SamplesAvailable;
    alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
    if (SamplesAvailable > 0)
    {
        std::size_t Start = Samples.size();
        Samples.resize(Start + SamplesAvailable);
        alcCaptureSamples(CaptureDevice, &Samples[Start], SamplesAvailable);
    }

	std::cout << "\rSpeech capture complete                   " << std::endl;

    // On sauvegarde les �chantillons captur�s dans un fichier
    SaveSound("vocal.wav", Samples);

    // Fermeture de la capture
    ShutdownCapture();

    // Fermeture d'OpenAL
    ShutdownOpenAL_capture();

    return EXIT_SUCCESS;
}
Esempio n. 11
0
// initializes hardware device from perferred/default/enumerated list
bool openal_init_device(SCP_string *playback, SCP_string *capture)
{
	if ( !Playback_device.empty() ) {
		if (playback) {
			*playback = Playback_device;
		}

		if (capture) {
			*capture = Capture_device;
		}

		return true;
	}

	if (playback) {
		playback->erase();
	}

	if (capture) {
		capture->erase();
	}

	// initialize default setup first, for version check...

	ALCdevice *device = alcOpenDevice(NULL);

	if (device == NULL) {
		return false;
	}

	ALCcontext *context = alcCreateContext(device, NULL);

	if (context == NULL) {
		alcCloseDevice(device);
		return false;
	}

	alcMakeContextCurrent(context);

	// version check (for 1.0 or 1.1)
	ALCint AL_minor_version = 0;
	alcGetIntegerv(NULL, ALC_MINOR_VERSION, sizeof(ALCint), &AL_minor_version);

	if (AL_minor_version < 1) {
#ifdef _WIN32
		MessageBox(NULL, "OpenAL 1.1 or newer is required for proper operation.  Please upgrade your OpenAL drivers, which\nare available at http://www.openal.org/downloads.html, and try running the game again.", NULL, MB_OK);
#else
		printf("OpenAL 1.1 or newer is required for proper operation.\n");
		printf("Please upgrade to a newer version if on OS X or switch\n");
		printf("to OpenAL-Soft on Linux.\n");
#endif

		alcMakeContextCurrent(NULL);
		alcDestroyContext(context);
		alcCloseDevice(device);

		return false;
	}

	alcGetError(device);

	// close default device
	alcMakeContextCurrent(NULL);
	alcDestroyContext(context);
	alcCloseDevice(device);


	// go through and find out what devices we actually want to use ...
	find_playback_device();
	find_capture_device();

	if ( Playback_device.empty() ) {
		return false;
	}


#ifndef NDEBUG
	if ( !PlaybackDevices.empty() ) {
		nprintf(("OpenAL", "  Available Playback Devices:\n"));

		for (size_t idx = 0; idx < PlaybackDevices.size(); idx++) {
			nprintf(("OpenAL", "    %s", PlaybackDevices[idx].device_name.c_str()));

			if (PlaybackDevices[idx].type == OAL_DEVICE_USER) {
				nprintf(("OpenAL", "  *preferred*\n"));
			} else if (PlaybackDevices[idx].type == OAL_DEVICE_DEFAULT) {
				nprintf(("OpenAL", "  *default*\n"));
			} else {
				nprintf(("OpenAL", "\n"));
			}
		}
	}

	if ( !CaptureDevices.empty() ) {
		if ( !PlaybackDevices.empty() ) {
			nprintf(("OpenAL", "\n"));
		}

		nprintf(("OpenAL", "  Available Capture Devices:\n"));

		for (size_t idx = 0; idx < CaptureDevices.size(); idx++) {
			nprintf(("OpenAL", "    %s", CaptureDevices[idx].device_name.c_str()));

			if (CaptureDevices[idx].type == OAL_DEVICE_USER) {
				nprintf(("OpenAL", "  *preferred*\n"));
			} else if (CaptureDevices[idx].type == OAL_DEVICE_DEFAULT) {
				nprintf(("OpenAL", "  *default*\n"));
			} else {
				nprintf(("OpenAL", "\n"));
			}
		}

		nprintf(("OpenAL", "\n"));
	}
#endif


	// cleanup
	PlaybackDevices.clear();
	CaptureDevices.clear();


	if (playback) {
		*playback = Playback_device;
	}

	if (capture) {
		*capture = Capture_device;
	}

	return true;
}
IKeOpenALAudioDevice::IKeOpenALAudioDevice( KeAudioDeviceDesc* audiodevice_desc ): device(NULL), context(NULL)
{
    ALint attributes[4] = {0};
    ALenum error = 0;
    
    initialized = No;
    
    /* Create the default OpenAL device */
    device = alcOpenDevice( NULL );
	if( !device )
    {
        DISPDBG_R( KE_ERROR, "Error initializing OpenAL audio device!" );
    }
    
#if defined(__APPLE__) && defined(__MOBILE_OS__)
    /* Not available for iOS afaik */
#else
    /* Does the user want to initialize EFX? */
    if( audiodevice_desc->aux_sends != 0 )
    {
        /* Verify the EFX extension is supported */
        /* If not, uninitialize and exit */
        if( !alcIsExtensionPresent( device, "ALC_EXT_EFX" ) )
        {
            DISPDBG( 1, "ALC_EXT_EFX extension is not present!\n" );
            alcCloseDevice( device );
            return;
        }
        
        /* Set EFX attributes */
        attributes[0] = ALC_MAX_AUXILIARY_SENDS;
        attributes[1] = audiodevice_desc->aux_sends;
        
        /* TODO: More? */
    }
#endif
    
    /* Create an OpenAL context */
	context = alcCreateContext( device, audiodevice_desc->aux_sends == 0 ? NULL : attributes );
    OALC_DISPDBG( KE_ERROR, "Error initializing OpenAL context!" );
	if( !context )
	{
		alcCloseDevice( device );
		return;
	}
    
    /* Set the newly created OpenAL context */
    ALboolean res = alcMakeContextCurrent( context );
	if( !res )
    {
        OALC_DISPDBG( KE_ERROR, "An error occured setting OpenAL context!" );
        alcDestroyContext( context );
        alcCloseDevice( device );
		return;
    }
    
	/* So far, so good, right? */
	error = alGetError();
    
#if defined(__APPLE__) && defined(__MOBILE_OS__)
    /* Not available for iOS afaik */
#else
    /* Verify that we get the desired number of auxiliry sends */
    if( audiodevice_desc->aux_sends != 0 )
    {
        int sends = 0;
        alcGetIntegerv( device, ALC_MAX_AUXILIARY_SENDS, 1, &sends );
        
        if( sends != audiodevice_desc->aux_sends )
            DISPDBG( 1, "Requested " << audiodevice_desc->aux_sends << " max auxiliary sends, got " << sends << "instead...\n" );
        else
            DISPDBG( 1, "Max auxiliary sends: " << sends << "\n" );
    }
#endif
    
    const ALCchar* extensions = alcGetString( device, ALC_EXTENSIONS );
    int extension_count = 0;
    std::vector<ALCchar> ext;
    
    ext.push_back('\t');
    ext.push_back('\t');
    
    /* Count extensions */
    for( int i = 0; i < strlen( extensions )+1; i++ )
    {
        if( extensions[i] == ' ' || extensions[i] == '\0' )
        {
            extension_count++;
            
            ext.push_back('\n');
            ext.push_back('\t');
            ext.push_back('\t');
        }
        else
            ext.push_back(extensions[i]);
    }
    
    ext.push_back('\n\0');
    
	/* Print OpenAL driver/implementation details */
    DISPDBG( 1, "\n\tOpenAL Vendor: " << alGetString( AL_VENDOR ) << 
		"\n\tOpenAL Version: " << alGetString( AL_VERSION ) << 
		"\n\tOpenAL Renderer: " << alGetString( AL_RENDERER ) << "\n" );

    /* Print extensions */
    std::stringstream sstr;
    sstr << extension_count;
    std::string ext_str = "\n\tOpenAL Extensions (" + sstr.str() + "):\n";
    ext_str += ext.data();
    
    DISPDBG( KE_DBGLVL(0), ext_str );
    
    initialized = Yes;
}
Esempio n. 13
0
int main()
{
	ALCdevice		*pDevice;
	ALCcontext		*pContext;
	ALCdevice		*pCaptureDevice;
	const ALCchar	*szDefaultCaptureDevice;
	ALint			iSamplesAvailable;
	FILE			*pFile;
	ALchar			Buffer[BUFFERSIZE];
	WAVEHEADER		sWaveHeader;
	ALint			iDataSize = 0;
	ALint			iSize;

	// NOTE : This code does NOT setup the Wave Device's Audio Mixer to select a recording input
	// or a recording level.

	// Initialize Framework
	ALFWInit();

	ALFWprintf("Capture Application\n");

	if (!ALFWInitOpenAL())
	{
		ALFWprintf("Failed to initialize OpenAL\n");
		ALFWShutdown();
		return 0;
	}

	// Check for Capture Extension support
	pContext = alcGetCurrentContext();
	pDevice = alcGetContextsDevice(pContext);
	if (alcIsExtensionPresent(pDevice, "ALC_EXT_CAPTURE") == AL_FALSE)
	{
		ALFWprintf("Failed to detect Capture Extension\n");
		ALFWShutdownOpenAL();
		ALFWShutdown();
		return 0;
	}

	// Get list of available Capture Devices
	const ALchar *pDeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
	if (pDeviceList)
	{
		ALFWprintf("\nAvailable Capture Devices are:-\n");

		while (*pDeviceList)
		{
			ALFWprintf("%s\n", pDeviceList);
			pDeviceList += strlen(pDeviceList) + 1;
		}
	}

	// Get the name of the 'default' capture device
	szDefaultCaptureDevice = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
	ALFWprintf("\nDefault Capture Device is '%s'\n\n", szDefaultCaptureDevice);

	// Open the default Capture device to record a 22050Hz 16bit Mono Stream using an internal buffer
	// of BUFFERSIZE Samples (== BUFFERSIZE * 2 bytes)
	pCaptureDevice = alcCaptureOpenDevice(szDefaultCaptureDevice, 22050, AL_FORMAT_MONO16, BUFFERSIZE);
	if (pCaptureDevice)
	{
		ALFWprintf("Opened '%s' Capture Device\n\n", alcGetString(pCaptureDevice, ALC_CAPTURE_DEVICE_SPECIFIER));

		// Create / open a file for the captured data
		pFile = fopen(OUTPUT_WAVE_FILE, "wb");

		// Prepare a WAVE file header for the captured data
		sprintf(sWaveHeader.szRIFF, "RIFF");
		sWaveHeader.lRIFFSize = 0;
		sprintf(sWaveHeader.szWave, "WAVE");
		sprintf(sWaveHeader.szFmt, "fmt ");
		sWaveHeader.lFmtSize = sizeof(WAVEFORMATEX);		
		sWaveHeader.wfex.nChannels = 1;
		sWaveHeader.wfex.wBitsPerSample = 16;
		sWaveHeader.wfex.wFormatTag = WAVE_FORMAT_PCM;
		sWaveHeader.wfex.nSamplesPerSec = 22050;
		sWaveHeader.wfex.nBlockAlign = sWaveHeader.wfex.nChannels * sWaveHeader.wfex.wBitsPerSample / 8;
		sWaveHeader.wfex.nAvgBytesPerSec = sWaveHeader.wfex.nSamplesPerSec * sWaveHeader.wfex.nBlockAlign;
		sWaveHeader.wfex.cbSize = 0;
		sprintf(sWaveHeader.szData, "data");
		sWaveHeader.lDataSize = 0;

		fwrite(&sWaveHeader, sizeof(WAVEHEADER), 1, pFile);

		// Start audio capture
		alcCaptureStart(pCaptureDevice);

		// Record for two seconds or until a key is pressed
		DWORD dwStartTime = timeGetTime();
		while (!ALFWKeyPress() && (timeGetTime() <= (dwStartTime + 2000)))
		{
			// Release some CPU time ...
			Sleep(1);

			// Find out how many samples have been captured
			alcGetIntegerv(pCaptureDevice, ALC_CAPTURE_SAMPLES, 1, &iSamplesAvailable);

			ALFWprintf("Samples available : %d\r", iSamplesAvailable);

			// When we have enough data to fill our BUFFERSIZE byte buffer, grab the samples
			if (iSamplesAvailable > (BUFFERSIZE / sWaveHeader.wfex.nBlockAlign))
			{
				// Consume Samples
				alcCaptureSamples(pCaptureDevice, Buffer, BUFFERSIZE / sWaveHeader.wfex.nBlockAlign);

				// Write the audio data to a file
				fwrite(Buffer, BUFFERSIZE, 1, pFile);

				// Record total amount of data recorded
				iDataSize += BUFFERSIZE;
			}
		}

		// Stop capture
		alcCaptureStop(pCaptureDevice);

		// Check if any Samples haven't been consumed yet
		alcGetIntegerv(pCaptureDevice, ALC_CAPTURE_SAMPLES, 1, &iSamplesAvailable);
		while (iSamplesAvailable)
		{
			if (iSamplesAvailable > (BUFFERSIZE / sWaveHeader.wfex.nBlockAlign))
			{
				alcCaptureSamples(pCaptureDevice, Buffer, BUFFERSIZE / sWaveHeader.wfex.nBlockAlign);
				fwrite(Buffer, BUFFERSIZE, 1, pFile);
				iSamplesAvailable -= (BUFFERSIZE / sWaveHeader.wfex.nBlockAlign);
				iDataSize += BUFFERSIZE;
			}
			else
			{
				alcCaptureSamples(pCaptureDevice, Buffer, iSamplesAvailable);
				fwrite(Buffer, iSamplesAvailable * sWaveHeader.wfex.nBlockAlign, 1, pFile);
				iDataSize += iSamplesAvailable * sWaveHeader.wfex.nBlockAlign;
				iSamplesAvailable = 0;
			}
		}

		// Fill in Size information in Wave Header
		fseek(pFile, 4, SEEK_SET);
		iSize = iDataSize + sizeof(WAVEHEADER) - 8;
		fwrite(&iSize, 4, 1, pFile);
		fseek(pFile, 42, SEEK_SET);
		fwrite(&iDataSize, 4, 1, pFile);

		fclose(pFile);

		ALFWprintf("\nSaved captured audio data to '%s'\n", OUTPUT_WAVE_FILE);

		// Close the Capture Device
		alcCaptureCloseDevice(pCaptureDevice);
	}

	// Close down OpenAL
	ALFWShutdownOpenAL();

	// Close down the Framework
	ALFWShutdown();

	return 0;
}
Esempio n. 14
0
int main() {
  int major, minor;
  alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &major);
  alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &minor);

  assert(major == 1);

  printf("ALC version: %i.%i\n", major, minor);
  printf("Default device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));

  ALCdevice* device = alcOpenDevice(NULL);
  ALCcontext* context = alcCreateContext(device, NULL);
  alcMakeContextCurrent(context);

  assert(alGetString(AL_VERSION));

  printf("OpenAL version: %s\n", alGetString(AL_VERSION));
  printf("OpenAL vendor: %s\n", alGetString(AL_VENDOR));
  printf("OpenAL renderer: %s\n", alGetString(AL_RENDERER));

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

  // check getting and setting global gain
  ALfloat volume;
  alGetListenerf(AL_GAIN, &volume);
  assert(volume == 1.0);
  alListenerf(AL_GAIN, 0.0);
  alGetListenerf(AL_GAIN, &volume);
  assert(volume == 0.0);

  alListenerf(AL_GAIN, 1.0); // reset gain to default

  ALuint buffers[1];

  alGenBuffers(1, buffers);

#ifdef __EMSCRIPTEN__
  FILE* source = fopen("audio.wav", "rb");
#else
  FILE* source = fopen("sounds/audio.wav", "rb");
#endif
  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);

  ALint val;
  alGetBufferi(buffers[0], AL_FREQUENCY, &val);
  assert(val == frequency);
  alGetBufferi(buffers[0], AL_SIZE, &val);
  assert(val == size - offset);
  alGetBufferi(buffers[0], AL_BITS, &val);
  assert(val == bits);
  alGetBufferi(buffers[0], AL_CHANNELS, &val);
  assert(val == channels);

  ALuint sources[1];
  alGenSources(1, sources);

  assert(alIsSource(sources[0]));

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

#ifdef __EMSCRIPTEN__
  emscripten_async_call(playSource, reinterpret_cast<void*>(sources[0]), 700);
#else
  usleep(700000);
  playSource(reinterpret_cast<void*>(sources[0]));
#endif

  return 0;
}
Esempio n. 15
0
CEFX::CEFX(ALCdevice* device)
	:enabled(false)
	,supported(false)
	,sfxProperties(NULL)
	,sfxSlot(0)
	,sfxReverb(0)
	,sfxFilter(0)
	,updates(0)
	,maxSlots(0)
	,maxSlotsPerSource(0)
{
	SetAirAbsorptionFactor(configHandler->GetFloat("snd_airAbsorption"));

	bool hasExtension = alcIsExtensionPresent(device, "ALC_EXT_EFX");

	if(hasExtension && alGenEffects && alDeleteEffects)
		supported = true;

	//! set default preset
	eaxPresets["default"] = eaxPresets[default_preset];

	//! always allocate this
	sfxProperties = new EAXSfxProps();
	*sfxProperties = eaxPresets[default_preset];

	if (!supported) {
		if(!hasExtension) {
			LOG("  EFX Supported: no");
		} else {
			LOG("  EFX is supported but software does not seem to work properly");
		}
		return;
	}

	//! clear log
	alGetError() ;

	//! Check Available Effects
	{
		static const ALuint effects[] = {
			AL_EFFECT_REVERB,
			AL_EFFECT_EAXREVERB,
			AL_EFFECT_CHORUS,
			AL_EFFECT_DISTORTION,
			AL_EFFECT_ECHO,
			AL_EFFECT_FLANGER,
			AL_EFFECT_FREQUENCY_SHIFTER,
			AL_EFFECT_VOCAL_MORPHER,
			AL_EFFECT_PITCH_SHIFTER,
			AL_EFFECT_RING_MODULATOR,
			AL_EFFECT_AUTOWAH,
			AL_EFFECT_COMPRESSOR,
			AL_EFFECT_EQUALIZER
		};

		ALuint alFx;
		alGenEffects(1, &alFx);
		if (alGetError() == AL_NO_ERROR) {
			for(size_t i = 0; i < sizeof(effects)/sizeof(effects[0]); i++) {
				const ALuint fx = effects[i];
				alEffecti(alFx, AL_EFFECT_TYPE, fx);
				effectsSupported[fx] = (alGetError() == AL_NO_ERROR);
			}
		}
		alDeleteEffects(1, &alFx);
	}

	//! Check Available Filters
	{
		static const ALuint filters[] = {
			AL_FILTER_LOWPASS,
			AL_FILTER_HIGHPASS,
			AL_FILTER_BANDPASS
		};

		ALuint alFilter;
		alGenFilters(1, &alFilter);
		if (alGetError() == AL_NO_ERROR) {
			for(size_t i = 0; i < sizeof(filters)/sizeof(filters[0]); i++) {
				const ALuint filter = filters[i];
				alFilteri(alFilter, AL_FILTER_TYPE, filter);
				filtersSupported[filter] = (alGetError() == AL_NO_ERROR);
			}
		}
		alDeleteFilters(1, &alFilter);
	}

	//! Check Max Available EffectSlots
	{
		int n;
		ALuint alFXSlots[128];
		for (n = 0; n < 128; n++) {
			alGenAuxiliaryEffectSlots(1, &alFXSlots[n]);
			if (alGetError() != AL_NO_ERROR)
				break;
		}
		maxSlots = n;

		alDeleteAuxiliaryEffectSlots(n, alFXSlots);
	}

	//! Check Max AUX FX SLOTS Per Sound Source
	alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, (ALCint*)&maxSlotsPerSource);


	//! Check requirements
	if (!effectsSupported[AL_EFFECT_EAXREVERB]
		|| !filtersSupported[AL_FILTER_LOWPASS]
		|| (maxSlots<1)
		|| (maxSlotsPerSource<1)
	) {
		if (enabled) {
			LOG_L(L_WARNING, "  EFX Supported: no");
		}
		supported = false;
		return;
	}


	//! Create our global sfx enviroment
	alGenAuxiliaryEffectSlots(1, &sfxSlot);
	alGenEffects(1, &sfxReverb);
		alEffecti(sfxReverb, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
	alGenFilters(1, &sfxFilter);
		alFilteri(sfxFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
	if (!alIsAuxiliaryEffectSlot(sfxSlot) || !alIsEffect(sfxReverb) || !alIsFilter(sfxFilter)) {
		LOG_L(L_ERROR, "  Initializing EFX failed!");
		alDeleteFilters(1, &sfxFilter);
		alDeleteEffects(1, &sfxReverb);
		alDeleteAuxiliaryEffectSlots(1, &sfxSlot);
		supported = false;
		return;
	}


	//! Load defaults
	CommitEffects();
	if (!CheckError("  EFX")) {
		LOG_L(L_ERROR, "  Initializing EFX failed!");
		alAuxiliaryEffectSloti(sfxSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
		alDeleteFilters(1, &sfxFilter);
		alDeleteEffects(1, &sfxReverb);
		alDeleteAuxiliaryEffectSlots(1, &sfxSlot);
		supported = false;
		return;
	}

	//! User may disable it (performance reasons?)
	enabled = configHandler->GetBool("UseEFX");
	LOG("  EFX Enabled: %s", (enabled ? "yes" : "no"));
	if (enabled) {
		LOG_L(L_DEBUG, "  EFX MaxSlots: %i", maxSlots);
		LOG_L(L_DEBUG, "  EFX MaxSlotsPerSource: %i", maxSlotsPerSource);
	}

	configHandler->NotifyOnChange(this);
}
Esempio n. 16
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;
}
Esempio n. 17
0
// Initialize digitized wav driver
//
// return : <int> 1 - initialized successfully
//                0 - init fail
//
int OpenALAudio::init_wav()
{
   ALCint size;

   std::vector<ALCint> attributes;

   assert(!this->wav_init_flag);

   this->wav_res.init(DIR_RES"A_WAVE2.RES", 0, 0);

   this->al_device = alcOpenDevice(NULL);
   if (this->al_device == NULL)
   {
      ERR("alcOpenDevice failed\n");
      goto err;
   }

   attributes.push_back(0);

   this->al_context = alcCreateContext(this->al_device, &attributes[0]);
   if (this->al_context == NULL)
   {
      ERR("alcCreateContext failed: 0x%x\n", alcGetError(this->al_device));
      goto err;
   }

   if (!alcMakeContextCurrent(this->al_context))
   {
      ERR("alcMakeContextCurrent failed: 0x%x\n", alcGetError(this->al_device));
      goto err;
   }

   attributes.clear();
   alcGetIntegerv(this->al_device, ALC_ATTRIBUTES_SIZE, 1, &size);
   attributes.resize(size);
   alcGetIntegerv(this->al_device, ALC_ALL_ATTRIBUTES,
		  attributes.size(), &attributes[0]);

   this->max_sources = 16; /* default, in case OpenAL doesn't tell us */

   for (int n = 0;; n += 2)
   {
      if (attributes[n] == 0)
	 break;

      switch (attributes[n])
      {
	 case ALC_MONO_SOURCES:
	    MSG("ALC_MONO_SOURCES: %i\n", attributes[n + 1]);
	    this->max_sources = attributes[n + 1];
	    break;
	 case ALC_STEREO_SOURCES:
	    MSG("ALC_STEREO_SOURCES: %i\n", attributes[n + 1]);
	    attributes[n + 1];
	    break;
      }
   }

   this->wav_init_flag = true;
   return 1;

err:
   this->deinit_wav();
   return 0;
}
Esempio n. 18
0
/**
 * @brief Enables the OpenAL EFX extension.
 *
 *    @return 0 on success.
 */
static int al_enableEFX (void)
{
   /* Get general information. */
   alcGetIntegerv( al_device, ALC_MAX_AUXILIARY_SENDS, 1, &al_info.efx_auxSends );
   alcGetIntegerv( al_device, ALC_EFX_MAJOR_VERSION, 1, &al_info.efx_major );
   alcGetIntegerv( al_device, ALC_EFX_MINOR_VERSION, 1, &al_info.efx_minor );

   /* Get function pointers. */
   nalGenAuxiliaryEffectSlots  = alGetProcAddress( "alGenAuxiliaryEffectSlots" );
   nalDeleteAuxiliaryEffectSlots = alGetProcAddress( "alDeleteAuxiliaryEffectSlots" );
   nalIsAuxiliaryEffectSlot    = alGetProcAddress( "alIsAuxiliaryEffectSlot" );
   nalAuxiliaryEffectSloti     = alGetProcAddress( "alAuxiliaryEffectSloti" );
   nalAuxiliaryEffectSlotiv    = alGetProcAddress( "alAuxiliaryEffectSlotiv" );
   nalAuxiliaryEffectSlotf     = alGetProcAddress( "alAuxiliaryEffectSlotf" );
   nalAuxiliaryEffectSlotfv    = alGetProcAddress( "alAuxiliaryEffectSlotfv" );
   nalGetAuxiliaryEffectSloti  = alGetProcAddress( "alGetAuxiliaryEffectSloti" );
   nalGetAuxiliaryEffectSlotiv = alGetProcAddress( "alGetAuxiliaryEffectSlotiv" );
   nalGetAuxiliaryEffectSlotf  = alGetProcAddress( "alGetAuxiliaryEffectSlotf" );
   nalGetAuxiliaryEffectSlotfv = alGetProcAddress( "alGetAuxiliaryEffectSlotfv" );
   nalGenFilters               = alGetProcAddress( "alGenFilters" );
   nalDeleteFilters            = alGetProcAddress( "alDeleteFilters" );
   nalFilteri                  = alGetProcAddress( "alFilteri" );
   nalFilteriv                 = alGetProcAddress( "alFilteriv" );
   nalFilterf                  = alGetProcAddress( "alFilterf" );
   nalFilterfv                 = alGetProcAddress( "alFilterfv" );
   nalGenEffects               = alGetProcAddress( "alGenEffects" );
   nalDeleteEffects            = alGetProcAddress( "alDeleteEffects" );
   nalEffecti                  = alGetProcAddress( "alEffecti" );
   nalEffectiv                 = alGetProcAddress( "alEffectiv" );
   nalEffectf                  = alGetProcAddress( "alEffectf" );
   nalEffectfv                 = alGetProcAddress( "alEffectfv" );
   if (!nalGenAuxiliaryEffectSlots || !nalDeleteAuxiliaryEffectSlots ||
         !nalIsAuxiliaryEffectSlot ||
         !nalAuxiliaryEffectSloti || !nalAuxiliaryEffectSlotiv ||
         !nalAuxiliaryEffectSlotf || !nalAuxiliaryEffectSlotfv ||
         !nalGetAuxiliaryEffectSloti || !nalGetAuxiliaryEffectSlotiv ||
         !nalGetAuxiliaryEffectSlotf || !nalGetAuxiliaryEffectSlotfv ||
         !nalGenFilters || !nalDeleteFilters ||
         !nalFilteri || !nalFilteriv || !nalFilterf || !nalFilterfv ||
         !nalGenEffects || !nalDeleteEffects ||
         !nalEffecti || !nalEffectiv || !nalEffectf || !nalEffectfv) {
      DEBUG("OpenAL EFX functions not found, disabling EFX.");
      al_info.efx = AL_FALSE;
      return -1;
   }

   /* Create auxiliary slot. */
   nalGenAuxiliaryEffectSlots( 1, &efx_directSlot );

   /* Create reverb effect. */
   nalGenEffects( 1, &efx_reverb );
   nalEffecti( efx_reverb, AL_EFFECT_TYPE, AL_EFFECT_REVERB );
   if(alGetError() != AL_NO_ERROR) {
      DEBUG("OpenAL Reverb not found, disabling.");
      al_info.efx_reverb = AL_FALSE;
      nalDeleteEffects( 1, &efx_reverb );
   }
   else {
      al_info.efx_reverb = AL_TRUE;

      /* Set Reverb parameters. */
      /*nalEffectf( efx_reverb, AL_REVERB_DECAY_TIME, 15. );*/
   }

   /* Create echo effect. */
   nalGenEffects( 1, &efx_echo );
   nalEffecti( efx_echo, AL_EFFECT_TYPE, AL_EFFECT_ECHO );
   if(alGetError() != AL_NO_ERROR) {
      DEBUG("OpenAL Echo not found, disabling.");
      al_info.efx_echo = AL_FALSE;
      nalDeleteEffects( 1, &efx_echo );
   }
   else {
      al_info.efx_echo = AL_TRUE;

      /* Set Echo parameters. */
      nalEffectf( efx_echo, AL_ECHO_DELAY, 0.207 );
   }

   /* Set up the listener. */
   alListenerf( AL_METERS_PER_UNIT, 5. );

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

   return 0;
}
Esempio n. 19
0
//----------------------------------------------------------------------------//
SoundDevices::SoundDevices()
{
	ALDEVICEINFO	ALDeviceInfo;
	char *devices;
	int index;
	const char *defaultDeviceName;
	const char *actualDeviceName;

	// DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
	vDeviceInfo.empty();
	vDeviceInfo.reserve(10);

	defaultDeviceIndex = 0;

	// grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices

	if (alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) 
	{
		devices = (char *)alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
		defaultDeviceName = (char *)alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
		index = 0;
		// go through device list (each device terminated with a single nullptr, list terminated with double nullptr)
		while (devices != nullptr) 
		{
			if (strcmp(defaultDeviceName, devices) == 0) 
			{
				defaultDeviceIndex = index;
			}
			ALCdevice *device = alcOpenDevice(devices);
			if (device) {
				ALCcontext *context = alcCreateContext(device, nullptr);
				if (context) {
					alcMakeContextCurrent(context);
					// if new actual device name isn't already in the list, then add it...
					actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
					bool bNewName = (getDeviceIndex(actualDeviceName) < 0);
					if ((bNewName) && (actualDeviceName != nullptr) && (strlen(actualDeviceName) > 0)) {
						memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO));
						ALDeviceInfo.bSelected = true;
						ALDeviceInfo.strDeviceName = actualDeviceName;
						alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
						alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);

						ALDeviceInfo.pvstrExtensions = new std::vector<Ogre::String>;

						// Check for ALC Extensions
						if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
						if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");

						// Check for AL Extensions
						if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");

						if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
						if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
						
						if (alIsExtensionPresent("EAX2.0") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
						if (alIsExtensionPresent("EAX3.0") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
						if (alIsExtensionPresent("EAX4.0") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
						if (alIsExtensionPresent("EAX5.0") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");

						if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
							ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");

						// Get Source Count
						ALDeviceInfo.uiSourceCount = getMaxNumSources();

						vDeviceInfo.push_back(ALDeviceInfo);
					}
					alcMakeContextCurrent(nullptr);
					alcDestroyContext(context);
				}
				alcCloseDevice(device);
			}
			devices += strlen(devices) + 1;
			index += 1;
		}
	}

	resetFilters();
}
Esempio n. 20
0
// initializes hardware device from perferred/default/enumerated list
bool openal_init_device(SCP_string *playback, SCP_string *capture)
{
	if ( !Playback_device.empty() ) {
		if (playback) {
			*playback = Playback_device;
		}

		if (capture) {
			*capture = Capture_device;
		}

		return true;
	}

	if (playback) {
		playback->erase();
	}

	if (capture) {
		capture->erase();
	}

	// initialize default setup first, for version check...

	ALCdevice *device = alcOpenDevice(NULL);

	if (device == NULL) {
		return false;
	}

	ALCcontext *context = alcCreateContext(device, NULL);

	if (context == NULL) {
		alcCloseDevice(device);
		return false;
	}

	alcMakeContextCurrent(context);

	// version check (for 1.0 or 1.1)
	ALCint AL_minor_version = 0;
	alcGetIntegerv(NULL, ALC_MINOR_VERSION, sizeof(ALCint), &AL_minor_version);

	if (AL_minor_version < 1) {
		os::dialogs::Message(os::dialogs::MESSAGEBOX_ERROR,
			"OpenAL 1.1 or newer is required for proper operation. On Linux and Windows OpenAL Soft is recommended. If you are on Mac OS X you need to upgrade your OS.");

		alcMakeContextCurrent(NULL);
		alcDestroyContext(context);
		alcCloseDevice(device);

		return false;
	}

	alcGetError(device);

	// close default device
	alcMakeContextCurrent(NULL);
	alcDestroyContext(context);
	alcCloseDevice(device);


	// go through and find out what devices we actually want to use ...
	find_playback_device();
	find_capture_device();

	if ( Playback_device.empty() ) {
		return false;
	}


#ifndef NDEBUG
	if ( !PlaybackDevices.empty() ) {
		nprintf(("OpenAL", "  Available Playback Devices:\n"));

		for (size_t idx = 0; idx < PlaybackDevices.size(); idx++) {
			nprintf(("OpenAL", "    %s", PlaybackDevices[idx].device_name.c_str()));

			if (PlaybackDevices[idx].type == OAL_DEVICE_USER) {
				nprintf(("OpenAL", "  *preferred*\n"));
			} else if (PlaybackDevices[idx].type == OAL_DEVICE_DEFAULT) {
				nprintf(("OpenAL", "  *default*\n"));
			} else {
				nprintf(("OpenAL", "\n"));
			}
		}
	}

	if ( !CaptureDevices.empty() ) {
		if ( !PlaybackDevices.empty() ) {
			nprintf(("OpenAL", "\n"));
		}

		nprintf(("OpenAL", "  Available Capture Devices:\n"));

		for (size_t idx = 0; idx < CaptureDevices.size(); idx++) {
			nprintf(("OpenAL", "    %s", CaptureDevices[idx].device_name.c_str()));

			if (CaptureDevices[idx].type == OAL_DEVICE_USER) {
				nprintf(("OpenAL", "  *preferred*\n"));
			} else if (CaptureDevices[idx].type == OAL_DEVICE_DEFAULT) {
				nprintf(("OpenAL", "  *default*\n"));
			} else {
				nprintf(("OpenAL", "\n"));
			}
		}

		nprintf(("OpenAL", "\n"));
	}
#endif


	// cleanup
	PlaybackDevices.clear();
	CaptureDevices.clear();


	if (playback) {
		*playback = Playback_device;
	}

	if (capture) {
		*capture = Capture_device;
	}

	return true;
}