Example #1
0
bool CheckError(const char* msg)
{
	ALenum e = alGetError();
	if (e != AL_NO_ERROR)
	{
		char *alerr = (char*)alGetString(e);
		std::string err = msg;
		err += ": ";
		err += (alerr != NULL) ? alerr : "Unknown error";

		LogObject(LOG_SOUND) << err.c_str();
		return false;
	}
	return true;
}
Example #2
0
void Sound::SetUISoundsVolume(int vol) {
    ALenum m_openal_error;

    /* normalize value, then apply to all sound sources */
    vol = std::max(0, std::min(vol, 255));
    GetOptionsDB().Set<int>("UI.sound.volume", vol);
    if (alcGetCurrentContext() != 0) {
        for (int it = 1; it < NUM_SOURCES; ++it)
            alSourcef(m_sources[it],AL_GAIN, ((ALfloat) vol)/255.0);
        /* it is highly unlikely that we'll get an error here but better safe than sorry */
        m_openal_error = alGetError();
        if (m_openal_error != AL_NONE)
            Logger().errorStream() << "PlaySound: OpenAL ERROR: " << alGetString(m_openal_error);
    }
}
Example #3
0
//! [static]
bool checkErrorStatus(const char * file, int line, const std::string & msg) {
	const ALenum error = alGetError();
	if (error == AL_NO_ERROR) {
		return true;
	}
	std::cerr << "AL ERROR (";
	const ALchar * errorString = alGetString(error);
	if(errorString != nullptr) {
		std::cerr << errorString;
	} else {
		std::cerr << error;
	}
	std::cerr << "): " << msg << " at " << file << ":" << line << std::endl;
	return false;
}
Example #4
0
void Sound::FreeSound(const boost::filesystem::path& path) {
    ALenum m_openal_error;
    std::string filename = path.string();
    std::map<std::string, ALuint>::iterator it = m_buffers.find(filename);

    if (it != m_buffers.end()) {
        alDeleteBuffers(1, &(it->second));
        m_openal_error = alGetError();
        if (m_openal_error != AL_NONE)
            Logger().errorStream() << "FreeSound: OpenAL ERROR: " << alGetString(m_openal_error);
        else
            m_buffers.erase(it); /* we don't erase if there was an error, as the buffer may not have been
                                    removed - potential memory leak */
    }
}
Example #5
0
		Mixer::Mixer ()
		{
			const ALCchar * device_name = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);

			AudioError::reset();
			_audio_device = _default_audio_device();
			_audio_context = alcCreateContext(_audio_device, NULL);
			AudioError::check("Initializing Audio Context");

			bool result = alcMakeContextCurrent(_audio_context);

			LogBuffer buffer;
			buffer << "OpenAL Context Initialized..." << std::endl;
			buffer << "OpenAL Vendor: " << alGetString(AL_VENDOR) << " " << alGetString(AL_VERSION) << std::endl;
			buffer << "OpenAL Device: '" << device_name << "'" << std::endl;
			logger()->log(LOG_INFO, buffer);

			//al_distance_model(AL_LINEAR_DISTANCE);
			set_listener_position(0);
			set_listener_velocity(0);
			set_listener_orientation(Vec3(0.0, 0.0, -1.0), Vec3(0.0, 1.0, 0.0));

			DREAM_ASSERT(result && "Failed to initialize audio hardware!?");
		}
Example #6
0
// -------------------  LoadSound -------------------------
static ALuint LoadSound(const char* name)
{
	SDL_AudioSpec wav_spec;
	Uint32 wav_length;
	Uint8 *wav_buffer;
	if (SDL_LoadWAV(name, &wav_spec, &wav_buffer, &wav_length) == NULL) {
		ERR("LoadSound(%s): SDL_LoadWAV failed: %s\n", name, SDL_GetError());
		return 0;
	}

	ALenum format = 0;
	if (wav_spec.channels == 1) {
		switch(wav_spec.format) {
		case AUDIO_U8:			format = AL_FORMAT_MONO8; break;
		case AUDIO_S16LSB:		format = AL_FORMAT_MONO16; break;
		case AUDIO_F32LSB:		format = AL_FORMAT_MONO_FLOAT32; break;
		}
	} else if (wav_spec.channels == 2) {
		switch(wav_spec.format) {
		case AUDIO_U8:			format = AL_FORMAT_STEREO8; break;
		case AUDIO_S16LSB:		format = AL_FORMAT_STEREO16; break;
		case AUDIO_F32LSB:		format = AL_FORMAT_STEREO_FLOAT32; break;
		}
	}

	if (format == 0) {
		// TODO: if needed, more channels / other formats.
		ERR("LoadSound(%s): Unsupported format (TODO): 0x%X\n", name, wav_spec.format);
		SDL_FreeWAV(wav_buffer);
		return 0;
	}

	ALuint buffer;
	alGenBuffers(1, &buffer);
	alBufferData(buffer, format, wav_buffer, wav_length, wav_spec.freq);
	SDL_FreeWAV(wav_buffer);

	ALenum err = alGetError();
	if(err != AL_NO_ERROR)
	{
		ERR("LoadSound(%s): alBufferData Error: %s\n", name, alGetString(err));
		if(alIsBuffer(buffer))
			alDeleteBuffers(1, &buffer);
		return 0;
	}

	return buffer;
}
Example #7
0
std::string checkALError()
{
#if defined(DF3D_DESKTOP)
    std::string errString;

    ALenum errCode = alGetError();
    if (errCode != AL_NO_ERROR)
    {
        errString = (char *)alGetString(errCode);
    }

    return errString;
#else
    return "";
#endif
}
Example #8
0
	bool CSoundEngine::Initialize(void *pEngine)
	{
		if (m_bInit) return false;
		m_bInit = true;

		s_pEngine = (IEngine*)pEngine;

		// memory leaks detection
#if defined(_DEBUG) && defined(_MSC_VER) && _MSC_VER >= 800
		_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
		//_CrtSetBreakAlloc(76);
#endif

		CON(MSG_INFO, _W("= Sound Device initialization ="));

		m_device = alcOpenDevice(NULL);
		if(!m_device)
		{
			CON(MSG_ERR_FATAL, _W(" Can't initialize OpenAL! Please try to reinstall OpenAL libraries..."));
			return false;
		}

		m_extensions = new COALExtProvider();
		if(m_extensions == NULL)
		{
			CON(MSG_INFO, _W(" Can't create OpenAL Extension provider instance!"));
			m_context = alcCreateContext(m_device, NULL);
			if(m_context != NULL)
				alcMakeContextCurrent(m_context);
		}
		else
			m_extensions->Create(m_device, m_context);
		
		if(m_context == NULL)
		{
			CON(MSG_ERR_FATAL, _W(" Can't create OpenAL context!"));
			return false;
		}

		
		if (!cSoundManager()->Create(m_extensions))
			CON(MSG_ERR_FATAL, _W(" Can't create Sound Manager!"));

		CON(MSG_INFO, _W(" ...using OpenAL version %s"), _A2W(alGetString(AL_VERSION)) );

		return true;
	}
Example #9
0
static void playFile(const char *fileName)
{
  ALenum format;
  void *data;
  ALsizei size;
  ALsizei frequency;

#if !defined(__APPLE__)
  ALboolean loop;
#endif
  ALuint buffer;
  ALuint source;
  ALenum error;
  ALint status;

  /* Create an AL buffer from the given sound file. */
  alutLoadWAVFile((ALbyte *) "file1.wav", &format, &data, &size, &frequency
#if !defined(__APPLE__)
                  , &loop
#endif
    );
  alGenBuffers(1, &buffer);
  alBufferData(buffer, format, data, size, frequency);
  free(data);

  /* Generate a single source, attach the buffer to it and start playing. */
  alGenSources(1, &source);
  alSourcei(source, AL_BUFFER, buffer);
  alSourcePlay(source);

  /* Normally nothing should go wrong above, but one never knows... */
  error = alGetError();
  if (error != ALUT_ERROR_NO_ERROR)
  {
    fprintf(stderr, "%s\n", alGetString(error));
    alutExit();
    exit(EXIT_FAILURE);
  }

  /* Check every 0.1 seconds if the sound is still playing. */
  do
  {
    alutSleep(0.1f);
    alGetSourcei(source, AL_SOURCE_STATE, &status);
  }
  while (status == AL_PLAYING);
}
// Start the sound sub-system
void SokobanSoundManager::Setup(void)
{
	// Initialise ALUT and eat any ALUT-specific command line flags
	if (!alutInit (NULL, NULL))
	{
		ALenum error = alutGetError ();
		fprintf (stderr, "%s\n", alutGetErrorString (error));
		// exit (EXIT_FAILURE);
		m_bIsSetup = false;
		return;
	}

	// Load the default sound
	//////////////////////////////////////////////////////////////////////////
	// NOTE: Cant use LoadSampleFromFile because if it fails it returns m_DefaultSoundID
	
	// Create an AL buffer from the given sound file
	m_DefaultSoundID = alutCreateBufferFromFile (".\\audio\\default.wav");
	if (m_DefaultSoundID == AL_NONE)
	{
		ALenum error = alutGetError ();
		fprintf (stderr, "Error loading file: '%s'\n", alutGetErrorString (error));
		alutExit ();
		// exit (EXIT_FAILURE);
		m_bIsSetup = false;
		return;
	}

	// Generate a single source
	alGenSources (1, &source);

	// Error check source generation
	ALenum error = alGetError ();
	if (error != ALUT_ERROR_NO_ERROR)
	{
		//	fprintf (stderr, "%s\n", alGetString (error));
		MessageBox (HWND_DESKTOP, alGetString(error), "Error 1", MB_OK | MB_ICONEXCLAMATION);
		alutExit ();
		exit (EXIT_FAILURE);
	}

	// toggle IsSetup
	m_bIsSetup = true;

	return;
}
Example #11
0
int main( int argc, char *argv[] )
{
	int attributeList[] = {
		ALC_FREQUENCY, 22050,
		0
	};
	time_t start = time( NULL );
	time_t shouldEnd;
	ALCcontext *context;
	ALuint movingSource;

	ALCdevice *device = alcOpenDevice( NULL );
	if( device == NULL ) {
		fprintf( stderr, "Could not open device\n" );
		return EXIT_FAILURE;
	}

	/* Initialize context. */
	context = alcCreateContext( device, attributeList );
	if( context == NULL ) {
		fprintf( stderr, "Could not open context: %s\n",
			 alGetString( alcGetError( device ) ) );
		return EXIT_FAILURE;
	}
	alcMakeContextCurrent( context );

	getExtensionEntries(  );
	palBombOnError(  );

	movingSource = init( ( argc == 1 ) ? "sample.wav" : argv[1] );

	alSourcePlay( movingSource );
	while( sourceIsPlaying( movingSource ) == AL_TRUE ) {
		iterate( movingSource );

		shouldEnd = time( NULL );
		if( ( shouldEnd - start ) > 30 ) {
			alSourceStop( movingSource );
		}
	}

	alcMakeContextCurrent( NULL );
	alcDestroyContext( context );
	alcCloseDevice( device );
	return EXIT_SUCCESS;
}
Example #12
0
	static void checkForErrors()
	{
		{
			ALCdevice* device = alcGetContextsDevice(alcGetCurrentContext());
			ALCenum error = alcGetError(device);
			if(error != ALC_NO_ERROR) {
				std::cout << boost::format("ALC error: '%s'\n")
					% static_cast<const char*>(alcGetString(device, error));
			}
		}
		{
			ALenum error = alGetError();
			if(error != AL_NO_ERROR) {
				std::cout << boost::format("AL error: '%s'\n")
					% static_cast<const char*>(alGetString(error));
			}
		}
	}
Example #13
0
void Sound::FreeAllSounds() {
    ALenum m_openal_error;

    for (std::map<std::string, ALuint>::iterator it = m_buffers.begin();
         it != m_buffers.end();)
    {
        alDeleteBuffers(1, &(it->second));
        m_openal_error = alGetError();
        if (m_openal_error != AL_NONE) {
            ErrorLogger() << "FreeAllSounds: OpenAL ERROR: " << alGetString(m_openal_error);
            ++it;
        } else {
            std::map<std::string, ALuint>::iterator temp = it;
            ++it;
            m_buffers.erase(temp);  // invalidates erased iterator only
        }
    }
}
Example #14
0
void Sound::Impl::SetMusicVolume(int vol) {
    if (!m_initialized)
        return;

    ALenum m_openal_error;

    /* normalize value, then apply to all sound sources */
    vol = std::max(0, std::min(vol, 255));
    GetOptionsDB().Set<int>("UI.sound.music-volume", vol);
    if (alcGetCurrentContext())
    {
        alSourcef(m_sources[0], AL_GAIN, ((ALfloat) vol)/255.0);
        /* it is highly unlikely that we'll get an error here but better safe than sorry */
        m_openal_error = alGetError();
        if (m_openal_error != AL_NONE)
            ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(m_openal_error);
    }
}
Example #15
0
BOOL	CSoundRender_TargetA::_initialize		()
{
	inherited::_initialize();
    // initialize buffer
	A_CHK(alGenBuffers	(sdef_target_count, pBuffers));	
    alGenSources		(1, &pSource);
    ALenum error		= alGetError();
    if (AL_NO_ERROR==error){
        A_CHK(alSourcei	(pSource, AL_LOOPING, AL_FALSE));
        A_CHK(alSourcef	(pSource, AL_MIN_GAIN, 0.f));
        A_CHK(alSourcef	(pSource, AL_MAX_GAIN, 1.f));
        A_CHK(alSourcef	(pSource, AL_GAIN, 	cache_gain));
        A_CHK(alSourcef	(pSource, AL_PITCH,	cache_pitch));
        return			TRUE;
    }else{
    	Msg				("! sound: OpenAL: Can't create source. Error: %s.",(LPCSTR)alGetString(error));
        return 			FALSE;
    }
}
COpenALSound::COpenALSound()
{
	Sources = NULL;

	maxSounds = configHandler.GetInt("MaxSounds", 16);
	if (maxSounds <= 0) {
		throw content_error("Internal error, (maxSounds <= 0) in COpenALSound");
	}

	globalVolume = 1.0f;

	cur = 0;

	ALCdevice *device = alcOpenDevice(NULL);
	if (device == NULL) {
		throw content_error("Could not create OpenAL audio device");
	} else {
		ALCcontext *context = alcCreateContext(device, NULL);
		if (context != NULL) {
			alcMakeContextCurrent(context);
		} else {
			alcCloseDevice(device);
			throw content_error("Could not create OpenAL audio context");
		}
	}

	printf("OpenAL: %s\n", (const char*)alGetString(AL_EXTENSIONS));

	// Generate sound sources
	Sources = SAFE_NEW ALuint[maxSounds];
	for (int a=0;a<maxSounds;a++) {
		Sources[a]=0;
	}

	// Set distance model (sound attenuation)
	alDistanceModel (AL_INVERSE_DISTANCE);

	posScale.x = 0.02f;
	posScale.y = 0.0005f;
	posScale.z = 0.02f;
}
Example #17
0
static void
playFile (const char *fileName)
{
  ALuint buffer;
  ALuint source;
  ALenum error;
  ALint status;

  /* Create an AL buffer from the given sound file. */
  buffer = alutCreateBufferFromFile (fileName);
  if (buffer == AL_NONE)
    {
      error = alutGetError ();
      fprintf (stderr, "Error loading file: '%s'\n",
               alutGetErrorString (error));
      alutExit ();
      exit (EXIT_FAILURE);
    }

  /* Generate a single source, attach the buffer to it and start playing. */
  alGenSources (1, &source);
  alSourcei (source, AL_BUFFER, buffer);
  alSourcePlay (source);

  /* Normally nothing should go wrong above, but one never knows... */
  error = alGetError ();
  if (error != ALUT_ERROR_NO_ERROR)
    {
      fprintf (stderr, "%s\n", alGetString (error));
      alutExit ();
      exit (EXIT_FAILURE);
    }

  /* Check every 0.1 seconds if the sound is still playing. */
  do
    {
      alutSleep (0.1f);
      alGetSourcei (source, AL_SOURCE_STATE, &status);
    }
  while (status == AL_PLAYING);
}
Example #18
0
//--------------------------------------------------------------------------
// openal_error_string()
//
// Returns the human readable error string if there is an error or NULL if not
//
const char *openal_error_string(int get_alc)
{
	int i;

	if (get_alc) {
		ALCdevice *device = alcGetContextsDevice( alcGetCurrentContext() );

		i = alcGetError(device);

		if ( i != ALC_NO_ERROR )
			return (const char*) alcGetString(device, i);
	}
	else {
		i = alGetError();

		if ( i != AL_NO_ERROR )
			return (const char*)alGetString(i);
	}

	return NULL;
}
Example #19
0
bool AudioAsset::LoadFromRawPCMWavData(const u8 *data, size_t numBytes, bool stereo, bool is16Bit, int frequency)
{
    // Clean up the previous OpenAL audio buffer handle, if old data existed.
    DoUnload();

#ifndef TUNDRA_NO_AUDIO
    if (!data || numBytes == 0)
    {
        LogError("Null data passed in AudioAsset::LoadFromWavData!");
        return false;
    }

    if (!CreateBuffer())
        return false;

    ALenum openALFormat;
    if (stereo && is16Bit) openALFormat = AL_FORMAT_STEREO16;
    else if (!stereo && is16Bit) openALFormat = AL_FORMAT_MONO16;
    else if (stereo && !is16Bit) openALFormat = AL_FORMAT_STEREO8;
    else /* (!stereo && !is16Bit)*/ openALFormat = AL_FORMAT_MONO8;

    // Copy the new data over.
    std::vector<u8> tmpData(data, data + numBytes);
    alBufferData(handle, openALFormat, &tmpData[0], tmpData.size(), frequency);
    ALenum error = alGetError();
    if (error != AL_NONE)
    {
        const ALchar unknownError[] = "unknown error";
        const ALchar *errorString = alGetString(error);
        if (!errorString)
            errorString = unknownError;
        LogError("Could not set OpenAL sound buffer data: OpenAL error number " + QString::number(error) + ": " + errorString);
        DoUnload();
        return false;
    }
    return true;
#else
    return false;
#endif
}
void idSoundHardware_OpenAL::PrintALCInfo( ALCdevice* device )
{
	ALCint major, minor;
	
	if( device )
	{
		const ALCchar* devname = NULL;
		idLib::Printf( "\n" );
		if( alcIsExtensionPresent( device, "ALC_ENUMERATE_ALL_EXT" ) != AL_FALSE )
		{
			devname = alcGetString( device, ALC_ALL_DEVICES_SPECIFIER );
		}
		
		if( CheckALCErrors( device ) != ALC_NO_ERROR || !devname )
		{
			devname = alcGetString( device, ALC_DEVICE_SPECIFIER );
		}
		
		idLib::Printf( "** Info for device \"%s\" **\n", devname );
	}
	
	if( CheckALCErrors( device ) == ALC_NO_ERROR ) {
		alcGetIntegerv( device, ALC_MAJOR_VERSION, 1, &major );
		alcGetIntegerv( device, ALC_MINOR_VERSION, 1, &minor );
		idLib::Printf( "ALC version: %d.%d\n", major, minor );
	}
		
	if( device )
	{
		idLib::Printf( "OpenAL extensions:\n%s\n", alGetString( AL_EXTENSIONS ) );
		
		//idLib::Printf("ALC extensions:");
		//printList(alcGetString(device, ALC_EXTENSIONS), ' ');
		CheckALCErrors( device );
	}
}
Example #21
0
__FORCE_ALIGN_STACK__
void CSound::StartThread(int maxSounds)
{
	{
		boost::recursive_mutex::scoped_lock lck(soundMutex);

		// alc... will create its own thread it will copy the name from the current thread.
		// Later we finally rename `our` audio thread.
		Threading::SetThreadName("openal");

		// NULL -> default device
		const ALchar* deviceName = NULL;
		std::string configDeviceName = "";

		// we do not want to set a default for snd_device,
		// so we do it like this ...
		if (configHandler->IsSet("snd_device"))
		{
			configDeviceName = configHandler->GetString("snd_device");
			deviceName = configDeviceName.c_str();
		}

		ALCdevice* device = alcOpenDevice(deviceName);

		if ((device == NULL) && (deviceName != NULL))
		{
			LOG_L(L_WARNING,
					"Could not open the sound device \"%s\", trying the default device ...",
					deviceName);
			configDeviceName = "";
			deviceName = NULL;
			device = alcOpenDevice(deviceName);
		}

		if (device == NULL)
		{
			LOG_L(L_ERROR, "Could not open a sound device, disabling sounds");
			CheckError("CSound::InitAL");
			return;
		}
		else
		{
			ALCcontext *context = alcCreateContext(device, NULL);
			if (context != NULL)
			{
				alcMakeContextCurrent(context);
				CheckError("CSound::CreateContext");
			}
			else
			{
				alcCloseDevice(device);
				LOG_L(L_ERROR, "Could not create OpenAL audio context");
				return;
			}
		}
		maxSounds = GetMaxMonoSources(device, maxSounds);

		LOG("OpenAL info:");
		if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
		{
			LOG("  Available Devices:");
			const char* deviceSpecifier = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
			while (*deviceSpecifier != '\0') {
				LOG("              %s", deviceSpecifier);
				while (*deviceSpecifier++ != '\0')
					;
			}
			LOG("  Device:     %s", (const char*)alcGetString(device, ALC_DEVICE_SPECIFIER));
		}
		LOG("  Vendor:         %s", (const char*)alGetString(AL_VENDOR));
		LOG("  Version:        %s", (const char*)alGetString(AL_VERSION));
		LOG("  Renderer:       %s", (const char*)alGetString(AL_RENDERER));
		LOG("  AL Extensions:  %s", (const char*)alGetString(AL_EXTENSIONS));
		LOG("  ALC Extensions: %s", (const char*)alcGetString(device, ALC_EXTENSIONS));

		// Init EFX
		efx = new CEFX(device);

		// Generate sound sources
		for (int i = 0; i < maxSounds; i++)
		{
			CSoundSource* thenewone = new CSoundSource();
			if (thenewone->IsValid()) {
				sources.push_back(thenewone);
			} else {
				maxSounds = std::max(i-1, 0);
				LOG_L(L_WARNING,
						"Your hardware/driver can not handle more than %i soundsources",
						maxSounds);
				delete thenewone;
				break;
			}
		}
		LOG("  Max Sounds: %i", maxSounds);

		// Set distance model (sound attenuation)
		alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
		alDopplerFactor(0.2f);

		alListenerf(AL_GAIN, masterVolume);
	}

	Threading::SetThreadName("audio");
	Watchdog::RegisterThread(WDT_AUDIO);

	while (!soundThreadQuit) {
		boost::this_thread::sleep(boost::posix_time::millisec(50)); //! 20Hz
		Watchdog::ClearTimer(WDT_AUDIO);
		Update();
	}

	Watchdog::DeregisterThread(WDT_AUDIO);

	sources.clear(); // delete all sources
	delete efx; // must happen after sources and before context
	efx = NULL;
	ALCcontext* curcontext = alcGetCurrentContext();
	ALCdevice* curdevice = alcGetContextsDevice(curcontext);
	alcMakeContextCurrent(NULL);
	alcDestroyContext(curcontext);
	alcCloseDevice(curdevice);
}
Example #22
0
void Sound::Impl::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/) {
    if (!m_initialized || !GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled()))
        return;

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

#ifdef FREEORION_WIN32
    ov_callbacks callbacks = {

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

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

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

    (long (*)(void *))                            ftell

    };
#endif

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

                        int loop = 0;

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

                        current_buffer = sound_handle;
                        found_buffer = true;
                        m_buffers.insert(std::make_pair(filename, sound_handle));
                    }
                    else
                    {
                        ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " too big to buffer. Aborting\n";
                    }
                    ov_clear(&ogg_file);
                }
                else
                {
                    ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n";
                }
            }
        }
        if (found_buffer) {
            /* Now that we have the buffer, we need to find a source to send it to */
            for (m_i = 1; m_i < NUM_SOURCES; ++m_i) {   // as we're playing sounds we start at 1. 0 is reserved for music
                alGetSourcei(m_sources[m_i], AL_SOURCE_STATE, &source_state);
                if ((source_state != AL_PLAYING) && (source_state != AL_PAUSED)) {
                    found_source = true;
                    alSourcei(m_sources[m_i], AL_BUFFER, current_buffer);
                    alSourcePlay(m_sources[m_i]);
                    break; // so that the sound won't block all the sources
                }
            }
            if (!found_source)
                ErrorLogger() << "PlaySound: Could not find aviable source - playback aborted\n";
        }
        source_state = alGetError();
        if (source_state != AL_NONE)
            ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(source_state);
            /* it's important to check for errors, as some functions won't work properly if
             * they're called when there is a unchecked previous error. */
    }
}
Example #23
0
void Sound::Impl::PlayMusic(const boost::filesystem::path& path, int loops /* = 0*/) {
    if (!m_initialized)
        return;

    ALenum m_openal_error;
    std::string filename = PathString(path);
    FILE* m_f = nullptr;
    vorbis_info* vorbis_info;
    m_music_loops = 0;

#ifdef FREEORION_WIN32
    ov_callbacks callbacks = {

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

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

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

    (long (*)(void *))                            ftell

    };
#endif

    if (alcGetCurrentContext())
    {
        if (m_music_name.size() > 0)
            StopMusic();
       
        if ((m_f = fopen(filename.c_str(), "rb")) != nullptr) // make sure we CAN open it
        {
#ifdef FREEORION_WIN32
            if (!(ov_test_callbacks(m_f, &m_ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg
#else
            if (!(ov_test(m_f, &m_ogg_file, nullptr, 0))) // check if it's a proper ogg
#endif
            {
                ov_test_open(&m_ogg_file); // it is, now fully open the file
                /* now we need to take some info we will need later */
                vorbis_info = ov_info(&m_ogg_file, -1);
                if (vorbis_info->channels == 1)
                    m_ogg_format = AL_FORMAT_MONO16;
                else
                    m_ogg_format = AL_FORMAT_STEREO16;
                m_ogg_freq = vorbis_info->rate;
                m_music_loops = loops;
                /* fill up the buffers and queue them up for the first time */
                if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[0], BUFFER_SIZE, m_music_loops))
                {
                    alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[0]); // queue up the buffer if we manage to fill it
                    if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[1], BUFFER_SIZE, m_music_loops))
                    {
                        alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[1]);
                        m_music_name = filename; // yup, we're playing something that takes up more than 2 buffers
                    }
                    else
                    {
                        m_music_name.clear();  // m_music_name.clear() must always be called before ov_clear. Otherwise
                    }
                    alSourcePlay(m_sources[0]); // play if at least one buffer is queued
                }
                else
                {
                    m_music_name.clear();  // m_music_name.clear() must always be called before ov_clear. Otherwise
                }
            }
            else
            {
                ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n";
                m_music_name.clear(); //just in case
                ov_clear(&m_ogg_file);
            }
        }
        else
            ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " I/O Error. Aborting\n";
    }
    m_openal_error = alGetError();
    if (m_openal_error != AL_NONE)
        ErrorLogger() << "PlayMusic: OpenAL ERROR: " << alGetString(m_openal_error);
}
Example #24
0
/// Initialize OpenAl and return true on success.
// TODO rewrite with std::unique_ptr and custom deleter to remove long
// chain of "destructor" code.
void Sound::Impl::InitOpenAL() {
    ALCcontext *context;
    ALCdevice *device;
    ALenum error_code;
    ALboolean status;

    device = alcOpenDevice(nullptr);

    if (!device) {
        ErrorLogger() << "Unable to initialise default OpenAL device.";
        m_initialized = false;
        return;
    }

    context = alcCreateContext(device, nullptr);
    if (!context) {
        error_code = alGetError();
        ErrorLogger() << "Unable to create OpenAL context: " << alGetString(error_code) << "\n";
        alcCloseDevice(device);
        m_initialized = false;
        return;
    }

    status = alcMakeContextCurrent(context);
    error_code = alGetError();
    if (status != AL_TRUE || error_code != AL_NO_ERROR) {
        ErrorLogger() << "Unable to make OpenAL context current: " << alGetString(error_code) << "\n";
        alcDestroyContext(context);
        alcCloseDevice(device);
        m_initialized = false;
        return;
    }

    alListenerf(AL_GAIN, 1.0);
    error_code = alGetError();
    if (error_code != AL_NO_ERROR) {
        ErrorLogger() << "Unable to create OpenAL listener: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n";
        alcMakeContextCurrent(nullptr);
        alcDestroyContext(context);
        alcCloseDevice(device);
        m_initialized = false;
        return;
    }

    alGenSources(NUM_SOURCES, m_sources);
    error_code = alGetError();
    if (error_code != AL_NO_ERROR) {
        ErrorLogger() << "Unable to create OpenAL sources: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n";
        alcMakeContextCurrent(nullptr);
        alcDestroyContext(context);
        alcCloseDevice(device);
        m_initialized = false;
        return;
    }

    alGenBuffers(NUM_MUSIC_BUFFERS, m_music_buffers);
    error_code = alGetError();
    if (error_code != AL_NO_ERROR) {
        ErrorLogger() << "Unable to create OpenAL buffers: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n";
        alDeleteSources(NUM_SOURCES, m_sources);
        alcMakeContextCurrent(nullptr);
        alcDestroyContext(context);
        alcCloseDevice(device);
        m_initialized = false;
        return;
    }

    for (int i = 0; i < NUM_SOURCES; ++i) {
        alSourcei(m_sources[i], AL_SOURCE_RELATIVE, AL_TRUE);
        error_code = alGetError();
        if (error_code != AL_NO_ERROR) {
            ErrorLogger() << "Unable to set OpenAL source to relative: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n";
            alDeleteBuffers(NUM_MUSIC_BUFFERS, m_music_buffers);
            alDeleteSources(NUM_SOURCES, m_sources);
            alcMakeContextCurrent(nullptr);
            alcDestroyContext(context);
            alcCloseDevice(device);
            m_initialized = false;
            return;
        }
    }
    DebugLogger() << "OpenAL initialized. Version "
                  << alGetString(AL_VERSION)
                  << " Renderer "
                  << alGetString(AL_RENDERER)
                  << " Vendor "
                  << alGetString(AL_VENDOR) << "\n"
                  << " Extensions: "
                  << alGetString(AL_EXTENSIONS) << "\n";
    m_initialized = true;
}
Example #25
0
/**
 * Initializes the audio device and creates sources.
 *
 * @warning:
 *
 * @return TRUE if initialization was successful, FALSE otherwise
 */
bool FALAudioDevice::InitializeHardware( void )
{
	// Make sure no interface classes contain any garbage
	Effects = NULL;
	DLLHandle = NULL;

	// Default to sensible channel count.
	if( MaxChannels < 1 )
	{
		MaxChannels = 32;
	}
	// Load ogg and vorbis dlls if they haven't been loaded yet
	//LoadVorbisLibraries();

	// Open device
	HardwareDevice = alcOpenDevice(nullptr);
	if( !HardwareDevice )
	{
		UE_LOG(LogALAudio, Log, TEXT( "ALAudio: no OpenAL devices found." ) );
		return  false  ;
	}

	// Display the audio device that was actually opened
	const ALCchar* OpenedDeviceName = alcGetString( HardwareDevice, ALC_DEVICE_SPECIFIER );
	UE_LOG(LogALAudio, Log, TEXT("ALAudio device opened : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(OpenedDeviceName)).Get());

	// Create a context
	int Caps[] =
	{
		ALC_FREQUENCY, 44100,
		ALC_STEREO_SOURCES, 4,
		0, 0
	};
#if PLATFORM_HTML5_WIN32 || PLATFORM_LINUX
	SoundContext = alcCreateContext( HardwareDevice, Caps );
#elif PLATFORM_HTML5
	SoundContext = alcCreateContext( HardwareDevice, 0 );
#endif

	if( !SoundContext )
	{
		return false ;
	}

	alcMakeContextCurrent(SoundContext);

	// Make sure everything happened correctly
	if( alError( TEXT( "Init" ) ) )
	{
		UE_LOG(LogALAudio, Warning, TEXT("ALAudio: alcMakeContextCurrent failed."));
		return false ;
	}

	UE_LOG(LogALAudio, Log, TEXT("AL_VENDOR      : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_VENDOR))).Get());
	UE_LOG(LogALAudio, Log, TEXT("AL_RENDERER    : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_RENDERER))).Get());
	UE_LOG(LogALAudio, Log, TEXT("AL_VERSION     : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_VERSION))).Get());
	UE_LOG(LogALAudio, Log, TEXT("AL_EXTENSIONS  : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_EXTENSIONS))).Get());

	// Get the enums for multichannel support
#if !PLATFORM_HTML5
	Surround40Format = alGetEnumValue( "AL_FORMAT_QUAD16" );
	Surround51Format = alGetEnumValue( "AL_FORMAT_51CHN16" );
	Surround61Format = alGetEnumValue( "AL_FORMAT_61CHN16" );
	Surround71Format = alGetEnumValue( "AL_FORMAT_71CHN16" );
#endif
	// Initialize channels.
	alError( TEXT( "Emptying error stack" ), 0 );
	for( int i = 0; i < (( MaxChannels >  MAX_AUDIOCHANNELS ) ? MAX_AUDIOCHANNELS : MaxChannels); i++ )
	{
		ALuint SourceId;
		alGenSources( 1, &SourceId );
		if( !alError( TEXT( "Init (creating sources)" ), 0 ) )
		{
			FALSoundSource* Source = new FALSoundSource( this );
			Source->SourceId = SourceId;
			Sources.Add( Source );
			FreeSources.Add( Source );
		}
		else
		{
			break;
		}
	}

	if( Sources.Num() < 1 )
	{
		UE_LOG(LogALAudio, Warning, TEXT("ALAudio: couldn't allocate any sources"));
		return false ;
	}

	// Update MaxChannels in case we couldn't create enough sources.
	MaxChannels = Sources.Num();
	UE_LOG(LogALAudio, Verbose, TEXT("ALAudioDevice: Allocated %i sources"), MaxChannels);

	// Use our own distance model.
	alDistanceModel( AL_NONE );

	// Set up a default (nop) effects manager
	Effects = new FAudioEffectsManager( this );

	return true ;
}
Example #26
0
value lime_al_get_string (value param) {

    return alloc_string (alGetString (val_int (param)));

}
Example #27
0
void SetupSound()
{
    unsigned char buf[BUFFER_SIZE];
    int i;
    
    // Get handle to device.
    pDevice = alcOpenDevice(NULL);
    if(checkALCError())
    {
        fprintf(stderr, "[SPU] alcOpenDevice failed.\n");
        return;
    }
    
    // ALC info.
    const ALCubyte* UNUSED_VARIABLE deviceName = (ALCubyte*)alcGetString(pDevice, ALC_DEVICE_SPECIFIER);
    //printf("[SPU] ALC_DEVICE_SPECIFIER = %s.\n", deviceName);
    
    const ALCubyte* UNUSED_VARIABLE extensionList = (ALCubyte*)alcGetString(pDevice, ALC_EXTENSIONS);
    //printf("[SPU] ALC_EXTENSIONS = %s.\n", extensionList);
    
    // Create audio context.
    pContext = alcCreateContext(pDevice, NULL);
    if(checkALCError())
    {
        fprintf(stderr, "[SPU] alcCreateContext failed.\n");
        return;
    }
    
    // Set active context.
    alcMakeContextCurrent( pContext );
    if( checkALCError() )
    {
        fprintf(stderr, "[SPU] alcMakeContextCurrent failed.\n");
        return;
    }
    
    // AL info.
    const ALubyte* UNUSED_VARIABLE version = (ALubyte*)alGetString(AL_VERSION);
    //printf("[SPU] AL_VERSION = %s.\n", version);
    
    const ALubyte* UNUSED_VARIABLE renderer = (ALubyte*)alGetString(AL_RENDERER);
    //printf("[SPU] AL_RENDERER = %s.\n", renderer);

    const ALubyte* UNUSED_VARIABLE vendor = (ALubyte*)alGetString(AL_VENDOR);
    //printf("[SPU] AL_VENDOR = %s.\n", vendor);
    
    // Create buffers.
    alGenBuffers(BUFFER_QUANTITY, buffers);
    checkALError();
    
    // Load sound data into a buffer.
    memset(buf, 0x00, BUFFER_SIZE);
    for(i = 0; i < BUFFER_QUANTITY; ++i)
    {
        alBufferData(buffers[i], format, buf, BUFFER_SIZE, sampleRate);
    }
    checkALError();
    
    // Create source.
    alGenSources(1, &source);
    checkALError();
    
    // Bind buffer with a source.
    alSourcef (source, AL_PITCH,           1.0f     );
    alSourcef (source, AL_GAIN,            1.0f     );
    alSourcefv(source, AL_POSITION,        SourcePos);
    alSourcefv(source, AL_VELOCITY,        SourceVel);
    alSourcefv(source, AL_DIRECTION,       SourceDir);
    alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE  );
    alSourcei (source, AL_LOOPING,         AL_FALSE );
    
    // Listener properties.
    alListenerfv(AL_POSITION,    ListenerPos);
    alListenerfv(AL_VELOCITY,    ListenerVel);
    alListenerfv(AL_ORIENTATION, ListenerOri);
    
    // Add buffers to queue.
    alSourceQueueBuffers(source, BUFFER_QUANTITY, buffers);
    checkALError();
    
    // Enable playing.
    alSourcePlay(source);
    checkALError();
}
Example #28
0
	bool cOpenALDeviceContext::initialize(const char* deviceName, int outputFrequency, int eaxEffectSlots)
	{
		cAudioMutexBasicLock lock(Mutex);

		if(Initialized)
			return false;

		//Stores the context attributes (MAX of 4, with 2 zeros to terminate)
		ALint attribs[6] = { 0 };

		unsigned int currentAttrib = 0;
		if(outputFrequency > 0)
		{
			attribs[currentAttrib++] = ALC_FREQUENCY;
			attribs[currentAttrib++] = outputFrequency;
		}
#if CAUDIO_EFX_ENABLED == 1
		if(eaxEffectSlots > 0)
		{
			attribs[currentAttrib++] = ALC_MAX_AUXILIARY_SENDS;
			attribs[currentAttrib++] = eaxEffectSlots;
		}
#endif

		//Create a new device
		Device = alcOpenDevice(deviceName);
		//Check if device can be created
		if (Device == NULL)
		{
			getLogger()->logError("AudioManager", "Failed to Create OpenAL Device.");
			checkError();
			return false;
		}

		Context = alcCreateContext(Device, attribs);
		if (Context == NULL)
		{
			getLogger()->logError("AudioManager", "Failed to Create OpenAL Context.");
			checkError();
			alcCloseDevice(Device);
			Device = NULL;
			return false;
		}

		if(!alcMakeContextCurrent(Context))
		{
			getLogger()->logError("AudioManager", "Failed to make OpenAL Context current.");
			checkError();
			alcDestroyContext(Context);
			alcCloseDevice(Device);
			Context = NULL;
			Device = NULL;
			return false;
		}

		getLogger()->logInfo("AudioManager", "OpenAL Version: %s", alGetString(AL_VERSION));
		getLogger()->logInfo("AudioManager", "Vendor: %s", alGetString(AL_VENDOR));
		getLogger()->logInfo("AudioManager", "Renderer: %s", alGetString(AL_RENDERER));

#if CAUDIO_EFX_ENABLED == 1
		initEffects.getEFXInterface()->Mutex.lock();
		EFXSupported = initEffects.getEFXInterface()->CheckEFXSupport(Device);
		initEffects.getEFXInterface()->Mutex.unlock();
		initEffects.checkEFXSupportDetails();

		if(EFXSupported)
		{
			int EFXMajorVersion = 0;
			int EFXMinorVersion = 0;
			alcGetIntegerv(Device, ALC_EFX_MAJOR_VERSION, 1, &EFXMajorVersion);
			alcGetIntegerv(Device, ALC_EFX_MINOR_VERSION, 1, &EFXMinorVersion);
			getLogger()->logInfo("AudioManager", "EFX Version: %i.%i", EFXMajorVersion, EFXMinorVersion);
			getLogger()->logInfo("AudioManager", "EFX supported and enabled.");
		}
		else
		{
			getLogger()->logWarning("AudioManager", "EFX is not supported, EFX disabled.");
		}
#endif
		getLogger()->logInfo("AudioManager", "Supported Extensions: %s", alGetString(AL_EXTENSIONS));

		return true;
	}
Example #29
0
void ActualizarMusica (  ){
        ALint error;
    	int cont = 0;
    	int contador = 0;
    	int i;
    	int posicion = 0;
        ALuint streambuffers[NUM_BUFFER_MUSICA]; /* Utilizado en la carga de archivos OGG */
        ALshort waveout [BUFFER_MUSICA];  /* Donde almacenamos los OGG Vorbis decodificados */
        ALuint streamsource[1]; /* Utilizado en la carga de archivos OGG */
        
      /* Generamos  buffers para hacer el streaming */
	alGenBuffers ( NUM_BUFFER_MUSICA, streambuffers);
     	if ( (error = alGetError()) != AL_NO_ERROR){
        	fprintf ( logs,"Fallo al crear los buffers para la musica:%s\n", alGetString(error));
        	exit (2);
     	}  
     /* Rellenamos los buffers creados con la musica decodificada */
     for ( i=0; i < NUM_BUFFER_MUSICA ; i++){
		cont = ov_read ( &buff, (char *)&waveout[posicion], BUFFER_MUSICA , 0, 2, 1, &current_section ) / 2;
        contador += cont;
        fprintf ( logs, "contador = \n");
        alBufferData ( streambuffers[i], formato, waveout , BUFFER_MUSICA , informacion->rate );
        if ( (error =alGetError ()) != AL_NO_ERROR ){
               	fprintf ( logs, "Error al anyadir datos al buffer %i:%s\n",i,alGetString(error));
        }
	}
        
        /* Creamos la fuente y definimos sus propiedades */
        alGenSources( 1, streamsource );
        if ( (error = alGetError()) != AL_NO_ERROR ){
                	fprintf ( logs, "Error al generar la fuente de sonido: %s\n", alGetString (error));
        }
         
        /* Defino propiedades para la fuente */
        /*alSourcei ( streamsource[0], AL_SOURCE_RELATIVE, AL_TRUE ); /* Para que se mueva con el listener */
        /*alSourcei ( streamsource[0], AL_LOOPING, AL_FALSE ); /* No se repite por ella sola */
        /*alSourcef ( streamsource[0], AL_GAIN, 0.9f ); /* Para que suene menos que los sonidos */

        /* Asignamos los buffers creados a la fuente */
        alSourceQueueBuffers ( streamsource[0], NUM_BUFFER_MUSICA, streambuffers );

        /* Se empieza a reproducir la musica */
        alSourcePlay ( streamsource[0] );
        if ( (error = alGetError ()) != AL_NO_ERROR ){
              fprintf ( logs, "Error al reproducir musica:%s\n",alGetString (error));
        }
	/* A partir de aqui es donde realmente empieza el Streaming*/
	while ( contador < tamanyo_cancion ){

            /* Comprobamos estado de los buffers */
        	alGetSourceiv ( streamsource[0], AL_BUFFERS_PROCESSED, &buffers_vacios);
        
       		/* Si algun buffer esta vacio, lo rellenamos */
       		if ( buffers_vacios > 0 ){
         
               while ( buffers_vacios ){
				
                    /* Desasignamos buffers para rellenarlos */
          			alSourceUnqueueBuffers ( streamsource[0], 1, &streambuffers );
          			if ( (alGetError( )) != AL_NO_ERROR ){
              				fprintf ( logs,"No va el streaming\n");
          			}
					/* Descomprimimos datos en el buffer intermedio */	
			   		cont = ov_read ( &buff, (char *)&waveout, BUFFER_MUSICA, 0, 2, 1, &current_section);
                	contador += cont;
                    /* Los  anyadimos en el buffer */
              		alBufferData ( streambuffers, formato, waveout, BUFFER_MUSICA, frecuencia );
					if ((alGetError()) != AL_NO_ERROR ){
						fprintf ( logs, "No se puede aƱadir datos al buffer\n");
					}
          			/* Asignamos de nuevo los buffers al streamsource */
          			alSourceQueueBuffers ( streamsource[0], 1, &streambuffers );
          			buffers_vacios --;
                    /* Compruebo si se ha acabado la cancion */
                    if ( contador < tamanyo_cancion){
                        break;
                    }
                }
             }
     }

     /* Cuando se acaba la cancion, paramos todo y borramos buffers y fuentes */
     alSourceStopv(1, streamsource);
     if (alGetError() != AL_NO_ERROR){
              fprintf ( logs,"No se pueden parar el streamsource\n");
     }
     alDeleteSources(1, streamsource);
     if (alGetError() != AL_NO_ERROR){
             fprintf ( logs,"No se puede borrar el stremsource\n");
     }
     alDeleteBuffers(NUM_BUFFER_MUSICA, streambuffers);
     if (alGetError() != AL_NO_ERROR){
             fprintf ( logs,"No se pueden borrar los buffers\n");
     }

     musica_on = 0;
}
Example #30
0
void sound_Update()
{
    SAMPLE_LIST *node = active_samples;
    SAMPLE_LIST *previous = NULL;
    ALCenum err;
    ALfloat gain;

    if (!openal_initialized)
    {
        return;
    }

    // Update all streaming audio
    sound_UpdateStreams();

    while (node != NULL)
    {
        ALenum state, err;

        // query what the gain is for this sample
        alGetSourcef(node->curr->iSample, AL_GAIN, &gain);
        err = sound_GetError();

        // if gain is 0, then we can't hear it, so we kill it.
        if (gain == 0.0f)
        {
            sound_DestroyIteratedSample(&previous, &node);
            continue;
        }

        //ASSERT(alIsSource(node->curr->iSample), "Not a valid source!");
        alGetSourcei(node->curr->iSample, AL_SOURCE_STATE, &state);

        // Check whether an error occurred while retrieving the state.
        // If one did, the state returned is useless. So instead of
        // using it continue with the next sample.
        err = sound_GetError();
        if (err != AL_NO_ERROR)
        {
            // Make sure to invoke the "finished" callback
            sound_FinishedCallback(node->curr);

            // Destroy this object and move to the next object
            sound_DestroyIteratedSample(&previous, &node);
            continue;
        }

        switch (state)
        {
        case AL_PLAYING:
        case AL_PAUSED:
            // If we haven't finished playing yet, just
            // continue with the next item in the list.

            // sound_SetObjectPosition(i->curr->iSample, i->curr->x, i->curr->y, i->curr->z);

            // Move to the next object
            previous = node;
            node = node->next;
            break;

        // NOTE: if it isn't playing | paused, then it is most likely either done
        // or a error.  In either case, we want to kill the sample in question.

        default:
            sound_DestroyIteratedSample(&previous, &node);
            break;
        }
    }

    // Reset the current error state
    alcGetError(device);

    alcProcessContext(context);

    err = sound_GetContextError(device);
    if (err != ALC_NO_ERROR)
    {
        debug(LOG_ERROR, "Error while processing audio context: %s", alGetString(err));
    }
}