summaryrefslogtreecommitdiffstats
path: root/Alc/ALu.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2010-11-26 17:47:43 -0800
committerChris Robinson <[email protected]>2010-11-26 17:47:43 -0800
commitfacb922f3e1d39af8514916c990acd9ff9d8baae (patch)
tree9547190fa5d1a07dbfb7acc773e483b0d476130e /Alc/ALu.c
parentd7987677ac5748576626b0ed7f47d2e607bb4e77 (diff)
Properly clamp high pitch values
Diffstat (limited to 'Alc/ALu.c')
-rw-r--r--Alc/ALu.c59
1 files changed, 35 insertions, 24 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 9619f595..a6151a10 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -104,34 +104,40 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
SourceVolume = ALSource->flGain;
MinVolume = ALSource->flMinGain;
MaxVolume = ALSource->flMaxGain;
+ Pitch = ALSource->flPitch;
//1. Multi-channel buffers always play "normal"
Channels = 0;
- Pitch = ALSource->flPitch;
BufferListItem = ALSource->queue;
while(BufferListItem != NULL)
{
ALbuffer *ALBuffer;
if((ALBuffer=BufferListItem->buffer) != NULL)
{
- Channels = aluChannelsFromFormat(ALBuffer->format);
+ ALint maxstep = STACK_DATA_SIZE /
+ aluFrameSizeFromFormat(ALBuffer->format);
+ maxstep -= ResamplerPadding[ALSource->Resampler] +
+ ResamplerPrePadding[ALSource->Resampler] + 1;
+ maxstep = min(maxstep, INT_MAX>>FRACTIONBITS);
+
Pitch = Pitch * ALBuffer->frequency / Frequency;
+ if(Pitch > (ALfloat)maxstep)
+ ALSource->Params.Step = maxstep<<FRACTIONBITS;
+ else
+ {
+ ALSource->Params.Step = Pitch*FRACTIONONE;
+ if(ALSource->Params.Step == 0)
+ ALSource->Params.Step = 1;
+ else if(ALSource->Params.Step > maxstep)
+ ALSource->Params.Step = maxstep;
+ }
+
+ Channels = aluChannelsFromFormat(ALBuffer->format);
break;
}
BufferListItem = BufferListItem->next;
}
- if(Pitch > (float)MAX_PITCH)
- ALSource->Params.Step = MAX_PITCH<<FRACTIONBITS;
- else if(!(Pitch > 0.0f))
- ALSource->Params.Step = FRACTIONONE;
- else
- {
- ALSource->Params.Step = Pitch*FRACTIONONE;
- if(ALSource->Params.Step == 0)
- ALSource->Params.Step = 1;
- }
-
DryGain = SourceVolume;
DryGain = __min(DryGain,MaxVolume);
DryGain = __max(DryGain,MinVolume);
@@ -587,23 +593,28 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
ALbuffer *ALBuffer;
if((ALBuffer=BufferListItem->buffer) != NULL)
{
+ ALint maxstep = STACK_DATA_SIZE /
+ aluFrameSizeFromFormat(ALBuffer->format);
+ maxstep -= ResamplerPadding[ALSource->Resampler] +
+ ResamplerPrePadding[ALSource->Resampler] + 1;
+ maxstep = min(maxstep, INT_MAX>>FRACTIONBITS);
+
Pitch = Pitch * ALBuffer->frequency / Frequency;
+ if(Pitch > (ALfloat)maxstep)
+ ALSource->Params.Step = maxstep<<FRACTIONBITS;
+ else
+ {
+ ALSource->Params.Step = Pitch*FRACTIONONE;
+ if(ALSource->Params.Step == 0)
+ ALSource->Params.Step = 1;
+ else if(ALSource->Params.Step > maxstep)
+ ALSource->Params.Step = maxstep;
+ }
break;
}
BufferListItem = BufferListItem->next;
}
- if(Pitch > (float)MAX_PITCH)
- ALSource->Params.Step = MAX_PITCH<<FRACTIONBITS;
- else if(!(Pitch > 0.0f))
- ALSource->Params.Step = FRACTIONONE;
- else
- {
- ALSource->Params.Step = Pitch*FRACTIONONE;
- 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)