From a191faf1756fed9c15e5cdef3db73adbbaad3376 Mon Sep 17 00:00:00 2001 From: sirlemonhead Date: Thu, 5 Dec 2019 21:17:58 +0000 Subject: [PATCH] Add Demand Feed audio streaming support back to ASS audiolib. This is from the Rise of the Triad source release. --- source/audiolib/include/fx_man.h | 2 + source/audiolib/include/multivoc.h | 3 + source/audiolib/src/_multivc.h | 2 + source/audiolib/src/fx_man.cpp | 33 ++++++++++ source/audiolib/src/multivoc.cpp | 100 +++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) diff --git a/source/audiolib/include/fx_man.h b/source/audiolib/include/fx_man.h index 12d50b3d2..05177cac8 100644 --- a/source/audiolib/include/fx_man.h +++ b/source/audiolib/include/fx_man.h @@ -69,6 +69,8 @@ int FX_PlayRaw(char *ptr, uint32_t ptrlength, int rate, int pitchoffset, int vol int FX_PlayLoopedRaw(char *ptr, uint32_t ptrlength, char *loopstart, char *loopend, int rate, int pitchoffset, int vol, int left, int right, int priority, float volume, intptr_t callbackval); +int FX_StartDemandFeedPlayback(void (*function)(const char** ptr, uint32_t* length), int rate, int pitchoffset, + int vol, int left, int right, int priority, fix16_t volume, uint32_t callbackval); int FX_SetPrintf(void(*function)(const char *, ...)); diff --git a/source/audiolib/include/multivoc.h b/source/audiolib/include/multivoc.h index 7a315e974..5828ad9d6 100644 --- a/source/audiolib/include/multivoc.h +++ b/source/audiolib/include/multivoc.h @@ -105,6 +105,9 @@ int MV_PlayVOC3D(char *ptr, uint32_t length, int loophow, int pitchoffset, int a int MV_PlayVOC(char *ptr, uint32_t length, int loopstart, int loopend, int pitchoffset, int vol, int left, int right, int priority, float volume, intptr_t callbackval); +int MV_StartDemandFeedPlayback(void (*function)(const char** ptr, uint32_t* length), int rate, + int pitchoffset, int vol, int left, int right, int priority, fix16_t volume, uint32_t callbackval); + decltype(MV_PlayVOC3D) MV_PlayWAV3D; decltype(MV_PlayVOC) MV_PlayWAV; decltype(MV_PlayVOC3D) MV_PlayVorbis3D; diff --git a/source/audiolib/src/_multivc.h b/source/audiolib/src/_multivc.h index 0cbf8ed7a..79d55056c 100644 --- a/source/audiolib/src/_multivc.h +++ b/source/audiolib/src/_multivc.h @@ -158,6 +158,8 @@ typedef struct VoiceNode uint32_t (*mix)(struct VoiceNode *, uint32_t); + void (*DemandFeed)(const char** ptr, uint32_t* length); + const char *sound; float LeftVolume, LeftVolumeDest; diff --git a/source/audiolib/src/fx_man.cpp b/source/audiolib/src/fx_man.cpp index 2d3d10799..9d0d702e7 100644 --- a/source/audiolib/src/fx_man.cpp +++ b/source/audiolib/src/fx_man.cpp @@ -225,3 +225,36 @@ int FX_SetPrintf(void (*function)(const char *, ...)) return FX_Ok; } + +/*--------------------------------------------------------------------- + Function: FX_StartDemandFeedPlayback + + Plays a digitized sound from a user controlled buffering system. +---------------------------------------------------------------------*/ + +int FX_StartDemandFeedPlayback +( + void (*function)(const char** ptr, uint32_t* length), + int rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + fix16_t volume, + uint32_t callbackval +) + +{ + int handle; + + handle = MV_StartDemandFeedPlayback(function, rate, + pitchoffset, vol, left, right, priority, volume, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} \ No newline at end of file diff --git a/source/audiolib/src/multivoc.cpp b/source/audiolib/src/multivoc.cpp index 4755b448a..96f2dc0fe 100644 --- a/source/audiolib/src/multivoc.cpp +++ b/source/audiolib/src/multivoc.cpp @@ -899,3 +899,103 @@ const char *MV_ErrorString(int ErrorNumber) } } +/*--------------------------------------------------------------------- + Function: MV_GetNextDemandFeedBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextDemandFeedBlock +( + VoiceNode* voice +) + +{ + if (voice->BlockLength > 0) + { + voice->position -= voice->length; + voice->sound += voice->length >> 16; + voice->length = min(voice->BlockLength, 0x8000u); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return(KeepPlaying); + } + + if (voice->DemandFeed == NULL) + { + return(NoMoreData); + } + + voice->position = 0; + (voice->DemandFeed)(&voice->sound, &voice->BlockLength); + voice->length = min(voice->BlockLength, 0x8000u); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + if ((voice->length > 0) && (voice->sound != NULL)) + { + return(KeepPlaying); + } + return(NoMoreData); +} + +/*--------------------------------------------------------------------- + Function: MV_StartDemandFeedPlayback + + Plays a digitized sound from a user controlled buffering system. +---------------------------------------------------------------------*/ + +int MV_StartDemandFeedPlayback +( + void (*function)(const char** ptr, uint32_t* length), + int rate, + int pitchoffset, + int vol, + int left, + int right, + int priority, + fix16_t volume, + uint32_t callbackval +) + +{ + VoiceNode* voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice(priority); + if (voice == NULL) + { + MV_SetErrorCode(MV_NoVoices); + return(MV_Error); + } + +// voice->wavetype = FMT_DEMANDFED; + voice->bits = 8; + voice->channels = 1; + voice->GetSound = MV_GetNextDemandFeedBlock; + voice->NextBlock = NULL; + voice->DemandFeed = function; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->BlockLength = 0; + voice->position = 0; + voice->sound = NULL; + voice->length = 0; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + + MV_SetVoicePitch(voice, rate, pitchoffset); + MV_SetVoiceVolume(voice, vol, left, right, volume); + MV_PlayVoice(voice); + + return(voice->handle); +}