aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALu.c59
-rw-r--r--Alc/mixer.c17
-rw-r--r--OpenAL32/Include/alu.h15
3 files changed, 49 insertions, 42 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)
diff --git a/Alc/mixer.c b/Alc/mixer.c
index 53ba4aca..18c93b84 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -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)
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 31d42ea9..c157a529 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -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 */