Siren audio engine in progress

Added HRTF (Kemar) samples for 3d spatialization
Exposed frame buffer width and height for camera renderFrame calls.
Fixed a bug that caused objects containing a mixture of both opaque and transparent materials to be rendered entirely in the transparent render pass.  Now the sub meshes are evaluated independently.
This commit is contained in:
2013-02-08 17:28:17 -08:00
parent 63d333ae46
commit 743955fbe0
19 changed files with 264 additions and 89 deletions

View File

@@ -68,6 +68,8 @@
E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BAD16444E120043185B /* KRParticleSystemNewtonian.cpp */; }; E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BAD16444E120043185B /* KRParticleSystemNewtonian.cpp */; };
E4324BAF16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BAD16444E120043185B /* KRParticleSystemNewtonian.cpp */; }; E4324BAF16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BAD16444E120043185B /* KRParticleSystemNewtonian.cpp */; };
E4324BB0164458930043185B /* KRParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BA716444C230043185B /* KRParticleSystem.cpp */; }; E4324BB0164458930043185B /* KRParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4324BA716444C230043185B /* KRParticleSystem.cpp */; };
E437849816C4884F0037FD43 /* hrtf_kemar.krbundle in Resources */ = {isa = PBXBuildFile; fileRef = E437849716C488360037FD43 /* hrtf_kemar.krbundle */; };
E437849916C488550037FD43 /* hrtf_kemar.krbundle in Resources */ = {isa = PBXBuildFile; fileRef = E437849716C488360037FD43 /* hrtf_kemar.krbundle */; };
E43B0AD615DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; }; E43B0AD615DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; };
E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; }; E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; };
E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -394,6 +396,7 @@
E4324BA716444C230043185B /* KRParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRParticleSystem.cpp; sourceTree = "<group>"; }; E4324BA716444C230043185B /* KRParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRParticleSystem.cpp; sourceTree = "<group>"; };
E4324BAA16444DEF0043185B /* KRParticleSystemNewtonian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRParticleSystemNewtonian.h; sourceTree = "<group>"; }; E4324BAA16444DEF0043185B /* KRParticleSystemNewtonian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRParticleSystemNewtonian.h; sourceTree = "<group>"; };
E4324BAD16444E120043185B /* KRParticleSystemNewtonian.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRParticleSystemNewtonian.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E4324BAD16444E120043185B /* KRParticleSystemNewtonian.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRParticleSystemNewtonian.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E437849716C488360037FD43 /* hrtf_kemar.krbundle */ = {isa = PBXFileReference; lastKnownFileType = file; path = hrtf_kemar.krbundle; sourceTree = "<group>"; };
E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRContextObject.cpp; sourceTree = "<group>"; }; E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRContextObject.cpp; sourceTree = "<group>"; };
E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = "<group>"; }; E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = "<group>"; };
E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = "<group>"; }; E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = "<group>"; };
@@ -721,6 +724,14 @@
name = "Particle Systems"; name = "Particle Systems";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
E437849616C4881A0037FD43 /* kraken_standard_assets */ = {
isa = PBXGroup;
children = (
E437849716C488360037FD43 /* hrtf_kemar.krbundle */,
);
path = kraken_standard_assets;
sourceTree = "<group>";
};
E461A170152E598200F2044A /* Resources */ = { E461A170152E598200F2044A /* Resources */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -930,6 +941,7 @@
E491015613C99B9D0098455B = { E491015613C99B9D0098455B = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
E437849616C4881A0037FD43 /* kraken_standard_assets */,
E491016613C99B9E0098455B /* kraken */, E491016613C99B9E0098455B /* kraken */,
E4C8E50C16B9B5ED0031DDCB /* kraken_ios */, E4C8E50C16B9B5ED0031DDCB /* kraken_ios */,
E4BBBB851512A40300F43B5B /* kraken_osx */, E4BBBB851512A40300F43B5B /* kraken_osx */,
@@ -1383,6 +1395,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
E437849816C4884F0037FD43 /* hrtf_kemar.krbundle in Resources */,
E4E6F68516BA5DF700E410F8 /* sky_box.fsh in Resources */, E4E6F68516BA5DF700E410F8 /* sky_box.fsh in Resources */,
E4E6F68616BA5DF700E410F8 /* debug_font.fsh in Resources */, E4E6F68616BA5DF700E410F8 /* debug_font.fsh in Resources */,
E4E6F68716BA5DF700E410F8 /* debug_font.vsh in Resources */, E4E6F68716BA5DF700E410F8 /* debug_font.vsh in Resources */,
@@ -1421,6 +1434,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
E437849916C488550037FD43 /* hrtf_kemar.krbundle in Resources */,
E4E6F6A316BA5E0A00E410F8 /* PostShader_osx.fsh in Resources */, E4E6F6A316BA5E0A00E410F8 /* PostShader_osx.fsh in Resources */,
E4E6F6A416BA5E0A00E410F8 /* PostShader_osx.vsh in Resources */, E4E6F6A416BA5E0A00E410F8 /* PostShader_osx.vsh in Resources */,
E4E6F6A516BA5E0A00E410F8 /* sky_box_osx.fsh in Resources */, E4E6F6A516BA5E0A00E410F8 /* sky_box_osx.fsh in Resources */,

View File

@@ -19,6 +19,8 @@ KRAudioBuffer::KRAudioBuffer(KRAudioManager *manager, KRAudioSample *sound, int
m_frameRate = frameRate; m_frameRate = frameRate;
m_bytesPerFrame = bytesPerFrame; m_bytesPerFrame = bytesPerFrame;
m_pData = NULL; m_pData = NULL;
m_audioSample = sound;
m_index = index;
m_pSoundManager->makeCurrentContext(); m_pSoundManager->makeCurrentContext();
m_pData = m_pSoundManager->getBufferData(m_frameCount * m_bytesPerFrame); m_pData = m_pSoundManager->getBufferData(m_frameCount * m_bytesPerFrame);
@@ -40,6 +42,10 @@ KRAudioBuffer::~KRAudioBuffer()
m_pSoundManager->recycleBufferData(m_pData); m_pSoundManager->recycleBufferData(m_pData);
} }
KRAudioSample *KRAudioBuffer::getAudioSample()
{
return m_audioSample;
}
unsigned int KRAudioBuffer::getBufferID() unsigned int KRAudioBuffer::getBufferID()
{ {
@@ -60,3 +66,8 @@ signed short *KRAudioBuffer::getFrameData()
{ {
return (signed short *)m_pData->getStart(); return (signed short *)m_pData->getStart();
} }
int KRAudioBuffer::getIndex()
{
return m_index;
}

View File

@@ -25,10 +25,13 @@ public:
int getFrameCount(); int getFrameCount();
int getFrameRate(); int getFrameRate();
signed short *getFrameData(); signed short *getFrameData();
KRAudioSample *getAudioSample();
int getIndex();
private: private:
KRAudioManager *m_pSoundManager; KRAudioManager *m_pSoundManager;
int m_index;
ALenum m_dataFormat; ALenum m_dataFormat;
int m_frameCount; int m_frameCount;
int m_frameRate; int m_frameRate;
@@ -36,6 +39,8 @@ private:
KRDataBlock *m_pData; KRDataBlock *m_pData;
unsigned int m_bufferID; unsigned int m_bufferID;
KRAudioSample *m_audioSample;
}; };
#endif /* defined(KRAUDIO_BUFFER_H) */ #endif /* defined(KRAUDIO_BUFFER_H) */

View File

@@ -48,6 +48,8 @@ KRAudioManager::KRAudioManager(KRContext &context) : KRContextObject(context)
// Siren // Siren
m_auGraph = NULL; m_auGraph = NULL;
m_auMixer = NULL; m_auMixer = NULL;
m_audio_frame = 0;
} }
void KRAudioManager::initAudio() void KRAudioManager::initAudio()
@@ -66,45 +68,39 @@ void KRAudioManager::initAudio()
void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData) void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData)
{ {
static float phase; // hrtf_kemar_H-10e000a.wav
static float pan_phase;
static float hrtf_workspace[128];
float speed_of_sound = 1126.0f; // feed per second FINDME - TODO - This needs to be configurable for scenes with different units
float head_radius = 0.7431f; // 0.74ft = 22cm
float half_max_itd_time = head_radius / speed_of_sound / 2.0f; // half of ITD time (Interaural time difference) when audio source is directly 90 degrees azimuth to one ear.
// KRVector3 m_listener_position;
// KRVector3 m_listener_forward;
// KRVector3 m_listener_up;
KRVector3 listener_right = KRVector3::Cross(m_listener_forward, m_listener_up);
KRVector3 listener_right_ear = m_listener_position + listener_right * head_radius / 2.0f;
KRVector3 listener_left_ear = m_listener_position - listener_right * head_radius / 2.0f;
// Get a pointer to the dataBuffer of the AudioBufferList // Get a pointer to the dataBuffer of the AudioBufferList
AudioUnitSampleType *outA = (AudioUnitSampleType *)ioData->mBuffers[0].mData; AudioUnitSampleType *outA = (AudioUnitSampleType *)ioData->mBuffers[0].mData;
AudioUnitSampleType *outB = (AudioUnitSampleType *)ioData->mBuffers[1].mData; // Non-Interleaved only AudioUnitSampleType *outB = (AudioUnitSampleType *)ioData->mBuffers[1].mData; // Non-Interleaved only
// Calculations to produce a 600 Hz sinewave
// A constant frequency value, you can pass in a reference vary this.
float freq = 300;
// The amount the phase changes in single sample
double phaseIncrement = M_PI * freq / 44100.0;
// Pass in a reference to the phase value, you have to keep track of this
// so that the sin resumes right where the last call left off
// Loop through the callback buffer, generating samples
for (UInt32 i = 0; i < inNumberFrames; ++i) { for (UInt32 i = 0; i < inNumberFrames; ++i) {
// calculate the next sample
float sinSignal = sin(phase);
// Put the sample into the buffer
// Scale the -1 to 1 values float to
// -32767 to 32767 and then cast to an integer
float left_channel = sinSignal * (sin(pan_phase) * 0.5f + 0.5f);
float right_channel = sinSignal * (-sin(pan_phase) * 0.5f + 0.5f);
left_channel = 0;
right_channel = 0;
#if CA_PREFER_FIXED_POINT #if CA_PREFER_FIXED_POINT
// Interleaved // Interleaved
// outA[i*2] = (SInt16)(left_channel * 32767.0f); // outA[i*2] = (SInt16)(left_channel * 32767.0f);
// outA[i*2 + 1] = (SInt16)(right_channel * 32767.0f); // outA[i*2 + 1] = (SInt16)(right_channel * 32767.0f);
// Non-Interleaved // Non-Interleaved
outA[i] = (SInt32)(left_channel * 0x1000000f); outA[i] = (SInt32)(0x1000000f);
outB[i] = (SInt32)(right_channel * 0x1000000f); outB[i] = (SInt32)(0x1000000f);
#else #else
// Interleaved // Interleaved
@@ -112,18 +108,12 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData)
// outA[i*2 + 1] = (Float32)right_channel; // outA[i*2 + 1] = (Float32)right_channel;
// Non-Interleaved // Non-Interleaved
outA[i] = (Float32)left_channel; outA[i] = (Float32)0.0f;
outB[i] = (Float32)right_channel; outB[i] = (Float32)0.0f;
#endif #endif
// calculate the phase for the next sample
phase = phase + phaseIncrement;
pan_phase = pan_phase + 1 / 44100.0 * M_PI;
}
// Reset the phase value to prevent the float from overflowing
if (phase >= M_PI * freq) {
phase = phase - M_PI * freq;
} }
/*
for(std::set<KRAudioSource *>::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) { for(std::set<KRAudioSource *>::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) {
int channel_count = 1; int channel_count = 1;
@@ -172,6 +162,64 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData)
} }
source->advanceFrames(frames_advanced); source->advanceFrames(frames_advanced);
} }
*/
for(std::set<KRAudioSource *>::iterator itr=m_activeAudioSources.begin(); itr != m_activeAudioSources.end(); itr++) {
KRAudioSource *source = *itr;
KRVector3 listener_to_source = source->getWorldTranslation() - m_listener_position;
KRVector3 right_ear_to_source = source->getWorldTranslation() - listener_right_ear;
KRVector3 left_ear_to_source = source->getWorldTranslation() - listener_left_ear;
KRVector3 source_direction = KRVector3::Normalize(listener_to_source);
float right_ear_distance = right_ear_to_source.magnitude();
float left_ear_distance = left_ear_to_source.magnitude();
float right_itd_time = right_ear_distance / speed_of_sound;
float left_itd_time = left_ear_distance / speed_of_sound;
float rolloff_factor = source->getRolloffFactor();
float left_gain = 1.0f / pow(left_ear_distance / rolloff_factor, 2.0f);
float right_gain = 1.0f / pow(left_ear_distance / rolloff_factor, 2.0f);
if(left_gain > 1.0f) left_gain = 1.0f;
if(right_gain > 1.0f) right_gain = 1.0f;
left_gain *= source->getGain();
right_gain *= source->getGain();
int left_itd_offset = (int)(left_itd_time * 44100.0f);
int right_itd_offset = (int)(right_itd_time * 44100.0f);
KRAudioSample *sample = source->getAudioSample();
if(sample) {
__int64_t source_start_frame = source->getStartAudioFrame();
int sample_frame = (int)(m_audio_frame - source_start_frame);
for (UInt32 i = 0; i < inNumberFrames; ++i) {
float left_channel=sample->sample(sample_frame + left_itd_offset, 44100, 0) * left_gain;
float right_channel = sample->sample(sample_frame + right_itd_offset, 44100, 0) * right_gain;
// left_channel = 0.0f;
// right_channel = 0.0f;
#if CA_PREFER_FIXED_POINT
// Interleaved
// outA[i*2] = (SInt16)(left_channel * 32767.0f);
// outA[i*2 + 1] = (SInt16)(right_channel * 32767.0f);
// Non-Interleaved
outA[i] += (SInt32)(left_channel * 0x1000000f);
outB[i] += (SInt32)(right_channel * 0x1000000f);
#else
// Interleaved
// outA[i*2] = (Float32)left_channel;
// outA[i*2 + 1] = (Float32)right_channel;
// Non-Interleaved
outA[i] += (Float32)left_channel;
outB[i] += (Float32)right_channel;
#endif
sample_frame++;
}
}
}
m_audio_frame += inNumberFrames;
} }
// audio render procedure, don't allocate memory, don't take any locks, don't waste time // audio render procedure, don't allocate memory, don't take any locks, don't waste time
@@ -457,17 +505,17 @@ void KRAudioManager::setViewMatrix(const KRMat4 &viewMatrix)
KRMat4 invView = viewMatrix; KRMat4 invView = viewMatrix;
invView.invert(); invView.invert();
KRVector3 player_position = KRMat4::Dot(invView, KRVector3(0.0, 0.0, 0.0)); m_listener_position = KRMat4::Dot(invView, KRVector3(0.0, 0.0, 0.0));
KRVector3 vectorForward = KRMat4::Dot(invView, KRVector3(0.0, 0.0, -1.0)) - player_position; m_listener_forward = KRMat4::Dot(invView, KRVector3(0.0, 0.0, -1.0)) - m_listener_position;
KRVector3 vectorUp = KRMat4::Dot(invView, KRVector3(0.0, 1.0, 0.0)) - player_position; m_listener_up = KRMat4::Dot(invView, KRVector3(0.0, 1.0, 0.0)) - m_listener_position;
vectorUp.normalize(); m_listener_up.normalize();
vectorForward.normalize(); m_listener_forward.normalize();
makeCurrentContext(); makeCurrentContext();
if(m_audio_engine == KRAKEN_AUDIO_OPENAL) { if(m_audio_engine == KRAKEN_AUDIO_OPENAL) {
ALDEBUG(alListener3f(AL_POSITION, player_position.x, player_position.y, player_position.z)); ALDEBUG(alListener3f(AL_POSITION, m_listener_position.x, m_listener_position.y, m_listener_position.z));
ALfloat orientation[] = {vectorForward.x, vectorForward.y, vectorForward.z, vectorUp.x, vectorUp.y, vectorUp.z}; ALfloat orientation[] = {m_listener_forward.x, m_listener_forward.y, m_listener_forward.z, m_listener_up.x, m_listener_up.y, m_listener_up.z};
ALDEBUG(alListenerfv(AL_ORIENTATION, orientation)); ALDEBUG(alListenerfv(AL_ORIENTATION, orientation));
} }
} }
@@ -570,3 +618,33 @@ void KRAudioManager::deactivateAudioSource(KRAudioSource *audioSource)
{ {
m_activeAudioSources.erase(audioSource); m_activeAudioSources.erase(audioSource);
} }
__int64_t KRAudioManager::getAudioFrame()
{
return m_audio_frame;
}
KRAudioBuffer *KRAudioManager::getBuffer(KRAudioSample &audio_sample, int buffer_index)
{
// ----====---- Try to find the buffer in the cache ----====----
for(std::vector<KRAudioBuffer *>::iterator itr=m_bufferCache.begin(); itr != m_bufferCache.end(); itr++) {
KRAudioBuffer *cache_buffer = *itr;
if(cache_buffer->getAudioSample() == &audio_sample && cache_buffer->getIndex() == buffer_index) {
return cache_buffer;
}
}
// ----====---- Make room in the cache for a new buffer ----====----
if(m_bufferCache.size() >= KRENGINE_AUDIO_MAX_POOL_SIZE) {
// delete a random entry from the cache
int index_to_delete = arc4random() % m_bufferCache.size();
std::vector<KRAudioBuffer *>::iterator itr_to_delete = m_bufferCache.begin() + index_to_delete;
delete *itr_to_delete;
m_bufferCache.erase(itr_to_delete);
}
// ----====---- Request new buffer, add to cache, and return it ----====----
KRAudioBuffer *buffer = audio_sample.getBuffer(buffer_index);
m_bufferCache.push_back(buffer);
return buffer;
}

View File

@@ -73,12 +73,21 @@ public:
void activateAudioSource(KRAudioSource *audioSource); void activateAudioSource(KRAudioSource *audioSource);
void deactivateAudioSource(KRAudioSource *audioSource); void deactivateAudioSource(KRAudioSource *audioSource);
__int64_t getAudioFrame();
KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index);
private: private:
KRVector3 m_listener_position;
KRVector3 m_listener_forward;
KRVector3 m_listener_up;
map<std::string, KRAudioSample *> m_sounds; map<std::string, KRAudioSample *> m_sounds;
std::vector<KRDataBlock *> m_bufferPoolIdle; std::vector<KRDataBlock *> m_bufferPoolIdle;
std::vector<KRAudioBuffer *> m_bufferCache;
std::set<KRAudioSource *> m_activeAudioSources; std::set<KRAudioSource *> m_activeAudioSources;
void initAudio(); void initAudio();
@@ -102,6 +111,8 @@ private:
AudioUnit m_auMixer; AudioUnit m_auMixer;
static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
void renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData); void renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData);
__int64_t m_audio_frame; // Number of audio frames processed since the start of the application
}; };
#endif /* defined(KRAUDIO_MANAGER_H) */ #endif /* defined(KRAUDIO_MANAGER_H) */

View File

@@ -72,6 +72,49 @@ KRAudioSample::~KRAudioSample()
delete m_pData; delete m_pData;
} }
int KRAudioSample::getChannelCount()
{
openFile();
return m_channelsPerFrame;
}
int KRAudioSample::getFrameCount(int frame_rate)
{
return (int)((__int64_t)m_totalFrames * (__int64_t)frame_rate / (__int64_t)m_frameRate);
}
float KRAudioSample::sample(int frame_offset, int frame_rate, int channel)
{
if(frame_offset < 0) {
return 0.0f; // Past the beginning of the recording
} else {
int sample_frame;
if(m_frameRate == frame_rate) {
// No resampling required
sample_frame = frame_offset;
} else {
// Need to resample from m_frameRate to frame_rate
sample_frame = (int)((__int64_t)frame_offset * (__int64_t)m_frameRate / (__int64_t)frame_rate);
}
int maxFramesPerBuffer = KRENGINE_AUDIO_MAX_BUFFER_SIZE / m_bytesPerFrame;
int buffer_index = sample_frame / maxFramesPerBuffer;
if(buffer_index >= m_bufferCount) {
return 0.0f; // Past the end of the recording
} else {
int buffer_offset = frame_offset - buffer_index * maxFramesPerBuffer;
KRAudioBuffer *buffer = getContext().getAudioManager()->getBuffer(*this, buffer_index);
if(buffer == NULL) {
return 0.0f;
} else if(buffer_offset >= buffer->getFrameCount()) {
return 0.0f; // past the end of the recording
} else {
short *frame = buffer->getFrameData() + (buffer_offset * m_channelsPerFrame);
return frame[channel] / 32767.0f;
}
}
}
}
OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc
void * inClientData, void * inClientData,
@@ -120,13 +163,9 @@ void KRAudioSample::openFile()
UInt32 propertySize; UInt32 propertySize;
// ---- Open audio file ---- // ---- Open audio file ----
// ExtAudioFileOpenURL((CFURLRef)m_soundURL, &_fileRef);
assert(AudioFileOpenWithCallbacks((void *)this, ReadProc, WriteProc, GetSizeProc, SetSizeProc, 0, &m_audio_file_id) == noErr); assert(AudioFileOpenWithCallbacks((void *)this, ReadProc, WriteProc, GetSizeProc, SetSizeProc, 0, &m_audio_file_id) == noErr);
assert(ExtAudioFileWrapAudioFileID(m_audio_file_id, false, &m_fileRef) == noErr); assert(ExtAudioFileWrapAudioFileID(m_audio_file_id, false, &m_fileRef) == noErr);
// ---- Get file format information ---- // ---- Get file format information ----
AudioStreamBasicDescription inputFormat; AudioStreamBasicDescription inputFormat;
propertySize = sizeof(inputFormat); propertySize = sizeof(inputFormat);

View File

@@ -54,6 +54,11 @@ public:
KRAudioBuffer *getBuffer(int index); KRAudioBuffer *getBuffer(int index);
int getBufferCount(); int getBufferCount();
// Siren audio engine interface
int getChannelCount();
int getFrameCount(int frame_rate);
float sample(int frame_offset, int frame_rate, int channel);
private: private:
std::string m_extension; std::string m_extension;

View File

@@ -54,6 +54,8 @@ KRAudioSource::KRAudioSource(KRScene &scene, std::string name) : KRNode(scene, n
m_rolloffFactor = 2.0f; m_rolloffFactor = 2.0f;
m_enable_occlusion = true; m_enable_occlusion = true;
m_enable_obstruction = true; m_enable_obstruction = true;
m_start_audio_frame = -1;
} }
KRAudioSource::~KRAudioSource() KRAudioSource::~KRAudioSource()
@@ -394,6 +396,7 @@ void KRAudioSource::physicsUpdate(float deltaTime)
void KRAudioSource::play() void KRAudioSource::play()
{ {
KRAudioManager *audioManager = getContext().getAudioManager(); KRAudioManager *audioManager = getContext().getAudioManager();
m_start_audio_frame = audioManager->getAudioFrame();
audioManager->activateAudioSource(this); audioManager->activateAudioSource(this);
if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) {
getContext().getAudioManager()->makeCurrentContext(); getContext().getAudioManager()->makeCurrentContext();
@@ -417,6 +420,7 @@ void KRAudioSource::play()
void KRAudioSource::stop() void KRAudioSource::stop()
{ {
m_start_audio_frame = -1;
m_playing = false; m_playing = false;
getContext().getAudioManager()->deactivateAudioSource(this); getContext().getAudioManager()->deactivateAudioSource(this);
} }
@@ -437,6 +441,14 @@ std::string KRAudioSource::getSample()
return m_audio_sample_name; return m_audio_sample_name;
} }
KRAudioSample *KRAudioSource::getAudioSample()
{
if(m_audioFile == NULL && m_audio_sample_name.size() != 0) {
m_audioFile = getContext().getAudioManager()->get(m_audio_sample_name);
}
return m_audioFile;
}
void KRAudioSource::updatePosition() void KRAudioSource::updatePosition()
{ {
if(m_is3d) { if(m_is3d) {
@@ -487,6 +499,11 @@ int KRAudioSource::getBufferFrame()
return m_currentBufferFrame; return m_currentBufferFrame;
} }
__int64_t KRAudioSource::getStartAudioFrame()
{
return m_start_audio_frame;
}
OSStatus alcASASetSourceProc(const ALuint property, ALuint source, ALvoid *data, ALuint dataSize) OSStatus alcASASetSourceProc(const ALuint property, ALuint source, ALvoid *data, ALuint dataSize)
{ {
OSStatus err = noErr; OSStatus err = noErr;

View File

@@ -58,6 +58,8 @@ public:
void setSample(const std::string &sound_name); void setSample(const std::string &sound_name);
std::string getSample(); std::string getSample();
KRAudioSample *getAudioSample();
float getGain(); float getGain();
void setGain(float gain); void setGain(float gain);
@@ -92,7 +94,11 @@ public:
KRAudioBuffer *getBuffer(); KRAudioBuffer *getBuffer();
int getBufferFrame(); int getBufferFrame();
__int64_t getStartAudioFrame();
private: private:
__int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback
int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer
void advanceBuffer(); void advanceBuffer();

View File

@@ -57,13 +57,12 @@ KRCamera::~KRCamera() {
destroyBuffers(); destroyBuffers();
} }
void KRCamera::renderFrame(float deltaTime) void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight)
{ {
GLint defaultFBO; GLint defaultFBO;
GLDEBUG(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO)); GLDEBUG(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO));
createBuffers(); createBuffers(renderBufferWidth, renderBufferHeight);
KRScene &scene = getScene(); KRScene &scene = getScene();
@@ -254,8 +253,8 @@ void KRCamera::renderFrame(float deltaTime)
// // Disable backface culling // // Disable backface culling
// GLDEBUG(glDisable(GL_CULL_FACE)); // GLDEBUG(glDisable(GL_CULL_FACE));
// //
// // Disable z-buffer write // Disable z-buffer write
// GLDEBUG(glDepthMask(GL_FALSE)); GLDEBUG(glDepthMask(GL_FALSE));
// //
// // Enable z-buffer test // // Enable z-buffer test
// GLDEBUG(glEnable(GL_DEPTH_TEST)); // GLDEBUG(glEnable(GL_DEPTH_TEST));
@@ -397,16 +396,7 @@ void KRCamera::renderFrame(float deltaTime)
} }
void KRCamera::createBuffers() { void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) {
GLint renderBufferWidth = 0, renderBufferHeight = 0;
#if TARGET_OS_IPHONE
GLDEBUG(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderBufferWidth));
GLDEBUG(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderBufferHeight));
#else
renderBufferWidth = 1920; // FINDME - HACK for OSX
renderBufferHeight = 1200;
#endif
if(renderBufferWidth != backingWidth || renderBufferHeight != backingHeight) { if(renderBufferWidth != backingWidth || renderBufferHeight != backingHeight) {
backingWidth = renderBufferWidth; backingWidth = renderBufferWidth;

View File

@@ -53,12 +53,12 @@ public:
KRCamera(KRScene &scene, std::string name); KRCamera(KRScene &scene, std::string name);
virtual ~KRCamera(); virtual ~KRCamera();
void renderFrame(float deltaTime); void renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight);
KRRenderSettings settings; KRRenderSettings settings;
private: private:
void createBuffers(); void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight);
GLint backingWidth, backingHeight; GLint backingWidth, backingHeight;
GLint volumetricBufferWidth, volumetricBufferHeight; GLint volumetricBufferWidth, volumetricBufferHeight;

View File

@@ -65,6 +65,7 @@ typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_F
-(void)setParameterValueWithName: (NSString *)name Value: (float)v; -(void)setParameterValueWithName: (NSString *)name Value: (float)v;
-(int)getParameterIndexWithName: (NSString *)name; -(int)getParameterIndexWithName: (NSString *)name;
- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height;
- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime; - (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime;
- (void)setNearZ: (float)dNearZ; - (void)setNearZ: (float)dNearZ;
- (void)setFarZ: (float)dFarZ; - (void)setFarZ: (float)dFarZ;

View File

@@ -95,9 +95,9 @@ using namespace std;
KRContext::KRENGINE_MAX_VBO_MEM = 256000000; KRContext::KRENGINE_MAX_VBO_MEM = 256000000;
KRContext::KRENGINE_MAX_SHADER_HANDLES = 100; KRContext::KRENGINE_MAX_SHADER_HANDLES = 100;
KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_MEM = 256000000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 192000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 96000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 256000000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000;
@@ -164,13 +164,21 @@ using namespace std;
return self; return self;
} }
- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime - (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime AndWidth: (int)width AndHeight: (int)height
{ {
KRCamera *camera = pScene->find<KRCamera>(); KRCamera *camera = pScene->find<KRCamera>();
if(camera) { if(camera) {
camera->settings = _settings; camera->settings = _settings;
} }
pScene->renderFrame(deltaTime); pScene->renderFrame(deltaTime, width, height);
}
- (void)renderScene: (KRScene *)pScene WithDeltaTime: (float)deltaTime
{
GLint renderBufferWidth = 0, renderBufferHeight = 0;
GLDEBUG(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderBufferWidth));
GLDEBUG(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderBufferHeight));
[self renderScene:pScene WithDeltaTime:deltaTime AndWidth:renderBufferWidth AndHeight:renderBufferHeight];
} }
- (BOOL)loadShaders - (BOOL)loadShaders
@@ -191,7 +199,7 @@ using namespace std;
NSString * p = nil; NSString * p = nil;
while (p = [bundleEnumerator nextObject]) { while (p = [bundleEnumerator nextObject]) {
NSString *file_name = [p lastPathComponent]; NSString *file_name = [p lastPathComponent];
if([file_name hasSuffix: @".vsh"] || [file_name hasSuffix: @".fsh"] || [file_name hasPrefix:@"font."]) { if([file_name hasSuffix: @".vsh"] || [file_name hasSuffix: @".fsh"] || [file_name hasSuffix: @".krbundle"] ||[file_name hasPrefix:@"font."]) {
NSLog(@" %@\n", file_name); NSLog(@" %@\n", file_name);
[self loadResource:p]; [self loadResource:p];
} }

View File

@@ -98,12 +98,13 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
KRNode::render(pCamera, lights, viewport, renderPass); KRNode::render(pCamera, lights, viewport, renderPass);
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && (renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT || this->hasTransparency()) && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
// Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
loadModel(); loadModel();
if(m_models.size() > 0) { if(m_models.size() > 0) {
// Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
float lod_coverage = getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling float lod_coverage = getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
if(lod_coverage > m_min_lod_coverage) { if(lod_coverage > m_min_lod_coverage) {
@@ -141,14 +142,6 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
} }
} }
bool KRModel::hasTransparency() {
if(m_models.size() > 0) {
return m_models[0]->hasTransparency();
} else {
return false;
}
}
KRAABB KRModel::getBounds() { KRAABB KRModel::getBounds() {
loadModel(); loadModel();
if(m_models.size() > 0) { if(m_models.size() > 0) {

View File

@@ -59,9 +59,6 @@ public:
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass); virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
bool hasTransparency();
virtual KRAABB getBounds(); virtual KRAABB getBounds();
private: private:

View File

@@ -59,7 +59,7 @@ KRScene::~KRScene() {
m_pRootNode = NULL; m_pRootNode = NULL;
} }
void KRScene::renderFrame(float deltaTime) { void KRScene::renderFrame(float deltaTime, int width, int height) {
getContext().startFrame(deltaTime); getContext().startFrame(deltaTime);
KRCamera *camera = find<KRCamera>(); KRCamera *camera = find<KRCamera>();
if(camera == NULL) { if(camera == NULL) {
@@ -67,7 +67,7 @@ void KRScene::renderFrame(float deltaTime) {
camera = new KRCamera(*this, "default_camera"); camera = new KRCamera(*this, "default_camera");
m_pRootNode->addChild(camera); m_pRootNode->addChild(camera);
} }
camera->renderFrame(deltaTime); camera->renderFrame(deltaTime, width, height);
getContext().endFrame(deltaTime); getContext().endFrame(deltaTime);
physicsUpdate(deltaTime); physicsUpdate(deltaTime);
} }

View File

@@ -64,7 +64,7 @@ public:
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask);
bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask);
void renderFrame(float deltaTime); void renderFrame(float deltaTime, int width, int height);
void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame); void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame);
void render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); void render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);

Binary file not shown.