コード例 #1
0
ファイル: audio_output.cpp プロジェクト: GiR-Zippo/bino
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;
    }
}
コード例 #2
0
ファイル: AudioController.cpp プロジェクト: jsethi/GamePlay
void AudioController::initialize()
{
#ifndef __ANDROID__
    _alcDevice = alcOpenDevice (NULL);
    if (!_alcDevice)
    {
        LOG_ERROR("AudioController::initialize() error. Unable to open OpenAL device.\n");
        return;  
    }
        
    _alcContext = alcCreateContext(_alcDevice, NULL);
    ALCenum alcErr = alcGetError(_alcDevice);
    if (!_alcContext || alcErr != ALC_NO_ERROR)
    {
        alcCloseDevice (_alcDevice);
        LOG_ERROR_VARG("AudioController::initialize() error. Unable to create OpenAL context. Error: %d\n", alcErr);
        return;
    }
    
    alcMakeContextCurrent(_alcContext);
    alcErr = alcGetError(_alcDevice);
    if (alcErr != ALC_NO_ERROR)
    {
        LOG_ERROR_VARG("AudioController::initialize() error. Unable to make OpenAL context current. Error: %d\n", alcErr);
    }
#else
    // Create the engine.
    SLresult result = slCreateEngine(&_engineObject, 0, NULL, 0, NULL, NULL);
    if (result != SL_RESULT_SUCCESS)
    {
        LOG_ERROR("AudioController::initialize() error. Unable to create OpenSL engine.");
        return;
    }

    // Realize the engine.
    result = (*_engineObject)->Realize(_engineObject, SL_BOOLEAN_FALSE);
    if (result != SL_RESULT_SUCCESS)
    {
        LOG_ERROR("AudioController::initialize() error. Unable to realize OpenSL engine.");
        return;
    }

    // Get the engine interface in order to create other objects later on.
    result = (*_engineObject)->GetInterface(_engineObject, SL_IID_ENGINE, &_engineEngine);
    if (result != SL_RESULT_SUCCESS)
    {
        LOG_ERROR("AudioController::initialize() error. Unable to retrieve OpenSL engine interface.");
        return;
    }

    // Create the output mix.
    result = (*_engineEngine)->CreateOutputMix(_engineEngine, &_outputMixObject, 0, NULL, NULL);
    if (result != SL_RESULT_SUCCESS)
    {
        LOG_ERROR("AudioController::initialize() error. Unable to create OpenSL output mix.");
        return;
    }

    // Realize the output mix.
    result = (*_outputMixObject)->Realize(_outputMixObject, SL_BOOLEAN_FALSE);
    if (result != SL_RESULT_SUCCESS)
    {
        LOG_ERROR("AudioController::initialize() error. Unable to realize OpenSL output mix.");
        return;
    }
#endif
}
コード例 #3
0
  Sound_Renderer_AL::Sound_Renderer_AL()
    : m_device(0),
    m_context(0),
    m_bgm(0),
    m_bgm_source(0)
  {
#ifndef _MACOSX
#ifdef _WINDOWS
    m_openal32 = LoadLibrary("OpenAL32.dll");
#else
    m_openal32 = LoadLibrary("libopenal.so");
    if(!m_openal32)
      m_openal32 = LoadLibrary("libopenal.so.1");
#endif
    if(!m_openal32) {
      std::cerr << "Loading OpenAL32.dll failed." << std::endl;

      throw Sound_Init_Failure();
    }

    g_alBufferData = (alBufferData_fcn)GetProcAddress(m_openal32, "alBufferData");
    g_alcCloseDevice = (alcCloseDevice_fcn)GetProcAddress(m_openal32, "alcCloseDevice");
    g_alcCreateContext = (alcCreateContext_fcn)GetProcAddress(m_openal32, "alcCreateContext");
    g_alcDestroyContext = (alcDestroyContext_fcn)GetProcAddress(m_openal32, "alcDestroyContext");
    g_alIsExtensionPresent = (alIsExtensionPresent_fcn)GetProcAddress(m_openal32, "alIsExtensionPresent");
    g_alcMakeContextCurrent = (alcMakeContextCurrent_fcn)GetProcAddress(m_openal32, "alcMakeContextCurrent");
    g_alcOpenDevice = (alcOpenDevice_fcn)GetProcAddress(m_openal32, "alcOpenDevice");
    g_alDeleteBuffers = (alDeleteBuffers_fcn)GetProcAddress(m_openal32, "alDeleteBuffers");
    g_alDeleteSources = (alDeleteSources_fcn)GetProcAddress(m_openal32, "alDeleteSources");
    g_alGenBuffers = (alGenBuffers_fcn)GetProcAddress(m_openal32, "alGenBuffers");
    g_alGetError = (alGetError_fcn)GetProcAddress(m_openal32, "alGetError");
    g_alGetListenerf = (alGetListenerf_fcn)GetProcAddress(m_openal32, "alGetListenerf");
    g_alGetListenerfv = (alGetListenerfv_fcn)GetProcAddress(m_openal32, "alGetListenerfv");
    g_alGetSourcef = (alGetSourcef_fcn)GetProcAddress(m_openal32, "alGetSourcef");
    g_alGetSourcefv = (alGetSourcefv_fcn)GetProcAddress(m_openal32, "alGetSourcefv");
    g_alGetSourcei = (alGetSourcei_fcn)GetProcAddress(m_openal32, "alGetSourcei");
    g_alGenSources = (alGenSources_fcn)GetProcAddress(m_openal32, "alGenSources");
    g_alListenerf = (alListenerf_fcn)GetProcAddress(m_openal32, "alListenerf");
    g_alListenerfv = (alListenerfv_fcn)GetProcAddress(m_openal32, "alListenerfv");
    g_alSourcef = (alSourcef_fcn)GetProcAddress(m_openal32, "alSourcef");
    g_alSourcefv = (alSourcefv_fcn)GetProcAddress(m_openal32, "alSourcefv");
    g_alSourcei = (alSourcei_fcn)GetProcAddress(m_openal32, "alSourcei");
    g_alSourcePause = (alSourcePause_fcn)GetProcAddress(m_openal32, "alSourcePause");
    g_alSourcePlay = (alSourcePlay_fcn)GetProcAddress(m_openal32, "alSourcePlay");
    g_alSourceStop = (alSourceStop_fcn)GetProcAddress(m_openal32, "alSourceStop");
    if(!g_alBufferData || !g_alcCloseDevice || !g_alcCreateContext || !g_alcDestroyContext ||
       !g_alIsExtensionPresent || !g_alcMakeContextCurrent || !g_alcOpenDevice || !g_alDeleteBuffers ||
       !g_alDeleteSources || !g_alGenBuffers || !g_alGetError || !g_alGetListenerf ||
       !g_alGetListenerfv || !g_alGetSourcef || !g_alGetSourcefv || !g_alGetSourcei ||
       !g_alGenSources || !g_alListenerf || !g_alListenerfv || !g_alSourcef ||
       !g_alSourcefv || !g_alSourcei || !g_alSourcePause || !g_alSourcePlay ||
       !g_alSourceStop)
    {
      std::cerr << "Loading OpenAL32.dll failed." << std::endl;

      zero_handles();
      FreeLibrary(m_openal32);

      throw Sound_Init_Failure();
    }
#else
    g_alBufferData = (alBufferData_fcn)::alBufferData;
    g_alcCloseDevice = (alcCloseDevice_fcn)::alcCloseDevice;
    g_alcCreateContext = (alcCreateContext_fcn)::alcCreateContext;
    g_alcDestroyContext = (alcDestroyContext_fcn)::alcDestroyContext;
    g_alIsExtensionPresent = (alIsExtensionPresent_fcn)::alIsExtensionPresent;
    g_alcMakeContextCurrent = (alcMakeContextCurrent_fcn)::alcMakeContextCurrent;
    g_alcOpenDevice = (alcOpenDevice_fcn)::alcOpenDevice;
    g_alDeleteBuffers = (alDeleteBuffers_fcn)::alDeleteBuffers;
    g_alDeleteSources = (alDeleteSources_fcn)::alDeleteSources;
    g_alGenBuffers = (alGenBuffers_fcn)::alGenBuffers;
    g_alGetError = (alGetError_fcn)::alGetError;
    g_alGetListenerf = (alGetListenerf_fcn)::alGetListenerf;
    g_alGetListenerfv = (alGetListenerfv_fcn)::alGetListenerfv;
    g_alGetSourcef = (alGetSourcef_fcn)::alGetSourcef;
    g_alGetSourcefv = (alGetSourcefv_fcn)::alGetSourcefv;
    g_alGetSourcei = (alGetSourcei_fcn)::alGetSourcei;
    g_alGenSources = (alGenSources_fcn)::alGenSources;
    g_alListenerf = (alListenerf_fcn)::alListenerf;
    g_alListenerfv = (alListenerfv_fcn)::alListenerfv;
    g_alSourcef = (alSourcef_fcn)::alSourcef;
    g_alSourcefv = (alSourcefv_fcn)::alSourcefv;
    g_alSourcei = (alSourcei_fcn)::alSourcei;
    g_alSourcePause = (alSourcePause_fcn)::alSourcePause;
    g_alSourcePlay = (alSourcePlay_fcn)::alSourcePlay;
    g_alSourceStop = (alSourceStop_fcn)::alSourceStop;
#endif

    m_device = alcOpenDevice()(0);
    if(!m_device) {
      zero_handles();
#ifndef _MACOSX
      FreeLibrary(m_openal32);
#endif

      throw Sound_Init_Failure();
    }

    m_context = alcCreateContext()(m_device, 0);
    if(!m_context) {
      alcCloseDevice()(m_device);

      zero_handles();
#ifndef _MACOSX
      FreeLibrary(m_openal32);
#endif

      throw Sound_Init_Failure();
    }

    if(!alcMakeContextCurrent()(m_context)) {
      alcDestroyContext()(m_context);
      alcCloseDevice()(m_device);

      zero_handles();
#ifndef _MACOSX
      FreeLibrary(m_openal32);
#endif

      throw Sound_Init_Failure();
    }

    // Check for Vorbis extension functionality; seems to always fail :(
    alIsExtensionPresent()("AL_EXT_vorbis");
    //cerr << "Valid Audio Formats: " << alutGetMIMETypes(ALUT_LOADER_BUFFER) << std::endl;

    ALfloat listener_position[] = {0.0f, 0.0f, 0.0f};
    ALfloat listener_velocity[] = {0.0f, 0.0f, 0.0f};
    ALfloat listener_forward_and_up[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};

    alListenerfv()(AL_POSITION, listener_position);
    alListenerfv()(AL_VELOCITY, listener_velocity);
    alListenerfv()(AL_ORIENTATION, listener_forward_and_up);
  }
コード例 #4
0
//*
// =======================================================================================================================
// =======================================================================================================================
//
bool sound_InitLibrary(void)
{
	int err;
	const ALfloat listenerVel[3] = { 0.0, 0.0, 0.0 };
	const ALfloat listenerOri[6] = { 0.0, 0.0, 1.0, 0.0, 1.0, 0.0 };
	char buf[512];
	const ALCchar *deviceName;

#if 0
	// This code is disabled because enumerating devices apparently crashes PulseAudio on Fedora12

	/* Get the available devices and print them.
	 * Devices are separated by NUL chars ('\0') and the list of devices is
	 * terminated by two NUL chars.
	 */
	deviceName = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
	while (deviceName != NULL && *deviceName != '\0')
	{
		debug(LOG_SOUND, "available OpenAL device(s) are: %s", deviceName);
		deviceName += strlen(deviceName) + 1;
	}
#endif

#ifdef WZ_OS_WIN
	/* HACK: Select the "software" OpenAL device on Windows because it
	 *       provides 256 sound sources (unlike most Creative's default
	 *       which provides only 16), causing our lack of source-management
	 *       to be significantly less noticeable.
	 */
	device = alcOpenDevice("Generic Software");

	// If the software device isn't available, fall back to default
	if (!device)
#endif
	{
		// Open default device
		device = alcOpenDevice(nullptr);
	}

	if (!device)
	{
		debug(LOG_ERROR, "Couldn't open audio device.");
		return false;
	}

	// Print current device name and add it to dump info
	deviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
	debug(LOG_SOUND, "Current audio device: %s", deviceName);
	ssprintf(buf, "OpenAL Device Name: %s", deviceName);
	addDumpInfo(buf);

	context = alcCreateContext(device, nullptr);		//NULL was contextAttributes
	if (!context)
	{
		debug(LOG_ERROR, "Couldn't open audio context.");
		return false;
	}

	alcMakeContextCurrent(context);

	err = sound_GetContextError(device);
	if (err != ALC_NO_ERROR)
	{
		debug(LOG_ERROR, "Couldn't initialize audio context: %s", alcGetString(device, err));
		return false;
	}

	// Dump Open AL device info (depends on context)
	// to the crash handler for the dump file and debug log
	ssprintf(buf, "OpenAL Vendor: %s", alGetString(AL_VENDOR));
	addDumpInfo(buf);
	debug(LOG_SOUND, "%s", buf);

	ssprintf(buf, "OpenAL Version: %s", alGetString(AL_VERSION));
	addDumpInfo(buf);
	debug(LOG_SOUND, "%s", buf);

	ssprintf(buf, "OpenAL Renderer: %s", alGetString(AL_RENDERER));
	addDumpInfo(buf);
	debug(LOG_SOUND, "%s", buf);

	ssprintf(buf, "OpenAL Extensions: %s", alGetString(AL_EXTENSIONS));
	addDumpInfo(buf);
	debug(LOG_SOUND, "%s", buf);

	openal_initialized = true;

	// Clear Error Codes
	alGetError();
	alcGetError(device);

	alListener3f(AL_POSITION, 0.f, 0.f, 0.f);
	alListenerfv(AL_VELOCITY, listenerVel);
	alListenerfv(AL_ORIENTATION, listenerOri);
	alDistanceModel(AL_NONE);
	sound_GetError();

	return true;
}
コード例 #5
0
ファイル: audio.cpp プロジェクト: Alber70g/tdesktop
void audioInit() {
	if (audioDevice) return;

	audioDevice = alcOpenDevice(NULL);
	if (!audioDevice) {
		LOG(("Audio Error: default sound device not present."));
		return;
	}
	
	ALCint attributes[] = { ALC_STEREO_SOURCES, 8, 0 };
	audioContext = alcCreateContext(audioDevice, attributes);
	alcMakeContextCurrent(audioContext);
	if (!_checkALCError()) return audioFinish();

	ALfloat v[] = { 0.f, 0.f, -1.f, 0.f, 1.f, 0.f };
	alListener3f(AL_POSITION, 0.f, 0.f, 0.f);
	alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f);
	alListenerfv(AL_ORIENTATION, v);

	alDistanceModel(AL_NONE);

	alGenSources(1, &notifySource);
	alSourcef(notifySource, AL_PITCH, 1.f);
	alSourcef(notifySource, AL_GAIN, 1.f);
	alSource3f(notifySource, AL_POSITION, 0, 0, 0);
	alSource3f(notifySource, AL_VELOCITY, 0, 0, 0);
	alSourcei(notifySource, AL_LOOPING, 0);

	alGenBuffers(1, &notifyBuffer);
	if (!_checkALError()) return audioFinish();

	QFile notify(st::newMsgSound);
	if (!notify.open(QIODevice::ReadOnly)) return audioFinish();

	QByteArray blob = notify.readAll();
	const char *data = blob.constData();
	if (blob.size() < 44) return audioFinish();

	if (*((const uint32*)(data + 0)) != 0x46464952) return audioFinish(); // ChunkID - "RIFF"
	if (*((const uint32*)(data + 4)) != uint32(blob.size() - 8)) return audioFinish(); // ChunkSize
	if (*((const uint32*)(data + 8)) != 0x45564157) return audioFinish(); // Format - "WAVE"
	if (*((const uint32*)(data + 12)) != 0x20746d66) return audioFinish(); // Subchunk1ID - "fmt "
	uint32 subchunk1Size = *((const uint32*)(data + 16)), extra = subchunk1Size - 16;
	if (subchunk1Size < 16 || (extra && extra < 2)) return audioFinish();
	if (*((const uint16*)(data + 20)) != 1) return audioFinish(); // AudioFormat - PCM (1)

	uint16 numChannels = *((const uint16*)(data + 22));
	if (numChannels != 1 && numChannels != 2) return audioFinish();

	uint32 sampleRate = *((const uint32*)(data + 24));
	uint32 byteRate = *((const uint32*)(data + 28));

	uint16 blockAlign = *((const uint16*)(data + 32));
	uint16 bitsPerSample = *((const uint16*)(data + 34));
	if (bitsPerSample % 8) return audioFinish();
	uint16 bytesPerSample = bitsPerSample / 8;
	if (bytesPerSample != 1 && bytesPerSample != 2) return audioFinish();

	if (blockAlign != numChannels * bytesPerSample) return audioFinish();
	if (byteRate != sampleRate * blockAlign) return audioFinish();

	if (extra) {
		uint16 extraSize = *((const uint16*)(data + 36));
        if (uint32(extraSize + 2) != extra) return audioFinish();
		if (uint32(blob.size()) < 44 + extra) return audioFinish();
	}

	if (*((const uint32*)(data + extra + 36)) != 0x61746164) return audioFinish(); // Subchunk2ID - "data"
	uint32 subchunk2Size = *((const uint32*)(data + extra + 40));
	if (subchunk2Size % (numChannels * bytesPerSample)) return audioFinish();
	uint32 numSamples = subchunk2Size / (numChannels * bytesPerSample);

	if (uint32(blob.size()) < 44 + extra + subchunk2Size) return audioFinish();
	data += 44 + extra;

	ALenum format = 0;
	switch (bytesPerSample) {
	case 1:
		switch (numChannels) {
		case 1: format = AL_FORMAT_MONO8; break;
		case 2: format = AL_FORMAT_STEREO8; break;
		}
	break;

	case 2:
		switch (numChannels) {
		case 1: format = AL_FORMAT_MONO16; break;
		case 2: format = AL_FORMAT_STEREO16; break;
		}
	break;
	}
	if (!format) return audioFinish();

	alBufferData(notifyBuffer, format, data, subchunk2Size, sampleRate);
	alSourcei(notifySource, AL_BUFFER, notifyBuffer);
	if (!_checkALError()) return audioFinish();

	voicemsgs = new VoiceMessages();
}
コード例 #6
0
ファイル: SoundDevices.cpp プロジェクト: drwbns/1stperson
//----------------------------------------------------------------------------//
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();
}
コード例 #7
0
ファイル: testvorbis.c プロジェクト: Aye1/RVProject
int main( int argc, char* argv[] ) {
	ALCdevice *dev;
	FILE *fh;
	struct stat sbuf;
	void *data;
	char *fname;
	int size;
	int i = 0;

	dev = alcOpenDevice( NULL );
	if( dev == NULL ) {
		return 1;
	}

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

		return 1;
	}

	alcMakeContextCurrent( context_id );

	fixup_function_pointers();

	init( );

	if(argc == 1) {
		fname = VORBIS_FILE;
	} else {
		fname = argv[1];
	}

	if(stat(fname, &sbuf) == -1) {
		perror(fname);
		return errno;
	}

	size = sbuf.st_size;
	data = malloc(size);
	if(data == NULL) {
		exit(1);
	}

	fh = fopen(fname, "rb");
	if(fh == NULL) {
		fprintf(stderr, "Could not open %s\n", fname);

		free(data);

		exit(1);
	}

	fread(data, size, 1, fh);

	alutLoadVorbisp = (vorbisLoader *) alGetProcAddress((ALubyte *) VORBIS_FUNC);
	if(alutLoadVorbisp == NULL) {
		free(data);

		fprintf(stderr, "Could not GetProc %s\n",
			(ALubyte *) VORBIS_FUNC);
		exit(-4);
	}

	if(alutLoadVorbisp(vorbbuf, data, size) != AL_TRUE) {
		fprintf(stderr, "alutLoadVorbis failed\n");
		exit(-2);
	}

	free(data);

	alSourcePlay( vorbsource );

	while(SourceIsPlaying(vorbsource) == AL_TRUE) {
		sleep(1);
	}

	cleanup();

	alcCloseDevice( dev );

	return 0;
}
コード例 #8
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;
}
コード例 #9
0
ファイル: OpenAL.cpp プロジェクト: Ardakaniz/NazaraEngine
	bool OpenAL::OpenDevice()
	{
		// Initialisation of the module
		s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // We choose the default device
		if (!s_device)
		{
			NazaraError("Failed to open default device");
			return false;
		}

		// One context is enough
		s_context = alcCreateContext(s_device, nullptr);
		if (!s_context)
		{
			NazaraError("Failed to create context");
			return false;
		}

		if (!alcMakeContextCurrent(s_context))
		{
			NazaraError("Failed to activate context");
			return false;
		}

		s_rendererName = reinterpret_cast<const char*>(alGetString(AL_RENDERER));
		s_vendorName = reinterpret_cast<const char*>(alGetString(AL_VENDOR));

		const ALchar* version = alGetString(AL_VERSION);
		if (version)
		{
			unsigned int major = version[0] - '0';
			unsigned int minor = version[2] - '0';

			if (major != 0 && major <= 9)
			{
				if (minor > 9)
				{
					NazaraWarning("Unable to retrieve OpenAL minor version (using 0)");
					minor = 0;
				}

				s_version = major*100 + minor*10;

				NazaraDebug("OpenAL version: " + String::Number(major) + '.' + String::Number(minor));
			}
			else
			{
				NazaraDebug("Unable to retrieve OpenAL major version");
				s_version = 0;
			}
		}
		else
		{
			NazaraDebug("Unable to retrieve OpenAL version");
			s_version = 0;
		}

		// We complete the formats table
		AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16;
		AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16;

		// "The presence of an enum value does not guarantee the applicability of an extension to the current context."
		if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
		{
			AudioFormat[AudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16");
			AudioFormat[AudioFormat_5_1]  = alGetEnumValue("AL_FORMAT_51CHN16");
			AudioFormat[AudioFormat_6_1]  = alGetEnumValue("AL_FORMAT_61CHN16");
			AudioFormat[AudioFormat_7_1]  = alGetEnumValue("AL_FORMAT_71CHN16");
		}
		else if (alIsExtensionPresent("AL_LOKI_quadriphonic"))
			AudioFormat[AudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16_LOKI");

		return true;
	}
コード例 #10
0
ファイル: sound.cpp プロジェクト: amanjainhiman/cylindrix
void SYS_InitSound()
{
	
#ifdef SYS_SOUNDDEBUG
	soundsLoaded = 0;
	soundsFree = SIZEOFWAVEPOOL;
	soundLog = fopen( soundLogFileName, "w" );
	fprintf(soundLog, "SYS_InitSound() - OpenAL SKU - %d sounds in pool\n", soundsFree);
	
	if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)
	{
		const char* devicesStr = alcGetString(0, ALC_DEVICE_SPECIFIER);
		const char* defaultDeviceStr = alcGetString(0, ALC_DEFAULT_DEVICE_SPECIFIER);
		fprintf(soundLog, "OpenAL default device = %s\n", defaultDeviceStr);
		
		fprintf(soundLog, "All devices:\n");
		const char* p = devicesStr;
		while( *p )
		{
			fprintf(soundLog, "%s\n", p);
			p += (strlen(p) + 1);
		}
	}
#endif

	// open device
	ALCdevice* device = alcOpenDevice(0);
	if ( !device )
	{
		SYS_Error("Error opening OpenAL device\n");
		return;
	}
	
#ifdef SYS_SOUNDDEBUG
	const char* extStr = alcGetString(device, ALC_EXTENSIONS);
	fprintf(soundLog, "OpenAL extentions : %s\n", extStr);
#endif

	alGetError(); // clear error code

	// create context
	ALCcontext* context = alcCreateContext(device,0);
	alcMakeContextCurrent(context);
	CheckForErrors();
	
	// use linear distance model & disable doppler.
	alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
	alDopplerFactor(0.0f);

	// init wave pools
	memset(wavePool, 0, sizeof(struct SYS_Wave) * SIZEOFWAVEPOOL);
	freeList = wavePool;
	usedList = 0;
	for ( int i = 0; i < SIZEOFWAVEPOOL; ++i )
	{
		freeList[i].prev = (i == 0) ? 0 : &wavePool[i-1];
		freeList[i].next = (i == SIZEOFWAVEPOOL-1) ? 0 : &wavePool[i+1];
	}

	// init source pool
	memset(sourcePool, 0, sizeof(ALuint) * SIZEOFSOURCEPOOL);
	CheckForErrors();
	
	int error = mpg123_init();
	if (error != MPG123_OK)
	{
		printf("Error mpg123_init() : %s\n", mpg123_plain_strerror(error));
	}
}
コード例 #11
0
bool fsLowLevelAPI::openSoundDevice(u8 channel_num, u16 sample_rate, u16 snd_mix_buf_msec, SoundMixFunction snd_mix_func)
{
	fprintf(stderr,"channel_num %d sample_rate %d snd_mix_buf_mse %d \n",channel_num, sample_rate, snd_mix_buf_msec);
    if (isSoundDeviceOpen())
    {
        closeSoundDevice();
    }

    pthread_mutex_init(&s_snd_mix_mutex, NULL);

    s_snd_mix_func =  snd_mix_func;

	m_pAudioDevice = alcOpenDevice(NULL);

	if (m_pAudioDevice)
	{
		m_pAlcContext = alcCreateContext(m_pAudioDevice, NULL);
		alcMakeContextCurrent(m_pAlcContext);
	}

	ALenum err = alGetError();
	if (err != AL_NO_ERROR)
	{
		return false;
	}

	alGenSources(1, &m_AudioSource);
	alGenBuffers(BUFFER_COUNT, m_AudioBuffers);
    s_channel_num = channel_num;
    s_sample_rate = sample_rate;
    s_snd_mix_buf_msec = snd_mix_buf_msec;

	s_snd_mix_buf_sample_num = sample_rate * snd_mix_buf_msec / 1000;
	s_bits_per_sample = 16;

    if (s_channel_num != 1 && s_channel_num != 2)
    {
        return false;
    }
	
	switch (s_bits_per_sample){
	case 8:
		m_AudioFormat = (channel_num == 1) ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8;
		break;
	case 16:
		m_AudioFormat = (channel_num == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
		break;
	default:
		return 0;
	}
	//	m_AudioFormat = AL_FORMAT_STEREO16;
	s_snd_mix_buf_size = 2 * s_channel_num * s_snd_mix_buf_sample_num;
	/*for (s32 i = 0; i < 2; i++)
	  {
	  s_snd_mix_buf[i] = ckMalloc(s_snd_mix_buf_size);
	  ckMemMgr::memset(s_snd_mix_buf[i], 0, s_snd_mix_buf_size);
	  }*/
	buf = fsMalloc(s_snd_mix_buf_size);
	s_snd_mix_buf = fsMalloc(s_snd_mix_buf_size*2);
	//alGenBuffers(BUFFER_COUNT, m_AudioBuffers);
	//alGenSources(1, &m_AudioSource);
	//alSourcePlay(m_AudioSource);

	s_is_playing = true;
	if (pthread_create(&s_snd_play_thread, NULL, soundPlayThread, NULL) != 0)
	{
		s_is_playing = false;
		closeSoundDevice();
		return false;
	}

//    if (pthread_create(&s_snd_play_thread, NULL, soundPlayThread, NULL) != 0)
//    {
//        s_is_playing = false;
//        closeSoundDevice();
//        return false;
//    }
//
    s_is_snd_dev_open = true;

	return true;
}
コード例 #12
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
}
コード例 #13
0
ファイル: openal_audio.cpp プロジェクト: brianV/7kaa
// 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;
}
コード例 #14
0
int main( int argc, char* argv[] ) {
	ALCdevice *dev;
	time_t shouldend;
	int attrlist[] = { ALC_FREQUENCY, DEFFREQ,
			   ALC_INVALID };
	char *musicitr = musicstr;
	ALfloat pitch = 1.0;
	int beats;
	char note;
	int i;
	
	dev = alcOpenDevice( NULL );
	if( dev == NULL ) {
		return 1;
	}

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

		return 1;
	}

	alcMakeContextCurrent( cc );

	fixup_function_pointers();

	if(argc == 1) {
		init(WAVEFILE);
	} else {
		init(argv[1]);
	}

	while(*musicitr) {
		alSourceStop( chords[0] );
		alSourceStop( chords[1] );
		alSourceStop( chords[2] );

		while(*musicitr == ' ') {
			musicitr++;
		}

		for(i = 0; i < 3; i++) {
			switch(*musicitr) {
				case 'c': pitch = 0.500010; break;
				case 'd': pitch = 0.561223; break;
				case 'e': pitch = 0.629967; break;
				case 'f': pitch = 0.667425; break;
				case 'g': pitch = 0.749164; break;
				case 'a': pitch = 0.840898; break;
				case 'b': pitch = 0.943870; break;
				case 'C': pitch = 1.0; break;
				case 'D': pitch = 1.122465; break;
				case 'E': pitch = 1.259933; break;
				case 'F': pitch = 1.339704; break;
				case 'G': pitch = 1.498309; break;
				case 'A': pitch = 1.681796; break;
				case 'B': pitch = 1.897754; break;
				default:
					fprintf(stderr, "unknown note %d\n", *musicitr); break;
			}

			note = *musicitr;
			musicitr++; /* skip note */

			fprintf(stderr, "chord[%d] = %c\n", i, note);

			alSourcef(chords[i], AL_PITCH, pitch);
		}

		alSourcePlayv(3, chords);

		while(*musicitr == ' ') {
			musicitr++;
		}

		beats = (int) *musicitr - '0';

		musicitr++;

		fprintf(stderr, "beats %d\n", beats);

		micro_sleep(beats / 4.0 * 1000000);
	}

	alcDestroyContext( cc );

	alcCloseDevice( dev );

	cleanup();


	return 0;
}
コード例 #15
0
int main( int argc, char* argv[] ) {
	ALCdevice *dev;
	int attrlist[] = { ALC_FREQUENCY, 44100,
			   ALC_INVALID };
	time_t shouldend;
	time_t start;
	int i;
	ALboolean done = AL_FALSE;

	dev = alcOpenDevice( NULL );
	if( dev == NULL ) {
		return 1;
	}

	/* Initialize ALUT. */
	for(i = 0; i < NUMCONTEXTS; i++) {
		context_ids[i] = alcCreateContext( dev, attrlist );
		if(context_ids[i] == NULL) {
			return 1;
		}
	}

	fixup_function_pointers();

	talBombOnError();

	if(argc == 1) {
		init("sample.wav");
	} else {
		init(argv[1]);
	}

	start = time(NULL);

	for(i = 0; i < NUMCONTEXTS; i++) {
		alcMakeContextCurrent(context_ids[i]);
		alSourcePlay( moving_sources[i] );
		sleep(1);
	}

#if 0
	while(done == AL_FALSE) {
		iterate();

		shouldend = time(NULL);
		if((shouldend - start) > 10) {
			for(i = 0; i < NUMCONTEXTS; i++) {
				alcMakeContextCurrent(context_ids[i]);
				alSourceStop(moving_sources[i]);
			}
		}

		done = AL_TRUE;
		for(i = 0; i < NUMCONTEXTS; i++) {
			alcMakeContextCurrent(context_ids[i]);
			done = done && !SourceIsPlaying( moving_sources[i] );
		}
	}
#else
	for(i = 0; i < 10; i++) {
		fprintf(stderr, "i = %d\n", i);
		sleep(1);
	}
#endif

	cleanup();

	return 0;
}
コード例 #16
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;
}
コード例 #17
0
ファイル: audio.c プロジェクト: 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");
}
コード例 #18
0
ファイル: main.cpp プロジェクト: Ancurio/mkxp-abs
int main(int argc, char *argv[])
{
	SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
//	SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");

	/* initialize SDL first */
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
	{
		showInitError(std::string("Error initializing SDL: ") + SDL_GetError());
		return 0;
	}

	if (!EventThread::allocUserEvents())
	{
		showInitError("Error allocating SDL user events");
		return 0;
	}

#ifndef WORKDIR_CURRENT
	/* set working directory */
	char *dataDir = SDL_GetBasePath();
	if (dataDir)
	{
		int result = chdir(dataDir);
		(void)result;
		SDL_free(dataDir);
	}
#endif

	/* now we load the config */
	Config conf;
	conf.read(argc, argv);

	if (!conf.gameFolder.empty())
		if (chdir(conf.gameFolder.c_str()) != 0)
		{
			showInitError(std::string("Unable to switch into gameFolder ") + conf.gameFolder);
			return 0;
		}

	conf.readGameINI();

	if (conf.windowTitle.empty())
		conf.windowTitle = conf.game.title;

	assert(conf.rgssVersion >= 1 && conf.rgssVersion <= 3);
	printRgssVersion(conf.rgssVersion);

	int imgFlags = IMG_INIT_PNG | IMG_INIT_JPG;
	if (IMG_Init(imgFlags) != imgFlags)
	{
		showInitError(std::string("Error initializing SDL_image: ") + SDL_GetError());
		SDL_Quit();

		return 0;
	}

	if (TTF_Init() < 0)
	{
		showInitError(std::string("Error initializing SDL_ttf: ") + SDL_GetError());
		IMG_Quit();
		SDL_Quit();

		return 0;
	}

	if (Sound_Init() == 0)
	{
		showInitError(std::string("Error initializing SDL_sound: ") + Sound_GetError());
		TTF_Quit();
		IMG_Quit();
		SDL_Quit();

		return 0;
	}

	SDL_Window *win;
	Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_FOCUS;

	if (conf.winResizable)
		winFlags |= SDL_WINDOW_RESIZABLE;
	if (conf.fullscreen)
		winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;

	win = SDL_CreateWindow(conf.windowTitle.c_str(),
	                       SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
	                       conf.defScreenW, conf.defScreenH, winFlags);

	if (!win)
	{
		showInitError(std::string("Error creating window: ") + SDL_GetError());
		return 0;
	}

	/* OSX and Windows have their own native ways of
	 * dealing with icons; don't interfere with them */
#ifdef __LINUX__
	setupWindowIcon(conf, win);
#else
	(void) setupWindowIcon;
#endif

	ALCdevice *alcDev = alcOpenDevice(0);

	if (!alcDev)
	{
		showInitError("Error opening OpenAL device");
		SDL_DestroyWindow(win);
		TTF_Quit();
		IMG_Quit();
		SDL_Quit();

		return 0;
	}

	SDL_DisplayMode mode;
	SDL_GetDisplayMode(0, 0, &mode);

	/* Can't sync to display refresh rate if its value is unknown */
	if (!mode.refresh_rate)
		conf.syncToRefreshrate = false;

	EventThread eventThread;
	RGSSThreadData rtData(&eventThread, argv[0], win,
	                      alcDev, mode.refresh_rate, conf);

	int winW, winH;
	SDL_GetWindowSize(win, &winW, &winH);
	rtData.windowSizeMsg.post(Vec2i(winW, winH));

	/* Load and post key bindings */
	rtData.bindingUpdateMsg.post(loadBindings(conf));

	/* Start RGSS thread */
	SDL_Thread *rgssThread =
	        SDL_CreateThread(rgssThreadFun, "rgss", &rtData);

	/* Start event processing */
	eventThread.process(rtData);

	/* Request RGSS thread to stop */
	rtData.rqTerm.set();

	/* Wait for RGSS thread response */
	for (int i = 0; i < 1000; ++i)
	{
		/* We can stop waiting when the request was ack'd */
		if (rtData.rqTermAck)
		{
			Debug() << "RGSS thread ack'd request after" << i*10 << "ms";
			break;
		}

		/* Give RGSS thread some time to respond */
		SDL_Delay(10);
	}

	/* If RGSS thread ack'd request, wait for it to shutdown,
	 * otherwise abandon hope and just end the process as is. */
	if (rtData.rqTermAck)
		SDL_WaitThread(rgssThread, 0);
	else
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(),
		                         "The RGSS script seems to be stuck and mkxp will now force quit", win);

	if (!rtData.rgssErrorMsg.empty())
	{
		Debug() << rtData.rgssErrorMsg;
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(),
		                         rtData.rgssErrorMsg.c_str(), win);
	}

	/* Clean up any remainin events */
	eventThread.cleanup();

	Debug() << "Shutting down.";

	alcCloseDevice(alcDev);
	SDL_DestroyWindow(win);

	Sound_Quit();
	TTF_Quit();
	IMG_Quit();
	SDL_Quit();

	return 0;
}
コード例 #19
0
ファイル: OAL_Device.cpp プロジェクト: HyperEye/OALWrapper
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;
}
コード例 #20
0
ファイル: phone.c プロジェクト: AllanDaemon/ProjectTox-Core
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 );
}
コード例 #21
0
ファイル: haudio.c プロジェクト: galexcode/OpenCraft
void Audio_Init(void)
{
	device = alcOpenDevice(NULL);
	context = alcCreateContext(device, NULL);
	alcMakeContextCurrent(context);
}
コード例 #22
0
ファイル: device.c プロジェクト: fars/toxic
// TODO: generate buffers separately
DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx)
{
    if (size[type] <= selection || selection < 0) return de_InvalidSelection;
    
    lock;
    
    uint32_t i;
    for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; i ++);
    
    if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; }
    else *device_idx = i;
    
    Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));;
    device->selection = selection;
    
    for (i = 0; i < *device_idx; i ++) { /* Check if any previous has the same selection */
        if ( running[type][i]->selection == selection ) {
            device->dhndl = running[type][i]->dhndl;
            if (type == output) {
                device->ctx = running[type][i]->ctx;
                memcpy(device->buffers, running[type][i]->buffers, sizeof(running[type][i]->buffers));
                device->source = running[type][i]->source;
            }
            device->ref_count++;
            pthread_mutex_init(device->mutex, NULL);
            unlock;
            return de_None;
        }
    }
    
    if (type == input) {
        device->dhndl = alcCaptureOpenDevice(devices_names[type][selection], 
                        av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, frame_size * 2);
        device->VAD_treshold = VAD_THRESHOLD_DEFAULT;
    }
    else { 
        device->dhndl = alcOpenDevice(devices_names[type][selection]);
        if ( !device->dhndl ) { 
            free(device);
            running[type][*device_idx] = NULL;
            unlock;
            return de_FailedStart;
        }
        
        device->ctx = alcCreateContext(device->dhndl, NULL);
        alcMakeContextCurrent(device->ctx);
        
        alGenBuffers(openal_bufs, device->buffers);
        alGenSources((uint32_t)1, &device->source);
        alSourcei(device->source, AL_LOOPING, AL_FALSE);
        
        uint16_t zeros[frame_size];
        memset(zeros, 0, frame_size*2);
        
        for ( i =0; i < openal_bufs; ++i) {
            alBufferData(device->buffers[i], AL_FORMAT_MONO16, zeros, frame_size*2, sample_rate);
        }
        
        alSourceQueueBuffers(device->source, openal_bufs, device->buffers);
        alSourcePlay(device->source);
    }
    
    if (alcGetError(device->dhndl) != AL_NO_ERROR) {
        free(device);
        running[type][*device_idx] = NULL;
        unlock;
        return de_FailedStart;
    }
    
    if (type == input) {
        alcCaptureStart(device->dhndl);
        thread_paused = _False;
    }
    
    pthread_mutex_init(device->mutex, NULL);
    unlock;
    return de_None;
}
コード例 #23
0
ファイル: main.cpp プロジェクト: xxxbxxx/testbed-openal
int main(int, char**)
{
	// Setup SDL
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
		return -1;

	// Setup window
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
	SDL_DisplayMode current;
	SDL_GetCurrentDisplayMode(0, &current);
	SDL_Window *sdl_window = SDL_CreateWindow("testbed", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
	SDL_GLContext glcontext = SDL_GL_CreateContext(sdl_window);

	// Setup ImGui binding
	ImGui_ImplSdl_Init(sdl_window);

	// OpenAL: Open and initialize a device with default settings
	// and set current context, making the program ready to call OpenAL functions.
	ALCdevice*	alc_device = NULL;
	ALCcontext*	alc_ctx = NULL;
	const char*	alc_device_spec = NULL;
	const char*	alc_ext = NULL;
	const char*	al_vendor = NULL;
	const char*	al_renderer = NULL;
	const char*	al_version = NULL;
	const char*	al_ext = NULL;
	{
		alc_device = alcOpenDevice(NULL);
		if(!alc_device)
		{
			ERR("Could not open a device!\n");
			return 1;
		}

		alc_ctx = alcCreateContext(alc_device, NULL);
		if(alc_ctx == NULL || alcMakeContextCurrent(alc_ctx) == ALC_FALSE)
		{
			if(alc_ctx != NULL)
				alcDestroyContext(alc_ctx);
			alcCloseDevice(alc_device);
			ERR("Could not set a context!\n");
			return 1;
		}

		alc_device_spec = alcGetString(alc_device, ALC_DEVICE_SPECIFIER);
		alc_ext = alcGetString(alc_device, ALC_EXTENSIONS);
		//alcGetIntegerv(alc_device, ALC_MAJOR_VERSION, 1, &alc_major);
		//alcGetIntegerv(alc_device, ALC_MINOR_VERSION, 1, &alc_minor);

		al_vendor = alGetString(AL_VENDOR);
		al_renderer = alGetString(AL_RENDERER);
		al_version = alGetString(AL_VERSION);
		al_ext = alGetString(AL_EXTENSIONS);
	}

	// Load resource
	SResources Resources;
	{
		bool ok = LoadResources(Resources);
		if (!ok) {
			ERR("Could not load all program resource.\n");
			return 1;
		}
	}

	// openal sources
	SMgrState MgrState;
	SEmitter* SpatialEmit;
	SEmitter* AmbiantLoop;
	{
		Mgr_Init(MgrState);

		SpatialEmit = &MgrState.Emitters[0];
		AmbiantLoop = &MgrState.Emitters[1];

		alSourcei(SpatialEmit->Source, AL_BUFFER, Resources.albuf_monoloop);
		alSourcei(SpatialEmit->Source, AL_LOOPING, AL_TRUE);
		alSourcei(SpatialEmit->Source, AL_DIRECT_CHANNELS_SOFT, AL_FALSE);
		SpatialEmit->active = false;
		SpatialEmit->dB = 0.f;
		SpatialEmit->pos[0] = .5f;
		SpatialEmit->pos[1] = .75f;
		SpatialEmit->pos[2] = -3;
		SpatialEmit->radius = 0.01f;

		alSourcei(AmbiantLoop->Source, AL_BUFFER, Resources.albuf_stereoloop);
		alSourcei(AmbiantLoop->Source, AL_LOOPING, AL_TRUE);
		alSourcei(AmbiantLoop->Source, AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
		AmbiantLoop->active = false;
		AmbiantLoop->dB = -9.f;
	}

	// Main loop
	bool done = false;
	while (!done)
	{
		SDL_Event event;
		while (SDL_PollEvent(&event))
		{
			ImGui_ImplSdl_ProcessEvent(&event);
			if (event.type == SDL_QUIT)
				done = true;
		}
		uint CurTimeMs = SDL_GetTicks();
		int ActiveSources = Mgr_Update(MgrState);

		ImGui_ImplSdl_NewFrame(sdl_window);

		ImGui::SetNextWindowPos(ImVec2(10, 10));
		ImGui::SetNextWindowSize(ImVec2(500, 700));
		ImGui::Begin("main", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove);

		// top bar.
		{
			if (ImGui::Button("Quit"))
				break;

			ImGui::SameLine();

			static bool ShowImguiHelp = false;
			ImGui::Checkbox("show imgui help", &ShowImguiHelp);
			if (ShowImguiHelp)
				ImGui::ShowTestWindow();		// documentation shortcut
		}

		ImGui::Spacing();	// -----------------

		// Openal info:
		if (ImGui::CollapsingHeader("OpenAL info"))
		{
			ImGui::Columns(2, "OpenAL_info");
			ImGui::Text("device");			ImGui::NextColumn();	ImGui::TextWrapped(alc_device_spec);	ImGui::NextColumn();
			ImGui::Text("vendor");			ImGui::NextColumn();	ImGui::TextWrapped(al_vendor);			ImGui::NextColumn();
			ImGui::Text("renderer");		ImGui::NextColumn();	ImGui::TextWrapped(al_renderer);		ImGui::NextColumn();
			ImGui::Text("version");			ImGui::NextColumn();	ImGui::TextWrapped(al_version);			ImGui::NextColumn();
			ImGui::Separator();
			ImGui::Text("ALC extensions");	ImGui::NextColumn();	ImGui::TextWrapped(alc_ext);			ImGui::NextColumn();
			ImGui::Separator();
			ImGui::Text("AL extensions");	ImGui::NextColumn();	ImGui::TextWrapped(al_ext);				ImGui::NextColumn();
			ImGui::Columns(1);
		}

		ImGui::Spacing();	// -----------------

		// basic test
		if (ImGui::CollapsingHeader("Basic", NULL, true, true))
		{
			static float mono_gaindB = -3.f;
			static float stereo_gaindB = -3.f;

			if (ImGui::Button("Play mono"))
			{
				Mgr_Play(MgrState, Resources.albuf_mono, mono_gaindB);
			}
			ImGui::SameLine();
			ImGui::SliderFloat("##vol1", &mono_gaindB, -60, 6, "%.1fdB");

			if (ImGui::Button("Play stereo"))
			{
				Mgr_Play(MgrState, Resources.albuf_stereo, stereo_gaindB);
			}
			ImGui::SameLine();
			ImGui::SliderFloat("##vol2", &stereo_gaindB, -60, 6, "%.1fdB");
		}

		ImGui::Spacing();	// -----------------

		// Direct
		if (ImGui::CollapsingHeader("Direct", NULL, true, true))
		{
			ImGui::Checkbox("Ambiance", &AmbiantLoop->active);
			ImGui::SameLine();
			ImGui::SliderFloat("##vol0", &AmbiantLoop->dB, -60, 6, "%.1fdB");
		}

		ImGui::Spacing();	// -----------------

		// Spatialized
		if (ImGui::CollapsingHeader("Spatialized", NULL, true, true))
		{
			ImGui::Checkbox("Mosquito", &SpatialEmit->active);
			ImGui::SameLine();
			ImGui::SliderFloat("##vol4", &SpatialEmit->dB, -60, 6, "%.1fdB");
			ImGui::SliderFloat("radius", &SpatialEmit->radius, 0, 5);

			static uint PrevTime = 0;
			static float PrevPos[3];
			static bool automove = false;
			ImGui::Checkbox("Auto move", &automove);
			if (automove) {
				struct SLocal {
					static void anim(float t, float v[3]) {
						float w = (t*2*PI);
						v[0] = 5*sinf(w*2+1) + 3*sinf(w*6+2) + 2*sinf(w*6+3) + 1*sinf(w*9+4);
						v[1] = 5*sinf(w*3+5) + 3*sinf(w*4+6) + 2*sinf(w*7+7) + 1*sinf(w*8+8);
						v[2] = 5*sinf(w*4+9) + 3*sinf(w*5+1) + 2*sinf(w*8+2) + 1*sinf(w*7+3);
					}
				};

				float t = (CurTimeMs % 60000) / 60000.f;
				SLocal::anim(t, SpatialEmit->pos);
			}

			ImGui::InputFloat3("pos", SpatialEmit->pos);
			ImGui::InputFloat3("vel", SpatialEmit->vel);
			ImGuiPointOnMap("top", &SpatialEmit->pos[0], &SpatialEmit->pos[2], SpatialEmit->radius, 10, 0.25f);
			ImGui::SameLine();
			ImGuiPointOnMap("front", &SpatialEmit->pos[0], &SpatialEmit->pos[1], SpatialEmit->radius, 10, 0.25f);

			if (PrevTime != 0 && CurTimeMs > PrevTime) {
				float dt = 0.001f*(CurTimeMs-PrevTime);
				float k = 1.f;
				SpatialEmit->vel[0] = k * ((SpatialEmit->pos[0] - PrevPos[0]) / dt);
				SpatialEmit->vel[1] = k * ((SpatialEmit->pos[1] - PrevPos[1]) / dt);
				SpatialEmit->vel[2] = k * ((SpatialEmit->pos[2] - PrevPos[2]) / dt);
			}
			PrevTime = CurTimeMs;
			memcpy(PrevPos, SpatialEmit->pos, sizeof(PrevPos));
		}

		ImGui::Spacing();	// -----------------

		// basic test
		if (ImGui::CollapsingHeader("Tests", NULL, true, true))
		{
			static const float Front[3] = {0,0,-1};
			if (ImGui::Button("stereo base"))
			{
				Mgr_Play(MgrState, Resources.albuf_stereo, -3, false);
			}
			ImGui::SameLine();
			if (ImGui::Button("stereo direct"))
			{
				Mgr_Play(MgrState, Resources.albuf_stereo, -3, true);
			}
			if (ImGui::Button("mono base"))
			{
				Mgr_Play(MgrState, Resources.albuf_mono, -3, false);
			}
			ImGui::SameLine();
			if (ImGui::Button("mono direct"))
			{
				Mgr_Play(MgrState, Resources.albuf_mono, -3, true);
			}
			ImGui::SameLine();
			if (ImGui::Button("mono 3d narrow"))
			{
				Mgr_Play(MgrState, Resources.albuf_mono, -3, Front, 0.01f);
			}
			ImGui::SameLine();
			if (ImGui::Button("mono 3d wide"))
			{
				Mgr_Play(MgrState, Resources.albuf_mono, -3, Front, 1.f);
			}
			ImGui::SameLine();
			if (ImGui::Button("mono 3d omni"))
			{
				Mgr_Play(MgrState, Resources.albuf_mono, -3, Front, 10.f);
			}
		}

		ImGui::Spacing();	// -----------------

		// status
		{
			ImGui::Separator();
			ImGui::Text("Active Sources: %d / %d\n", ActiveSources, MGR_MAX_SOURCES);
			ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		}

		ImGui::End();

		// Rendering
		ImVec4 clear_color = ImColor(114, 144, 154);
		glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);
		glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
		glClear(GL_COLOR_BUFFER_BIT);
		ImGui::Render();
		SDL_GL_SwapWindow(sdl_window);
	}

	Mgr_Destroy(MgrState);
	FreeResources(Resources);

	// OpenAL: cleanup
	{
		alcMakeContextCurrent(NULL);
		alcDestroyContext(alc_ctx);
		alcCloseDevice(alc_device);
	}

	// Cleanup
	ImGui_ImplSdl_Shutdown();
	SDL_GL_DeleteContext(glcontext);
	SDL_DestroyWindow(sdl_window);
	SDL_Quit();

	return 0;
}
コード例 #24
0
ファイル: device.c プロジェクト: selukov/toxic
// TODO: generate buffers separately
DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration, uint8_t channels)
{
    if (size[type] <= selection || selection < 0) return de_InvalidSelection;

    if (channels != 1 && channels != 2) return de_UnsupportedMode;
    
    lock;

    const uint32_t frame_size = (sample_rate * frame_duration / 1000);
    
    uint32_t i;
    for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; ++i);
    
    if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; }
    else *device_idx = i;
    
    for (i = 0; i < MAX_DEVICES; i ++) { /* Check if any device has the same selection */
        if ( running[type][i] && running[type][i]->selection == selection ) {
//             printf("a%d-%d:%p ", selection, i, running[type][i]->dhndl);
            
            running[type][*device_idx] = running[type][i];            
            running[type][i]->ref_count ++;
            
            unlock;
            return de_None;
        }
    }
    
    Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));
    device->selection = selection;
    
    device->sample_rate = sample_rate;
    device->frame_duration = frame_duration;
    device->sound_mode = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
    
    if (pthread_mutex_init(device->mutex, NULL) != 0) {
        free(device);
        unlock;
        return de_InternalError;
    }
    
    if (type == input) {
        device->dhndl = alcCaptureOpenDevice(devices_names[type][selection], 
                                             sample_rate, device->sound_mode, frame_size * 2);
    #ifdef AUDIO
        device->VAD_treshold = user_settings->VAD_treshold;
    #endif
    }
    else { 
        device->dhndl = alcOpenDevice(devices_names[type][selection]);
        if ( !device->dhndl ) { 
            free(device);
            running[type][*device_idx] = NULL;
            unlock;
            return de_FailedStart;
        }
        
        device->ctx = alcCreateContext(device->dhndl, NULL);
        alcMakeContextCurrent(device->ctx);
        
        alGenBuffers(OPENAL_BUFS, device->buffers);
        alGenSources((uint32_t)1, &device->source);
        alSourcei(device->source, AL_LOOPING, AL_FALSE);
        
        uint16_t zeros[frame_size];
        memset(zeros, 0, frame_size*2);
        
        for ( i = 0; i < OPENAL_BUFS; ++i ) {
            alBufferData(device->buffers[i], device->sound_mode, zeros, frame_size*2, sample_rate);
        }
        
        alSourceQueueBuffers(device->source, OPENAL_BUFS, device->buffers);
        alSourcePlay(device->source);
    }
    
    if (alcGetError(device->dhndl) != AL_NO_ERROR) {
        free(device);
        running[type][*device_idx] = NULL;
        unlock;
        return de_FailedStart;
    }
    
    if (type == input) {
        alcCaptureStart(device->dhndl);
        thread_paused = false;
    }
    
    unlock;
    return de_None;
}
コード例 #25
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);
}
コード例 #26
0
// virtual
bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata)
{
	mWindGen = NULL;
	LLAudioEngine::init(num_channels, userdata);

	if (!alutInit(NULL, NULL))
	{
		llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl;
		return false;
	}

	// check for extensions
	const ALCchar* device_list(NULL);
	const ALCchar* device_default(NULL);
	if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)
	{
		device_default = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
		device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
		llinfos << "Results for ALC_ENUMERATION_EXT:\n" 
				<< ll_safe_string(device_list)
				<< llendl;

	}

	// initialize device
    ALCdevice* mDevice = alcOpenDevice(NULL); 
    if (mDevice == NULL)
	{
		llinfos << "Could not find a default device, trying to open default manually: " 
				<< ll_safe_string(device_default) 
				<< llendl;
		mDevice = alcOpenDevice(device_default);
		if (mDevice == NULL)
		{
			const ALCchar* device_list_walk = device_list;
			do
			{
				mDevice = alcOpenDevice(device_list_walk);
				if (mDevice != NULL)
				{
					break;
				}
				else
				{
					device_list_walk += strlen(device_list_walk)+1;
				}
			}
			while (device_list_walk[0] != '\0');

			if (mDevice == NULL)
			{
				llinfos << "OpenAL could not find an installed audio device. Aborting" << llendl;
				ALCenum error = alcGetError(mDevice);
				if (error != ALC_NO_ERROR)
				{
					llinfos << "ALC error: " << ll_safe_string(alcGetString(mDevice, error)) << llendl;
				}
				return false;
			}
		}
	}

	// create context
	ALCcontext* mContext = alcCreateContext(mDevice, NULL);
	if (mContext != NULL)
	{
		if (!alcMakeContextCurrent(mContext))
		{
			ALenum error = alGetError();
			if (error != AL_NO_ERROR)
			{
				llinfos << "ALC error: " << convertALErrorToString(error) << ". Could not set current context!" << llendl;
			}
			alcDestroyContext(mContext);
			return false;
		}
	}
	else
	{
		llinfos << "ALC error: could not create context from device!" << llendl;
		alcCloseDevice(mDevice);
		return false;
	}

	llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;

	llinfos << "ALC default device: " 
			<< ll_safe_string(alcGetString(mDevice, ALC_DEFAULT_DEVICE_SPECIFIER)) 
			<< llendl;

	llinfos << "OpenAL version: "
		<< ll_safe_string(alGetString(AL_VERSION)) << llendl;
	llinfos << "OpenAL vendor: "
		<< ll_safe_string(alGetString(AL_VENDOR)) << llendl;
	llinfos << "OpenAL renderer: "
		<< ll_safe_string(alGetString(AL_RENDERER)) << llendl;

	ALint major = alutGetMajorVersion();
	ALint minor = alutGetMinorVersion();
	llinfos << "ALUT version: " << major << "." << minor << llendl;

	alcGetIntegerv(mDevice, ALC_MAJOR_VERSION, 1, &major);
	alcGetIntegerv(mDevice, ALC_MINOR_VERSION, 1, &minor);
	llinfos << "ALC version: " << major << "." << minor << llendl;

	return true;
}
コード例 #27
0
ファイル: sound_openal.c プロジェクト: naev/naev
/**
 * @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;
}
コード例 #28
0
ファイル: audio.cpp プロジェクト: alexanderkjall/ValyriaTear
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()
コード例 #29
0
/*
========================
idSoundHardware_OpenAL::Init
========================
*/
void idSoundHardware_OpenAL::Init()
{
	cmdSystem->AddCommand( "listDevices", listDevices_f, 0, "Lists the connected sound devices", NULL );
	
	common->Printf( "Setup OpenAL device and context... " );
	
	openalDevice = alcOpenDevice( NULL );
	if( openalDevice == NULL )
	{
		common->FatalError( "idSoundHardware_OpenAL::Init: alcOpenDevice() failed\n" );
		return;
	}
	
	openalContext = alcCreateContext( openalDevice, NULL );
	if( alcMakeContextCurrent( openalContext ) == 0 )
	{
		common->FatalError( "idSoundHardware_OpenAL::Init: alcMakeContextCurrent( %p) failed\n", openalContext );
		return;
	}
	
	common->Printf( "Done.\n" );
	
	common->Printf( "OpenAL vendor: %s\n", alGetString( AL_VENDOR ) );
	common->Printf( "OpenAL renderer: %s\n", alGetString( AL_RENDERER ) );
	common->Printf( "OpenAL version: %s\n", alGetString( AL_VERSION ) );
	common->Printf( "OpenAL extensions: %s\n", alGetString( AL_EXTENSIONS ) );
	
	//pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) );
	
	//outputChannels = deviceDetails.OutputFormat.Format.nChannels;
	//channelMask = deviceDetails.OutputFormat.dwChannelMask;
	
	//idSoundVoice::InitSurround( outputChannels, channelMask );
	
	// ---------------------
	// Create VU Meter Effect
	// ---------------------
	/*
	IUnknown* vuMeter = NULL;
	XAudio2CreateVolumeMeter( &vuMeter, 0 );
	
	XAUDIO2_EFFECT_DESCRIPTOR descriptor;
	descriptor.InitialState = true;
	descriptor.OutputChannels = outputChannels;
	descriptor.pEffect = vuMeter;
	
	XAUDIO2_EFFECT_CHAIN chain;
	chain.EffectCount = 1;
	chain.pEffectDescriptors = &descriptor;
	
	pMasterVoice->SetEffectChain( &chain );
	
	vuMeter->Release();
	*/
	
	// ---------------------
	// Create VU Meter Graph
	// ---------------------
	
	/*
	vuMeterRMS = console->CreateGraph( outputChannels );
	vuMeterPeak = console->CreateGraph( outputChannels );
	vuMeterRMS->Enable( false );
	vuMeterPeak->Enable( false );
	
	memset( vuMeterPeakTimes, 0, sizeof( vuMeterPeakTimes ) );
	
	vuMeterPeak->SetFillMode( idDebugGraph::GRAPH_LINE );
	vuMeterPeak->SetBackgroundColor( idVec4( 0.0f, 0.0f, 0.0f, 0.0f ) );
	
	vuMeterRMS->AddGridLine( 0.500f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
	vuMeterRMS->AddGridLine( 0.250f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
	vuMeterRMS->AddGridLine( 0.125f, idVec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
	
	const char* channelNames[] = { "L", "R", "C", "S", "Lb", "Rb", "Lf", "Rf", "Cb", "Ls", "Rs" };
	for( int i = 0, ci = 0; ci < sizeof( channelNames ) / sizeof( channelNames[0] ); ci++ )
	{
		if( ( channelMask & BIT( ci ) ) == 0 )
		{
			continue;
		}
		vuMeterRMS->SetLabel( i, channelNames[ ci ] );
		i++;
	}
	*/
	
	// OpenAL doesn't really impose a maximum number of sources
	voices.SetNum( voices.Max() );
	freeVoices.SetNum( voices.Max() );
	zombieVoices.SetNum( 0 );
	for( int i = 0; i < voices.Num(); i++ )
	{
		freeVoices[i] = &voices[i];
	}
}
コード例 #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;
}