Properly clamp high pitch values
This commit is contained in:
@@ -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)
|
||||
|
||||
-17
@@ -612,12 +612,6 @@ DECL_TEMPLATE(ALubyte, cubic8)
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
|
||||
/* Stack data size can be whatever. Larger values need more stack, while
|
||||
* smaller values may need more iterations */
|
||||
#ifndef STACK_DATA_SIZE
|
||||
#define STACK_DATA_SIZE 16384
|
||||
#endif
|
||||
|
||||
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
ALbufferlistitem *BufferListItem;
|
||||
@@ -859,17 +853,6 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
|
||||
BufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
|
||||
BufferSize = min(BufferSize, (SamplesToDo-OutPos));
|
||||
if(BufferSize == 0)
|
||||
{
|
||||
AL_PRINT("No samples to mix! Pitch too high (%u, %g)?\n",
|
||||
increment, increment/(double)FRACTIONONE);
|
||||
State = AL_STOPPED;
|
||||
BufferListItem = Source->queue;
|
||||
BuffersPlayed = Source->BuffersInQueue;
|
||||
DataPosInt = 0;
|
||||
DataPosFrac = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
SrcData += BufferPrePadding*FrameSize;
|
||||
switch(Resampler)
|
||||
|
||||
+14
-1
@@ -80,7 +80,20 @@ typedef enum {
|
||||
#define FRACTIONBITS (14)
|
||||
#define FRACTIONONE (1<<FRACTIONBITS)
|
||||
#define FRACTIONMASK (FRACTIONONE-1)
|
||||
#define MAX_PITCH (INT_MAX & ~FRACTIONMASK)
|
||||
|
||||
/* Size for temporary stack storage of buffer data. Larger values need more
|
||||
* stack, while smaller values may need more iterations. The value needs to be
|
||||
* a sensible size, however, as it constrains the max stepping value used for
|
||||
* mixing.
|
||||
* The mixer requires being able to do two samplings per mixing loop. A 16KB
|
||||
* buffer can hold 512 sample frames for a 7.1 float buffer. With the cubic
|
||||
* resampler (which requires 3 padding sample frames), this limits the maximum
|
||||
* step to about 508. This means that buffer_freq*source_pitch cannot exceed
|
||||
* device_freq*508 for an 8-channel 32-bit buffer. */
|
||||
#ifndef STACK_DATA_SIZE
|
||||
#define STACK_DATA_SIZE 16384
|
||||
#endif
|
||||
|
||||
|
||||
/* NOTE: The AL_FORMAT_REAR* enums aren't handled here because they're
|
||||
* converted to AL_FORMAT_QUAD* when loaded */
|
||||
|
||||
Reference in New Issue
Block a user