merge mixsdl and openal decoders. This removes a lot of duplicate code,

and should make maintenance a lot easier


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@605 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
ghaushe
2003-01-30 06:21:23 +00:00
parent 4fdceafc52
commit 56735c4662
20 changed files with 385 additions and 2091 deletions
+1 -1
View File
@@ -9,5 +9,5 @@ else
uqm_CFLAGS="$uqm_CFLAGS -DSOUNDMODULE_SDL" uqm_CFLAGS="$uqm_CFLAGS -DSOUNDMODULE_SDL"
fi fi
uqm_CFILES="fileinst.c resinst.c sound_common.c" uqm_CFILES="fileinst.c resinst.c sound_common.c sound.c sfx.c music.c stream.c trackplayer.c"
+1 -1
View File
@@ -1 +1 @@
uqm_CFILES="mixer.c sound.c music.c sfx.c stream.c trackplayer.c" uqm_CFILES="mixer.c sound_mixsdl.c"
@@ -17,12 +17,8 @@
*/ */
#ifdef SOUNDMODULE_MIXSDL #ifdef SOUNDMODULE_MIXSDL
#include "libs/graphics/sdl/sdl_common.h" #include "libs/graphics/sdl/sdl_common.h"
#include "libs/sound/sound_common.h" #include "libs/sound/sound.h"
#include "sound.h"
TFB_SoundSource soundSource[NUM_SOUNDSOURCES];
static Task StreamDecoderTask; static Task StreamDecoderTask;
int int
@@ -134,116 +130,4 @@ TFB_UninitSound (void)
mixSDL_CloseAudio (); mixSDL_CloseAudio ();
} }
void #endif
StopSound (void)
{
int i;
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
{
mixSDL_SourceRewind (soundSource[i].handle);
}
}
BOOLEAN
SoundPlaying (void)
{
int i;
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
{
TFB_SoundSample *sample;
sample = soundSource[i].sample;
if (sample && sample->decoder)
{
BOOLEAN result;
LockMutex (soundSource[i].stream_mutex);
result = PlayingStream (i);
UnlockMutex (soundSource[i].stream_mutex);
if (result)
return TRUE;
}
else
{
uint32 state;
mixSDL_GetSourcei (soundSource[i].handle, MIX_SOURCE_STATE, &state);
if (state == MIX_PLAYING)
return TRUE;
}
}
return FALSE;
}
TFB_SoundChain *
create_soundchain (TFB_SoundDecoder *decoder, float startTime)
{
TFB_SoundChain *chain;
chain = (TFB_SoundChain *)HMalloc (sizeof (TFB_SoundChain));
chain->decoder = decoder;
chain->next =NULL;
chain->start_time = startTime;
chain->tag.buf_name = 0;
chain->tag.type = 0;
return (chain);
}
void
destroy_soundchain (TFB_SoundChain *chain)
{
while (chain->next)
{
TFB_SoundChain *tmp_chain = chain->next;
chain->next = chain->next->next;
if (tmp_chain->decoder)
SoundDecoder_Free (tmp_chain->decoder);
HFree (tmp_chain);
}
SoundDecoder_Free (chain->decoder);
HFree (chain);
}
TFB_SoundChain *
get_previous_chain (TFB_SoundChain *first_chain, TFB_SoundChain *current_chain)
{
TFB_SoundChain *prev_chain;
prev_chain = first_chain;
if (prev_chain == current_chain)
return (prev_chain);
while (prev_chain->next)
{
if (prev_chain->next == current_chain)
return (prev_chain);
prev_chain = prev_chain->next;
}
return (first_chain);
}
// Status: Ignored
BOOLEAN
InitSound (int argc, char* argv[])
{
return TRUE;
}
// Status: Ignored
void
UninitSound (void)
{
}
void SetSFXVolume (float volume)
{
int i;
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
{
mixSDL_Sourcef (soundSource[i].handle, MIX_GAIN, volume);
}
}
void SetSpeechVolume (float volume)
{
mixSDL_Sourcef (soundSource[SPEECH_SOURCE].handle, MIX_GAIN, volume);
}
#endif
@@ -0,0 +1,70 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/
#include "mixer.h"
#define TFBSound_Object mixSDL_Object
/*************************************************
* General interface
*/
#define TFBSound_GetError mixSDL_GetError
#define TFBSound_OpenAudio mixSDL_OpenAudio
#define TFBSound_CloseAudio mixSDL_CloseAudio
#define TFBSound_QuerySpec mixSDL_QuerySpec
/*************************************************
* Sources
*/
#define TFBSound_GenSources mixSDL_GenSources
#define TFBSound_DeleteSources mixSDL_DeleteSources
#define TFBSound_IsSource mixSDL_IsSource
#define TFBSound_Sourcei mixSDL_Sourcei
#define TFBSound_Sourcef mixSDL_Sourcef
#define TFBSound_GetSourcei mixSDL_GetSourcei
#define TFBSound_GetSourcef mixSDL_GetSourcef
#define TFBSound_SourceRewind mixSDL_SourceRewind
#define TFBSound_SourcePlay mixSDL_SourcePlay
#define TFBSound_SourcePause mixSDL_SourcePause
#define TFBSound_SourceStop mixSDL_SourceStop
#define TFBSound_SourceQueueBuffers mixSDL_SourceQueueBuffers
#define TFBSound_SourceUnqueueBuffers mixSDL_SourceUnqueueBuffers
/*************************************************
* Buffers
*/
#define TFBSound_GenBuffers mixSDL_GenBuffers
#define TFBSound_DeleteBuffers mixSDL_DeleteBuffers
#define TFBSound_IsBuffer mixSDL_IsBuffer
#define TFBSound_GetBufferi mixSDL_GetBufferi
#define TFBSound_BufferData mixSDL_BufferData
#define TFBSound_ConvertBuffer mixSDL_ConvertBuffer
#define TFBSOUND_GAIN MIX_GAIN
#define TFBSOUND_BUFFER MIX_BUFFER
#define TFBSOUND_SOURCE_STATE MIX_SOURCE_STATE
#define TFBSOUND_PLAYING MIX_PLAYING
#define TFBSOUND_PAUSED MIX_PAUSED
#define TFBSOUND_FORMAT_MONO16 MIX_FORMAT_MONO16
#define TFBSOUND_FORMAT_STEREO16 MIX_FORMAT_STEREO16
#define TFBSOUND_FORMAT_STEREO8 MIX_FORMAT_STEREO8
#define TFBSOUND_LOOPING MIX_LOOPING
#define TFBSOUND_BUFFERS_PROCESSED MIX_BUFFERS_PROCESSED
#define TFBSOUND_BUFFERS_QUEUED MIX_BUFFERS_QUEUED
#define TFBSOUND_NO_ERROR MIX_NO_ERROR
#define TFBSOUND_SIZE MIX_SIZE
@@ -17,7 +17,7 @@
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23 /* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/ */
#ifdef SOUNDMODULE_MIXSDL #if defined SOUNDMODULE_MIXSDL || defined SOUNDMODULE_OPENAL
#include "sound.h" #include "sound.h"
#include "options.h" #include "options.h"
@@ -108,7 +108,7 @@ SetMusicVolume (COUNT Volume)
{ {
float f = (Volume / (float)MAX_VOLUME) * musicVolumeScale; float f = (Volume / (float)MAX_VOLUME) * musicVolumeScale;
musicVolume = Volume; musicVolume = Volume;
mixSDL_Sourcef (soundSource[MUSIC_SOURCE].handle, MIX_GAIN, f); TFBSound_Sourcef (soundSource[MUSIC_SOURCE].handle, TFBSOUND_GAIN, f);
} }
MEM_HANDLE MEM_HANDLE
@@ -174,8 +174,8 @@ _GetMusicData (FILE *fp, DWORD length)
(*pmus)->decoder->frequency, (*pmus)->decoder->format); (*pmus)->decoder->frequency, (*pmus)->decoder->format);
(*pmus)->num_buffers = 64; (*pmus)->num_buffers = 64;
(*pmus)->buffer = (mixSDL_Object *) HMalloc (sizeof (mixSDL_Object) * (*pmus)->num_buffers); (*pmus)->buffer = (TFBSound_Object *) HMalloc (sizeof (TFBSound_Object) * (*pmus)->num_buffers);
mixSDL_GenBuffers ((*pmus)->num_buffers, (*pmus)->buffer); TFBSound_GenBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
} }
} }
@@ -208,7 +208,7 @@ _ReleaseMusicData (MEM_HANDLE handle)
(*pmus)->decoder = NULL; (*pmus)->decoder = NULL;
SoundDecoder_Free (decoder); SoundDecoder_Free (decoder);
mixSDL_DeleteBuffers ((*pmus)->num_buffers, (*pmus)->buffer); TFBSound_DeleteBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
HFree ((*pmus)->buffer); HFree ((*pmus)->buffer);
} }
HFree (*pmus); HFree (*pmus);
+1 -1
View File
@@ -1 +1 @@
uqm_CFILES="music.c sfx.c sound.c stream.c trackplayer.c" uqm_CFILES="sound_openal.c"
-223
View File
@@ -1,223 +0,0 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/
#ifdef SOUNDMODULE_OPENAL
#include "sound.h"
#include "options.h"
#include "file.h"
static MUSIC_REF curMusicRef;
void
PLRPlaySong (MUSIC_REF MusicRef, BOOLEAN Continuous, BYTE Priority)
{
TFB_SoundSample **pmus;
LockMusicData (MusicRef, &pmus);
if (pmus)
{
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
PlayStream ((*pmus), MUSIC_SOURCE, Continuous,
speechVolumeScale == 0.0f ? AL_TRUE : AL_FALSE,
AL_TRUE);
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
curMusicRef = MusicRef;
}
(void) Priority; /* Satisfy compiler because of unused variable */
}
void
PLRStop (MUSIC_REF MusicRef)
{
if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)
{
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
StopStream (MUSIC_SOURCE);
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
UnlockMusicData (curMusicRef);
curMusicRef = 0;
}
}
BOOLEAN
PLRPlaying (MUSIC_REF MusicRef)
{
if (curMusicRef && (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0))
{
BOOLEAN playing;
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
playing = PlayingStream (MUSIC_SOURCE);
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
return playing;
}
return FALSE;
}
void
PLRPause (MUSIC_REF MusicRef)
{
if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)
{
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
PauseStream (MUSIC_SOURCE);
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
}
}
void
PLRResume (MUSIC_REF MusicRef)
{
if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)
{
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
ResumeStream (MUSIC_SOURCE);
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
}
}
BOOLEAN
DestroyMusic (MUSIC_REF MusicRef)
{
return (FreeMusicData (MusicRef));
}
void
SetMusicVolume (COUNT Volume)
{
float f = (Volume / (ALfloat)MAX_VOLUME) * musicVolumeScale;
musicVolume = Volume;
alSourcef (soundSource[MUSIC_SOURCE].handle, AL_GAIN, f);
}
MEM_HANDLE
_GetMusicData (FILE *fp, DWORD length)
{
MEM_HANDLE h;
extern char *_cur_resfile_name;
h = 0;
if (_cur_resfile_name && (h = AllocMusicData (sizeof (void *))))
{
TFB_SoundSample **pmus;
LockMusicData (h, &pmus);
if (!pmus)
{
UnlockMusicData (h);
mem_release (h);
h = 0;
}
else
{
char filename[1000];
*pmus = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
(*pmus)->buffer_tag = 0;
(*pmus)->read_chain_ptr = NULL;
strcpy (filename, _cur_resfile_name);
switch (optWhichMusic)
{
default:
case OPT_3DO:
{
char threedoname[1000];
strcpy (threedoname, filename);
strcpy (&threedoname[strlen (threedoname)-3], "ogg");
if (fileExists (threedoname))
{
strcpy (filename, threedoname);
}
break;
}
case OPT_PC:
{
break;
}
}
fprintf (stderr, "_GetMusicData(): loading %s\n", filename);
if (((*pmus)->decoder = SoundDecoder_Load (filename, 4096, 0, 0)) == 0)
{
fprintf (stderr, "_GetMusicData(): couldn't load %s\n", filename);
UnlockMusicData (h);
mem_release (h);
h = 0;
}
else
{
fprintf (stderr, " decoder: %s, rate %d format %x\n", (*pmus)->decoder->decoder_info,
(*pmus)->decoder->frequency, (*pmus)->decoder->format);
(*pmus)->num_buffers = 64;
(*pmus)->buffer = (ALuint *) HMalloc (sizeof (ALuint) * (*pmus)->num_buffers);
alGenBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
}
}
UnlockMusicData (h);
}
(void) fp; /* satisfy compiler (unused parameter) */
(void) length; /* satisfy compiler (unused parameter) */
return (h);
}
BOOLEAN
_ReleaseMusicData (MEM_HANDLE handle)
{
TFB_SoundSample **pmus;
LockMusicData (handle, &pmus);
if (pmus == 0)
return (FALSE);
if ((*pmus)->decoder)
{
TFB_SoundDecoder *decoder = (*pmus)->decoder;
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
if (soundSource[MUSIC_SOURCE].sample == (*pmus))
{
StopStream (MUSIC_SOURCE);
}
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
(*pmus)->decoder = NULL;
SoundDecoder_Free (decoder);
alDeleteBuffers ((*pmus)->num_buffers, (*pmus)->buffer);
HFree ((*pmus)->buffer);
}
HFree (*pmus);
UnlockMusicData (handle);
mem_release (handle);
return (TRUE);
}
#endif
-267
View File
@@ -1,267 +0,0 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/
#ifdef SOUNDMODULE_OPENAL
#ifdef WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "sound.h"
void
PlayChannel (COUNT channel, PVOID sample, COUNT sample_length, COUNT loop_begin,
COUNT loop_length, unsigned char priority)
{
TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample;
soundSource[channel].sample = tfb_sample;
alSourceRewind (soundSource[channel].handle);
alSourcei (soundSource[channel].handle, AL_BUFFER, tfb_sample->buffer[0]);
alSourcePlay (soundSource[channel].handle);
}
void
StopChannel(COUNT channel, unsigned char Priority)
{
alSourceRewind (soundSource[channel].handle);
}
BOOLEAN
ChannelPlaying (COUNT WhichChannel)
{
ALint state;
alGetSourcei (soundSource[WhichChannel].handle, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING)
return TRUE;
return FALSE;
}
void
SetChannelVolume (COUNT channel, COUNT volume, BYTE priority)
// I wonder what this whole priority business is...
// I can probably ignore it.
{
alSourcef (soundSource[channel].handle, AL_GAIN,
(volume / (ALfloat)MAX_VOLUME) * sfxVolumeScale);
}
// Status: Ignored
PBYTE
GetSampleAddress (SOUND sound)
// I might be prototyping this wrong, type-wise.
{
return ((PBYTE)GetSoundAddress (sound));
}
// Status: Ignored
COUNT
GetSampleLength (SOUND sound)
{
return 0;
}
// Status: Ignored
void
SetChannelRate (COUNT channel, DWORD rate_hz, unsigned char priority)
{
}
// Status: Ignored
COUNT
GetSampleRate (SOUND sound)
{
return 0;
}
MEM_HANDLE
_GetSoundBankData (FILE *fp, DWORD length)
{
#ifdef WIN32
int omode;
#endif
int snd_ct, n;
DWORD opos;
char CurrentLine[1024], filename[1024];
#define MAX_FX 256
TFB_SoundSample *sndfx[MAX_FX];
STRING_TABLE Snd;
opos = ftell (fp);
{
char *s1, *s2;
extern char *_cur_resfile_name;
if (_cur_resfile_name == 0
|| (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0)
&& (s2 = strrchr (_cur_resfile_name, '\\')) == 0))
n = 0;
else
{
if (s2 > s1)
s1 = s2;
n = s1 - _cur_resfile_name + 1;
strncpy (filename, _cur_resfile_name, n);
}
}
#ifdef WIN32
omode = _setmode (fileno (fp), O_TEXT);
#endif
snd_ct = 0;
while (fgets (CurrentLine, sizeof (CurrentLine), fp) && snd_ct < MAX_FX)
{
if (sscanf(CurrentLine, "%s", &filename[n]) == 1)
{
fprintf (stderr, "_GetSoundBankData(): loading %s\n", filename);
sndfx[snd_ct] = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
sndfx[snd_ct]->buffer_tag = 0;
sndfx[snd_ct]->read_chain_ptr = NULL;
sndfx[snd_ct]->decoder = SoundDecoder_Load (filename, 4096, 0, 0);
if (!sndfx[snd_ct]->decoder)
{
fprintf (stderr, "_GetSoundBankData(): couldn't load %s\n", filename);
HFree (sndfx[snd_ct]);
}
else
{
ALuint decoded_bytes;
decoded_bytes = SoundDecoder_DecodeAll (sndfx[snd_ct]->decoder);
//fprintf (stderr, "_GetSoundBankData(): decoded_bytes %d\n", decoded_bytes);
sndfx[snd_ct]->num_buffers = 1;
sndfx[snd_ct]->buffer = (ALuint *) HMalloc (sizeof (ALuint) * sndfx[snd_ct]->num_buffers);
alGenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer);
alBufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format,
sndfx[snd_ct]->decoder->buffer, decoded_bytes,
sndfx[snd_ct]->decoder->frequency);
SoundDecoder_Free (sndfx[snd_ct]->decoder);
sndfx[snd_ct]->decoder = NULL;
++snd_ct;
}
}
else
{
fprintf (stderr, "_GetSoundBankData: Bad file!\n");
}
// pkunk insult fix 2002/11/12 (ftell shouldn't be needed for loop to terminate)
/*if (ftell (fp) - opos >= length)
break;*/
}
#ifdef WIN32
_setmode (fileno (fp), omode);
#endif
Snd = 0;
if (snd_ct && (Snd = AllocStringTable (
sizeof (STRING_TABLE_DESC)
+ (sizeof (DWORD) * snd_ct)
+ (sizeof (sndfx[0]) * snd_ct)
)))
{
STRING_TABLEPTR fxTab;
LockStringTable (Snd, &fxTab);
if (fxTab == 0)
{
while (snd_ct--)
{
if (sndfx[snd_ct]->decoder)
SoundDecoder_Free (sndfx[snd_ct]->decoder);
HFree (sndfx[snd_ct]);
}
FreeStringTable (Snd);
Snd = 0;
}
else
{
DWORD *offs, StringOffs;
fxTab->StringCount = snd_ct;
fxTab->flags = 0;
offs = fxTab->StringOffsets;
StringOffs = sizeof (STRING_TABLE_DESC) + (sizeof (DWORD) * snd_ct);
memcpy ((BYTE *)fxTab + StringOffs, sndfx, sizeof (sndfx[0]) * snd_ct);
do
{
*offs++ = StringOffs;
StringOffs += sizeof (sndfx[0]);
} while (snd_ct--);
UnlockStringTable (Snd);
}
}
return ((MEM_HANDLE)Snd);
}
BOOLEAN
_ReleaseSoundBankData (MEM_HANDLE Snd)
{
STRING_TABLEPTR fxTab;
LockStringTable (Snd, &fxTab);
if (fxTab)
{
int snd_ct;
TFB_SoundSample **sptr;
snd_ct = fxTab->StringCount;
sptr = (TFB_SoundSample **)((BYTE *)fxTab + fxTab->StringOffsets[0]);
while (snd_ct--)
{
int i;
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
{
if (soundSource[i].sample == (*sptr))
soundSource[i].sample = NULL;
}
if ((*sptr)->decoder)
SoundDecoder_Free ((*sptr)->decoder);
alDeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer);
HFree ((*sptr)->buffer);
HFree (*sptr);
*sptr++ = 0;
}
UnlockStringTable (Snd);
FreeStringTable (Snd);
return (TRUE);
}
return (FALSE);
}
BOOLEAN
DestroySound(SOUND_REF target)
{
return (_ReleaseSoundBankData (target));
}
#endif
-112
View File
@@ -1,112 +0,0 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/
#ifdef WIN32
#include <al.h>
#include <alc.h>
#pragma comment (lib, "OpenAL32.lib")
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#include "starcon.h"
#include "misc.h"
#include "libs/strings/strintrn.h"
#include "libs/sound/sndintrn.h"
#include "libs/sound/sound_common.h"
#include "mixer.h"
#include "libs/sound/decoders/decoder.h"
#define FIRST_SFX_SOURCE 0
#define LAST_SFX_SOURCE 4
#define MUSIC_SOURCE (LAST_SFX_SOURCE + 1)
#define SPEECH_SOURCE (MUSIC_SOURCE + 1)
#define NUM_SOUNDSOURCES (SPEECH_SOURCE + 1)
#define PAD_SCOPE_BYTES 8096
typedef struct
{
ALuint buf_name;
int type;
void *value;
} TFB_SoundTag;
enum
{
AL_BUFFER_TAG_TEXT = 1,
AL_BUFFER_TAG_TEXTPAGE
};
typedef struct tfb_soundchain
{
TFB_SoundDecoder *decoder; // points at the decoder to read from
float start_time;
TFB_SoundTag tag;
struct tfb_soundchain *next;
} TFB_SoundChain;
// audio data
typedef struct tfb_soundsample
{
TFB_SoundDecoder *decoder; // decoder to read from
TFB_SoundChain *read_chain_ptr; // points to chain read poistion
TFB_SoundChain *play_chain_ptr; // points to chain playing position
float length; // total length of decoder chain in seconds
ALuint *buffer;
ALuint num_buffers;
TFB_SoundTag **buffer_tag;
} TFB_SoundSample;
// equivalent to channel in legacy sound code
typedef struct tfb_soundsource
{
TFB_SoundSample *sample;
ALuint handle;
BOOLEAN stream_should_be_playing;
Mutex stream_mutex;
ALint start_time;
// for oscilloscope
void *sbuffer;
ALuint sbuf_start;
ALuint sbuf_size;
ALuint sbuf_offset;
ALuint sbuf_lasttime;
} TFB_SoundSource;
extern ALCcontext *alcContext; // OpenAL context
extern ALCdevice *alcDevice; // OpenAL device
extern ALfloat listenerPos[]; // listener position (3 floats)
extern ALfloat listenerVel[]; // listener velocity (3 floats)
extern ALfloat listenerOri[]; // listener orientation (two 3 float vectors, "look at" and "up")
extern TFB_SoundSource soundSource[];
void SetSFXVolume (float volume);
void SetSpeechVolume (float volume);
void DoTrackTag (TFB_SoundTag *tag);
TFB_SoundChain *create_soundchain (TFB_SoundDecoder *decoder, float startTime);
void destroy_soundchain (TFB_SoundChain *chain);
TFB_SoundChain *get_previous_chain (TFB_SoundChain *first_chain, TFB_SoundChain *current_chain);
#include "stream.h"
@@ -16,17 +16,15 @@
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23 /* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/ */
#ifdef SOUNDMODULE_OPENAL #ifdef SOUNDMODULE_OPENAL
#include "sound.h" #include "libs/sound/sound.h"
ALCcontext *alcContext = NULL; ALCcontext *alcContext = NULL;
ALCdevice *alcDevice = NULL; ALCdevice *alcDevice = NULL;
ALfloat listenerPos[] = {0.0f, 0.0f, 0.0f}; ALfloat listenerPos[] = {0.0f, 0.0f, 0.0f};
ALfloat listenerVel[] = {0.0f, 0.0f, 0.0f}; ALfloat listenerVel[] = {0.0f, 0.0f, 0.0f};
ALfloat listenerOri[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f}; ALfloat listenerOri[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f};
TFB_SoundSource soundSource[NUM_SOUNDSOURCES];
static Task StreamDecoderTask; static Task StreamDecoderTask;
@@ -143,117 +141,4 @@ TFB_UninitSound (void)
SoundDecoder_Uninit (); SoundDecoder_Uninit ();
} }
void #endif
StopSound (void)
{
int i;
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
{
alSourceRewind (soundSource[i].handle);
}
}
BOOLEAN
SoundPlaying (void)
{
int i;
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
{
TFB_SoundSample *sample;
sample = soundSource[i].sample;
if (sample && sample->decoder)
{
BOOLEAN result;
LockMutex (soundSource[i].stream_mutex);
result = PlayingStream (i);
UnlockMutex (soundSource[i].stream_mutex);
if (result)
return TRUE;
}
else
{
ALint state;
alGetSourcei (soundSource[i].handle, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING)
return TRUE;
}
}
return FALSE;
}
TFB_SoundChain *
create_soundchain (TFB_SoundDecoder *decoder, float startTime)
{
TFB_SoundChain *chain;
chain = (TFB_SoundChain *)HMalloc (sizeof (TFB_SoundChain));
chain->decoder = decoder;
chain->next =NULL;
chain->start_time = startTime;
chain->tag.buf_name = 0;
chain->tag.type = 0;
return (chain);
}
void
destroy_soundchain (TFB_SoundChain *chain)
{
while (chain->next)
{
TFB_SoundChain *tmp_chain = chain->next;
chain->next = chain->next->next;
if (tmp_chain->decoder)
SoundDecoder_Free (tmp_chain->decoder);
HFree (tmp_chain);
}
SoundDecoder_Free (chain->decoder);
HFree (chain);
}
TFB_SoundChain *
get_previous_chain (TFB_SoundChain *first_chain, TFB_SoundChain *current_chain)
{
TFB_SoundChain *prev_chain;
prev_chain = first_chain;
if (prev_chain == current_chain)
return (prev_chain);
while (prev_chain->next)
{
if (prev_chain->next == current_chain)
return (prev_chain);
prev_chain = prev_chain->next;
}
return (first_chain);
}
// Status: Ignored
BOOLEAN
InitSound (int argc, char* argv[])
{
return TRUE;
}
// Status: Ignored
void
UninitSound (void)
{
}
void SetSFXVolume (float volume)
{
int i;
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
{
alSourcef (soundSource[i].handle, AL_GAIN, volume);
}
}
void SetSpeechVolume (float volume)
{
alSourcef (soundSource[SPEECH_SOURCE].handle, AL_GAIN, volume);
}
#endif
@@ -0,0 +1,81 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/
#ifdef WIN32
#include <al.h>
#include <alc.h>
#pragma comment (lib, "OpenAL32.lib")
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#include "mixer.h"
#define TFBSound_Object ALuint
/*************************************************
* General interface
*/
#define TFBSound_GetError alGetError
#define TFBSound_OpenAudio alOpenAudio
#define TFBSound_CloseAudio alCloseAudio
#define TFBSound_QuerySpec alQuerySpec
/*************************************************
* Sources
*/
#define TFBSound_GenSources alGenSources
#define TFBSound_DeleteSources alDeleteSources
#define TFBSound_IsSource alIsSource
#define TFBSound_Sourcei alSourcei
#define TFBSound_Sourcef alSourcef
#define TFBSound_GetSourcei alGetSourcei
#define TFBSound_GetSourcef alGetSourcef
#define TFBSound_SourceRewind alSourceRewind
#define TFBSound_SourcePlay alSourcePlay
#define TFBSound_SourcePause alSourcePause
#define TFBSound_SourceStop alSourceStop
#define TFBSound_SourceQueueBuffers alSourceQueueBuffers
#define TFBSound_SourceUnqueueBuffers alSourceUnqueueBuffers
/*************************************************
* Buffers
*/
#define TFBSound_GenBuffers alGenBuffers
#define TFBSound_DeleteBuffers alDeleteBuffers
#define TFBSound_IsBuffer alIsBuffer
#define TFBSound_GetBufferi alGetBufferi
#define TFBSound_BufferData alBufferData
#define TFBSound_ConvertBuffer alConvertBuffer
#define TFBSound_BufferData_Linux alBufferWriteData_LOKI
#define TFBSOUND_GAIN AL_GAIN
#define TFBSOUND_BUFFER AL_BUFFER
#define TFBSOUND_SOURCE_STATE AL_SOURCE_STATE
#define TFBSOUND_PLAYING AL_PLAYING
#define TFBSOUND_PAUSED AL_PAUSED
#define TFBSOUND_FORMAT_MONO16 AL_FORMAT_MONO16
#define TFBSOUND_FORMAT_STEREO16 AL_FORMAT_STEREO16
#define TFBSOUND_FORMAT_STEREO8 AL_FORMAT_STEREO8
#define TFBSOUND_LOOPING AL_LOOPING
#define TFBSOUND_BUFFERS_PROCESSED AL_BUFFERS_PROCESSED
#define TFBSOUND_BUFFERS_QUEUED AL_BUFFERS_QUEUED
#define TFBSOUND_NO_ERROR AL_NO_ERROR
#define TFBSOUND_SIZE AL_SIZE
-449
View File
@@ -1,449 +0,0 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* By Mika Kolehmainen, 2002-10-23
*/
#ifdef SOUNDMODULE_OPENAL
#include <assert.h>
#include "sound.h"
#if !defined (WIN32) // && !defined (MacOS and BeOS too)
#include <AL/alext.h>
#endif
BOOLEAN speech_advancetrack = FALSE;
void
PlayStream (TFB_SoundSample *sample, ALuint source, ALboolean looping,
ALboolean scope, ALboolean rewind)
{
ALuint i, pos = 0;
ALint offset = 0;
if (!sample || (!sample->read_chain_ptr && !sample->decoder))
return;
StopStream (source);
if (sample->read_chain_ptr)
{
sample->decoder = sample->read_chain_ptr->decoder;
offset = (ALint) (sample->read_chain_ptr->start_time * (float)ONE_SECOND);
}
else
offset= 0;
if (rewind)
SoundDecoder_Rewind (sample->decoder);
else
offset += (ALint)(SoundDecoder_GetTime (sample->decoder) * (float)ONE_SECOND);
soundSource[source].sample = sample;
soundSource[source].sample->play_chain_ptr = sample->read_chain_ptr;
soundSource[source].sample->decoder->looping = looping;
alSourcei (soundSource[source].handle, AL_LOOPING, AL_FALSE);
if (scope)
{
pos = PAD_SCOPE_BYTES;
soundSource[source].sbuffer = HMalloc (pos);
}
if (sample->read_chain_ptr && sample->read_chain_ptr->tag.type)
{
DoTrackTag(&sample->read_chain_ptr->tag);
}
for (i = 0; i < sample->num_buffers; ++i)
{
ALuint decoded_bytes;
if (sample->buffer_tag)
sample->buffer_tag[i] = 0;
decoded_bytes = SoundDecoder_Decode (sample->decoder);
//fprintf (stderr, "PlayStream(): source %d filename:%s start: %d position:%d bytes %d\n", source,
// sample->decoder->filename, sample->decoder->start_sample,
// sample->decoder->pos, decoded_bytes);
if (decoded_bytes == 0)
break;
#if !defined (WIN32) // && !defined (MacOS and BeOS too)
// *nix OpenAL implementation has to handle stereo data differently to avoid mixing it to mono
if (sample->decoder->format == AL_FORMAT_STEREO8 ||
sample->decoder->format == AL_FORMAT_STEREO16)
{
alBufferWriteData_LOKI (sample->buffer[i], sample->decoder->format, sample->decoder->buffer,
decoded_bytes, sample->decoder->frequency, sample->decoder->format);
}
else
{
alBufferData (sample->buffer[i], sample->decoder->format, sample->decoder->buffer,
decoded_bytes, sample->decoder->frequency);
}
#else
alBufferData (sample->buffer[i], sample->decoder->format, sample->decoder->buffer,
decoded_bytes, sample->decoder->frequency);
#endif
alSourceQueueBuffers (soundSource[source].handle, 1, &sample->buffer[i]);
if (scope)
{
UBYTE *p;
soundSource[source].sbuffer = HRealloc (soundSource[source].sbuffer,
pos + decoded_bytes);
p = (UBYTE *)soundSource[source].sbuffer;
memcpy (&p[pos], sample->decoder->buffer, decoded_bytes);
pos += decoded_bytes;
}
if (sample->decoder->error)
{
if (sample->decoder->error == SOUNDDECODER_EOF && sample->read_chain_ptr->next)
{
sample->read_chain_ptr = sample->read_chain_ptr->next;
sample->decoder = sample->read_chain_ptr->decoder;
SoundDecoder_Rewind (sample->decoder);
fprintf (stderr, "Switching to stream %s at pos %d\n",
sample->decoder->filename, sample->decoder->start_sample);
if (sample->buffer_tag && sample->read_chain_ptr->tag.type)
{
sample->buffer_tag[i] = &sample->read_chain_ptr->tag;
sample->read_chain_ptr->tag.buf_name = sample->buffer[i];
}
}
else
break;
}
}
if (sample->buffer_tag)
for ( ; i <sample->num_buffers; ++i)
sample->buffer_tag[i] = 0;
soundSource[source].sbuf_size = pos;
soundSource[source].sbuf_start = pos - PAD_SCOPE_BYTES;
soundSource[source].sbuf_lasttime = GetTimeCounter ();
soundSource[source].start_time = (ALint)GetTimeCounter () - offset;
soundSource[source].stream_should_be_playing = TRUE;
alSourcePlay (soundSource[source].handle);
}
void
StopStream (ALuint source)
{
ALuint queued, processed;
ALuint *buffer;
soundSource[source].stream_should_be_playing = FALSE;
soundSource[source].sample = NULL;
if (soundSource[source].sbuffer)
{
void *sbuffer = soundSource[source].sbuffer;
soundSource[source].sbuffer = NULL;
HFree (sbuffer);
}
soundSource[source].sbuf_start = 0;
soundSource[source].sbuf_size = 0;
soundSource[source].sbuf_offset = 0;
alSourceStop (soundSource[source].handle);
alGetSourcei (soundSource[source].handle, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei (soundSource[source].handle, AL_BUFFERS_QUEUED, &queued);
//fprintf (stderr, "StopStream(): source %d processed %d queued %d num_buffers %d\n", source, processed, queued, soundSource[source].sample->num_buffers);
if (processed != 0)
{
buffer = (ALuint *) HMalloc (sizeof (ALuint) * processed);
alSourceUnqueueBuffers (soundSource[source].handle, processed, buffer);
HFree (buffer);
}
}
void
PauseStream (ALuint source)
{
// TODO: how to handle start_time
soundSource[source].stream_should_be_playing = FALSE;
alSourcePause (soundSource[source].handle);
}
void
ResumeStream (ALuint source)
{
// TODO: how to handle start_time
soundSource[source].stream_should_be_playing = TRUE;
alSourcePlay (soundSource[source].handle);
}
BOOLEAN
PlayingStream (ALuint source)
{
return soundSource[source].stream_should_be_playing;
}
int
StreamDecoderTaskFunc (void *data)
{
Task task = (Task)data;
int i;
ALuint last_buffer[NUM_SOUNDSOURCES];
for (i = 0; i < NUM_SOUNDSOURCES; i++)
last_buffer[i] = 0;
while (!Task_ReadState (task, TASK_EXIT))
{
TaskSwitch ();
for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i)
{
ALuint processed, queued;
ALint state;
ALboolean do_speech_advancetrack = AL_FALSE;
LockMutex (soundSource[i].stream_mutex);
if (!soundSource[i].sample ||
!soundSource[i].sample->decoder ||
!soundSource[i].stream_should_be_playing ||
soundSource[i].sample->decoder->error == SOUNDDECODER_ERROR)
{
UnlockMutex (soundSource[i].stream_mutex);
continue;
}
alGetSourcei (soundSource[i].handle, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei (soundSource[i].handle, AL_BUFFERS_QUEUED, &queued);
if (processed == 0)
{
alGetSourcei (soundSource[i].handle, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING)
{
if (queued == 0 && soundSource[i].sample->decoder->error == SOUNDDECODER_EOF)
{
fprintf (stderr, "StreamDecoderTaskFunc(): finished playing %s, source %d\n", soundSource[i].sample->decoder->filename, i);
soundSource[i].stream_should_be_playing = FALSE;
if (i == SPEECH_SOURCE)
{
soundSource[i].sample->decoder = NULL;
soundSource[i].sample->read_chain_ptr = NULL;
if (speech_advancetrack)
do_speech_advancetrack = AL_TRUE;
}
}
else
{
fprintf (stderr, "StreamDecoderTaskFunc(): buffer underrun when playing %s, source %d\n",
soundSource[i].sample->decoder->filename, i);
alSourcePlay (soundSource[i].handle);
}
}
}
//fprintf (stderr, "StreamDecoderTaskFunc(): source %d, processed %d queued %d\n", i, processed, queued);
while (processed)
{
ALenum error;
ALuint buffer;
ALuint decoded_bytes;
ALuint buf_num;
alGetError (); // clear error state
alSourceUnqueueBuffers (soundSource[i].handle, 1, &buffer);
if ((error = alGetError()) != AL_NO_ERROR)
{
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceUnqueueBuffers: %x, file %s, source %d\n", error, soundSource[i].sample->decoder->filename, i);
break;
}
if (i == SPEECH_SOURCE)
{
for (buf_num = 0; buf_num < soundSource[i].sample->num_buffers; buf_num++)
{
TFB_SoundTag *cur_tag = soundSource[i].sample->buffer_tag[buf_num];
if (cur_tag && cur_tag->buf_name == buffer)
{
// ...do tag stuff ...
DoTrackTag (cur_tag);
soundSource[i].sample->buffer_tag[buf_num] = NULL;
soundSource[i].sample->play_chain_ptr = soundSource[i].sample->read_chain_ptr;
cur_tag->buf_name = 0;
break;
}
}
}
{
ALuint buf_size;
soundSource[i].sbuf_lasttime = GetTimeCounter ();
alGetBufferi(buffer, AL_SIZE, &buf_size);
soundSource[i].sbuf_offset += buf_size;
if (soundSource[i].sbuf_offset > soundSource[i].sbuf_size)
soundSource[i].sbuf_offset -= soundSource[i].sbuf_size;
}
if (soundSource[i].sample->decoder->error)
{
if (soundSource[i].sample->decoder->error == SOUNDDECODER_EOF)
{
if (soundSource[i].sample->read_chain_ptr &&
soundSource[i].sample->read_chain_ptr->next)
{
soundSource[i].sample->read_chain_ptr = soundSource[i].sample->read_chain_ptr->next;
soundSource[i].sample->decoder = soundSource[i].sample->read_chain_ptr->decoder;
SoundDecoder_Rewind (soundSource[i].sample->decoder);
fprintf (stderr, "Switching to stream %s at pos %d\n",
soundSource[i].sample->decoder->filename,
soundSource[i].sample->decoder->start_sample);
if (i == SPEECH_SOURCE)
{
for (buf_num = 0; buf_num < soundSource[i].sample->num_buffers; buf_num++)
{
if (soundSource[i].sample->buffer_tag[buf_num] == 0)
{
soundSource[i].sample->buffer_tag[buf_num] = &soundSource[i].sample->read_chain_ptr->tag;
soundSource[i].sample->read_chain_ptr->tag.buf_name = last_buffer[i];
break;
}
}
}
}
else
{
//fprintf (stderr, "StreamDecoderTaskFunc(): decoder->error is eof for %s\n", soundSource[i].sample->decoder->filename);
processed--;
continue;
}
}
else
{
//fprintf (stderr, "StreamDecoderTaskFunc(): decoder->error is %d for %s\n", soundSource[i].sample->decoder->error, soundSource[i].sample->decoder->filename);
processed--;
continue;
}
}
decoded_bytes = SoundDecoder_Decode (soundSource[i].sample->decoder);
if (soundSource[i].sample->decoder->error == SOUNDDECODER_ERROR)
{
fprintf (stderr, "StreamDecoderTaskFunc(): SoundDecoder_Decode error %d, file %s, source %d\n", soundSource[i].sample->decoder->error, soundSource[i].sample->decoder->filename, i);
soundSource[i].stream_should_be_playing = FALSE;
processed--;
continue;
}
if (decoded_bytes > 0)
{
#if !defined (WIN32) // && !defined (MacOS and BeOS too)
// *nix OpenAL implementation has to handle stereo data differently to avoid mixing it to mono
if (soundSource[i].sample->decoder->format == AL_FORMAT_STEREO8 ||
soundSource[i].sample->decoder->format == AL_FORMAT_STEREO16)
{
alBufferWriteData_LOKI (buffer, soundSource[i].sample->decoder->format, soundSource[i].sample->decoder->buffer,
decoded_bytes, soundSource[i].sample->decoder->frequency,
soundSource[i].sample->decoder->format);
}
else
{
alBufferData (buffer, soundSource[i].sample->decoder->format,
soundSource[i].sample->decoder->buffer, decoded_bytes,
soundSource[i].sample->decoder->frequency);
}
#else
alBufferData (buffer, soundSource[i].sample->decoder->format,
soundSource[i].sample->decoder->buffer, decoded_bytes,
soundSource[i].sample->decoder->frequency);
#endif
if ((error = alGetError()) != AL_NO_ERROR)
{
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alBufferData: %x, file %s, source %d, decoded_bytes %d\n",
error, soundSource[i].sample->decoder->filename, i, decoded_bytes);
}
else
{
alSourceQueueBuffers (soundSource[i].handle, 1, &buffer);
last_buffer[i] = buffer;
if (soundSource[i].sbuffer)
{
// copies decoded data to oscilloscope buffer
ALuint j, remaining_bytes = 0;
UBYTE *sbuffer = (UBYTE *) soundSource[i].sbuffer;
UBYTE *decoder_buffer = (UBYTE *) soundSource[i].sample->decoder->buffer;
if (soundSource[i].sbuf_start + decoded_bytes > soundSource[i].sbuf_size)
{
j = soundSource[i].sbuf_size;
remaining_bytes = decoded_bytes - (j - soundSource[i].sbuf_start);
}
else
{
j = soundSource[i].sbuf_start + decoded_bytes;
}
if (j - soundSource[i].sbuf_start >= 1)
{
//fprintf (stderr, "copying_a to %d - %d, %d bytes\n", soundSource[i].sbuf_start, j, j - soundSource[i].sbuf_start);
memcpy (&sbuffer[soundSource[i].sbuf_start], decoder_buffer, j - soundSource[i].sbuf_start);
}
if (remaining_bytes)
{
//fprintf (stderr, "copying_b to 0 - %d\n", remaining_bytes);
memcpy (sbuffer, &decoder_buffer[j - soundSource[i].sbuf_start], remaining_bytes);
soundSource[i].sbuf_start = remaining_bytes;
}
else
{
soundSource[i].sbuf_start += decoded_bytes;
}
}
if ((error = alGetError()) != AL_NO_ERROR)
{
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceQueueBuffers: %x, file %s, source %d, decoded_bytes %d\n",
error, i, soundSource[i].sample->decoder->filename, decoded_bytes);
}
}
}
processed--;
}
UnlockMutex (soundSource[i].stream_mutex);
if (i == SPEECH_SOURCE)
{
if (do_speech_advancetrack)
{
fprintf (stderr, "StreamDecoderTaskFunc(): calling advance_track\n");
do_speech_advancetrack = AL_FALSE;
advance_track (0);
}
}
}
}
FinishTask (task);
return 0;
}
#endif
@@ -1,34 +0,0 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* By Mika Kolehmainen, 2002-10-23
*/
#ifndef STREAM_H
#define STREAM_H
void PlayStream (TFB_SoundSample *sample, ALuint source, ALboolean looping,
ALboolean scope, ALboolean rewind);
void StopStream (ALuint source);
void PauseStream (ALuint source);
void ResumeStream (ALuint source);
BOOLEAN PlayingStream (ALuint source);
int StreamDecoderTaskFunc (void *data);
extern BOOLEAN speech_advancetrack;
void advance_track (int channel_finished);
#endif
@@ -1,703 +0,0 @@
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/
#ifdef SOUNDMODULE_OPENAL
#include <assert.h>
#include "sound.h"
#include "libs/sound/trackplayer.h"
extern int do_subtitles (UNICODE *pStr, UNICODE *TimeStamp, int method);
static int tct; //total number of subtitle tracks
static int tcur; //currently playing subtitle track
static int cur_page = 0; //current page of subtitle track
static int no_page_break = 0;
static int no_voice;
static int track_pos_changed = 0; // set whenever ff, frev is enabled
#define MAX_CLIPS 50
static TFB_SoundSample *sound_sample = NULL;
static TFB_SoundChain *first_chain = NULL; //first decoder in linked list
static TFB_SoundChain *last_chain = NULL; //last decoder in linked list
static UNICODE *TrackTextArray[MAX_CLIPS]; //storage for subtitlle text
static Mutex track_mutex; //protects tcur and tct
void
JumpTrack (int abort)
{
speech_advancetrack = FALSE;
if (sound_sample)
{
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
StopStream (SPEECH_SOURCE);
if (abort)
{
sound_sample->read_chain_ptr = NULL;
sound_sample->decoder = NULL;
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
no_voice = 1;
do_subtitles ((void *)~0, (void *)~0, 1);
if (abort)
LockMutex (track_mutex);
tcur = tct;
UnlockMutex(track_mutex);
}
void
advance_track (int channel_finished)
{
if (channel_finished <= 0)
{
if (sound_sample->read_chain_ptr || sound_sample->decoder)
{
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
PlayStream (sound_sample,
SPEECH_SOURCE, AL_FALSE,
speechVolumeScale != 0.0f,
!track_pos_changed);
track_pos_changed = 0;
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
else if (channel_finished == 0)
{
no_voice = 1;
}
}
}
void
ResumeTrack ()
{
if (sound_sample && sound_sample->read_chain_ptr)
{
ALint state;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
alGetSourcei (soundSource[SPEECH_SOURCE].handle, AL_SOURCE_STATE, &state);
if (!track_pos_changed && !soundSource[SPEECH_SOURCE].stream_should_be_playing &&
state == AL_PAUSED)
{
ResumeStream (SPEECH_SOURCE);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
else if (!no_voice)
{
if (tcur == 0)
{
speech_advancetrack = TRUE;
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
advance_track (-1);
}
else
{
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
}
}
COUNT
PlayingTrack ()
{
if (sound_sample->decoder)
{
int last_track, last_page;
LockMutex (track_mutex);
last_track = tcur;
last_page = cur_page;
UnlockMutex (track_mutex);
if (do_subtitles (TrackTextArray[last_track], (void *)last_page, 1) ||
(no_voice && ++tcur < tct && do_subtitles (0, (void *)~0, 1)))
{
return (tcur + 1);
}
else if (sound_sample)
{
COUNT result;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
result = (PlayingStream (SPEECH_SOURCE) ? (COUNT)(last_track + 1) : 0);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
return result;
}
}
return (0);
}
void
StopTrack ()
{
int i;
speech_advancetrack = FALSE;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
StopStream (SPEECH_SOURCE);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
for (i = 0; i < tct; i++)
{
HFree (TrackTextArray[i]);
TrackTextArray[i] = 0;
}
if (first_chain)
{
destroy_soundchain (first_chain);
first_chain = NULL;
}
if (sound_sample)
{
DestroyMutex (track_mutex);
alDeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
HFree (sound_sample->buffer);
HFree (sound_sample->buffer_tag);
HFree (sound_sample);
sound_sample = NULL;
}
tct = tcur = 0;
no_voice = 0;
do_subtitles (0, (void *)~0, 1);
}
void
DoTrackTag (TFB_SoundTag *tag)
{
if (tag->type == AL_BUFFER_TAG_TEXT)
{
LockMutex (track_mutex);
tcur = ((int)tag->value) >> 8;
cur_page = ((int)tag->value) & 0xFF;
UnlockMutex (track_mutex);
}
}
int
GetTimeStamps(UNICODE *TimeStamps, unsigned long *time_stamps)
{
int pos;
int num = 0;
while (*TimeStamps && (pos = wstrcspn (TimeStamps, ",\n")))
{
UNICODE valStr[10];
wstrncpy (valStr, TimeStamps, pos);
valStr[pos] = '\0';
*time_stamps = wstrtoul(valStr,NULL,10);
if (*time_stamps)
{
num++;
time_stamps++;
}
TimeStamps += pos;
if (*TimeStamps)
TimeStamps++;
}
*time_stamps = 0;
return (num);
}
// decodes several tracks into one and adds it to queue
// track list is NULL-terminated
void
SpliceMultiTrack (UNICODE *TrackNames[], UNICODE *TrackText)
{
#define MAX_MULTI_TRACKS 20
#define MAX_MULTI_BUFFERS 100
TFB_SoundDecoder* track_decs[MAX_MULTI_TRACKS + 1];
TFB_SoundChain *begin_chain;
int tracks;
int slen;
if (!TrackText)
{
#ifdef DEBUG
fprintf (stderr, "SpliceMultiTrack(): no track text\n");
#endif
return;
}
if (tct >= MAX_CLIPS)
{
fprintf (stderr, "SpliceMultiTrack(): no more clip slots (%d)\n",
MAX_CLIPS);
return;
}
if (! sound_sample)
{
fprintf (stderr, "SpliceMultiTrack(): Cannot be called before SpliceTrack()\n");
return;
}
fprintf (stderr, "SpliceMultiTrack(): loading...\n");
for (tracks = 0; *TrackNames && tracks < MAX_MULTI_TRACKS; TrackNames++, tracks++)
{
track_decs[tracks] = SoundDecoder_Load (*TrackNames, 32768, 0, 0);
if (track_decs[tracks])
{
fprintf (stderr, " track: %s, decoder: %s, rate %d format %x\n",
*TrackNames,
track_decs[tracks]->decoder_info,
track_decs[tracks]->frequency,
track_decs[tracks]->format);
SoundDecoder_DecodeAll (track_decs[tracks]);
last_chain->next = create_soundchain (track_decs[tracks], sound_sample->length);
last_chain = last_chain->next;
if (tracks == 0)
begin_chain = last_chain;
sound_sample->length += track_decs[tracks]->length;
}
else
{
fprintf (stderr, " couldn't load %s\n", *TrackNames);
tracks--;
}
}
track_decs[tracks] = 0; // term
if (tracks == 0)
{
fprintf (stderr, " no tracks loaded\n");
return;
}
slen = wstrlen (TrackText);
if (tct)
{
int slen1;
slen1 = wstrlen (TrackTextArray[tct - 1]);
TrackTextArray[tct - 1] = HRealloc (TrackTextArray[tct - 1], slen1 + slen + 1);
wstrcpy (&TrackTextArray[tct - 1][slen1], TrackText);
}
else
{
TrackTextArray[tct] = HMalloc (slen + 1);
wstrcpy (TrackTextArray[tct++], TrackText);
begin_chain->tag.type = AL_BUFFER_TAG_TEXT;
begin_chain->tag.value = (void *)((tct - 1) << 8);
}
no_page_break = 1;
if (tracks > 0)
return;
else
{
fprintf (stderr, " no tracks loaded\n");
}
}
void
SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp)
{
unsigned long startTime;
if (TrackText)
{
if (TrackName == 0)
{
if (tct)
{
int slen1, slen2;
UNICODE *oTT;
oTT = TrackTextArray[tct - 1];
slen1 = wstrlen (oTT);
slen2 = wstrlen (TrackText);
TrackTextArray[tct - 1] = HRealloc (oTT, slen1 + slen2 + 1);
wstrcpy (&TrackTextArray[tct - 1][slen1], TrackText);
}
}
else
{
int num_pages, cur_page;
unsigned long time_stamps[50];
if (no_page_break && tct)
{
int slen1, slen2;
UNICODE *oTT;
oTT = TrackTextArray[tct - 1];
slen1 = wstrlen (oTT);
slen2 = wstrlen (TrackText);
TrackTextArray[tct - 1] = HRealloc (oTT, slen1 + slen2 + 1);
wstrcpy (&TrackTextArray[tct - 1][slen1], TrackText);
}
else
{
TrackTextArray[tct] = HMalloc (sizeof (UNICODE) * (wstrlen (TrackText) + 1));
wstrcpy (TrackTextArray[tct++], TrackText);
}
if (TimeStamp)
num_pages = GetTimeStamps (TimeStamp, time_stamps);
else
num_pages = 0;
fprintf (stderr, "SpliceTrack(): loading %s\n", TrackName);
startTime = 0;
for (cur_page = 0; cur_page <= num_pages; cur_page++)
{
if (! sound_sample)
{
TFB_SoundDecoder *decoder;
track_mutex = CreateMutex();
sound_sample = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
sound_sample->num_buffers = 8;
sound_sample->buffer_tag = HMalloc (sizeof (TFB_SoundTag *) * sound_sample->num_buffers);
sound_sample->buffer = HMalloc (sizeof (ALuint) * sound_sample->num_buffers);
alGenBuffers (sound_sample->num_buffers, sound_sample->buffer);
decoder = SoundDecoder_Load (TrackName, 4096, startTime, time_stamps[cur_page]);
sound_sample->read_chain_ptr = create_soundchain (decoder, 0.0);
sound_sample->decoder = decoder;
first_chain = last_chain = sound_sample->read_chain_ptr;
sound_sample->length = 0;
}
else
{
TFB_SoundDecoder *decoder;
decoder = SoundDecoder_Load (TrackName, 4096, startTime, time_stamps[cur_page]);
last_chain->next = create_soundchain (decoder, sound_sample->length);
last_chain = last_chain->next;
}
startTime += time_stamps[cur_page];
// fprintf (stderr, "page (%d of %d): %d\n",cur_page, num_pages, startTime);
if (last_chain->decoder)
{
//fprintf (stderr, " decoder: %s, rate %d format %x\n",
// last_chain->decoder->decoder_info,
// last_chain->decoder->frequency,
// last_chain->decoder->format);
sound_sample->length += last_chain->decoder->length;
if (! no_page_break)
{
last_chain->tag.type = AL_BUFFER_TAG_TEXT;
last_chain->tag.value = (void *)(((tct - 1) << 8) | cur_page);
}
no_page_break = 0;
}
else
{
fprintf (stderr, "SpliceTrack(): couldn't load %s\n", TrackName);
alDeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
destroy_soundchain (first_chain);
first_chain = NULL;
HFree (sound_sample->buffer);
HFree (sound_sample);
sound_sample = NULL;
}
}
}
}
}
void
PauseTrack ()
{
if (sound_sample && sound_sample->decoder)
{
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
PauseStream (SPEECH_SOURCE);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
}
void
recompute_track_pos (TFB_SoundSample *sample, TFB_SoundChain *first_chain, ALint offset)
{
TFB_SoundChain *cur_chain = first_chain;
while (cur_chain->next &&
(ALint)(cur_chain->next->start_time * (float)ONE_SECOND) < offset)
cur_chain = cur_chain->next;
if (cur_chain->tag.type)
DoTrackTag (&cur_chain->tag);
if ((ALint)((cur_chain->start_time + cur_chain->decoder->length) * (float)ONE_SECOND) < offset)
{
sample->read_chain_ptr = NULL;
sample->decoder = NULL;
}
else
{
sample->read_chain_ptr = cur_chain;
SoundDecoder_Seek(sample->read_chain_ptr->decoder,
(ALuint)(1000 * (offset / (float)ONE_SECOND - cur_chain->start_time)));
}
}
void
FastReverse_Smooth ()
{
if (sound_sample)
{
ALint offset;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
PauseStream (SPEECH_SOURCE);
track_pos_changed = 1;
soundSource[SPEECH_SOURCE].start_time += ACCEL_SCROLL_SPEED;
if (soundSource[SPEECH_SOURCE].start_time > (ALint)GetTimeCounter())
{
soundSource[SPEECH_SOURCE].start_time = GetTimeCounter();
offset = 0;
}
else
offset = GetTimeCounter() - soundSource[SPEECH_SOURCE].start_time;
recompute_track_pos(soundSource[SPEECH_SOURCE].sample, first_chain, offset);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
PlayingTrack();
}
}
void
FastReverse_Page ()
{
if (sound_sample)
{
TFB_SoundChain *prev_chain;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
prev_chain = get_previous_chain(first_chain, sound_sample->play_chain_ptr);
if (prev_chain)
{
sound_sample->read_chain_ptr = prev_chain;
PlayStream (sound_sample,
SPEECH_SOURCE, AL_FALSE,
speechVolumeScale != 0.0f, AL_TRUE);
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
}
void
FastForward_Smooth ()
{
if (sound_sample)
{
ALint offset;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
PauseStream (SPEECH_SOURCE);
soundSource[SPEECH_SOURCE].start_time -= ACCEL_SCROLL_SPEED;
offset = GetTimeCounter() - soundSource[SPEECH_SOURCE].start_time;
track_pos_changed = 1;
recompute_track_pos(sound_sample, first_chain, offset);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
PlayingTrack();
}
}
void
FastForward_Page ()
{
if (sound_sample)
{
TFB_SoundChain *cur_ptr = sound_sample->play_chain_ptr;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
while (cur_ptr->next && ! cur_ptr->tag.type)
cur_ptr = cur_ptr->next;
if (cur_ptr->next)
{
sound_sample->read_chain_ptr = cur_ptr->next;
PlayStream (sound_sample,
SPEECH_SOURCE, AL_FALSE,
speechVolumeScale != 0.0f, AL_TRUE);
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
//no_voice = 0;
}
// processes sound data to oscilloscope
int
GetSoundData (void *data)
{
if (speechVolumeScale != 0.0f)
{
// speech is enabled
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
if (soundSource[SPEECH_SOURCE].sample && soundSource[SPEECH_SOURCE].sample->decoder &&
PlayingStream (SPEECH_SOURCE) && soundSource[SPEECH_SOURCE].sbuffer &&
soundSource[SPEECH_SOURCE].sbuf_size > 0)
{
float played_time = (GetTimeCounter () - soundSource[SPEECH_SOURCE].sbuf_lasttime) /
(float)ONE_SECOND;
int delta = (int) (played_time * (float)soundSource[SPEECH_SOURCE].
sample->decoder->frequency * 2.0f);
unsigned long pos, i;
UBYTE *scopedata = (UBYTE *) data;
UBYTE *sbuffer = soundSource[SPEECH_SOURCE].sbuffer;
assert (soundSource[SPEECH_SOURCE].sample->decoder->frequency == 11025);
assert (soundSource[SPEECH_SOURCE].sample->decoder->format == AL_FORMAT_MONO16);
if (delta < 0)
{
//fprintf (stderr, "GetSoundData(): something's messed with timing, delta %d\n", delta);
delta = 0;
}
else if (delta > (int)(soundSource[SPEECH_SOURCE].sbuf_size * 2))
{
//fprintf (stderr, "GetSoundData(): something's messed with timing, delta %d\n", delta);
delta = 0;
}
//fprintf (stderr, "played_data %d total_decoded %d delta %d\n", played_data, soundSource[SPEECH_SOURCE].total_decoded, delta);
pos = soundSource[SPEECH_SOURCE].sbuf_offset + delta;
if (pos % 2 == 1)
pos++;
assert (pos >= 0);
for (i = 0; i < RADAR_WIDTH; ++i)
{
SDWORD s;
for (;;)
{
if (pos >= soundSource[SPEECH_SOURCE].sbuf_size)
pos = pos - soundSource[SPEECH_SOURCE].sbuf_size;
else
break;
}
s = *(SWORD*) (&sbuffer[pos]);
s = (s / 1260) + (RADAR_HEIGHT >> 1);
if (s < 0)
s = 0;
else if (s >= RADAR_HEIGHT)
s = RADAR_HEIGHT - 1;
scopedata[i] = (UBYTE) s;
pos += 2;
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
return 1;
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
}
else if (musicVolumeScale != 0.0f)
{
// speech is disabled but music is not so process it instead
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
if (soundSource[MUSIC_SOURCE].sample && soundSource[MUSIC_SOURCE].sample->decoder &&
PlayingStream (MUSIC_SOURCE) && soundSource[MUSIC_SOURCE].sbuffer &&
soundSource[MUSIC_SOURCE].sbuf_size > 0)
{
float played_time = (GetTimeCounter () - soundSource[MUSIC_SOURCE].sbuf_lasttime) /
(float)ONE_SECOND;
int delta = (int) (played_time * (float)soundSource[MUSIC_SOURCE].
sample->decoder->frequency * 4.0f);
unsigned long pos, i, step;
UBYTE *scopedata = (UBYTE *) data;
UBYTE *sbuffer = soundSource[MUSIC_SOURCE].sbuffer;
assert (soundSource[MUSIC_SOURCE].sample->decoder->frequency >= 11025);
assert (soundSource[MUSIC_SOURCE].sample->decoder->format == AL_FORMAT_STEREO16);
step = soundSource[MUSIC_SOURCE].sample->decoder->frequency / 11025 * 16;
if (step % 2 == 1)
step++;
if (delta < 0)
{
//fprintf (stderr, "GetSoundData(): something's messed with timing, delta %d\n", delta);
delta = 0;
}
else if (delta > (int)(soundSource[MUSIC_SOURCE].sbuf_size * 2))
{
//fprintf (stderr, "GetSoundData(): something's messed with timing, delta %d\n", delta);
delta = 0;
}
//fprintf (stderr, "played_data %d total_decoded %d delta %d\n", played_data, soundSource[MUSIC_SOURCE].total_decoded, delta);
pos = soundSource[MUSIC_SOURCE].sbuf_offset + delta;
if (pos % 2 == 1)
pos++;
assert (pos >= 0);
for (i = 0; i < RADAR_WIDTH; ++i)
{
SDWORD s;
for (;;)
{
if (pos >= soundSource[MUSIC_SOURCE].sbuf_size)
pos = pos - soundSource[MUSIC_SOURCE].sbuf_size;
else
break;
}
s = (*(SWORD*)(&sbuffer[pos])) + (*(SWORD*)(&sbuffer[pos + 2]));
s = (s / 1260) + (RADAR_HEIGHT >> 1);
if (s < 0)
s = 0;
else if (s >= RADAR_HEIGHT)
s = RADAR_HEIGHT - 1;
scopedata[i] = (UBYTE) s;
pos += step;
}
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
return 1;
}
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
}
return 0;
}
// tells current position of streaming speech
int
GetSoundInfo (int max_len)
{
ALuint length, offset;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
if (soundSource[SPEECH_SOURCE].sample)
{
length = (ALuint) (soundSource[SPEECH_SOURCE].sample->length * (float)ONE_SECOND);
offset = (ALuint) (GetTimeCounter () - soundSource[SPEECH_SOURCE].start_time);
}
else
{
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
return (0);
}
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
if (offset > length)
return max_len;
return (int)(max_len * offset / length);
}
#endif
@@ -17,7 +17,7 @@
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23 /* OpenAL specific code by Mika Kolehmainen, 2002-10-23
*/ */
#ifdef SOUNDMODULE_MIXSDL #if defined SOUNDMODULE_MIXSDL || defined SOUNDMODULE_OPENAL
#ifdef WIN32 #ifdef WIN32
#include <io.h> #include <io.h>
@@ -33,24 +33,24 @@ PlayChannel (COUNT channel, PVOID sample, COUNT sample_length, COUNT loop_begin,
{ {
TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample; TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample;
soundSource[channel].sample = tfb_sample; soundSource[channel].sample = tfb_sample;
mixSDL_SourceRewind (soundSource[channel].handle); TFBSound_SourceRewind (soundSource[channel].handle);
mixSDL_Sourcei (soundSource[channel].handle, MIX_BUFFER, tfb_sample->buffer[0]); TFBSound_Sourcei (soundSource[channel].handle, TFBSOUND_BUFFER, tfb_sample->buffer[0]);
mixSDL_SourcePlay (soundSource[channel].handle); TFBSound_SourcePlay (soundSource[channel].handle);
} }
void void
StopChannel(COUNT channel, unsigned char Priority) StopChannel(COUNT channel, unsigned char Priority)
{ {
mixSDL_SourceRewind (soundSource[channel].handle); TFBSound_SourceRewind (soundSource[channel].handle);
} }
BOOLEAN BOOLEAN
ChannelPlaying (COUNT WhichChannel) ChannelPlaying (COUNT WhichChannel)
{ {
mixSDL_Object state; TFBSound_Object state;
mixSDL_GetSourcei (soundSource[WhichChannel].handle, MIX_SOURCE_STATE, &state); TFBSound_GetSourcei (soundSource[WhichChannel].handle, TFBSOUND_SOURCE_STATE, &state);
if (state == MIX_PLAYING) if (state == TFBSOUND_PLAYING)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@@ -60,7 +60,7 @@ SetChannelVolume (COUNT channel, COUNT volume, BYTE priority)
// I wonder what this whole priority business is... // I wonder what this whole priority business is...
// I can probably ignore it. // I can probably ignore it.
{ {
mixSDL_Sourcef (soundSource[channel].handle, MIX_GAIN, TFBSound_Sourcef (soundSource[channel].handle, TFBSOUND_GAIN,
(volume / (float)MAX_VOLUME) * sfxVolumeScale); (volume / (float)MAX_VOLUME) * sfxVolumeScale);
} }
@@ -152,10 +152,10 @@ _GetSoundBankData (FILE *fp, DWORD length)
//fprintf (stderr, "_GetSoundBankData(): decoded_bytes %d\n", decoded_bytes); //fprintf (stderr, "_GetSoundBankData(): decoded_bytes %d\n", decoded_bytes);
sndfx[snd_ct]->num_buffers = 1; sndfx[snd_ct]->num_buffers = 1;
sndfx[snd_ct]->buffer = (mixSDL_Object *) HMalloc ( sndfx[snd_ct]->buffer = (TFBSound_Object *) HMalloc (
sizeof (mixSDL_Object) * sndfx[snd_ct]->num_buffers); sizeof (TFBSound_Object) * sndfx[snd_ct]->num_buffers);
mixSDL_GenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer); TFBSound_GenBuffers (sndfx[snd_ct]->num_buffers, sndfx[snd_ct]->buffer);
mixSDL_BufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format, TFBSound_BufferData (sndfx[snd_ct]->buffer[0], sndfx[snd_ct]->decoder->format,
sndfx[snd_ct]->decoder->buffer, decoded_bytes, sndfx[snd_ct]->decoder->buffer, decoded_bytes,
sndfx[snd_ct]->decoder->frequency); sndfx[snd_ct]->decoder->frequency);
@@ -246,7 +246,7 @@ _ReleaseSoundBankData (MEM_HANDLE Snd)
if ((*sptr)->decoder) if ((*sptr)->decoder)
SoundDecoder_Free ((*sptr)->decoder); SoundDecoder_Free ((*sptr)->decoder);
mixSDL_DeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer); TFBSound_DeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer);
HFree ((*sptr)->buffer); HFree ((*sptr)->buffer);
HFree (*sptr); HFree (*sptr);
*sptr++ = 0; *sptr++ = 0;
+140
View File
@@ -0,0 +1,140 @@
//Copyright Paul Reiche, Fred Ford. 1992-2002
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if defined SOUNDMODULE_MIXSDL || defined SOUNDMODULE_OPENAL
#include "libs/sound/sound_common.h"
#include "sound.h"
TFB_SoundSource soundSource[NUM_SOUNDSOURCES];
static Task StreamDecoderTask;
void
StopSound (void)
{
int i;
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
{
TFBSound_SourceRewind (soundSource[i].handle);
}
}
BOOLEAN
SoundPlaying (void)
{
int i;
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
{
TFB_SoundSample *sample;
sample = soundSource[i].sample;
if (sample && sample->decoder)
{
BOOLEAN result;
LockMutex (soundSource[i].stream_mutex);
result = PlayingStream (i);
UnlockMutex (soundSource[i].stream_mutex);
if (result)
return TRUE;
}
else
{
uint32 state;
TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_SOURCE_STATE, &state);
if (state == TFBSOUND_PLAYING)
return TRUE;
}
}
return FALSE;
}
TFB_SoundChain *
create_soundchain (TFB_SoundDecoder *decoder, float startTime)
{
TFB_SoundChain *chain;
chain = (TFB_SoundChain *)HMalloc (sizeof (TFB_SoundChain));
chain->decoder = decoder;
chain->next =NULL;
chain->start_time = startTime;
chain->tag.buf_name = 0;
chain->tag.type = 0;
return (chain);
}
void
destroy_soundchain (TFB_SoundChain *chain)
{
while (chain->next)
{
TFB_SoundChain *tmp_chain = chain->next;
chain->next = chain->next->next;
if (tmp_chain->decoder)
SoundDecoder_Free (tmp_chain->decoder);
HFree (tmp_chain);
}
SoundDecoder_Free (chain->decoder);
HFree (chain);
}
TFB_SoundChain *
get_previous_chain (TFB_SoundChain *first_chain, TFB_SoundChain *current_chain)
{
TFB_SoundChain *prev_chain;
prev_chain = first_chain;
if (prev_chain == current_chain)
return (prev_chain);
while (prev_chain->next)
{
if (prev_chain->next == current_chain)
return (prev_chain);
prev_chain = prev_chain->next;
}
return (first_chain);
}
// Status: Ignored
BOOLEAN
InitSound (int argc, char* argv[])
{
return TRUE;
}
// Status: Ignored
void
UninitSound (void)
{
}
void SetSFXVolume (float volume)
{
int i;
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
{
TFBSound_Sourcef (soundSource[i].handle, TFBSOUND_GAIN, volume);
}
}
void SetSpeechVolume (float volume)
{
TFBSound_Sourcef (soundSource[SPEECH_SOURCE].handle, TFBSOUND_GAIN, volume);
}
#endif
@@ -22,7 +22,11 @@
#include "libs/strings/strintrn.h" #include "libs/strings/strintrn.h"
#include "libs/sound/sndintrn.h" #include "libs/sound/sndintrn.h"
#include "libs/sound/sound_common.h" #include "libs/sound/sound_common.h"
#include "mixer.h" #if defined SOUNDMODULE_MIXSDL
#include "mixsdl/sound_mixsdl.h"
#elif defined SOUNDMODULE_OPENAL
#include "openal/sound_openal.h"
#endif
#include "libs/sound/decoders/decoder.h" #include "libs/sound/decoders/decoder.h"
@@ -35,7 +39,7 @@
typedef struct typedef struct
{ {
mixSDL_Object buf_name; TFBSound_Object buf_name;
int type; int type;
void *value; void *value;
} TFB_SoundTag; } TFB_SoundTag;
@@ -61,7 +65,7 @@ typedef struct tfb_soundsample
TFB_SoundChain *read_chain_ptr; // points to chain read poistion TFB_SoundChain *read_chain_ptr; // points to chain read poistion
TFB_SoundChain *play_chain_ptr; // points to chain playing position TFB_SoundChain *play_chain_ptr; // points to chain playing position
float length; // total length of decoder chain in seconds float length; // total length of decoder chain in seconds
mixSDL_Object *buffer; TFBSound_Object *buffer;
uint32 num_buffers; uint32 num_buffers;
TFB_SoundTag **buffer_tag; TFB_SoundTag **buffer_tag;
} TFB_SoundSample; } TFB_SoundSample;
@@ -70,7 +74,7 @@ typedef struct tfb_soundsample
typedef struct tfb_soundsource typedef struct tfb_soundsource
{ {
TFB_SoundSample *sample; TFB_SoundSample *sample;
mixSDL_Object handle; TFBSound_Object handle;
bool stream_should_be_playing; bool stream_should_be_playing;
Mutex stream_mutex; Mutex stream_mutex;
sint32 start_time; sint32 start_time;
@@ -17,11 +17,10 @@
/* By Mika Kolehmainen, 2002-10-23 /* By Mika Kolehmainen, 2002-10-23
*/ */
#ifdef SOUNDMODULE_MIXSDL #if defined SOUNDMODULE_MIXSDL || defined SOUNDMODULE_OPENAL
#include <assert.h> #include <assert.h>
#include "sound.h" #include "sound.h"
#include "mixer.h"
bool speech_advancetrack = FALSE; bool speech_advancetrack = FALSE;
@@ -49,7 +48,7 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo
soundSource[source].sample = sample; soundSource[source].sample = sample;
soundSource[source].sample->play_chain_ptr = sample->read_chain_ptr; soundSource[source].sample->play_chain_ptr = sample->read_chain_ptr;
soundSource[source].sample->decoder->looping = looping; soundSource[source].sample->decoder->looping = looping;
mixSDL_Sourcei (soundSource[source].handle, MIX_LOOPING, false); TFBSound_Sourcei (soundSource[source].handle, TFBSOUND_LOOPING, false);
if (scope) if (scope)
{ {
@@ -73,9 +72,9 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo
if (decoded_bytes == 0) if (decoded_bytes == 0)
break; break;
mixSDL_BufferData (sample->buffer[i], sample->decoder->format, sample->decoder->buffer, TFBSound_BufferData (sample->buffer[i], sample->decoder->format, sample->decoder->buffer,
decoded_bytes, sample->decoder->frequency); decoded_bytes, sample->decoder->frequency);
mixSDL_SourceQueueBuffers (soundSource[source].handle, 1, &sample->buffer[i]); TFBSound_SourceQueueBuffers (soundSource[source].handle, 1, &sample->buffer[i]);
if (scope) if (scope)
{ {
@@ -114,7 +113,7 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo
soundSource[source].sbuf_lasttime = GetTimeCounter (); soundSource[source].sbuf_lasttime = GetTimeCounter ();
soundSource[source].start_time = (sint32)GetTimeCounter () - offset; soundSource[source].start_time = (sint32)GetTimeCounter () - offset;
soundSource[source].stream_should_be_playing = TRUE; soundSource[source].stream_should_be_playing = TRUE;
mixSDL_SourcePlay (soundSource[source].handle); TFBSound_SourcePlay (soundSource[source].handle);
} }
void void
@@ -136,16 +135,16 @@ StopStream (uint32 source)
soundSource[source].sbuf_size = 0; soundSource[source].sbuf_size = 0;
soundSource[source].sbuf_offset = 0; soundSource[source].sbuf_offset = 0;
mixSDL_SourceStop (soundSource[source].handle); TFBSound_SourceStop (soundSource[source].handle);
mixSDL_GetSourcei (soundSource[source].handle, MIX_BUFFERS_PROCESSED, &processed); TFBSound_GetSourcei (soundSource[source].handle, TFBSOUND_BUFFERS_PROCESSED, &processed);
mixSDL_GetSourcei (soundSource[source].handle, MIX_BUFFERS_QUEUED, &queued); TFBSound_GetSourcei (soundSource[source].handle, TFBSOUND_BUFFERS_QUEUED, &queued);
//fprintf (stderr, "StopStream(): source %d processed %d queued %d num_buffers %d\n", source, processed, queued, soundSource[source].sample->num_buffers); //fprintf (stderr, "StopStream(): source %d processed %d queued %d num_buffers %d\n", source, processed, queued, soundSource[source].sample->num_buffers);
if (processed != 0) if (processed != 0)
{ {
buffer = (uint32 *) HMalloc (sizeof (uint32) * processed); buffer = (uint32 *) HMalloc (sizeof (uint32) * processed);
mixSDL_SourceUnqueueBuffers (soundSource[source].handle, processed, buffer); TFBSound_SourceUnqueueBuffers (soundSource[source].handle, processed, buffer);
HFree (buffer); HFree (buffer);
} }
} }
@@ -155,7 +154,7 @@ PauseStream (uint32 source)
{ {
// TODO: how to handle start_time // TODO: how to handle start_time
soundSource[source].stream_should_be_playing = FALSE; soundSource[source].stream_should_be_playing = FALSE;
mixSDL_SourcePause (soundSource[source].handle); TFBSound_SourcePause (soundSource[source].handle);
} }
void void
@@ -163,7 +162,7 @@ ResumeStream (uint32 source)
{ {
// TODO: how to handle start_time // TODO: how to handle start_time
soundSource[source].stream_should_be_playing = TRUE; soundSource[source].stream_should_be_playing = TRUE;
mixSDL_SourcePlay (soundSource[source].handle); TFBSound_SourcePlay (soundSource[source].handle);
} }
BOOLEAN BOOLEAN
@@ -177,7 +176,7 @@ StreamDecoderTaskFunc (void *data)
{ {
Task task = (Task)data; Task task = (Task)data;
int i; int i;
mixSDL_Object last_buffer[NUM_SOUNDSOURCES]; TFBSound_Object last_buffer[NUM_SOUNDSOURCES];
for (i = 0; i < NUM_SOUNDSOURCES; i++) for (i = 0; i < NUM_SOUNDSOURCES; i++)
last_buffer[i] = 0; last_buffer[i] = 0;
@@ -190,7 +189,7 @@ StreamDecoderTaskFunc (void *data)
for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i) for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i)
{ {
uint32 processed, queued; uint32 processed, queued;
mixSDL_Object state; TFBSound_Object state;
bool do_speech_advancetrack = false; bool do_speech_advancetrack = false;
LockMutex (soundSource[i].stream_mutex); LockMutex (soundSource[i].stream_mutex);
@@ -204,13 +203,13 @@ StreamDecoderTaskFunc (void *data)
continue; continue;
} }
mixSDL_GetSourcei (soundSource[i].handle, MIX_BUFFERS_PROCESSED, &processed); TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_BUFFERS_PROCESSED, &processed);
mixSDL_GetSourcei (soundSource[i].handle, MIX_BUFFERS_QUEUED, &queued); TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_BUFFERS_QUEUED, &queued);
if (processed == 0) if (processed == 0)
{ {
mixSDL_GetSourcei (soundSource[i].handle, MIX_SOURCE_STATE, &state); TFBSound_GetSourcei (soundSource[i].handle, TFBSOUND_SOURCE_STATE, &state);
if (state != MIX_PLAYING) if (state != TFBSOUND_PLAYING)
{ {
if (queued == 0 && soundSource[i].sample->decoder->error == SOUNDDECODER_EOF) if (queued == 0 && soundSource[i].sample->decoder->error == SOUNDDECODER_EOF)
{ {
@@ -228,7 +227,7 @@ StreamDecoderTaskFunc (void *data)
{ {
fprintf (stderr, "StreamDecoderTaskFunc(): buffer underrun when playing %s, source %d\n", fprintf (stderr, "StreamDecoderTaskFunc(): buffer underrun when playing %s, source %d\n",
soundSource[i].sample->decoder->filename, i); soundSource[i].sample->decoder->filename, i);
mixSDL_SourcePlay (soundSource[i].handle); TFBSound_SourcePlay (soundSource[i].handle);
} }
} }
} }
@@ -238,15 +237,15 @@ StreamDecoderTaskFunc (void *data)
while (processed) while (processed)
{ {
uint32 error; uint32 error;
mixSDL_Object buffer; TFBSound_Object buffer;
uint32 decoded_bytes; uint32 decoded_bytes;
uint32 buf_num; uint32 buf_num;
mixSDL_GetError (); // clear error state TFBSound_GetError (); // clear error state
mixSDL_SourceUnqueueBuffers (soundSource[i].handle, 1, &buffer); TFBSound_SourceUnqueueBuffers (soundSource[i].handle, 1, &buffer);
if ((error = mixSDL_GetError()) != MIX_NO_ERROR) if ((error = TFBSound_GetError()) != TFBSOUND_NO_ERROR)
{ {
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceUnqueueBuffers: %x, file %s, source %d\n", error, soundSource[i].sample->decoder->filename, i); fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceUnqueueBuffers: %x, file %s, source %d\n", error, soundSource[i].sample->decoder->filename, i);
break; break;
@@ -271,7 +270,7 @@ StreamDecoderTaskFunc (void *data)
{ {
uint32 buf_size; uint32 buf_size;
soundSource[i].sbuf_lasttime = GetTimeCounter (); soundSource[i].sbuf_lasttime = GetTimeCounter ();
mixSDL_GetBufferi(buffer, MIX_SIZE, &buf_size); TFBSound_GetBufferi(buffer, TFBSOUND_SIZE, &buf_size);
soundSource[i].sbuf_offset += buf_size; soundSource[i].sbuf_offset += buf_size;
if (soundSource[i].sbuf_offset > soundSource[i].sbuf_size) if (soundSource[i].sbuf_offset > soundSource[i].sbuf_size)
soundSource[i].sbuf_offset -= soundSource[i].sbuf_size; soundSource[i].sbuf_offset -= soundSource[i].sbuf_size;
@@ -330,19 +329,38 @@ StreamDecoderTaskFunc (void *data)
if (decoded_bytes > 0) if (decoded_bytes > 0)
{ {
mixSDL_BufferData (buffer, soundSource[i].sample->decoder->format, #if defined SOUNDMODULE_OPENAL && !defined (WIN32) // && !defined (MacOS and BeOS too)
soundSource[i].sample->decoder->buffer, decoded_bytes, // *nix OpenAL implementation has to handle stereo data differently to avoid mixing it to mono
soundSource[i].sample->decoder->frequency);
if (soundSource[i].sample->decoder->format == TFBSOUND_FORMAT_STEREO8 ||
if ((error = mixSDL_GetError()) != MIX_NO_ERROR) soundSource[i].sample->decoder->format == TFBSOUND_FORMAT_STEREO16)
{ {
fprintf (stderr, "StreamDecoderTaskFunc(): mixSDL error after mixSDL_BufferData: %x, file %s, source %d, decoded_bytes %d\n", TFBSound_BufferData_Linux (buffer, soundSource[i].sample->decoder->format,
soundSource[i].sample->decoder->buffer, decoded_bytes,
soundSource[i].sample->decoder->frequency,
soundSource[i].sample->decoder->format);
}
else
{
TFBSound_BufferData (buffer, soundSource[i].sample->decoder->format,
soundSource[i].sample->decoder->buffer, decoded_bytes,
soundSource[i].sample->decoder->frequency);
}
#else
TFBSound_BufferData (buffer, soundSource[i].sample->decoder->format,
soundSource[i].sample->decoder->buffer, decoded_bytes,
soundSource[i].sample->decoder->frequency);
#endif
if ((error = TFBSound_GetError()) != TFBSOUND_NO_ERROR)
{
fprintf (stderr, "StreamDecoderTaskFunc(): TFBSound error after TFBSound_BufferData: %x, file %s, source %d, decoded_bytes %d\n",
error, soundSource[i].sample->decoder->filename, i, decoded_bytes); error, soundSource[i].sample->decoder->filename, i, decoded_bytes);
} }
else else
{ {
last_buffer[i] = buffer; last_buffer[i] = buffer;
mixSDL_SourceQueueBuffers (soundSource[i].handle, 1, &buffer); TFBSound_SourceQueueBuffers (soundSource[i].handle, 1, &buffer);
if (soundSource[i].sbuffer) if (soundSource[i].sbuffer)
{ {
@@ -380,9 +398,9 @@ StreamDecoderTaskFunc (void *data)
} }
} }
if ((error = mixSDL_GetError()) != MIX_NO_ERROR) if ((error = TFBSound_GetError()) != TFBSOUND_NO_ERROR)
{ {
fprintf (stderr, "StreamDecoderTaskFunc(): mixSDL error after mixSDL_SourceQueueBuffers: %x, file %s, source %d, decoded_bytes %d\n", fprintf (stderr, "StreamDecoderTaskFunc(): TFBSound error after TFBSound_SourceQueueBuffers: %x, file %s, source %d, decoded_bytes %d\n",
error, i, soundSource[i].sample->decoder->filename, decoded_bytes); error, i, soundSource[i].sample->decoder->filename, decoded_bytes);
} }
} }
@@ -18,7 +18,7 @@
* Adapted for MixSDL * Adapted for MixSDL
*/ */
#ifdef SOUNDMODULE_MIXSDL #if defined SOUNDMODULE_MIXSDL || defined SOUNDMODULE_OPENAL
#include <assert.h> #include <assert.h>
#include "sound.h" #include "sound.h"
@@ -97,10 +97,10 @@ ResumeTrack ()
uint32 state; uint32 state;
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex); LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
mixSDL_GetSourcei (soundSource[SPEECH_SOURCE].handle, MIX_SOURCE_STATE, &state); TFBSound_GetSourcei (soundSource[SPEECH_SOURCE].handle, TFBSOUND_SOURCE_STATE, &state);
if (!track_pos_changed && !soundSource[SPEECH_SOURCE].stream_should_be_playing && if (!track_pos_changed && !soundSource[SPEECH_SOURCE].stream_should_be_playing &&
state == MIX_PAUSED) state == TFBSOUND_PAUSED)
{ {
ResumeStream (SPEECH_SOURCE); ResumeStream (SPEECH_SOURCE);
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex); UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
@@ -172,7 +172,7 @@ StopTrack ()
if (sound_sample) if (sound_sample)
{ {
DestroyMutex (track_mutex); DestroyMutex (track_mutex);
mixSDL_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer); TFBSound_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
HFree (sound_sample->buffer); HFree (sound_sample->buffer);
HFree (sound_sample->buffer_tag); HFree (sound_sample->buffer_tag);
HFree (sound_sample); HFree (sound_sample);
@@ -369,7 +369,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp)
sound_sample->num_buffers = 8; sound_sample->num_buffers = 8;
sound_sample->buffer_tag = HMalloc (sizeof (TFB_SoundTag *) * sound_sample->num_buffers); sound_sample->buffer_tag = HMalloc (sizeof (TFB_SoundTag *) * sound_sample->num_buffers);
sound_sample->buffer = HMalloc (sizeof (uint32) * sound_sample->num_buffers); sound_sample->buffer = HMalloc (sizeof (uint32) * sound_sample->num_buffers);
mixSDL_GenBuffers (sound_sample->num_buffers, sound_sample->buffer); TFBSound_GenBuffers (sound_sample->num_buffers, sound_sample->buffer);
decoder = SoundDecoder_Load (TrackName, 4096, startTime, time_stamps[cur_page]); decoder = SoundDecoder_Load (TrackName, 4096, startTime, time_stamps[cur_page]);
sound_sample->read_chain_ptr = create_soundchain (decoder, 0.0); sound_sample->read_chain_ptr = create_soundchain (decoder, 0.0);
sound_sample->decoder = decoder; sound_sample->decoder = decoder;
@@ -404,7 +404,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp)
else else
{ {
fprintf (stderr, "SpliceTrack(): couldn't load %s\n", TrackName); fprintf (stderr, "SpliceTrack(): couldn't load %s\n", TrackName);
mixSDL_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer); TFBSound_DeleteBuffers (sound_sample->num_buffers, sound_sample->buffer);
destroy_soundchain (first_chain); destroy_soundchain (first_chain);
first_chain = NULL; first_chain = NULL;
HFree (sound_sample->buffer); HFree (sound_sample->buffer);
@@ -554,11 +554,11 @@ GetSoundData (void *data)
UBYTE *sbuffer = soundSource[SPEECH_SOURCE].sbuffer; UBYTE *sbuffer = soundSource[SPEECH_SOURCE].sbuffer;
assert (soundSource[SPEECH_SOURCE].sample->decoder->frequency == 11025); assert (soundSource[SPEECH_SOURCE].sample->decoder->frequency == 11025);
assert (soundSource[SPEECH_SOURCE].sample->decoder->format == MIX_FORMAT_MONO16); assert (soundSource[SPEECH_SOURCE].sample->decoder->format == TFBSOUND_FORMAT_MONO16);
if (delta < 0) if (delta < 0)
{ {
//fprintf (stderr, "GetSoundData(): something's messed with timing, delta %d\n", delta); fprintf (stderr, "GetSoundData(): something's messed with timing, delta %d\n", delta);
delta = 0; delta = 0;
} }
else if (delta > (int)(soundSource[SPEECH_SOURCE].sbuf_size * 2)) else if (delta > (int)(soundSource[SPEECH_SOURCE].sbuf_size * 2))
@@ -622,7 +622,7 @@ GetSoundData (void *data)
UBYTE *sbuffer = soundSource[MUSIC_SOURCE].sbuffer; UBYTE *sbuffer = soundSource[MUSIC_SOURCE].sbuffer;
assert (soundSource[MUSIC_SOURCE].sample->decoder->frequency >= 11025); assert (soundSource[MUSIC_SOURCE].sample->decoder->frequency >= 11025);
assert (soundSource[MUSIC_SOURCE].sample->decoder->format == MIX_FORMAT_STEREO16); assert (soundSource[MUSIC_SOURCE].sample->decoder->format == TFBSOUND_FORMAT_STEREO16);
step = soundSource[MUSIC_SOURCE].sample->decoder->frequency / 11025 * 16; step = soundSource[MUSIC_SOURCE].sample->decoder->frequency / 11025 * 16;
if (step % 2 == 1) if (step % 2 == 1)