Audiolib housekeeping

git-svn-id: https://svn.eduke32.com/eduke32@7918 1a8010ca-5511-0410-912e-c29ae57300e0

# Conflicts:
#	source/audiolib/src/multivoc.cpp
This commit is contained in:
terminx 2019-08-07 22:44:41 +00:00 committed by Christoph Oelckers
parent 9302e48cef
commit 635a929359
3 changed files with 93 additions and 112 deletions

View file

@ -96,7 +96,7 @@ private:
};
#define MV_MIXBUFFERSIZE 256
#define MV_NUMBEROFBUFFERS 16
#define MV_NUMBEROFBUFFERS 32
#define MV_TOTALBUFFERSIZE ( MV_MIXBUFFERSIZE * MV_NUMBEROFBUFFERS )
typedef enum

View file

@ -34,23 +34,23 @@
#define MIXBUFFERPOSITIONS 8
static int32_t ErrorCode = DSErr_Ok;
static int32_t ErrorCode;
static int32_t Initialised;
static int32_t Playing;
static char * MixBuffer = NULL;
static char * MixBuffer;
static int32_t MixBufferSize;
static int32_t MixBufferCount;
static int32_t MixBufferCurrent;
static int32_t MixBufferUsed;
static void (*MixCallBack)(void) = NULL;
static void (*MixCallBack)(void);
static LPDIRECTSOUND lpds = NULL;
static LPDIRECTSOUNDBUFFER lpdsbprimary = NULL, lpdsbsec = NULL;
static LPDIRECTSOUNDNOTIFY lpdsnotify = NULL;
static LPDIRECTSOUND lpds;
static LPDIRECTSOUNDBUFFER lpdsbprimary, lpdsbsec;
static LPDIRECTSOUNDNOTIFY lpdsnotify;
static HANDLE mixThread = NULL;
static HANDLE mixThread;
static mutex_t mutex;
static DSBPOSITIONNOTIFY notifyPositions[MIXBUFFERPOSITIONS + 1] = {};

View file

@ -88,15 +88,15 @@ int32_t MV_ErrorCode = MV_NotInstalled;
float MV_GlobalVolume = 1.f;
float MV_VolumeSmooth = 1.f;
static int32_t lockdepth = 0;
static int lockdepth = 0;
void DisableInterrupts(void)
static inline void MV_Lock(void)
{
if (!lockdepth++)
SoundDriver_Lock();
}
void RestoreInterrupts(void)
static inline void MV_Unlock(void)
{
if (!--lockdepth)
SoundDriver_Unlock();
@ -104,100 +104,73 @@ void RestoreInterrupts(void)
MV_Printf("RestoreInterrupts(): lockdepth < 0!\n");
}
const char *MV_ErrorString(int32_t ErrorNumber)
{
switch (ErrorNumber)
{
case MV_Error:
return MV_ErrorString(MV_ErrorCode);
case MV_Ok:
return "Multivoc ok.";
case MV_NotInstalled:
return "Multivoc not installed.";
case MV_DriverError:
return SoundDriver_ErrorString(SoundDriver_GetError());
case MV_NoVoices:
return "No free voices available to Multivoc.";
case MV_NoMem:
return "Out of memory in Multivoc.";
case MV_VoiceNotFound:
return "No voice with matching handle found.";
case MV_InvalidFile:
return "Invalid file passed in to Multivoc.";
default:
return "Unknown Multivoc error code.";
}
}
static bool MV_Mix(VoiceNode *voice, int const buffer)
static bool MV_Mix(VoiceNode * const voice, int const buffer)
{
/* cheap fix for a crash under 64-bit linux */
/* v v v v */
if (voice->length == 0 && (voice->GetSound == NULL || voice->GetSound(voice) != KeepPlaying))
return false;
float const gv = MV_GlobalVolume;
if (voice->priority == FX_MUSIC_PRIORITY)
MV_GlobalVolume = 1.f;
int32_t length = MV_MIXBUFFERSIZE;
uint32_t FixedPointBufferSize = voice->FixedPointBufferSize;
uint32_t bufsiz = voice->FixedPointBufferSize;
uint32_t const rate = voice->RateScale;
MV_MixDestination = MV_MixBuffer[buffer];
// Add this voice to the mix
do
{
uint32_t const rate = voice->RateScale;
int32_t mixlen = length;
uint32_t const position = voice->position;
int32_t voclength;
uint32_t const voclen = voice->length;
// Check if the last sample in this buffer would be
// beyond the length of the sample block
if ((position + FixedPointBufferSize) >= voice->length)
if ((position + bufsiz) >= voclen)
{
if (position >= voice->length)
if (position >= voclen)
{
voice->GetSound(voice);
return true;
break;
}
voclength = (voice->length - position + rate - voice->channels) / rate;
mixlen = (voclen - position + rate - voice->channels) / rate;
}
else
voclength = length;
float const gv = MV_GlobalVolume;
voice->position = voice->mix(voice, mixlen);
length -= mixlen;
if (voice->priority == FX_MUSIC_PRIORITY)
MV_GlobalVolume = 1.f;
voice->position = voice->mix(voice, voclength);
MV_GlobalVolume = gv;
length -= voclength;
if (voice->position >= voice->length)
if (voice->position >= voclen)
{
// Get the next block of sound
if (voice->GetSound(voice) == NoMoreData)
return false;
if (length > (voice->channels - 1))
{
// Get the position of the last sample in the buffer
FixedPointBufferSize = voice->RateScale * (length - voice->channels);
MV_GlobalVolume = gv;
return false;
}
// Get the position of the last sample in the buffer
if (length > (voice->channels - 1))
bufsiz = voice->RateScale * (length - voice->channels);
}
} while (length > 0);
MV_GlobalVolume = gv;
return true;
}
void MV_PlayVoice(VoiceNode *voice)
{
DisableInterrupts();
MV_Lock();
LL::SortedInsert(&VoiceList, voice, &VoiceNode::priority);
voice->LeftVolume = voice->LeftVolumeDest;
voice->RightVolume = voice->RightVolumeDest;
RestoreInterrupts();
MV_Unlock();
}
static void MV_CleanupVoice(VoiceNode *voice)
@ -225,12 +198,11 @@ static void MV_CleanupVoice(VoiceNode *voice)
static void MV_StopVoice(VoiceNode *voice)
{
MV_Lock();
MV_CleanupVoice(voice);
DisableInterrupts();
// move the voice from the play list to the free list
LL::Move(voice, &VoicePool);
RestoreInterrupts();
MV_Unlock();
}
/*---------------------------------------------------------------------
@ -243,15 +215,10 @@ static void MV_StopVoice(VoiceNode *voice)
static void MV_ServiceVoc(void)
{
// Toggle which buffer we'll mix next
if (++MV_MixPage >= MV_NumberOfBuffers)
MV_MixPage -= MV_NumberOfBuffers;
++MV_MixPage &= MV_NumberOfBuffers-1;
if (MV_ReverbLevel == 0)
{
// Initialize buffer
//Commented out so that the buffer is always cleared.
//This is so the guys at Echo Speech can mix into the
//buffer even when no sounds are playing.
if (!MV_BufferEmpty[MV_MixPage])
{
Bmemset(MV_MixBuffer[MV_MixPage], 0, MV_BufferSize);
@ -261,47 +228,37 @@ static void MV_ServiceVoc(void)
else
{
char const *const end = MV_MixBuffer[0] + MV_BufferLength;
char *dest = MV_MixBuffer[MV_MixPage];
char const *source = MV_MixBuffer[MV_MixPage] - MV_ReverbDelay;
char * dest = MV_MixBuffer[MV_MixPage];
char const * source = MV_MixBuffer[MV_MixPage] - MV_ReverbDelay;
if (source < MV_MixBuffer[ 0 ])
source += MV_BufferLength;
int32_t length = MV_BufferSize;
while (length > 0)
do
{
int const count = (source + length > end) ? (end - source) : length;
MV_16BitReverb(source, dest, MV_ReverbVolume, count / 2);
MV_16BitReverb(source, dest, MV_ReverbVolume, count >> 1);
// if we go through the loop again, it means that we've wrapped around the buffer
source = MV_MixBuffer[ 0 ];
dest += count;
length -= count;
} while (length > 0);
}
}
// Play any waiting voices
//DisableInterrupts();
if (!VoiceList.next || VoiceList.next == &VoiceList)
return;
VoiceNode *voice = VoiceList.next;
int iter = 0;
VoiceNode *next;
do
{
next = voice->next;
if (++iter > MV_MaxVoices && MV_Printf)
MV_Printf("more iterations than voices! iter: %d\n",iter);
if (voice->Paused)
continue;
@ -315,8 +272,6 @@ static void MV_ServiceVoc(void)
}
}
while ((voice = next) != &VoiceList);
//RestoreInterrupts();
}
static VoiceNode *MV_GetVoice(int32_t handle)
@ -328,18 +283,18 @@ static VoiceNode *MV_GetVoice(int32_t handle)
return NULL;
}
DisableInterrupts();
MV_Lock();
for (VoiceNode *voice = VoiceList.next; voice != &VoiceList; voice = voice->next)
{
if (handle == voice->handle)
{
RestoreInterrupts();
MV_Unlock();
return voice;
}
}
RestoreInterrupts();
MV_Unlock();
MV_SetErrorCode(MV_VoiceNotFound);
return NULL;
}
@ -357,12 +312,12 @@ VoiceNode *MV_BeginService(int32_t handle)
return NULL;
}
DisableInterrupts();
MV_Lock();
return voice;
}
static inline void MV_EndService(void) { RestoreInterrupts(); }
static inline void MV_EndService(void) { MV_Unlock(); }
int32_t MV_VoicePlaying(int32_t handle)
{
@ -374,11 +329,11 @@ int32_t MV_KillAllVoices(void)
if (!MV_Installed)
return MV_Error;
DisableInterrupts();
MV_Lock();
if (&VoiceList == VoiceList.next)
{
RestoreInterrupts();
MV_Unlock();
return MV_Ok;
}
@ -397,7 +352,7 @@ int32_t MV_KillAllVoices(void)
voice = VoiceList.prev;
}
RestoreInterrupts();
MV_Unlock();
return MV_Ok;
}
@ -420,14 +375,14 @@ int32_t MV_VoicesPlaying(void)
if (!MV_Installed)
return 0;
DisableInterrupts();
MV_Lock();
int NumVoices = 0;
for (VoiceNode *voice = VoiceList.next; voice != &VoiceList; voice = voice->next)
NumVoices++;
RestoreInterrupts();
MV_Unlock();
return NumVoices;
}
@ -436,7 +391,7 @@ VoiceNode *MV_AllocVoice(int32_t priority)
{
VoiceNode *voice, *node;
DisableInterrupts();
MV_Lock();
// Check if we have any free voices
if (LL::Empty(&VoicePool))
@ -454,14 +409,14 @@ VoiceNode *MV_AllocVoice(int32_t priority)
if (LL::Empty(&VoicePool))
{
// No free voices
RestoreInterrupts();
MV_Unlock();
return NULL;
}
}
voice = VoicePool.next;
LL::Remove(voice);
RestoreInterrupts();
MV_Unlock();
int32_t vhan = MV_MINVOICEHANDLE;
@ -483,7 +438,7 @@ int32_t MV_VoiceAvailable(int32_t priority)
if (!LL::Empty(&VoicePool))
return TRUE;
DisableInterrupts();
MV_Lock();
VoiceNode *voice, *node;
@ -496,11 +451,11 @@ int32_t MV_VoiceAvailable(int32_t priority)
if ((voice == &VoiceList) || (priority < voice->priority))
{
RestoreInterrupts();
MV_Unlock();
return FALSE;
}
RestoreInterrupts();
MV_Unlock();
return TRUE;
}
@ -563,7 +518,7 @@ int32_t MV_SetFrequency(int32_t handle, int32_t frequency)
void MV_SetVoiceMixMode(VoiceNode *voice)
{
int32_t type = T_DEFAULT;
int type = T_DEFAULT;
if (MV_Channels == 1)
type |= T_MONO;
@ -717,7 +672,6 @@ void MV_SetReverb(int32_t reverb)
}
int32_t MV_GetMaxReverbDelay(void) { return MV_MIXBUFFERSIZE * MV_NumberOfBuffers; }
int32_t MV_GetReverbDelay(void) { return MV_ReverbDelay / MV_SampleSize; }
void MV_SetReverbDelay(int32_t delay)
@ -735,6 +689,7 @@ static int32_t MV_SetMixMode(int32_t numchannels)
MV_BufferSize = MV_MIXBUFFERSIZE * MV_SampleSize;
MV_NumberOfBuffers = MV_TOTALBUFFERSIZE / MV_BufferSize;
Bassert(isPow2(MV_NumberOfBuffers));
MV_BufferLength = MV_TOTALBUFFERSIZE;
MV_RightChannelOffset = MV_SampleSize >> 1;
@ -766,7 +721,7 @@ static void MV_StopPlayback(void)
SoundDriver_StopPlayback();
// Make sure all callbacks are done.
DisableInterrupts();
MV_Lock();
for (VoiceNode *voice = VoiceList.next, *next; voice != &VoiceList; voice = next)
{
@ -774,7 +729,7 @@ static void MV_StopPlayback(void)
MV_StopVoice(voice);
}
RestoreInterrupts();
MV_Unlock();
}
static void MV_CalcPanTable(void)
@ -942,3 +897,29 @@ void MV_SetPrintf(void (*function)(const char *, ...)) { MV_Printf = function; }
const char *loopStartTags[loopStartTagCount] = { "LOOP_START", "LOOPSTART", "LOOP" };
const char *loopEndTags[loopEndTagCount] = { "LOOP_END", "LOOPEND" };
const char *loopLengthTags[loopLengthTagCount] = { "LOOP_LENGTH", "LOOPLENGTH" };
const char *MV_ErrorString(int32_t ErrorNumber)
{
switch (ErrorNumber)
{
case MV_Error:
return MV_ErrorString(MV_ErrorCode);
case MV_Ok:
return "Multivoc ok.";
case MV_NotInstalled:
return "Multivoc not installed.";
case MV_DriverError:
return SoundDriver_ErrorString(SoundDriver_GetError());
case MV_NoVoices:
return "No free voices available to Multivoc.";
case MV_NoMem:
return "Out of memory in Multivoc.";
case MV_VoiceNotFound:
return "No voice with matching handle found.";
case MV_InvalidFile:
return "Invalid file passed in to Multivoc.";
default:
return "Unknown Multivoc error code.";
}
}