Patch from Nuke.YKT to replace audiolib's volume table with floating point calculations

This fixes an issue where rapidly changing the player's angle could result in the audio "popping" due to the sudden change to a new position in the volume table, and the resulting difference in volume between one sample and the next. This also fixes a DC offset issue when applying the volume level to certain sample types.

git-svn-id: https://svn.eduke32.com/eduke32@7773 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2019-07-08 00:41:08 +00:00 committed by Christoph Oelckers
parent cf7ac8f16e
commit 027afc2347
4 changed files with 94 additions and 148 deletions

View file

@ -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 <typename T>
static inline conditional_t< is_signed<T>::value, make_unsigned_t<T>, make_signed_t<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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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)