From 635a92935929cdee46642269517378436da86c2c Mon Sep 17 00:00:00 2001 From: terminx Date: Wed, 7 Aug 2019 22:44:41 +0000 Subject: [PATCH] Audiolib housekeeping git-svn-id: https://svn.eduke32.com/eduke32@7918 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/audiolib/src/multivoc.cpp --- source/audiolib/src/_multivc.h | 2 +- source/audiolib/src/driver_directsound.cpp | 14 +- source/audiolib/src/multivoc.cpp | 189 +++++++++------------ 3 files changed, 93 insertions(+), 112 deletions(-) diff --git a/source/audiolib/src/_multivc.h b/source/audiolib/src/_multivc.h index d094377c0..ba8e2fb98 100644 --- a/source/audiolib/src/_multivc.h +++ b/source/audiolib/src/_multivc.h @@ -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 diff --git a/source/audiolib/src/driver_directsound.cpp b/source/audiolib/src/driver_directsound.cpp index bf601a52e..b1192485c 100644 --- a/source/audiolib/src/driver_directsound.cpp +++ b/source/audiolib/src/driver_directsound.cpp @@ -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] = {}; diff --git a/source/audiolib/src/multivoc.cpp b/source/audiolib/src/multivoc.cpp index 49ff0a965..9c0dacee0 100644 --- a/source/audiolib/src/multivoc.cpp +++ b/source/audiolib/src/multivoc.cpp @@ -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; - int32_t length = MV_MIXBUFFERSIZE; - uint32_t FixedPointBufferSize = voice->FixedPointBufferSize; + float const gv = MV_GlobalVolume; + + if (voice->priority == FX_MUSIC_PRIORITY) + MV_GlobalVolume = 1.f; + + int32_t length = MV_MIXBUFFERSIZE; + 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); @@ -260,48 +227,38 @@ 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 const *const end = MV_MixBuffer[0] + MV_BufferLength; + 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."; + } +} +