diff --git a/kraken/KRAudioManager.cpp b/kraken/KRAudioManager.cpp index 058e360..bc1cade 100755 --- a/kraken/KRAudioManager.cpp +++ b/kraken/KRAudioManager.cpp @@ -68,11 +68,6 @@ KRAudioManager::KRAudioManager(KRContext &context) // Apple Core Audio m_auGraph = NULL; m_auMixer = NULL; - - // Apple vDSP - for (int i = KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { - m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N] = NULL; - } #endif m_audio_frame = 0; @@ -1041,7 +1036,9 @@ void KRAudioManager::initAudio() m_reverb_sequence = 0; for(int i=KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { - KRDSP::CreateFFTWorkspace(m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N], KRENGINE_REVERB_MAX_FFT_LOG2); + m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N].create(i); + // FINDME, TODO.. Apple's vDSP only needs one + // KRDSP::FFTWorkspace, initialized with the maximum size } // ----====---- Initialize HRTF Engine ----====---- @@ -1204,10 +1201,7 @@ void KRAudioManager::cleanupAudio() } for(int i=KRENGINE_AUDIO_BLOCK_LOG2N; i <= KRENGINE_REVERB_MAX_FFT_LOG2; i++) { - if(m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N]) { - KRDSP::DestroyFFTWorkspace(m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N]); - m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N] = NULL; - } + m_fft_setup[i - KRENGINE_AUDIO_BLOCK_LOG2N].destroy(); } } diff --git a/kraken/KRDSP.h b/kraken/KRDSP.h index 64cdf7c..0b702e0 100644 --- a/kraken/KRDSP.h +++ b/kraken/KRDSP.h @@ -35,20 +35,44 @@ namespace KRDSP { #ifdef __APPLE__ +#define KRDSP_APPLE_VDSP +#else + // Slow, but portable fallback implementation +#define KRDSP_SLOW +#endif + +#if defined(KRDSP_APPLE_VDSP) + // Apple vDSP typedef DSPSplitComplex SplitComplex; - typedef FFTSetup FFTWorkspace; -#else + struct FFTWorkspace { + FFTSetup setup; + + FFTWorkspace(); + ~FFTWorkspace(); + }; + +#elif defined(KRDSP_SLOW) + typedef struct { float *realp; float *imagp; } SplitComplex; - typedef int FFTWorkspace; // FINDME!! KIP!! TODO!! IMPLEMENT + struct FFTWorkspace { + float *sin_table; + float *cos_table; + + void create(size_t length); + void destroy(); + FFTWorkspace(); + ~FFTWorkspace(); + }; + +#else +#error Not Implemented #endif -void CreateFFTWorkspace(FFTWorkspace &workspace, size_t length); -void DestroyFFTWorkspace(FFTWorkspace &workspace); void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count); void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count); void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count); diff --git a/kraken/KRDSP_slow.cpp b/kraken/KRDSP_slow.cpp new file mode 100644 index 0000000..906952a --- /dev/null +++ b/kraken/KRDSP_slow.cpp @@ -0,0 +1,128 @@ +// +// KREngine.h +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +#include "KRDSP.h" + +#ifdef KRDSP_SLOW + +#include "KREngine-common.h" + +namespace KRDSP { + +FFTWorkspace::FFTWorkspace() +{ + sin_table = nullptr; + cos_table = nullptr; +} + +FFTWorkspace::~FFTWorkspace() +{ + destroy(); +} + +void FFTWorkspace::create(size_t length) +{ + size_t size = (length / 2); + cos_table = new float[size]; + sin_table = new float[size]; + for (int i = 0; i < size / 2; i++) { + cos_table[i] = cos(2 * M_PI * i / length); + sin_table[i] = sin(2 * M_PI * i / length); + } +} + +void FFTWorkspace::destroy() +{ + if (sin_table) { + delete sin_table; + sin_table = nullptr; + } + if (cos_table) { + delete cos_table; + cos_table = nullptr; + } +} + +void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count) +{ +#error TODO - Implement +} + +void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count) +{ +#error TODO - Implement +} + +void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count) +{ +#error TODO - Implement +} + +void Scale(float *buffer, float scale, size_t count) +{ +#error TODO - Implement +} + +void ScaleCopy(const float *src, float scale, float *dest, size_t count) +{ +#error TODO - Implement +} + +void ScaleCopy(const SplitComplex *src, float scale, SplitComplex *dest, size_t count) +{ + ScaleCopy(src->realp, scale, dest->realp, count); + ScaleCopy(src->imagp, scale, dest->imagp, count); +} + +void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count) +{ +#error TODO - Implement +} + +void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t buffer2Stride, size_t count) +{ +#error TODO - Implement +} + +void Accumulate(SplitComplex *buffer, const SplitComplex *buffer2, size_t count) +{ +#error TODO - Implement +} + + +void Multiply(const SplitComplex *a, const SplitComplex *b, SplitComplex *c, size_t count) +{ +#error TODO - Implement +} + +} // namespace KRDSP + +#endif // KRDSP_SLOW diff --git a/kraken/KRDSP.cpp b/kraken/KRDSP_vDSP.cpp similarity index 73% rename from kraken/KRDSP.cpp rename to kraken/KRDSP_vDSP.cpp index 5be95f5..9f4dab9 100644 --- a/kraken/KRDSP.cpp +++ b/kraken/KRDSP_vDSP.cpp @@ -31,75 +31,60 @@ #include "KRDSP.h" -#ifdef __APPLE__ +#ifdef KRDSP_APPLE_VDSP + #include -#define KRDSP_APPLE_VDSP -#endif namespace KRDSP { -void CreateFFTWorkspace(FFTWorkspace &workspace, size_t length) + +FFTWorkspace::FFTWorkspace() { -#ifdef KRDSP_APPLE_VDSP - workspace = vDSP_create_fftsetup(length, kFFTRadix2); -#else -#error TODO - Implement -#endif + setup = nullptr; } -void DestroyFFTWorkspace(FFTWorkspace &workspace) +FFTWorkspace::~FFTWorkspace() { -#ifdef KRDSP_APPLE_VDSP - vDSP_destroy_fftsetup(workspace); -#else -#error TODO - Implement -#endif + destroy(); +} + +void FFTWorkspace::Create(size_t length) +{ + setup = vDSP_create_fftsetup(length, kFFTRadix2); +} + +void FFTWorkspace::destroy() +{ + if (setup) { + vDSP_destroy_fftsetup(setup); + setup = nullptr; + } } void FFTForward(const FFTWorkspace &workspace, SplitComplex *src, size_t count) { -#ifdef KRDSP_APPLE_VDSP - vDSP_fft_zip(workspace, src, 1, count, kFFTDirection_Forward); -#else -#error TODO - Implement -#endif + vDSP_fft_zip(workspace.setup, src, 1, count, kFFTDirection_Forward); } void FFTInverse(const FFTWorkspace &workspace, SplitComplex *src, size_t count) { -#ifdef KRDSP_APPLE_VDSP - vDSP_fft_zip(workspace, src, 1, count, kFFTDirection_Inverse); -#else -#error TODO - Implement -#endif + vDSP_fft_zip(workspace.setup, src, 1, count, kFFTDirection_Inverse); } void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count) { -#ifdef KRDSP_APPLE_VDSP vDSP_vflt16(src, srcStride, dest, destStride, count); -#else -#error TODO - Implement -#endif } void Scale(float *buffer, float scale, size_t count) { -#ifdef KRDSP_APPLE_VDSP vDSP_vsmul(buffer, 1, &scale, buffer, 1, count); -#else -#error TODO - Implement -#endif } void ScaleCopy(const float *src, float scale, float *dest, size_t count) { -#ifdef KRDSP_APPLE_VDSP vDSP_vsmul(src, 1, scale, dest, 1, count); -#else -#error TODO - Implement -#endif } void ScaleCopy(const SplitComplex *src, float scale, SplitComplex *dest, size_t count) @@ -110,42 +95,25 @@ void ScaleCopy(const SplitComplex *src, float scale, SplitComplex *dest, size_t void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count) { -#ifdef KRDSP_APPLE_VDSP - vDSP_vrampmul(buffer, 1, - &scaleStart, &scaleStep, - buffer, 1, - count); -#else -#error TODO - Implement -#endif + vDSP_vrampmul(buffer, 1, &scaleStart, &scaleStep, buffer, 1, count); } void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t buffer2Stride, size_t count) { -#ifdef KRDSP_APPLE_VDSP vDSP_vadd(buffer, bufferStride, buffer2, buffer2Stride, buffer, bufferStride, count); -#else -#error TODO - Implement -#endif } void Accumulate(SplitComplex *buffer, const SplitComplex *buffer2, size_t count) { -#ifdef KRDSP_APPLE_VDSP vDSP_zvadd(buffer2, 1, buffer, 1, buffer, 1, count); -#else -#error TODO - Implement -#endif } void Multiply(const SplitComplex *a, const SplitComplex *b, SplitComplex *c, size_t count) { -#ifdef KRDSP_APPLE_VDSP vDSP_zvmul(a, 1, b, 1, c, 1, count, 1); -#else -#error TODO - Implement -#endif } } // namespace KRDSP + +#endif // KRDSP_APPLE_VDSP \ No newline at end of file diff --git a/kraken_win/kraken.vcxproj b/kraken_win/kraken.vcxproj index 37f4ca9..9ea1ae5 100755 --- a/kraken_win/kraken.vcxproj +++ b/kraken_win/kraken.vcxproj @@ -143,7 +143,8 @@ - + + diff --git a/kraken_win/kraken.vcxproj.filters b/kraken_win/kraken.vcxproj.filters index fbf1bac..0234575 100755 --- a/kraken_win/kraken.vcxproj.filters +++ b/kraken_win/kraken.vcxproj.filters @@ -243,7 +243,10 @@ Source Files - + + Source Files + + Source Files