diff --git a/.gitignore b/.gitignore index 9a6c14e..0757f81 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ Kraken.xcodeproj/xcuserdata +kraken_win/build/ diff --git a/kraken/KRAudioManager.cpp b/kraken/KRAudioManager.cpp index b264076..8903f7e 100755 --- a/kraken/KRAudioManager.cpp +++ b/kraken/KRAudioManager.cpp @@ -37,6 +37,7 @@ #include "KRContext.h" #include "KRVector2.h" #include "KRCollider.h" +#include "KRDSP.h" #ifdef __APPLE__ #include #endif @@ -261,7 +262,7 @@ void KRAudioManager::renderReverbImpulseResponse(int impulse_response_offset, in } else { // Subsequent samples write to the second half of the FFT input buffer, which is then added to the first half (the second half will be zero'ed out anyways and works as a convenient temporary buffer) zi.reverb_sample->sample(impulse_response_offset, frame_count, channel, impulse_block_data_complex.realp + frame_count, zi.weight, false); - vDSP_vadd(impulse_block_data_complex.realp, 1, impulse_block_data_complex.realp + frame_count, 1, impulse_block_data_complex.realp, 1, frame_count); + KRDSP::Accumulate(impulse_block_data_complex.realp, 1, impulse_block_data_complex.realp + frame_count, 1, frame_count); } } @@ -275,7 +276,7 @@ void KRAudioManager::renderReverbImpulseResponse(int impulse_response_offset, in vDSP_fft_zip(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &impulse_block_data_complex, 1, fft_size_log2, kFFTDirection_Forward); vDSP_zvmul(&reverb_sample_data_complex, 1, &impulse_block_data_complex, 1, &conv_data_complex, 1, fft_size, 1); vDSP_fft_zip(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], &conv_data_complex, 1, fft_size_log2, kFFTDirection_Inverse); - vDSP_vsmul(conv_data_complex.realp, 1, &scale, conv_data_complex.realp, 1, fft_size); + KRDSP::Scale(conv_data_complex.realp, scale, fft_size); int output_offset = (m_output_accumulation_block_start + impulse_response_offset * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); @@ -283,7 +284,9 @@ void KRAudioManager::renderReverbImpulseResponse(int impulse_response_offset, in while(frames_left) { int frames_to_process = (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS - output_offset) / KRENGINE_MAX_OUTPUT_CHANNELS; if(frames_to_process > frames_left) frames_to_process = frames_left; - vDSP_vadd(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, conv_data_complex.realp + fft_size - frames_left, 1, m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, frames_to_process); + KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, + conv_data_complex.realp + fft_size - frames_left, 1, + frames_to_process); frames_left -= frames_to_process; output_offset = (output_offset + frames_to_process * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); } @@ -314,7 +317,7 @@ void KRAudioManager::renderReverb() float reverb_send_level = m_global_reverb_send_level * m_global_gain * source->getReverb() * containment_factor; if(reverb_send_level > 0.0f) { source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, reverb_data, reverb_send_level); - vDSP_vadd(reverb_accum, 1, reverb_data, 1, reverb_accum, 1, KRENGINE_AUDIO_BLOCK_LENGTH); + KRDSP::Accumulate(reverb_accum, 1, reverb_data, 1, KRENGINE_AUDIO_BLOCK_LENGTH); } } } @@ -1567,8 +1570,10 @@ void KRAudioManager::renderAmbient() KRAudioSample *source_sample = zi.ambient_sample; if(source_sample) { for(int channel=0; channel < KRENGINE_MAX_OUTPUT_CHANNELS; channel++) { - source_sample->sample(getContext().getAudioManager()->getAudioFrame(), KRENGINE_AUDIO_BLOCK_LENGTH, channel, buffer, gain, true); - vDSP_vadd(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, buffer, 1, m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, KRENGINE_AUDIO_BLOCK_LENGTH); + source_sample->sample(getContext().getAudioManager()->getAudioFrame(), KRENGINE_AUDIO_BLOCK_LENGTH, channel, buffer, gain, true); + KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, + buffer, 1, + KRENGINE_AUDIO_BLOCK_LENGTH); } } } @@ -1608,9 +1613,9 @@ void KRAudioManager::renderHRTF() source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, sample_buffer, 1.0); float ramp_gain = gain_anticlick; float ramp_step = (gain - gain_anticlick) / KRENGINE_AUDIO_ANTICLICK_SAMPLES; - vDSP_vrampmul(sample_buffer, 1, &ramp_gain, &ramp_step, sample_buffer, 1, KRENGINE_AUDIO_ANTICLICK_SAMPLES); + KRDSP::ScaleRamp(sample_buffer, ramp_gain, ramp_step, KRENGINE_AUDIO_ANTICLICK_SAMPLES); if(KRENGINE_AUDIO_BLOCK_LENGTH > KRENGINE_AUDIO_ANTICLICK_SAMPLES) { - vDSP_vsmul(sample_buffer + KRENGINE_AUDIO_ANTICLICK_SAMPLES, 1, &gain, sample_buffer + KRENGINE_AUDIO_ANTICLICK_SAMPLES, 1, KRENGINE_AUDIO_BLOCK_LENGTH - KRENGINE_AUDIO_ANTICLICK_SAMPLES); + KRDSP::Scale(sample_buffer + KRENGINE_AUDIO_ANTICLICK_SAMPLES, gain, KRENGINE_AUDIO_BLOCK_LENGTH - KRENGINE_AUDIO_ANTICLICK_SAMPLES); } } else { // Don't need to perform anti-click filtering, so just sample @@ -1621,7 +1626,7 @@ void KRAudioManager::renderHRTF() first_source = false; } else { // Accumulate samples on subsequent sources - vDSP_vadd(hrtf_sample->realp, 1, sample_buffer, 1, hrtf_sample->realp, 1, KRENGINE_AUDIO_BLOCK_LENGTH); + KRDSP::Accumulate(hrtf_sample->realp, 1, sample_buffer, 1, KRENGINE_AUDIO_BLOCK_LENGTH); } itr++; @@ -1659,8 +1664,8 @@ void KRAudioManager::renderHRTF() for(int i=0; i < 1 /*4 */; i++) { if(mix[i] > 0.0f) { SplitComplex hrtf_impulse_sample = getHRTFSpectral(dir[i], channel); - vDSP_vsmul(hrtf_impulse_sample.realp, 1, mix+i, hrtf_impulse->realp, 1, fft_size); - vDSP_vsmul(hrtf_impulse_sample.imagp, 1, mix+i, hrtf_impulse->imagp, 1, fft_size); + KRDSP::ScaleCopy(hrtf_impulse_sample.realp, mix[i], hrtf_impulse->realp, fft_size); + KRDSP::ScaleCopy(hrtf_impulse_sample.imagp, mix[i], hrtf_impulse->imagp, fft_size); vDSP_zvadd(hrtf_impulse, 1, hrtf_accum, 1, hrtf_accum, 1, fft_size); } } @@ -1674,14 +1679,16 @@ void KRAudioManager::renderHRTF() vDSP_fft_zip(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], hrtf_sample, 1, fft_size_log2, kFFTDirection_Forward); vDSP_zvmul(hrtf_sample, 1, &hrtf_spectral, 1, hrtf_convolved, 1, fft_size, 1); vDSP_fft_zip(m_fft_setup[fft_size_log2 - KRENGINE_AUDIO_BLOCK_LOG2N], hrtf_convolved, 1, fft_size_log2, kFFTDirection_Inverse); - vDSP_vsmul(hrtf_convolved->realp, 1, &scale, hrtf_convolved->realp, 1, fft_size); + KRDSP::Scale(hrtf_convolved->realp, scale, fft_size); int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); int frames_left = fft_size; while(frames_left) { int frames_to_process = (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS - output_offset) / KRENGINE_MAX_OUTPUT_CHANNELS; if(frames_to_process > frames_left) frames_to_process = frames_left; - vDSP_vadd(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, hrtf_convolved->realp + fft_size - frames_left, 1, m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, frames_to_process); + KRDSP::Accumulate(m_output_accumulation + output_offset + channel, KRENGINE_MAX_OUTPUT_CHANNELS, + hrtf_convolved->realp + fft_size - frames_left, 1, + frames_to_process); frames_left -= frames_to_process; output_offset = (output_offset + frames_to_process * KRENGINE_MAX_OUTPUT_CHANNELS) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); } diff --git a/kraken/KRAudioManager.h b/kraken/KRAudioManager.h index c112654..9aabe2b 100755 --- a/kraken/KRAudioManager.h +++ b/kraken/KRAudioManager.h @@ -38,6 +38,7 @@ #include "KRDataBlock.h" #include "KRMat4.h" #include "KRAudioSource.h" +#include "KRDSP.h" const int KRENGINE_AUDIO_MAX_POOL_SIZE = 60; //32; // for Circa we play a maximum of 11 mono audio streams at once + cross fading with ambient @@ -199,12 +200,6 @@ private: #ifdef __APPLE__ // Apple vDSP FFTSetup m_fft_setup[KRENGINE_REVERB_MAX_FFT_LOG2 - KRENGINE_AUDIO_BLOCK_LOG2N + 1]; - typedef DSPSplitComplex SplitComplex; -#else - typedef struct { - float *realp; - float *imagp; - } SplitComplex; #endif __int64_t m_audio_frame; // Number of audio frames processed since the start of the application diff --git a/kraken/KRAudioSample.cpp b/kraken/KRAudioSample.cpp index 29f97a3..4c33828 100755 --- a/kraken/KRAudioSample.cpp +++ b/kraken/KRAudioSample.cpp @@ -34,9 +34,7 @@ #include "KRDataBlock.h" #include "KRAudioBuffer.h" #include "KRContext.h" -#ifdef __APPLE__ -#include -#endif +#include "KRDSP.h" KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension) : KRResource(context, name) { @@ -186,7 +184,7 @@ void KRAudioSample::sample(__int64_t frame_offset, int frame_count, int channel, if(frames_to_copy > frames_left) frames_to_copy = frames_left; if(frames_to_copy > 0) { signed short *source_data = source_buffer->getFrameData() + buffer_offset * m_channelsPerFrame + c; - vDSP_vflt16(source_data, m_channelsPerFrame, buffer + processed_frames, 1, frames_to_copy); + KRDSP::Int16ToFloat(source_data, m_channelsPerFrame, buffer + processed_frames, 1, frames_to_copy); //memcpy(buffer + processed_frames, source_buffer->getFrameData() + buffer_offset, frames_to_copy * m_channelsPerFrame * sizeof(float)); processed_frames += frames_to_copy; } @@ -197,7 +195,7 @@ void KRAudioSample::sample(__int64_t frame_offset, int frame_count, int channel, } float scale = amplitude / 32768.0f; - vDSP_vsmul(buffer, 1, &scale, buffer, 1, frame_count); + KRDSP::Scale(buffer, scale, frame_count); } } diff --git a/kraken/KRDSP.cpp b/kraken/KRDSP.cpp new file mode 100644 index 0000000..5eab874 --- /dev/null +++ b/kraken/KRDSP.cpp @@ -0,0 +1,89 @@ +// +// 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 __APPLE__ +#include +#define KRDSP_APPLE_VDSP +#endif + +namespace KRDSP { + +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 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 +} + +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 +} + +} // namespace KRDSP diff --git a/kraken/KRDSP.h b/kraken/KRDSP.h new file mode 100644 index 0000000..aeef5f1 --- /dev/null +++ b/kraken/KRDSP.h @@ -0,0 +1,56 @@ +// +// 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. +// + +#ifndef _KRDSP_H +#define _KRDSP_H + +#ifdef __APPLE__ +// Apple vDSP +typedef DSPSplitComplex SplitComplex; +#else +typedef struct { + float *realp; + float *imagp; +} SplitComplex; +#endif + +namespace KRDSP { + +void Int16ToFloat(const short *src, size_t srcStride, float *dest, size_t destStride, size_t count); +void Scale(float *buffer, float scale, size_t count); +void ScaleCopy(const float *src, float scale, float *dest, size_t count); +void ScaleRamp(float *buffer, float scaleStart, float scaleStep, size_t count); +void Accumulate(float *buffer, size_t bufferStride, const float *buffer2, size_t buffer2Stride, size_t count); + +} // namespace KRDSP + +#endif // _KRDSP_H + diff --git a/kraken_win/kraken.vcxproj b/kraken_win/kraken.vcxproj index 26be808..3b9ab2c 100755 --- a/kraken_win/kraken.vcxproj +++ b/kraken_win/kraken.vcxproj @@ -219,6 +219,7 @@ + diff --git a/kraken_win/kraken.vcxproj.filters b/kraken_win/kraken.vcxproj.filters index f7be939..45fc444 100755 --- a/kraken_win/kraken.vcxproj.filters +++ b/kraken_win/kraken.vcxproj.filters @@ -13,6 +13,15 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + {1ccb2d2f-3dba-4fa4-a77f-5aef119ca916} + + + {218ed471-6978-45cb-9a64-c25d07ecdcc1} + + + {b1389da0-01b5-4d0b-bb62-bf912979a845} + @@ -239,9 +248,6 @@ Header Files - - Header Files - Header Files @@ -464,5 +470,20 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files\3rdparty\forsyth.h + + + Header Files + \ No newline at end of file