示例#1
0
void sound_ShutdownLibrary( void )
{
#if !defined(WZ_NOSOUND)
	AUDIO_STREAM* stream;
#endif
	SAMPLE_LIST * aSample = active_samples, * tmpSample = NULL;

	if ( !openal_initialized )
	{
		return;
	}
	debug(LOG_SOUND, "starting shutdown");

#if !defined(WZ_NOSOUND)
	// Stop all streams, sound_UpdateStreams() will deallocate all stopped streams
	for (stream = active_streams; stream != NULL; stream = stream->next)
	{
		sound_StopStream(stream);
	}
	sound_UpdateStreams();
	
	alcGetError(device);	// clear error codes

	/* On Linux since this caused some versions of OpenAL to hang on exit. - Per */
	debug(LOG_SOUND, "make default context NULL");
	alcMakeContextCurrent(NULL);
	sound_GetContextError(device);

	debug(LOG_SOUND, "destroy previous context");
	alcDestroyContext(context); // this gives a long delay on some impl.
	sound_GetContextError(device);

	debug(LOG_SOUND, "close device");
	if (alcCloseDevice(device) == ALC_FALSE)
	{
		debug(LOG_SOUND, "OpenAl could not close the audio device." ); 
	}
#endif

	while( aSample )
	{
		tmpSample = aSample->next;
		free( aSample );
		aSample = tmpSample;
	}
	active_samples = NULL;
}
示例#2
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));
    }
}