Updating Siren for portability, WIP

This commit is contained in:
Kearwood Gilbert
2017-06-11 18:50:04 -07:00
parent 6ee26e2ae4
commit f62e8715ba
8 changed files with 195 additions and 27 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
Kraken.xcodeproj/xcuserdata
kraken_win/build/

View File

@@ -37,6 +37,7 @@
#include "KRContext.h"
#include "KRVector2.h"
#include "KRCollider.h"
#include "KRDSP.h"
#ifdef __APPLE__
#include <Accelerate/Accelerate.h>
#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);
}

View File

@@ -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

View File

@@ -34,9 +34,7 @@
#include "KRDataBlock.h"
#include "KRAudioBuffer.h"
#include "KRContext.h"
#ifdef __APPLE__
#include <Accelerate/Accelerate.h>
#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);
}
}

89
kraken/KRDSP.cpp Normal file
View File

@@ -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 <Accelerate/Accelerate.h>
#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

56
kraken/KRDSP.h Normal file
View File

@@ -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

View File

@@ -219,6 +219,7 @@
<ClInclude Include="..\kraken\KRContextObject.h" />
<ClInclude Include="..\kraken\KRDataBlock.h" />
<ClInclude Include="..\kraken\KRDirectionalLight.h" />
<ClInclude Include="..\kraken\KRDSP.h" />
<ClInclude Include="..\kraken\KREngine-common.h" />
<ClInclude Include="..\kraken\KREngine.h" />
<ClInclude Include="..\kraken\KRFloat.h" />

View File

@@ -13,6 +13,15 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Header Files\3rdparty">
<UniqueIdentifier>{1ccb2d2f-3dba-4fa4-a77f-5aef119ca916}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\3rdparty\ffts">
<UniqueIdentifier>{218ed471-6978-45cb-9a64-c25d07ecdcc1}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\3rdparty\forsyth.h">
<UniqueIdentifier>{b1389da0-01b5-4d0b-bb62-bf912979a845}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\3rdparty\tinyxml2\tinyxml2.cpp">
@@ -239,9 +248,6 @@
<ClInclude Include="..\3rdparty\tinyxml2\tinyxml2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\3rdparty\forsyth\forsyth.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\kraken\KRVector2.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -464,5 +470,20 @@
<ClInclude Include="..\kraken\KRUnknownManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="3rdparty\glew\glew-1.13.0\include\GL\glew.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="3rdparty\glew\glew-1.13.0\include\GL\glxew.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="3rdparty\glew\glew-1.13.0\include\GL\wglew.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\3rdparty\forsyth\forsyth.h">
<Filter>Header Files\3rdparty\forsyth.h</Filter>
</ClInclude>
<ClInclude Include="..\kraken\KRDSP.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>