Example #1
0
 /*
  * Uploads a sample to OpenAL and places
  * a dummy entry in the frontends cache.
  * This is not nice but necessary for the
  * frontend to work.
  */
 sfxcache_t *
 AL_UploadSfx ( sfx_t *s, wavinfo_t *s_info, byte *data )
 {
   sfxcache_t *sc;
   ALsizei size;
   ALenum format;
   ALuint name;
   size = s_info->samples * s_info->width;
   format = s_info->width == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;

   if ( !size ) {
     return NULL;
   }

   qalGetError();
   qalGenBuffers ( 1, &name );
   qalBufferData ( name, format, data, size, s_info->rate );
   active_buffers++;

   if ( qalGetError() != AL_NO_ERROR ) {
     return NULL;
   }

   /* allocate placeholder sfxcache */
   sc = s->cache = Z_TagMalloc ( sizeof ( *sc ), 0 );
   sc->length = s_info->samples * 1000 / s_info->rate;
   sc->loopstart = s_info->loopstart;
   sc->width = s_info->width;
   sc->size = size;
   sc->bufnum = name;
   return sc;
 }
/*
=================
S_AL_RawSamples
=================
*/
static
void S_AL_RawSamples(int samples, int rate, int width, int channels, const byte *data, float volume)
{
	ALuint buffer;
	ALuint format;

	format = S_AL_Format( width, channels );

	// Create the streamSource if necessary
	if(streamSourceHandle == -1)
	{
		S_AL_AllocateStreamChannel();
	
		// Failed?
		if(streamSourceHandle == -1)
		{
			Com_Printf( S_COLOR_RED "ERROR: Can't allocate streaming streamSource\n");
			return;
		}
	}

	// Create a buffer, and stuff the data into it
	qalGenBuffers(1, &buffer);
	qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);

	// Shove the data onto the streamSource
	qalSourceQueueBuffers(streamSource, 1, &buffer);

	// Volume
	qalSourcef (streamSource, AL_GAIN, volume * s_volume->value * s_alGain->value);
}
Example #3
0
File: al.c Project: jayschwa/q2pro
sfxcache_t *AL_UploadSfx(sfx_t *s)
{
    sfxcache_t *sc;
    ALsizei size = s_info.samples * s_info.width;
    ALenum format = s_info.width == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
    ALuint name;

    if (!size) {
        s->error = Q_ERR_TOO_FEW;
        return NULL;
    }

    qalGetError();
    qalGenBuffers(1, &name);
    qalBufferData(name, format, s_info.data, size, s_info.rate);
    if (qalGetError() != AL_NO_ERROR) {
        s->error = Q_ERR_LIBRARY_ERROR;
        return NULL;
    }

    // allocate placeholder sfxcache
    sc = s->cache = S_Malloc(sizeof(*sc));
    sc->length = s_info.samples * 1000 / s_info.rate; // in msec
    sc->loopstart = s_info.loopstart;
    sc->width = s_info.width;
    sc->size = size;
    sc->bufnum = name;

    return sc;
}
/*
=================
S_StreamRawSamples

Cinematic streaming
=================
*/
void S_StreamRawSamples (const byte *data, int samples, int rate, int width, int channels)
{
	int			processed, state, size;
	unsigned	format, buffer;

	if (!s_initialized)
		return;

	if (!s_streamingChannel)
		return;

	// Unqueue and delete any processed buffers
	qalGetSourcei(s_streamingChannel->sourceNum, AL_BUFFERS_PROCESSED, &processed);
	if (processed > 0){
		while (processed--){
			qalSourceUnqueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);
			qalDeleteBuffers(1, &buffer);
		}
	}

	// Calculate buffer size
	size = samples * width * channels;

	// Set buffer format
	if (width == 2)
	{
		if (channels == 2)
			format = AL_FORMAT_STEREO16;
		else
			format = AL_FORMAT_MONO16;
	}
	else
	{
		if (channels == 2)
			format = AL_FORMAT_STEREO8;
		else
			format = AL_FORMAT_MONO8;
	}

	// Upload and queue the new buffer
	qalGenBuffers(1, &buffer);
	qalBufferData(buffer, format, (byte *)data, size, rate);
	qalSourceQueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);

	// Update volume
	qalSourcef(s_streamingChannel->sourceNum, AL_GAIN, s_sfxVolume->value);

	// If not playing, then do so
	qalGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state);
	if (state != AL_PLAYING)
		qalSourcePlay(s_streamingChannel->sourceNum);
}
Example #5
0
static qboolean music_process( ALuint b )
{
    int l = 0;
    ALuint format;
    ALenum error;
    snd_stream_t *music_stream;

start:
    if( s_bgTrackBuffering )
        return qtrue;

    music_stream = s_bgTrack->stream;
    if( music_stream ) {
        l = S_ReadStream( music_stream, MUSIC_BUFFER_SIZE, decode_buffer );
    }
    else {
        l = 0;
    }

    if( !l )
    {
        bgTrack_t *cur;

        cur = s_bgTrack;
        if( !S_AdvanceBackgroundTrack( 1 ) )
        {
            if( !S_ValidMusicFile( s_bgTrack ) )
                return qfalse;
        }
        else
        {
            // we've advanced to the next track, close this one
            S_CloseMusicTrack( cur );
            goto start;
        }

        if( !S_ResetStream( music_stream ) )
        {
            // if failed, close the track?
            return qfalse;
        }

        goto start;
    }

    format = S_SoundFormat( music_stream->info.width, music_stream->info.channels );
    qalBufferData( b, format, decode_buffer, l, music_stream->info.rate );
    if( ( error = qalGetError() ) != AL_NO_ERROR )
        return qfalse;

    return qtrue;
}
Example #6
0
/*
 * Queues raw samples for playback. Used
 * by the background music an cinematics.
 */
void
AL_RawSamples(int samples, int rate, int width, int channels,
		byte *data, float volume)
{
	ALuint buffer;
	ALuint format = 0;

	/* Work out format */
	if (width == 1)
	{
		if (channels == 1)
		{
			format = AL_FORMAT_MONO8;
		}
		else if (channels == 2)
		{
			format = AL_FORMAT_STEREO8;
		}
	}
	else if (width == 2)
	{
		if (channels == 1)
		{
			format = AL_FORMAT_MONO16;
		}
		else if (channels == 2)
		{
			format = AL_FORMAT_STEREO16;
		}
	}

	/* Create a buffer, and stuff the data into it */
	qalGenBuffers(1, &buffer);
	qalBufferData(buffer, format, (ALvoid *)data,
			(samples * width * channels), rate);
	active_buffers++;

    /* set volume */
	if (volume > 1.0f)
	{
		volume = 1.0f;
	}

	qalSourcef(streamSource, AL_GAIN, volume);

	/* Shove the data onto the streamSource */
	qalSourceQueueBuffers(streamSource, 1, &buffer);

	/* emulate behavior of S_RawSamples for s_rawend */
	s_rawend += samples;
}
Example #7
0
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume )
{
	ALuint buffer;
	ALuint format;

	format = S_AL_Format( width, channels );

	// Create a buffer, and stuff the data into it
	qalGenBuffers(1, &buffer);
	qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);
	active_buffers++;

	// set volume
	qalSourcef( streamSource, AL_GAIN, volume );

	// Shove the data onto the streamSource
	qalSourceQueueBuffers(streamSource, 1, &buffer);

	// emulate behavior of S_RawSamples for s_rawend
	s_rawend += samples;
}
Example #8
0
void al_mus_process( ALuint b )
{
	int    l;
	ALuint format;

	l = si.StreamRead( mus_stream, BUFFER_SIZE, decode_buffer );

	if ( l == 0 )
	{
		si.StreamClose( mus_stream );
		mus_stream = si.StreamOpen( s_backgroundLoop );

		if ( !mus_stream )
		{
			SndAl_StopBackgroundTrack();
			return;
		}

		l = si.StreamRead( mus_stream, BUFFER_SIZE, decode_buffer );
	}

	format = al_format( mus_stream->info.width, mus_stream->info.channels );
	qalBufferData( b, format, decode_buffer, l, mus_stream->info.rate );
}
/*
=================
S_AL_BufferLoad
=================
*/
static void S_AL_BufferLoad(sfxHandle_t sfx)
{
	ALenum error;

	void *data;
	snd_info_t info;
	ALuint format;

	// Nothing?
	if(knownSfx[sfx].filename[0] == '\0')
		return;

	// Player SFX
	if(knownSfx[sfx].filename[0] == '*')
		return;

	// Already done?
	if((knownSfx[sfx].inMemory) || (knownSfx[sfx].isDefault))
		return;

	// Try to load
	data = S_CodecLoad(knownSfx[sfx].filename, &info);
	if(!data)
	{
		S_AL_BufferUseDefault(sfx);
		return;
	}

	format = S_AL_Format(info.width, info.channels);

	// Create a buffer
	qalGenBuffers(1, &knownSfx[sfx].buffer);
	if((error = qalGetError()) != AL_NO_ERROR)
	{
		S_AL_BufferUseDefault(sfx);
		Z_Free(data);
		Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n",
				knownSfx[sfx].filename, S_AL_ErrorMsg(error));
		return;
	}

	// Fill the buffer
	if( info.size == 0 )
	{
		// We have no data to buffer, so buffer silence
		byte dummyData[ 2 ] = { 0 };

		qalBufferData(knownSfx[sfx].buffer, AL_FORMAT_MONO16, (void *)dummyData, 2, 22050);
	}
	else
		qalBufferData(knownSfx[sfx].buffer, format, data, info.size, info.rate);

	error = qalGetError();

	// If we ran out of memory, start evicting the least recently used sounds
	while(error == AL_OUT_OF_MEMORY)
	{
		if( !S_AL_BufferEvict( ) )
		{
			S_AL_BufferUseDefault(sfx);
			Z_Free(data);
			Com_Printf( S_COLOR_RED "ERROR: Out of memory loading %s\n", knownSfx[sfx].filename);
			return;
		}

		// Try load it again
		qalBufferData(knownSfx[sfx].buffer, format, data, info.size, info.rate);
		error = qalGetError();
	}

	// Some other error condition
	if(error != AL_NO_ERROR)
	{
		S_AL_BufferUseDefault(sfx);
		Z_Free(data);
		Com_Printf( S_COLOR_RED "ERROR: Can't fill sound buffer for %s - %s\n",
				knownSfx[sfx].filename, S_AL_ErrorMsg(error));
		return;
	}

	// Free the memory
	Z_Free(data);

	// Woo!
	knownSfx[sfx].inMemory = qtrue;
}
/*
=================
S_AL_MusicProcess
=================
*/
static
void S_AL_MusicProcess(ALuint b)
{
	ALenum error;
	int l;
	ALuint format;
	snd_stream_t *curstream;

	if(intro_stream)
		curstream = intro_stream;
	else
		curstream = mus_stream;

	if(!curstream)
		return;

	l = S_CodecReadStream(curstream, MUSIC_BUFFER_SIZE, decode_buffer);

	// Run out data to read, start at the beginning again
	if(l == 0)
	{
		S_CodecCloseStream(curstream);

		// the intro stream just finished playing so we don't need to reopen
		// the music stream.
		if(intro_stream)
			intro_stream = NULL;
		else
			mus_stream = S_CodecOpenStream(s_backgroundLoop);
		
		curstream = mus_stream;

		if(!curstream)
		{
			S_AL_StopBackgroundTrack();
			return;
		}

		l = S_CodecReadStream(curstream, MUSIC_BUFFER_SIZE, decode_buffer);
	}

	format = S_AL_Format(curstream->info.width, curstream->info.channels);

	if( l == 0 )
	{
		// We have no data to buffer, so buffer silence
		byte dummyData[ 2 ] = { 0 };

		qalBufferData( b, AL_FORMAT_MONO16, (void *)dummyData, 2, 22050 );
	}
	else
		qalBufferData(b, format, decode_buffer, l, curstream->info.rate);

	if( ( error = qalGetError( ) ) != AL_NO_ERROR )
	{
		S_AL_StopBackgroundTrack( );
		Com_Printf( S_COLOR_RED "ERROR: while buffering data for music stream - %s\n",
				S_AL_ErrorMsg( error ) );
		return;
	}
}
Example #11
0
void SndAl_RawSamples( int stream, int samples, int rate, int width, int channels, const byte *data, float volume, int entityNum )
{
	ALuint buffer;
	ALuint format = AL_FORMAT_STEREO16;
	ALint  state;

	// Work out AL format
	if ( width == 1 )
	{
		if ( channels == 1 )
		{
			format = AL_FORMAT_MONO8;
		}
		else if ( channels == 2 )
		{
			format = AL_FORMAT_STEREO8;
		}
	}
	else if ( width == 2 )
	{
		if ( channels == 1 )
		{
			format = AL_FORMAT_MONO16;
		}
		else if ( channels == 2 )
		{
			format = AL_FORMAT_STEREO16;
		}
	}

	// Create the source if necessary
	if ( source_handle == -1 )
	{
		allocate_channel();

		// Failed?
		if ( source_handle == -1 )
		{
			si.Printf( PRINT_ALL, "Can't allocate streaming source\n" );
			return;
		}
	}

	// Create a buffer, and stuff the data into it
	qalGenBuffers( 1, &buffer );
	qalBufferData( buffer, format, data, ( samples * width * channels ), rate );

	// Shove the data onto the source
	qalSourceQueueBuffers( source, 1, &buffer );

	// Start the source playing if necessary
	qalGetSourcei( source, AL_SOURCE_STATE, &state );

	// Volume
	qalSourcef( source, AL_GAIN, volume * s_volume->value * s_gain->value );

	if ( !is_playing )
	{
		qalSourcePlay( source );
		is_playing = qtrue;
	}
}
Example #12
0
bool S_LoadBuffer( sfx_t *sfx )
{
	ALenum error;
	void *data;
	snd_info_t info;
	ALuint format;

	if( !sfx ) {
		return false;
	}
	if( sfx->filename[0] == '\0' || sfx->inMemory )
		return false;
	if( trap_FS_IsUrl( sfx->filename ) )
		return false;

	data = S_LoadSound( sfx->filename, &info );
	if( !data )
	{
		//Com_DPrintf( "Couldn't load %s\n", sfx->filename );
		return false;
	}

	if( info.channels > 1 )
	{
		void *temp = stereo_mono( data, &info );
		if( temp )
		{
			S_Free( data );
			data = temp;
		}
	}

	format = S_SoundFormat( info.width, info.channels );

	qalGenBuffers( 1, &sfx->buffer );
	if( ( error = qalGetError() ) != AL_NO_ERROR )
	{
		S_Free( data );
		Com_Printf( "Couldn't create a sound buffer for %s (%s)\n", sfx->filename, S_ErrorMessage( error ) );
		return false;
	}

	qalBufferData( sfx->buffer, format, data, info.size, info.rate );
	error = qalGetError();

	// If we ran out of memory, start evicting the least recently used sounds
	while( error == AL_OUT_OF_MEMORY )
	{
		if( !buffer_evict() )
		{
			S_Free( data );
			Com_Printf( "Out of memory loading %s\n", sfx->filename );
			return false;
		}

		// Try load it again
		qalGetError();
		qalBufferData( sfx->buffer, format, data, info.size, info.rate );
		error = qalGetError();
	}

	// Some other error condition
	if( error != AL_NO_ERROR )
	{
		S_Free( data );
		Com_Printf( "Couldn't fill sound buffer for %s (%s)", sfx->filename, S_ErrorMessage( error ) );
		return false;
	}

	S_Free( data );
	sfx->inMemory = true;

	return true;
}