diff --git a/source/audiolib/src/_multivc.h b/source/audiolib/src/_multivc.h index 4a72e9643..12a8354f7 100644 --- a/source/audiolib/src/_multivc.h +++ b/source/audiolib/src/_multivc.h @@ -40,8 +40,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define T_MONO 2 #define T_16BITSOURCE 4 #define T_STEREOSOURCE 8 -#define T_LEFTQUIET 16 -#define T_RIGHTQUIET 32 #define T_DEFAULT T_SIXTEENBIT_STEREO #define MV_MAXPANPOSITION 127 /* formerly 31 */ @@ -55,6 +53,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define MIX_VOLUME(volume) ((max(0, min((volume), 255)) * (MV_MAXVOLUME + 1)) >> 8) extern float MV_GlobalVolume; +extern float MV_VolumeSmooth; + +static FORCE_INLINE float SMOOTH_VOLUME(float const volume, float const dest) +{ + return volume + (dest - volume) * MV_VolumeSmooth; +} template static inline conditional_t< is_signed::value, make_unsigned_t, make_signed_t > FLIP_SIGN(T src) @@ -109,12 +113,12 @@ typedef struct VoiceNode playbackstatus (*GetSound)(struct VoiceNode *); - uint32_t (*mix)(struct VoiceNode const *, uint32_t); + uint32_t (*mix)(struct VoiceNode *, uint32_t); const char *sound; - const int16_t *LeftVolume; - const int16_t *RightVolume; + float LeftVolume, LeftVolumeDest; + float RightVolume, RightVolumeDest; void *rawdataptr; @@ -210,21 +214,19 @@ void MV_ReleaseXAVoice(VoiceNode *voice); void MV_ReleaseXMPVoice(VoiceNode *voice); // implemented in mix.c -uint32_t MV_Mix16BitMono(struct VoiceNode const *voice, uint32_t length); -uint32_t MV_Mix16BitStereo(struct VoiceNode const *voice, uint32_t length); -uint32_t MV_Mix16BitMono16(struct VoiceNode const *voice, uint32_t length); -uint32_t MV_Mix16BitStereo16(struct VoiceNode const *voice, uint32_t length); -void MV_16BitReverb(char const *src, char *dest, const int16_t *volume, int32_t count); +uint32_t MV_Mix16BitMono(struct VoiceNode *voice, uint32_t length); +uint32_t MV_Mix16BitStereo(struct VoiceNode *voice, uint32_t length); +uint32_t MV_Mix16BitMono16(struct VoiceNode *voice, uint32_t length); +uint32_t MV_Mix16BitStereo16(struct VoiceNode *voice, uint32_t length); +void MV_16BitReverb(char const *src, char *dest, const float volume, int32_t count); // implemented in mixst.c -uint32_t MV_Mix16BitMono8Stereo(struct VoiceNode const *voice, uint32_t length); -uint32_t MV_Mix16BitStereo8Stereo(struct VoiceNode const *voice, uint32_t length); -uint32_t MV_Mix16BitMono16Stereo(struct VoiceNode const *voice, uint32_t length); -uint32_t MV_Mix16BitStereo16Stereo(struct VoiceNode const *voice, uint32_t length); +uint32_t MV_Mix16BitMono8Stereo(struct VoiceNode *voice, uint32_t length); +uint32_t MV_Mix16BitStereo8Stereo(struct VoiceNode *voice, uint32_t length); +uint32_t MV_Mix16BitMono16Stereo(struct VoiceNode *voice, uint32_t length); +uint32_t MV_Mix16BitStereo16Stereo(struct VoiceNode *voice, uint32_t length); extern char *MV_MixDestination; // pointer to the next output sample -extern const int16_t *MV_LeftVolume; -extern const int16_t *MV_RightVolume; extern int32_t MV_SampleSize; extern int32_t MV_RightChannelOffset; diff --git a/source/audiolib/src/mix.cpp b/source/audiolib/src/mix.cpp index 8d34440a3..ab08cde9c 100644 --- a/source/audiolib/src/mix.cpp +++ b/source/audiolib/src/mix.cpp @@ -28,23 +28,25 @@ */ // 8-bit mono source, 16-bit mono output -uint32_t MV_Mix16BitMono(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitMono(struct VoiceNode * const voice, uint32_t length) { auto const source = (uint8_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; uint32_t position = voice->position; uint32_t const rate = voice->RateScale; - float const volume = voice->volume; + float const volume = voice->volume*MV_GlobalVolume; do { - uint8_t const usample0 = SCALE_SAMPLE(source[position >> 16], volume); + int32_t const isample0 = FLIP_SIGN(source[position >> 16]) << 8; position += rate; - *dest = (int16_t)clamp(SCALE_SAMPLE(MV_LeftVolume[usample0], MV_GlobalVolume) + *dest, INT16_MIN, INT16_MAX); + *dest = (int16_t)clamp(SCALE_SAMPLE(isample0, volume*voice->LeftVolume) + *dest, INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); } while (--length); @@ -54,25 +56,28 @@ uint32_t MV_Mix16BitMono(struct VoiceNode const * const voice, uint32_t length) } // 8-bit mono source, 16-bit stereo output -uint32_t MV_Mix16BitStereo(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitStereo(struct VoiceNode * const voice, uint32_t length) { auto const source = (uint8_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; uint32_t position = voice->position; uint32_t const rate = voice->RateScale; - float const volume = voice->volume; + float const volume = voice->volume*MV_GlobalVolume; do { - uint8_t const usample0 = SCALE_SAMPLE(source[position >> 16], volume); + int32_t const isample0 = FLIP_SIGN(source[position >> 16]) << 8; position += rate; - *dest = (int16_t)clamp(SCALE_SAMPLE(MV_LeftVolume[usample0], MV_GlobalVolume) + *dest, INT16_MIN, INT16_MAX); + *dest = (int16_t)clamp(SCALE_SAMPLE(isample0, volume*voice->LeftVolume) + *dest, INT16_MIN, INT16_MAX); *(dest + (MV_RightChannelOffset >> 1)) - = (int16_t)clamp(SCALE_SAMPLE(MV_RightVolume[usample0], MV_GlobalVolume) + *(dest + (MV_RightChannelOffset >> 1)), INT16_MIN, INT16_MAX); + = (int16_t)clamp(SCALE_SAMPLE(isample0, volume*voice->RightVolume) + *(dest + (MV_RightChannelOffset >> 1)), INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); + voice->RightVolume = SMOOTH_VOLUME(voice->RightVolume, voice->RightVolumeDest); } while (--length); @@ -82,27 +87,27 @@ uint32_t MV_Mix16BitStereo(struct VoiceNode const * const voice, uint32_t length } // 16-bit mono source, 16-bit mono output -uint32_t MV_Mix16BitMono16(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitMono16(struct VoiceNode * const voice, uint32_t length) { auto const source = (int16_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; uint32_t position = voice->position; uint32_t const rate = voice->RateScale; - float const volume = voice->volume; + float const volume = voice->volume*MV_GlobalVolume; do { - int16_t const isample0 = B_LITTLE16(source[position >> 16]); - split16_t const usample0{FLIP_SIGN(SCALE_SAMPLE(isample0, volume))}; + int32_t const isample0 = B_LITTLE16(source[position >> 16]); position += rate; - int32_t const sample0 = (SCALE_SAMPLE(MV_LeftVolume[usample0.l()], MV_GlobalVolume) >> 8) + - SCALE_SAMPLE(MV_LeftVolume[usample0.h()], MV_GlobalVolume) + 128; + int32_t const sample0 = SCALE_SAMPLE(isample0, volume*voice->LeftVolume); *dest = (int16_t)clamp(sample0 + *dest, INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); } while (--length); @@ -112,7 +117,7 @@ uint32_t MV_Mix16BitMono16(struct VoiceNode const * const voice, uint32_t length } // 16-bit mono source, 16-bit stereo output -uint32_t MV_Mix16BitStereo16(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitStereo16(struct VoiceNode * const voice, uint32_t length) { auto const source = (int16_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; @@ -123,20 +128,20 @@ uint32_t MV_Mix16BitStereo16(struct VoiceNode const * const voice, uint32_t leng do { - int16_t const isample0 = B_LITTLE16(source[position >> 16]); - split16_t const usample0{FLIP_SIGN(SCALE_SAMPLE(isample0, volume))}; + int32_t const isample0 = B_LITTLE16(source[position >> 16]); position += rate; - int32_t const sample0 = (SCALE_SAMPLE(MV_LeftVolume[usample0.l()], MV_GlobalVolume) >> 8) + - SCALE_SAMPLE(MV_LeftVolume[usample0.h()], MV_GlobalVolume) + 128; - int32_t const sample1 = (SCALE_SAMPLE(MV_RightVolume[usample0.l()], MV_GlobalVolume) >> 8) + - SCALE_SAMPLE(MV_RightVolume[usample0.h()], MV_GlobalVolume) + 128; + int32_t const sample0 = SCALE_SAMPLE(isample0, volume*voice->LeftVolume); + int32_t const sample1 = SCALE_SAMPLE(isample0, volume*voice->RightVolume); *dest = (int16_t)clamp(sample0 + *dest, INT16_MIN, INT16_MAX); *(dest + (MV_RightChannelOffset >> 1)) = (int16_t)clamp(sample1 + *(dest + (MV_RightChannelOffset >> 1)), INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); + voice->RightVolume = SMOOTH_VOLUME(voice->RightVolume, voice->RightVolumeDest); } while (--length); @@ -145,25 +150,15 @@ uint32_t MV_Mix16BitStereo16(struct VoiceNode const * const voice, uint32_t leng return position; } -void MV_16BitReverb(char const *src, char *dest, const int16_t *volume, int32_t count) +void MV_16BitReverb(char const *src, char *dest, const float volume, int32_t count) { auto input = (uint16_t const *)src; auto output = (int16_t *)dest; do { - int const sample0 = *input++; -#if 0 // def BIGENDIAN - int sample0l = sample0 >> 8; - int sample0h = (sample0 & 255) ^ 128; -#else - int sample0l = sample0 & 255; - int sample0h = (sample0 >> 8) ^ 128; -#endif - - sample0l = (volume)[sample0l] >> 8; - sample0h = (volume)[sample0h]; - *output++ = (int16_t)(sample0l + sample0h + 128); + int16_t const isample0 = (int16_t)*input++; + *output++ = SCALE_SAMPLE(isample0, volume); } while (--count > 0); } diff --git a/source/audiolib/src/mixst.cpp b/source/audiolib/src/mixst.cpp index dc5edd6cc..a3c7fa88e 100644 --- a/source/audiolib/src/mixst.cpp +++ b/source/audiolib/src/mixst.cpp @@ -28,25 +28,26 @@ */ // 8-bit stereo source, 16-bit mono output -uint32_t MV_Mix16BitMono8Stereo(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitMono8Stereo(struct VoiceNode * const voice, uint32_t length) { auto const source = (uint8_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; uint32_t position = voice->position; uint32_t const rate = voice->RateScale; - float const volume = voice->volume; + float const volume = voice->volume*MV_GlobalVolume; do { - uint8_t const usample0 = SCALE_SAMPLE(source[(position >> 16) << 1], volume); - uint8_t const usample1 = SCALE_SAMPLE(source[((position >> 16) << 1) + 1], volume); + int32_t const isample0 = FLIP_SIGN(source[(position >> 16) << 1]) << 8; + int32_t const isample1 = FLIP_SIGN(source[((position >> 16) << 1) + 1]) << 8; position += rate; - *dest = (int16_t)clamp(((SCALE_SAMPLE(MV_LeftVolume[usample0], MV_GlobalVolume) + - SCALE_SAMPLE(MV_LeftVolume[usample1], MV_GlobalVolume)) >> 1) + *dest, INT16_MIN, INT16_MAX); + *dest = (int16_t)clamp((SCALE_SAMPLE((isample0 + isample1) >> 1, volume*voice->LeftVolume)) + *dest, INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); } while (--length); @@ -56,26 +57,29 @@ uint32_t MV_Mix16BitMono8Stereo(struct VoiceNode const * const voice, uint32_t l } // 8-bit stereo source, 16-bit stereo output -uint32_t MV_Mix16BitStereo8Stereo(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitStereo8Stereo(struct VoiceNode * const voice, uint32_t length) { auto const source = (uint8_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; uint32_t position = voice->position; uint32_t const rate = voice->RateScale; - float const volume = voice->volume; + float const volume = voice->volume*MV_GlobalVolume; do { - uint8_t const usample0 = SCALE_SAMPLE(source[(position >> 16) << 1], volume); - uint8_t const usample1 = SCALE_SAMPLE(source[((position >> 16) << 1) + 1], volume); + int32_t const isample0 = FLIP_SIGN(source[(position >> 16) << 1]) << 8; + int32_t const isample1 = FLIP_SIGN(source[((position >> 16) << 1) + 1]) << 8; position += rate; - *dest = (int16_t)clamp(SCALE_SAMPLE(MV_LeftVolume[usample0], MV_GlobalVolume) + *dest, INT16_MIN, INT16_MAX); + *dest = (int16_t)clamp(SCALE_SAMPLE(isample0, volume*voice->LeftVolume) + *dest, INT16_MIN, INT16_MAX); *(dest + (MV_RightChannelOffset >> 1)) - = (int16_t)clamp(SCALE_SAMPLE(MV_RightVolume[usample1], MV_GlobalVolume) + *(dest + (MV_RightChannelOffset >> 1)), INT16_MIN, INT16_MAX); + = (int16_t)clamp(SCALE_SAMPLE(isample1, volume*voice->RightVolume) + *(dest + (MV_RightChannelOffset >> 1)), INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); + voice->RightVolume = SMOOTH_VOLUME(voice->RightVolume, voice->RightVolumeDest); } while (--length); @@ -85,7 +89,7 @@ uint32_t MV_Mix16BitStereo8Stereo(struct VoiceNode const * const voice, uint32_t } // 16-bit stereo source, 16-bit mono output -uint32_t MV_Mix16BitMono16Stereo(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitMono16Stereo(struct VoiceNode * const voice, uint32_t length) { auto const source = (int16_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; @@ -96,20 +100,17 @@ uint32_t MV_Mix16BitMono16Stereo(struct VoiceNode const * const voice, uint32_t do { - int16_t const isample0 = B_LITTLE16(source[(position >> 16) << 1]); - int16_t const isample1 = B_LITTLE16(source[((position >> 16) << 1) + 1]); - split16_t const usample0{FLIP_SIGN(SCALE_SAMPLE(isample0, volume))}; - split16_t const usample1{FLIP_SIGN(SCALE_SAMPLE(isample1, volume))}; + int32_t const isample0 = B_LITTLE16(source[(position >> 16) << 1]); + int32_t const isample1 = B_LITTLE16(source[((position >> 16) << 1) + 1]); position += rate; - int32_t const sample0 = (SCALE_SAMPLE(MV_LeftVolume[usample0.l()], MV_GlobalVolume)>> 8) + - SCALE_SAMPLE(MV_LeftVolume[usample0.h()], MV_GlobalVolume) + 128; - int32_t const sample1 = (SCALE_SAMPLE(MV_LeftVolume[usample1.l()], MV_GlobalVolume) >> 8) + - SCALE_SAMPLE(MV_LeftVolume[usample1.h()], MV_GlobalVolume) + 128; + int32_t const sample0 = SCALE_SAMPLE((isample0 + isample1) >> 1, volume*voice->LeftVolume); - *dest = (int16_t)clamp(((sample0 + sample1) >> 1) + *dest, INT16_MIN, INT16_MAX); + *dest = (int16_t)clamp(sample0 + *dest, INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); } while (--length); @@ -119,7 +120,7 @@ uint32_t MV_Mix16BitMono16Stereo(struct VoiceNode const * const voice, uint32_t } // 16-bit stereo source, 16-bit stereo output -uint32_t MV_Mix16BitStereo16Stereo(struct VoiceNode const * const voice, uint32_t length) +uint32_t MV_Mix16BitStereo16Stereo(struct VoiceNode * const voice, uint32_t length) { auto const source = (int16_t const *)voice->sound; auto dest = (int16_t *)MV_MixDestination; @@ -130,22 +131,21 @@ uint32_t MV_Mix16BitStereo16Stereo(struct VoiceNode const * const voice, uint32_ do { - int16_t const isample0 = B_LITTLE16(source[(position >> 16) << 1]); - int16_t const isample1 = B_LITTLE16(source[((position >> 16) << 1) + 1]); - split16_t const usample0{FLIP_SIGN(SCALE_SAMPLE(isample0, volume))}; - split16_t const usample1{FLIP_SIGN(SCALE_SAMPLE(isample1, volume))}; + int32_t const isample0 = B_LITTLE16(source[(position >> 16) << 1]); + int32_t const isample1 = B_LITTLE16(source[((position >> 16) << 1) + 1]); position += rate; - int32_t const sample0 = (SCALE_SAMPLE(MV_LeftVolume[usample0.l()], MV_GlobalVolume)>> 8) + - SCALE_SAMPLE(MV_LeftVolume[usample0.h()], MV_GlobalVolume) + 128; - int32_t const sample1 = (SCALE_SAMPLE(MV_LeftVolume[usample1.l()], MV_GlobalVolume) >> 8) + - SCALE_SAMPLE(MV_LeftVolume[usample1.h()], MV_GlobalVolume) + 128; + int32_t const sample0 = SCALE_SAMPLE(isample0, volume*voice->LeftVolume); + int32_t const sample1 = SCALE_SAMPLE(isample1, volume*voice->RightVolume); *dest = (int16_t)clamp(sample0 + *dest, INT16_MIN, INT16_MAX); *(dest + (MV_RightChannelOffset >> 1)) = (int16_t)clamp(sample1 + *(dest + (MV_RightChannelOffset >> 1)), INT16_MIN, INT16_MAX); dest += MV_SampleSize >> 1; + + voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); + voice->RightVolume = SMOOTH_VOLUME(voice->RightVolume, voice->RightVolumeDest); } while (--length); diff --git a/source/audiolib/src/multivoc.cpp b/source/audiolib/src/multivoc.cpp index ec46dfabe..6fb136d3e 100644 --- a/source/audiolib/src/multivoc.cpp +++ b/source/audiolib/src/multivoc.cpp @@ -45,15 +45,10 @@ static void MV_ServiceVoc(void); static VoiceNode *MV_GetVoice(int32_t handle); -static const int16_t *MV_GetVolumeTable(int32_t vol); - -#define IS_QUIET(ptr) ((void const *)(ptr) == (void *)&MV_VolumeTable[0]) - static int32_t MV_ReverbLevel; static int32_t MV_ReverbDelay; -static int16_t *MV_ReverbTable = NULL; +static float MV_ReverbVolume; -static int16_t MV_VolumeTable[MV_MAXVOLUME + 1][256]; Pan MV_PanTable[MV_NUMPANPOSITIONS][MV_MAXVOLUME + 1]; int32_t MV_Installed = FALSE; @@ -85,14 +80,13 @@ void (*MV_Printf)(const char *fmt, ...) = NULL; static void (*MV_CallBackFunc)(intptr_t) = NULL; char *MV_MixDestination; -const int16_t *MV_LeftVolume; -const int16_t *MV_RightVolume; int32_t MV_SampleSize = 1; int32_t MV_RightChannelOffset; int32_t MV_ErrorCode = MV_NotInstalled; float MV_GlobalVolume = 1.f; +float MV_VolumeSmooth = 1.f; static int32_t lockdepth = 0; @@ -146,14 +140,6 @@ static bool MV_Mix(VoiceNode *voice, int const buffer) uint32_t FixedPointBufferSize = voice->FixedPointBufferSize; MV_MixDestination = MV_MixBuffer[buffer]; - MV_LeftVolume = voice->LeftVolume; - MV_RightVolume = voice->RightVolume; - - if ((MV_Channels == 2) && (IS_QUIET(MV_LeftVolume))) - { - MV_LeftVolume = MV_RightVolume; - MV_MixDestination += MV_RightChannelOffset; - } // Add this voice to the mix do @@ -209,6 +195,8 @@ void MV_PlayVoice(VoiceNode *voice) { DisableInterrupts(); LL::SortedInsert(&VoiceList, voice, &VoiceNode::priority); + voice->LeftVolume = voice->LeftVolumeDest; + voice->RightVolume = voice->RightVolumeDest; RestoreInterrupts(); } @@ -285,7 +273,7 @@ static void MV_ServiceVoc(void) { int const count = (source + length > end) ? (end - source) : length; - MV_16BitReverb(source, dest, MV_ReverbTable, count / 2); + MV_16BitReverb(source, dest, MV_ReverbVolume, count / 2); // if we go through the loop again, it means that we've wrapped around the buffer source = MV_MixBuffer[ 0 ]; @@ -553,8 +541,6 @@ int32_t MV_SetFrequency(int32_t handle, int32_t frequency) return MV_Ok; } -static inline const int16_t *MV_GetVolumeTable(int32_t vol) { return MV_VolumeTable[MIX_VOLUME(vol)]; } - /*--------------------------------------------------------------------- Function: MV_SetVoiceMixMode @@ -581,36 +567,18 @@ void MV_SetVoiceMixMode(VoiceNode *voice) if (MV_Channels == 1) type |= T_MONO; - else - { - if (IS_QUIET(voice->RightVolume)) - type |= T_RIGHTQUIET; - else if (IS_QUIET(voice->LeftVolume)) - type |= T_LEFTQUIET; - } if (voice->bits == 16) type |= T_16BITSOURCE; if (voice->channels == 2) - { type |= T_STEREOSOURCE; - type &= ~(T_RIGHTQUIET | T_LEFTQUIET); - } switch (type) { - case T_16BITSOURCE | T_LEFTQUIET: - MV_LeftVolume = MV_RightVolume; - fallthrough__; - case T_16BITSOURCE | T_MONO: - case T_16BITSOURCE | T_RIGHTQUIET: voice->mix = MV_Mix16BitMono16; break; + case T_16BITSOURCE | T_MONO: voice->mix = MV_Mix16BitMono16; break; - case T_LEFTQUIET: - MV_LeftVolume = MV_RightVolume; - fallthrough__; - case T_MONO: - case T_RIGHTQUIET: voice->mix = MV_Mix16BitMono; break; + case T_MONO: voice->mix = MV_Mix16BitMono; break; case T_16BITSOURCE: voice->mix = MV_Mix16BitStereo16; break; @@ -633,17 +601,11 @@ void MV_SetVoiceVolume(VoiceNode *voice, int32_t vol, int32_t left, int32_t righ if (MV_Channels == 1) left = right = vol; - voice->LeftVolume = MV_GetVolumeTable(left); + voice->LeftVolumeDest = float(left)*(1.f/MV_MAXTOTALVOLUME); + voice->RightVolumeDest = float(right)*(1.f/MV_MAXTOTALVOLUME); - if (left == right) - voice->RightVolume = voice->LeftVolume; - else - { - voice->RightVolume = MV_GetVolumeTable(right); - - if (MV_ReverseStereo) - swapptr(&voice->LeftVolume, &voice->RightVolume); - } + if (MV_ReverseStereo) + swapfloat(&voice->LeftVolumeDest, &voice->RightVolumeDest); voice->volume = volume; @@ -765,7 +727,7 @@ int32_t MV_Pan3D(int32_t handle, int32_t angle, int32_t distance) void MV_SetReverb(int32_t reverb) { MV_ReverbLevel = MIX_VOLUME(reverb); - MV_ReverbTable = &MV_VolumeTable[MV_ReverbLevel][0]; + MV_ReverbVolume = float(MV_ReverbLevel)*(1.f/MV_MAXVOLUME); } int32_t MV_GetMaxReverbDelay(void) { return MV_MIXBUFFERSIZE * MV_NumberOfBuffers; } @@ -829,20 +791,6 @@ static void MV_StopPlayback(void) RestoreInterrupts(); } -static void MV_CalcVolume(int32_t MaxVolume) -{ - // For each volume level, create a translation table with the - // appropriate volume calculated. - - for (int volume = 0; volume <= MV_MAXVOLUME; volume++) - { - int const level = (volume * MaxVolume) / MV_MAXTOTALVOLUME; - - for (int i = 0; i < 65536; i += 256) - MV_VolumeTable[volume][i / 256] = ((i - 0x8000) * level) / MV_MAXVOLUME; - } -} - static void MV_CalcPanTable(void) { const int32_t HalfAngle = MV_NUMPANPOSITIONS / 2; @@ -936,7 +884,7 @@ int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numc MV_Installed = TRUE; MV_CallBackFunc = NULL; MV_ReverbLevel = 0; - MV_ReverbTable = NULL; + MV_ReverbVolume = 0.f; // Set the sampling rate MV_MixRate = MixRate; @@ -955,7 +903,8 @@ int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numc // Calculate pan table MV_CalcPanTable(); - MV_CalcVolume(MV_MAXTOTALVOLUME); + + MV_VolumeSmooth = 1.f-powf(0.1f, 30.f/MixRate); // Start the playback engine if (MV_StartPlayback() != MV_Ok)