From 7789cc8e32f71201a603809484031fe9988258c1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 22 Mar 2018 09:55:15 -0700 Subject: Define the Hanning window globally once for the pitch shifter --- Alc/effects/pshifter.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'Alc/effects') diff --git a/Alc/effects/pshifter.c b/Alc/effects/pshifter.c index 4597da6b..33c3e121 100644 --- a/Alc/effects/pshifter.c +++ b/Alc/effects/pshifter.c @@ -66,7 +66,6 @@ typedef struct ALpshifterState { ALfloat LastPhase[STFT_HALF_SIZE+1]; ALfloat SumPhase[STFT_HALF_SIZE+1]; ALfloat OutputAccum[STFT_SIZE]; - ALfloat window[STFT_SIZE]; ALcomplex FFTbuffer[STFT_SIZE]; @@ -89,6 +88,23 @@ DECLARE_DEFAULT_ALLOCATORS(ALpshifterState) DEFINE_ALEFFECTSTATE_VTABLE(ALpshifterState); +/* Define a Hanning window, used to filter the STFT input and output. */ +alignas(16) static ALfloat HanningWindow[STFT_SIZE]; + +static void InitHanningWindow(void) +{ + ALsizei i; + + /* Create lookup table of the Hanning window for the desired size, i.e. STFT_SIZE */ + for(i = 0;i < STFT_SIZE>>1;i++) + { + ALdouble val = 1.0 - cos((ALdouble)i / (ALdouble)(STFT_SIZE-1) * (M_PI*2.0)); + HanningWindow[i] = HanningWindow[STFT_SIZE-(i+1)] = (ALfloat)val * 0.5f; + } +} +static alonce_flag HanningInitOnce = AL_ONCE_FLAG_INIT; + + /* Converts ALcomplex to ALphasor*/ static inline ALphasor rect2polar( ALcomplex number ) { @@ -203,17 +219,10 @@ static inline ALvoid FFT(ALcomplex *FFTBuffer, ALsizei FFTSize, ALfloat Sign) static void ALpshifterState_Construct(ALpshifterState *state) { - ALsizei i; - ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); SET_VTABLE2(ALpshifterState, ALeffectState, state); - /* Create lockup table of the Hann window for the desired size, i.e. STFT_size */ - for ( i = 0; i < STFT_SIZE>>1 ; i++ ) - { - state->window[i] = state->window[STFT_SIZE-(i+1)] - = 0.5f * ( 1 - cosf(F_TAU*(ALfloat)i/(ALfloat)(STFT_SIZE-1))); - } + alcall_once(&HanningInitOnce, InitHanningWindow); } static ALvoid ALpshifterState_Destruct(ALpshifterState *state) @@ -285,7 +294,7 @@ static ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToD /* Real signal windowing and store in FFTbuffer */ for(k = 0;k < STFT_SIZE;k++) { - state->FFTbuffer[k].Real = state->InFIFO[k] * state->window[k]; + state->FFTbuffer[k].Real = state->InFIFO[k] * HanningWindow[k]; state->FFTbuffer[k].Imag = 0.0f; } @@ -374,7 +383,7 @@ static ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToD /* Windowing and add to output */ for(k = 0;k < STFT_SIZE;k++) - state->OutputAccum[k] += 2.0f * state->window[k]*state->FFTbuffer[k].Real / + state->OutputAccum[k] += 2.0f * HanningWindow[k]*state->FFTbuffer[k].Real / (STFT_HALF_SIZE * OVERSAMP); /* Shift accumulator, input & output FIFO */ -- cgit v1.2.3