diff options
-rw-r--r-- | Alc/ALu.c | 45 | ||||
-rw-r--r-- | Alc/mixer.c | 15 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 5 |
4 files changed, 48 insertions, 19 deletions
@@ -84,6 +84,7 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALfloat WetGain[MAX_SENDS]; ALfloat WetGainHF[MAX_SENDS]; ALint NumSends, Frequency; + ALfloat Pitch; ALfloat cw; ALint i; @@ -100,19 +101,30 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) MaxVolume = ALSource->flMaxGain; //1. Multi-channel buffers always play "normal" + Pitch = ALSource->flPitch; BufferListItem = ALSource->queue; while(BufferListItem != NULL) { ALbuffer *ALBuffer; if((ALBuffer=BufferListItem->buffer) != NULL) { - ALSource->Params.Pitch = ALSource->flPitch*ALBuffer->frequency / - Frequency; + Pitch = Pitch * ALBuffer->frequency / Frequency; break; } BufferListItem = BufferListItem->next; } + if(Pitch > (float)MAX_PITCH) + ALSource->Params.Step = MAX_PITCH<<FRACTIONBITS; + else if(!(Pitch > 0.0f)) + ALSource->Params.Step = 1<<FRACTIONBITS; + else + { + ALSource->Params.Step = Pitch*(1<<FRACTIONBITS); + if(ALSource->Params.Step == 0) + ALSource->Params.Step = 1; + } + DryGain = SourceVolume; DryGain = __min(DryGain,MaxVolume); DryGain = __max(DryGain,MinVolume); @@ -178,6 +190,7 @@ ALvoid CalcNonAttnStereoSourceParams(ALsource *ALSource, const ALCcontext *ALCon ALfloat WetGainHF[MAX_SENDS]; ALint NumSends, Frequency; ALboolean DupStereo; + ALfloat Pitch; ALenum Format; ALfloat cw; ALint i; @@ -197,19 +210,30 @@ ALvoid CalcNonAttnStereoSourceParams(ALsource *ALSource, const ALCcontext *ALCon MaxVolume = ALSource->flMaxGain; //1. Multi-channel buffers always play "normal" + Pitch = ALSource->flPitch; BufferListItem = ALSource->queue; while(BufferListItem != NULL) { ALbuffer *ALBuffer; if((ALBuffer=BufferListItem->buffer) != NULL) { - ALSource->Params.Pitch = ALSource->flPitch*ALBuffer->frequency / - Frequency; + Pitch = Pitch * ALBuffer->frequency / Frequency; break; } BufferListItem = BufferListItem->next; } + if(Pitch > (float)MAX_PITCH) + ALSource->Params.Step = MAX_PITCH<<FRACTIONBITS; + else if(!(Pitch > 0.0f)) + ALSource->Params.Step = 1<<FRACTIONBITS; + else + { + ALSource->Params.Step = Pitch*(1<<FRACTIONBITS); + if(ALSource->Params.Step == 0) + ALSource->Params.Step = 1; + } + DryGain = SourceVolume; DryGain = __min(DryGain,MaxVolume); DryGain = __max(DryGain,MinVolume); @@ -663,12 +687,23 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALbuffer *ALBuffer; if((ALBuffer=BufferListItem->buffer) != NULL) { - ALSource->Params.Pitch = Pitch*ALBuffer->frequency / Frequency; + Pitch = Pitch * ALBuffer->frequency / Frequency; break; } BufferListItem = BufferListItem->next; } + if(Pitch > (float)MAX_PITCH) + ALSource->Params.Step = MAX_PITCH<<FRACTIONBITS; + else if(!(Pitch > 0.0f)) + ALSource->Params.Step = 1<<FRACTIONBITS; + else + { + ALSource->Params.Step = Pitch*(1<<FRACTIONBITS); + if(ALSource->Params.Step == 0) + ALSource->Params.Step = 1; + } + // Use energy-preserving panning algorithm for multi-speaker playback length = __max(OrigDist, MinDist); if(length > 0.0f) diff --git a/Alc/mixer.c b/Alc/mixer.c index 6b0406be..64b4a13a 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -36,9 +36,6 @@ #include "alu.h" #include "bs2b.h" -#define FRACTIONBITS 14 -#define FRACTIONMASK ((1L<<FRACTIONBITS)-1) -#define MAX_PITCH 65536 /* Minimum ramp length in milliseconds. The value below was chosen to * adequately reduce clicks and pops from harsh gain changes. */ @@ -156,16 +153,8 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, wetGainStep[i] = (ALSource->Params.WetGains[i]-WetSend[i]) / rampLength; - /* Compute 18.14 fixed point step */ - if(ALSource->Params.Pitch > (float)MAX_PITCH) - increment = MAX_PITCH << FRACTIONBITS; - else if(!(ALSource->Params.Pitch > 0.f)) - increment = (1<<FRACTIONBITS); - else - { - increment = (ALint)(ALSource->Params.Pitch*(1L<<FRACTIONBITS)); - if(increment == 0) increment = 1; - } + /* Get fixed point step */ + increment = ALSource->Params.Step; DryFilter = &ALSource->Params.iirFilter; for(i = 0;i < MAX_SENDS;i++) diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 97ecbecf..9cee835b 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -91,7 +91,7 @@ typedef struct ALsource struct { ALfloat DryGains[OUTPUTCHANNELS]; ALfloat WetGains[MAX_SENDS]; - ALfloat Pitch; + ALint Step; struct { FILTER iirFilter; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 73f70224..fe2f42ba 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -5,6 +5,7 @@ #include "AL/alc.h" #include "AL/alext.h" +#include <limits.h> #include <math.h> #ifdef HAVE_FLOAT_H #include <float.h> @@ -76,6 +77,10 @@ typedef enum { #define BUFFERSIZE 8192 +#define FRACTIONBITS (14) +#define FRACTIONMASK ((1<<FRACTIONBITS)-1) +#define MAX_PITCH (INT_MAX & ~FRACTIONMASK) + /* NOTE: The AL_FORMAT_REAR* enums aren't handled here because they're * converted to AL_FORMAT_QUAD* when loaded */ static __inline ALuint aluBytesFromFormat(ALenum format) |