mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
OpenAL Streaming Sound stuff
from zeq2, but adapted/stripped down for our needs. Videos work (for me), music does not (yet)
This commit is contained in:
parent
6384b850f1
commit
04fd7f2cda
4 changed files with 211 additions and 52 deletions
|
@ -181,6 +181,7 @@ void AL_StopChannel( channel_t *ch );
|
|||
void AL_PlayChannel( channel_t *ch );
|
||||
void AL_StopAllChannels( void );
|
||||
void AL_Update( void );
|
||||
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*
|
||||
This Source File was taken from the Q2Pro Port.
|
||||
This Source File - except for the last few functions - see the other copyright
|
||||
notice further down the - was taken from the Q2Pro Port.
|
||||
|
||||
Copyright (C) 2010 skuller.net
|
||||
2012 Some changes by the Yamagi Quake2 developers
|
||||
2012 Some changes by the Yamagi Quake II developers
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
@ -26,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "../header/client.h"
|
||||
#include "header/local.h"
|
||||
#include "header/qal_api.h"
|
||||
#include "header/vorbis.h"
|
||||
|
||||
// translates from AL coordinate system to quake
|
||||
#define AL_UnpackVector(v) -v[1],v[2],-v[0]
|
||||
|
@ -34,9 +36,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// OpenAL implementation should support at least this number of sources
|
||||
#define MIN_CHANNELS 16
|
||||
|
||||
static ALuint s_srcnums[MAX_CHANNELS];
|
||||
qboolean streamPlaying;
|
||||
static ALuint streamSource;
|
||||
|
||||
static ALuint s_srcnums[MAX_CHANNELS-1];
|
||||
static int s_framecount;
|
||||
|
||||
// Forward Declarations
|
||||
static void S_AL_StreamUpdate( void );
|
||||
static void S_AL_StreamDie( void );
|
||||
// /Forward Declarations
|
||||
|
||||
void AL_SoundInfo( void ) {
|
||||
Com_Printf( "AL_VENDOR: %s\n", qalGetString( AL_VENDOR ) );
|
||||
Com_Printf( "AL_RENDERER: %s\n", qalGetString( AL_RENDERER ) );
|
||||
|
@ -45,6 +55,18 @@ void AL_SoundInfo( void ) {
|
|||
Com_Printf( "Number of sources: %d\n", s_numchannels );
|
||||
}
|
||||
|
||||
static void AL_InitStreamSource() {
|
||||
qalSourcei (streamSource, AL_BUFFER, 0 );
|
||||
qalSourcei (streamSource, AL_LOOPING, AL_FALSE );
|
||||
qalSource3f(streamSource, AL_POSITION, 0.0, 0.0, 0.0);
|
||||
qalSource3f(streamSource, AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
qalSource3f(streamSource, AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
qalSourcef (streamSource, AL_ROLLOFF_FACTOR, 0.0 );
|
||||
qalSourcei (streamSource, AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
|
||||
// srcList[cursrc].scaleGain = 0.0f; FIXME - something like that?
|
||||
}
|
||||
|
||||
qboolean AL_Init( void ) {
|
||||
int i;
|
||||
|
||||
|
@ -61,19 +83,29 @@ qboolean AL_Init( void ) {
|
|||
|
||||
// generate source names
|
||||
qalGetError();
|
||||
for( i = 0; i < MAX_CHANNELS; i++ ) {
|
||||
qalGenSources( 1, &s_srcnums[i] );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
qalGenSources( 1, &streamSource );
|
||||
if( qalGetError() != AL_NO_ERROR )
|
||||
{
|
||||
Com_Printf( "ERROR: Couldn't get a single Source.\n" );
|
||||
goto fail;
|
||||
|
||||
if( i < MIN_CHANNELS ) {
|
||||
Com_Printf( "ERROR: Required at least %d sources, but got %d.\n", MIN_CHANNELS, i );
|
||||
goto fail;
|
||||
} else {
|
||||
// -1 because we already got one channel for streaming
|
||||
for( i = 0; i < MAX_CHANNELS - 1; i++ ) {
|
||||
qalGenSources( 1, &s_srcnums[i] );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i < MIN_CHANNELS - 1 ) {
|
||||
Com_Printf( "ERROR: Required at least %d sources, but got %d.\n", MIN_CHANNELS, i+1 );
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
s_numchannels = i;
|
||||
AL_InitStreamSource();
|
||||
|
||||
Com_Printf( "OpenAL initialized.\n" );
|
||||
return true;
|
||||
|
@ -92,7 +124,7 @@ void AL_Shutdown( void ) {
|
|||
memset( s_srcnums, 0, sizeof( s_srcnums ) );
|
||||
s_numchannels = 0;
|
||||
}
|
||||
|
||||
S_AL_StreamDie();
|
||||
QAL_Shutdown();
|
||||
}
|
||||
|
||||
|
@ -204,6 +236,8 @@ void AL_StopAllChannels( void ) {
|
|||
continue;
|
||||
AL_StopChannel( ch );
|
||||
}
|
||||
s_rawend = 0;
|
||||
S_AL_StreamDie();
|
||||
}
|
||||
|
||||
static channel_t *AL_FindLoopingSound( int entnum, sfx_t *sfx ) {
|
||||
|
@ -291,34 +325,6 @@ static void AL_IssuePlaysounds( void ) {
|
|||
break;
|
||||
S_IssuePlaysound (ps);
|
||||
}
|
||||
// TODO: streaming sounds from s_rawsamples, equivalent to code below - see also ioq3's code
|
||||
|
||||
#if 0
|
||||
/* clear the paint buffer */
|
||||
if ( s_rawend < paintedtime )
|
||||
{
|
||||
memset( paintbuffer, 0, ( end - paintedtime ) * sizeof ( portable_samplepair_t ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* copy from the streaming sound source */
|
||||
int s;
|
||||
int stop;
|
||||
|
||||
stop = ( end < s_rawend ) ? end : s_rawend;
|
||||
|
||||
for ( i = paintedtime; i < stop; i++ )
|
||||
{
|
||||
s = i & ( MAX_RAW_SAMPLES - 1 );
|
||||
paintbuffer [ i - paintedtime ] = s_rawsamples [ s ];
|
||||
}
|
||||
|
||||
for ( ; i < end; i++ )
|
||||
{
|
||||
paintbuffer [ i - paintedtime ].left = paintbuffer [ i - paintedtime ].right = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AL_Update( void ) {
|
||||
|
@ -326,13 +332,13 @@ void AL_Update( void ) {
|
|||
channel_t *ch;
|
||||
vec_t orientation[6];
|
||||
|
||||
/*
|
||||
/* FIXME
|
||||
if( !s_active ) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
paintedtime = cl.time;
|
||||
// paintedtime = cl.time; // FIXME: this does *not* make music work.
|
||||
|
||||
// set listener parameters
|
||||
qalListener3f( AL_POSITION, AL_UnpackVector( listener_origin ) );
|
||||
|
@ -380,10 +386,156 @@ void AL_Update( void ) {
|
|||
// add loopsounds
|
||||
AL_AddLoopSounds ();
|
||||
|
||||
// FIXME: About here some ogg vorbis stuff (maybe calling OGG_Stream()
|
||||
// like in S_Update()) should be done.
|
||||
// add music
|
||||
OGG_Stream();
|
||||
S_AL_StreamUpdate();
|
||||
|
||||
AL_IssuePlaysounds();
|
||||
|
||||
//paintedtime = <begintime of last pending play>; ??
|
||||
// evtl paintedtime = soundtime falls paintedtime < soundtime - aber soundtime ist eigentlich DMA spezifisch
|
||||
// paintedtime = cl.time; FIXME: das allein reicht nicht damit musik funktioniert
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
* The remaining functions in this file are from zeq2 who seem to have got
|
||||
* them from ioquake3. Adapted for Yamagi Quake II (e.g. we only need one
|
||||
* non-spatialized stream)
|
||||
*
|
||||
* They came with the following copyright notice (modified to make clear
|
||||
* that only the rest of this file is affected):
|
||||
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
Copyright (C) 2005 Stuart Dalton (badcdev@gmail.com)
|
||||
2012 Some changes by the Yamagi Quake II developers
|
||||
|
||||
The rest of this file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
static void S_AL_StreamDie( void )
|
||||
{
|
||||
int numBuffers;
|
||||
|
||||
|
||||
streamPlaying = false;
|
||||
qalSourceStop(streamSource);
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
qalGetSourcei( streamSource, AL_BUFFERS_PROCESSED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
|
||||
qalDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
// S_AL_FreeStreamChannel(stream);
|
||||
}
|
||||
|
||||
static void S_AL_StreamUpdate( void )
|
||||
{
|
||||
int numBuffers;
|
||||
ALint state;
|
||||
|
||||
// Un-queue any buffers, and delete them
|
||||
qalGetSourcei( streamSource, AL_BUFFERS_PROCESSED, &numBuffers );
|
||||
while( numBuffers-- )
|
||||
{
|
||||
ALuint buffer;
|
||||
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
|
||||
qalDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
// Start the streamSource playing if necessary
|
||||
qalGetSourcei( streamSource, AL_BUFFERS_QUEUED, &numBuffers );
|
||||
|
||||
qalGetSourcei(streamSource, AL_SOURCE_STATE, &state);
|
||||
if(state == AL_STOPPED)
|
||||
{
|
||||
streamPlaying = false;
|
||||
|
||||
// If there are no buffers queued up, release the streamSource
|
||||
//if( !numBuffers )
|
||||
// S_AL_FreeStreamChannel( stream );
|
||||
}
|
||||
|
||||
if( !streamPlaying && numBuffers )
|
||||
{
|
||||
qalSourcePlay( streamSource );
|
||||
streamPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
static ALuint S_AL_Format(int width, int channels)
|
||||
{
|
||||
ALuint format = AL_FORMAT_MONO16;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
/*
|
||||
// get this buffers speed/frequency
|
||||
ALint speed = 0;
|
||||
qalGetBufferi(buffer, AL_FREQUENCY, &speed);
|
||||
// FIXME: the buffers are leaking I think
|
||||
float scale = (float) rate / speed;
|
||||
|
||||
if( samples > 0 && scale >= 0.0f ) {
|
||||
s_rawend += samples/scale;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endif // USE_OPENAL
|
||||
|
|
|
@ -1101,16 +1101,20 @@ S_RawSamples ( int samples, int rate, int width, int channels, byte *data, float
|
|||
return;
|
||||
}
|
||||
|
||||
// FIXME!!
|
||||
if( sound_started == SS_OAL )
|
||||
return;
|
||||
|
||||
if ( s_rawend < paintedtime )
|
||||
{
|
||||
s_rawend = paintedtime;
|
||||
}
|
||||
|
||||
scale = (float) rate / dma.speed; // FIXME: dma.speed is not available (0) when using openal
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL )
|
||||
{
|
||||
AL_RawSamples(samples, rate, width, channels, data, volume);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
scale = (float) rate / dma.speed;
|
||||
intVolume = (int) (256 * volume);
|
||||
|
||||
if ( ( channels == 2 ) && ( width == 2 ) )
|
||||
|
@ -1243,7 +1247,9 @@ S_Update ( vec3_t origin, vec3_t forward, vec3_t right, vec3_t up )
|
|||
* dma buffer while loading */
|
||||
if ( cls.disable_screen )
|
||||
{
|
||||
S_ClearBuffer();
|
||||
if (sound_started == SS_DMA ) {
|
||||
S_ClearBuffer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -602,7 +602,7 @@ OGG_Stream ( void )
|
|||
return;
|
||||
}
|
||||
|
||||
while ( ogg_status == PLAY && paintedtime + MAX_RAW_SAMPLES - 2048 > s_rawend )
|
||||
while ( ogg_status == PLAY && paintedtime + MAX_RAW_SAMPLES - 2048 > s_rawend )
|
||||
{
|
||||
OGG_Read();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue