diff options
author | Chris Robinson <[email protected]> | 2013-05-20 04:41:03 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-05-20 04:41:03 -0700 |
commit | c6872d4d868dad5935f731b4aa7275f44b5f7597 (patch) | |
tree | 769fc1978659b8dcaa8fbcb15d9d2665d1778916 | |
parent | 5b706f3bdc1a8c8f064a253b53b4e86f9d88da8d (diff) |
Process 64 samples at a time for chorus and flanger effects
-rw-r--r-- | Alc/alcChorus.c | 113 | ||||
-rw-r--r-- | Alc/alcFlanger.c | 113 |
2 files changed, 130 insertions, 96 deletions
diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index 8323d2b5..5b62c910 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -169,7 +169,7 @@ static ALvoid ChorusUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff } } -static __inline void CalcTriangleDelays(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) +static __inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) { ALfloat lfo_value; @@ -186,7 +186,7 @@ static __inline void CalcTriangleDelays(ALint *delay_left, ALint *delay_right, A *delay_right = (ALint)(lfo_value * state->frequency); } -static __inline void CalcSinusoidDelays(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) +static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) { ALfloat lfo_value; @@ -202,56 +202,73 @@ static __inline void CalcSinusoidDelays(ALint *delay_left, ALint *delay_right, A *delay_right = (ALint)(lfo_value * state->frequency); } -static ALvoid ChorusProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) -{ - ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); - const ALuint mask = state->BufferLength-1; - ALuint it; - ALuint kt; - ALint offset; - ALint delay_left = 0; - ALint delay_right = 0; - ALfloat smp; - - offset = state->offset; - - switch(state->waveform) - { - case AL_CHORUS_WAVEFORM_TRIANGLE: - for (it = 0; it < SamplesToDo; it++, offset++) - { - CalcTriangleDelays(&delay_left, &delay_right, offset, state); - - smp = state->SampleBufferLeft[(offset-delay_left) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[0][kt]; - state->SampleBufferLeft[offset & mask] = (smp + SamplesIn[it]) * state->feedback; +#define DECL_TEMPLATE(func) \ +static void Process##func(ALchorusState *state, ALuint SamplesToDo, \ + const ALfloat *RESTRICT SamplesIn, \ + ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \ +{ \ + const ALint mask = state->BufferLength-1; \ + ALint offset = state->offset; \ + ALuint it, kt; \ + ALuint base; \ + \ + for(base = 0;base < SamplesToDo;) \ + { \ + ALfloat temps[64][2]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + \ + for(it = 0;it < td;it++,offset++) \ + { \ + ALint delay_left, delay_right; \ + (func)(&delay_left, &delay_right, offset, state); \ + \ + temps[it][0] = state->SampleBufferLeft[(offset-delay_left)&mask]; \ + state->SampleBufferLeft[offset&mask] = (temps[it][0] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + \ + temps[it][1] = state->SampleBufferRight[(offset-delay_right)&mask];\ + state->SampleBufferRight[offset&mask] = (temps[it][1] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + } \ + \ + for(kt = 0;kt < MaxChannels;kt++) \ + { \ + ALfloat gain = state->Gain[0][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][0] * gain; \ + } \ + \ + gain = state->Gain[1][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][1] * gain; \ + } \ + } \ + \ + base += td; \ + } \ + \ + state->offset = offset; \ +} - smp = state->SampleBufferRight[(offset-delay_right) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[1][kt]; - state->SampleBufferRight[offset & mask] = (smp + SamplesIn[it]) * state->feedback; - } - break; - case AL_CHORUS_WAVEFORM_SINUSOID: - for (it = 0; it < SamplesToDo; it++, offset++) - { - CalcSinusoidDelays(&delay_left, &delay_right, offset, state); +DECL_TEMPLATE(Triangle) +DECL_TEMPLATE(Sinusoid) - smp = state->SampleBufferLeft[(offset-delay_left) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[0][kt]; - state->SampleBufferLeft[offset & mask] = (smp + SamplesIn[it]) * state->feedback; +#undef DECL_TEMPLATE - smp = state->SampleBufferRight[(offset-delay_right) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[1][kt]; - state->SampleBufferRight[offset & mask] = (smp + SamplesIn[it]) * state->feedback; - } - break; - } +static ALvoid ChorusProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +{ + ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); - state->offset = offset; + if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) + ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); + else if(state->waveform == AL_CHORUS_WAVEFORM_SINUSOID) + ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); } ALeffectState *ChorusCreate(void) diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index 2d3c35b0..4f9a4f22 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -153,7 +153,7 @@ static ALvoid FlangerUpdate(ALeffectState *effect, ALCdevice *Device, const ALef } } -static __inline void CalcTriangleDelays(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) +static __inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) { ALfloat lfo_value; @@ -170,7 +170,7 @@ static __inline void CalcTriangleDelays(ALint *delay_left, ALint *delay_right, A *delay_right = (ALint)(lfo_value * state->frequency); } -static __inline void CalcSinusoidDelays(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) +static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) { ALfloat lfo_value; @@ -186,56 +186,73 @@ static __inline void CalcSinusoidDelays(ALint *delay_left, ALint *delay_right, A *delay_right = (ALint)(lfo_value * state->frequency); } +#define DECL_TEMPLATE(func) \ +static void Process##func(ALflangerState *state, ALuint SamplesToDo, \ + const ALfloat *RESTRICT SamplesIn, \ + ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \ +{ \ + const ALint mask = state->BufferLength-1; \ + ALint offset = state->offset; \ + ALuint it, kt; \ + ALuint base; \ + \ + for(base = 0;base < SamplesToDo;) \ + { \ + ALfloat temps[64][2]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + \ + for(it = 0;it < td;it++,offset++) \ + { \ + ALint delay_left, delay_right; \ + (func)(&delay_left, &delay_right, offset, state); \ + \ + temps[it][0] = state->SampleBufferLeft[(offset-delay_left)&mask]; \ + state->SampleBufferLeft[offset&mask] = (temps[it][0] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + \ + temps[it][1] = state->SampleBufferRight[(offset-delay_right)&mask];\ + state->SampleBufferRight[offset&mask] = (temps[it][1] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + } \ + \ + for(kt = 0;kt < MaxChannels;kt++) \ + { \ + ALfloat gain = state->Gain[0][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][0] * gain; \ + } \ + \ + gain = state->Gain[1][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][1] * gain; \ + } \ + } \ + \ + base += td; \ + } \ + \ + state->offset = offset; \ +} + +DECL_TEMPLATE(Triangle) +DECL_TEMPLATE(Sinusoid) + +#undef DECL_TEMPLATE + static ALvoid FlangerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); - const ALuint mask = state->BufferLength-1; - ALuint it; - ALuint kt; - ALint offset; - ALint delay_left = 0; - ALint delay_right = 0; - ALfloat smp; - - offset = state->offset; - - switch(state->waveform) - { - case AL_FLANGER_WAVEFORM_TRIANGLE: - for(it = 0;it < SamplesToDo;it++,offset++) - { - CalcTriangleDelays(&delay_left, &delay_right, offset, state); - - smp = state->SampleBufferLeft[(offset-delay_left) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[0][kt]; - state->SampleBufferLeft[offset & mask] = (smp + SamplesIn[it]) * state->feedback; - - smp = state->SampleBufferRight[(offset-delay_right) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[1][kt]; - state->SampleBufferRight[offset & mask] = (smp + SamplesIn[it]) * state->feedback; - } - break; - case AL_FLANGER_WAVEFORM_SINUSOID: - for(it = 0;it < SamplesToDo;it++,offset++) - { - CalcSinusoidDelays(&delay_left, &delay_right, offset, state); - - smp = state->SampleBufferLeft[(offset-delay_left) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[0][kt]; - state->SampleBufferLeft[offset & mask] = (smp + SamplesIn[it]) * state->feedback; - - smp = state->SampleBufferRight[(offset-delay_right) & mask]; - for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += smp * state->Gain[1][kt]; - state->SampleBufferRight[offset & mask] = (smp + SamplesIn[it]) * state->feedback; - } - break; - } - state->offset = offset; + if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) + ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); + else if(state->waveform == AL_FLANGER_WAVEFORM_SINUSOID) + ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); } ALeffectState *FlangerCreate(void) |