From 516115f4d54349ee3c2eed3e32fcda7e8b81c68e Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Mon, 13 Jan 2014 11:54:21 -0800 Subject: [PATCH 1/9] Updated the constants defined for the audio block size --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index 2c14c92..c2bff56 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -44,12 +44,15 @@ const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32; const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; const int KRENGINE_AUDIO_BUFFERS_PER_SOURCE = 3; -const int KRENGINE_AUDIO_BLOCK_LENGTH = 1024; // Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution +const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH + // 7 is 128, 8 -> 256, 9 -> 512, 10 -> 1024 (the size of the hardware (AUgraph) framebuffer) + // NOTE: the hrtf code use magic numbers everywhere and is hardcoded to 128 samples per frame + +const int KRENGINE_AUDIO_BLOCK_LENGTH = 1 << KRENGINE_AUDIO_BLOCK_LOG2N; + // Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution // the AUGraph works in 1024 sample chunks. If we put a value of less then 1024 in here then we are making mutliple calls to our render functions without any // improvement in latency and our audio render perfomance goes down significantly -const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH - const int KRENGINE_REVERB_MAX_FFT_LOG2 = 15; const int KRENGINE_REVERB_WORKSPACE_SIZE = 1 << KRENGINE_REVERB_MAX_FFT_LOG2; From 45b86e8ccb2035235f79888a209899267cbcf76f Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Mon, 13 Jan 2014 15:16:30 -0800 Subject: [PATCH 2/9] Temporary fix to stop the app from crashing when it runs the texture resize routine with a size of 1024 for 2 minutes. Take a look at the FINDME comment. --HG-- branch : nfb --- KREngine/kraken/KRTextureManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 2f554c8..0e02202 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -329,6 +329,10 @@ void KRTextureManager::balanceTextureMemory() } } + if (maxDimActive > 512) maxDimActive = 512; // FINDME - hack to stop the texture resizer from blowing out its brains .. + // when the texture quality goes up to 1024, the app runs for about 2 mins and then + // runs out of memory. + // Resize active textures to balance the memory usage and mipmap levels for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { KRTexture *activeTexture = *itr; From d2f9434e13aafa7501608f0b07d38cfe77664527 Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Mon, 13 Jan 2014 19:03:41 -0800 Subject: [PATCH 3/9] =?UTF-8?q?Peter=E2=80=99s=20experiments=20with=20audi?= =?UTF-8?q?o=20..=20to=20be=20revised?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.cpp | 78 +++++++++++++++++++++++++++--- KREngine/kraken/KRAudioManager.h | 5 +- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index fd7f485..dbd2be4 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -393,11 +393,12 @@ void KRAudioManager::renderBlock() if(m_enable_audio) { // ----====---- Render Direct / HRTF audio ----====---- - if(m_enable_hrtf) { - renderHRTF(); - } else { - renderITD(); - } +// if(m_enable_hrtf) { +// renderHRTF(); +// } else { +// renderITD(); +// } + renderHRTFbypass(); // ----====---- Render Indirect / Reverb channel ----====---- if(m_enable_reverb) { @@ -833,7 +834,7 @@ void KRAudioManager::initHRTF() sample->sample(0, 128, channel, spectral.realp, 1.0f, false); memset(spectral.realp + 128, 0, sizeof(float) * 128); memset(spectral.imagp, 0, sizeof(float) * 256); - vDSP_fft_zip(m_fft_setup[8 - KRENGINE_AUDIO_BLOCK_LOG2N], &spectral, 1, 8, kFFTDirection_Forward); +//**** vDSP_fft_zip(m_fft_setup[8 - KRENGINE_AUDIO_BLOCK_LOG2N], &spectral, 1, 8, kFFTDirection_Forward); m_hrtf_spectral[channel][pos] = spectral; } sample_index++; @@ -1778,6 +1779,71 @@ void KRAudioManager::renderHRTF() } } +void KRAudioManager::renderHRTFbypass() +{ + static float buffer[KRENGINE_AUDIO_BLOCK_LENGTH]; + + bool hack = true; + + unordered_multimap > >::iterator itr=m_mapped_sources.begin(); + while(itr != m_mapped_sources.end()) { + // Get the info for each sound source that should be run through the HRTF algorythm + KRVector2 source_direction = (*itr).first; + KRAudioSource *source = (*itr).second.first; + float gain_anticlick = (*itr).second.second.first; // this is the gain that we have at the start of the buffer + float gain = (*itr).second.second.second; // this is the gain that we want at the end of the buffer + + const char *unique = source->getSample().c_str(); // a unique identifier for a sound source +// printf("%s\n", unique); + + //??? Does the gain need to be stored into gain_anticlick when we are done? or is this done by the sound state update loop? + + source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, buffer, 1.0); + float *input = buffer; + + // Get pointers to the left and right channels of our stereo interleaved output buffer + int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + float *left = m_output_accumulation + output_offset; + float *right = left + 1; + + // panning +// if (hack) printf("Direction vector = %2.3f, %2.3f\n", source_direction.x, source_direction.y); + hack = false; + + // I think that -ve y is left, +ve y is right. + // Do the panning as a linear function since the distance gain is already set + double x = source_direction.x; + double y = source_direction.y; + double r = sqrt(x * x + y * y); + x = x / r; // normalized x + y = y / r; + + float vol_left = (-y + 1.0) / 1.5; if (vol_left < 0.05) vol_left = 0.05; if (vol_left > 1.0) vol_left = 1.0; + float vol_right = (y + 1.0) / 1.5; if (vol_right < 0.05) vol_right = 0.05; if (vol_right > 1.0) vol_right = 1.0; + +// vol_left = 1.0; +// vol_right = 1.0; +// printf("vol left = %2.3f, vol right = %2.3f for %2.3f, %2.3f\n", vol_left, vol_right, x, y); + + // Setup volume curve + float vol_start = gain_anticlick; + float vol_delta = (gain - gain_anticlick) / ((float) KRENGINE_AUDIO_BLOCK_LENGTH); + float mono = 0.0; + + for (long i = 0; i < KRENGINE_AUDIO_BLOCK_LENGTH; i++) { + mono = *input * vol_start; + *left += (mono * vol_left); + *right += (mono * vol_right); + vol_start += vol_delta; + left += 2; + right += 2; + input += 1; + } + + itr++; + } // end of while(itr) +} + void KRAudioManager::renderITD() { // FINDME, TODO - Need Inter-Temperal based phase shifting to support 3-d spatialized audio without headphones diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index c2bff56..6fbbb12 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -44,7 +44,7 @@ const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32; const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; const int KRENGINE_AUDIO_BUFFERS_PER_SOURCE = 3; -const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH +const int KRENGINE_AUDIO_BLOCK_LOG2N = 10; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH // 7 is 128, 8 -> 256, 9 -> 512, 10 -> 1024 (the size of the hardware (AUgraph) framebuffer) // NOTE: the hrtf code use magic numbers everywhere and is hardcoded to 128 samples per frame @@ -218,7 +218,8 @@ private: void renderBlock(); void renderReverb(); void renderAmbient(); - void renderHRTF(); + void renderHRTF(); // render full HRTF + void renderHRTFbypass(); // render gain changes and panning relative to direction, but don't render HRTF void renderITD(); void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2); From dea797a69c09bc557ba98e40499b9a69654bfedf Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Tue, 14 Jan 2014 10:22:42 -0800 Subject: [PATCH 4/9] Removing experimental code --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.cpp | 78 +++--------------------------- KREngine/kraken/KRAudioManager.h | 5 +- 2 files changed, 8 insertions(+), 75 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index dbd2be4..fd7f485 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -393,12 +393,11 @@ void KRAudioManager::renderBlock() if(m_enable_audio) { // ----====---- Render Direct / HRTF audio ----====---- -// if(m_enable_hrtf) { -// renderHRTF(); -// } else { -// renderITD(); -// } - renderHRTFbypass(); + if(m_enable_hrtf) { + renderHRTF(); + } else { + renderITD(); + } // ----====---- Render Indirect / Reverb channel ----====---- if(m_enable_reverb) { @@ -834,7 +833,7 @@ void KRAudioManager::initHRTF() sample->sample(0, 128, channel, spectral.realp, 1.0f, false); memset(spectral.realp + 128, 0, sizeof(float) * 128); memset(spectral.imagp, 0, sizeof(float) * 256); -//**** vDSP_fft_zip(m_fft_setup[8 - KRENGINE_AUDIO_BLOCK_LOG2N], &spectral, 1, 8, kFFTDirection_Forward); + vDSP_fft_zip(m_fft_setup[8 - KRENGINE_AUDIO_BLOCK_LOG2N], &spectral, 1, 8, kFFTDirection_Forward); m_hrtf_spectral[channel][pos] = spectral; } sample_index++; @@ -1779,71 +1778,6 @@ void KRAudioManager::renderHRTF() } } -void KRAudioManager::renderHRTFbypass() -{ - static float buffer[KRENGINE_AUDIO_BLOCK_LENGTH]; - - bool hack = true; - - unordered_multimap > >::iterator itr=m_mapped_sources.begin(); - while(itr != m_mapped_sources.end()) { - // Get the info for each sound source that should be run through the HRTF algorythm - KRVector2 source_direction = (*itr).first; - KRAudioSource *source = (*itr).second.first; - float gain_anticlick = (*itr).second.second.first; // this is the gain that we have at the start of the buffer - float gain = (*itr).second.second.second; // this is the gain that we want at the end of the buffer - - const char *unique = source->getSample().c_str(); // a unique identifier for a sound source -// printf("%s\n", unique); - - //??? Does the gain need to be stored into gain_anticlick when we are done? or is this done by the sound state update loop? - - source->sample(KRENGINE_AUDIO_BLOCK_LENGTH, 0, buffer, 1.0); - float *input = buffer; - - // Get pointers to the left and right channels of our stereo interleaved output buffer - int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); - float *left = m_output_accumulation + output_offset; - float *right = left + 1; - - // panning -// if (hack) printf("Direction vector = %2.3f, %2.3f\n", source_direction.x, source_direction.y); - hack = false; - - // I think that -ve y is left, +ve y is right. - // Do the panning as a linear function since the distance gain is already set - double x = source_direction.x; - double y = source_direction.y; - double r = sqrt(x * x + y * y); - x = x / r; // normalized x - y = y / r; - - float vol_left = (-y + 1.0) / 1.5; if (vol_left < 0.05) vol_left = 0.05; if (vol_left > 1.0) vol_left = 1.0; - float vol_right = (y + 1.0) / 1.5; if (vol_right < 0.05) vol_right = 0.05; if (vol_right > 1.0) vol_right = 1.0; - -// vol_left = 1.0; -// vol_right = 1.0; -// printf("vol left = %2.3f, vol right = %2.3f for %2.3f, %2.3f\n", vol_left, vol_right, x, y); - - // Setup volume curve - float vol_start = gain_anticlick; - float vol_delta = (gain - gain_anticlick) / ((float) KRENGINE_AUDIO_BLOCK_LENGTH); - float mono = 0.0; - - for (long i = 0; i < KRENGINE_AUDIO_BLOCK_LENGTH; i++) { - mono = *input * vol_start; - *left += (mono * vol_left); - *right += (mono * vol_right); - vol_start += vol_delta; - left += 2; - right += 2; - input += 1; - } - - itr++; - } // end of while(itr) -} - void KRAudioManager::renderITD() { // FINDME, TODO - Need Inter-Temperal based phase shifting to support 3-d spatialized audio without headphones diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index 6fbbb12..c2bff56 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -44,7 +44,7 @@ const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32; const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; const int KRENGINE_AUDIO_BUFFERS_PER_SOURCE = 3; -const int KRENGINE_AUDIO_BLOCK_LOG2N = 10; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH +const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH // 7 is 128, 8 -> 256, 9 -> 512, 10 -> 1024 (the size of the hardware (AUgraph) framebuffer) // NOTE: the hrtf code use magic numbers everywhere and is hardcoded to 128 samples per frame @@ -218,8 +218,7 @@ private: void renderBlock(); void renderReverb(); void renderAmbient(); - void renderHRTF(); // render full HRTF - void renderHRTFbypass(); // render gain changes and panning relative to direction, but don't render HRTF + void renderHRTF(); void renderITD(); void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2); From 89f31f00ecbb32ce1d4117e4d11446827d9ff831 Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Tue, 14 Jan 2014 13:32:56 -0800 Subject: [PATCH 5/9] Added limiter and mute methods to KRAudioManager --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.cpp | 115 ++++++++++++++++++++++++++++- KREngine/kraken/KRAudioManager.h | 4 +- 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index fd7f485..8634bba 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -406,6 +406,9 @@ void KRAudioManager::renderBlock() // ----====---- Render Ambient Sound ----====---- renderAmbient(); + + // ----====---- Render Ambient Sound ----====---- + renderLimiter(); } // ----====---- Advance audio sources ----====---- @@ -1931,4 +1934,114 @@ void KRAudioManager::renderITD() */ -} \ No newline at end of file +} + +static bool audioIsMuted = false; +static bool audioShouldBecomeMuted = false; +static bool audioShouldBecomeUnmuted = false; + +void audioLimit_Mute(bool onNotOff) { + if (onNotOff) { + if (audioIsMuted) return; + audioShouldBecomeMuted = true; + audioShouldBecomeUnmuted = false; + } + else { + if (!audioIsMuted) return; + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = true; + } +} + +float audioGetLimitParameters_Stereo(float *buffer, unsigned long framesize, + unsigned long *attack_sample_position, float *peak) +{ + float limitvol = 1.0; + long attack_position = -1; + *peak = 0.0; + float max = 0.0; + float amplitude = 0.0; + + float *src = buffer; + for (unsigned long i = 0; i < framesize * 2; i++) { + amplitude = fabs(*src); src++; + if (amplitude > max) max = amplitude; + if (amplitude > 0.995) if (attack_position < 0) attack_position = (i+1) / 2; + } + if (max > 0.995) limitvol = 0.995 / max; + *peak = max; + + if (attack_position < 0) attack_position = framesize; + *attack_sample_position = (unsigned long) attack_position; + return limitvol; +} // returns the new limit volume, *attack_sample_position tells how fast we need to reach the new limit + +void audioLimit_Stereo(float *stereo_buffer, unsigned long framesize) +{ + static float limit_value = 1.0; + + // (1) get the limiting parameters for the incoming audio data + float previouslimitvol = limit_value; + float peak; + unsigned long attack_sample_position; + + // (1a) check for a mute or unmute state then get the next limit volume + float nextlimitvol = 0.0; + if (audioIsMuted && audioShouldBecomeUnmuted) { audioIsMuted = false; audioShouldBecomeUnmuted = false; } + if (audioShouldBecomeMuted) { audioIsMuted = true; audioShouldBecomeMuted = false; } + if (!audioIsMuted) nextlimitvol = audioGetLimitParameters_Stereo(stereo_buffer, framesize, &attack_sample_position, &peak); + + // (1b) if no limiting is needed then return + if ((1.0 == nextlimitvol) && (1.0 == previouslimitvol)) { return; } // no limiting necessary + + // (2) calculate limiting factors + float deltavol = 0.0; + if (previouslimitvol != nextlimitvol) { + deltavol = (nextlimitvol - previouslimitvol) / (float) attack_sample_position; + } + + // (3) do the limiting + float *src = stereo_buffer; + + if (0.0 == deltavol) { // fixed volume + for (unsigned long i=0; i < framesize; i++) { + *src = *src * nextlimitvol; + src++; + *src = *src * nextlimitvol; + src++; + } + } + else { + for (unsigned long i=0; i < attack_sample_position; i++) { // attack phase + *src = *src * previouslimitvol; + src++; + *src = *src * previouslimitvol; + src++; + previouslimitvol += deltavol; + } + if (nextlimitvol < 1.0) { // plateau phase + for (unsigned long i = attack_sample_position; i < framesize; i++) { + *src = *src * nextlimitvol; + src++; + *src = *src * nextlimitvol; + src++; + } + } + } + + // (4) save our limit level for next time + limit_value = nextlimitvol; +} + +void KRAudioManager::mute(bool onNotOff) +{ + audioLimit_Mute(onNotOff); +} + +void KRAudioManager::renderLimiter() +{ + int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + float *output = m_output_accumulation + output_offset; + unsigned long numframes = KRENGINE_AUDIO_BLOCK_LENGTH; + audioLimit_Stereo(output, numframes); +} diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index c2bff56..a39357c 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -41,7 +41,7 @@ #include "KRAudioSource.h" const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32; -const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; +const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; // this is the buffer for our decoded audio (not the source file data) const int KRENGINE_AUDIO_BUFFERS_PER_SOURCE = 3; const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH @@ -133,6 +133,7 @@ public: KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index); + void mute(bool onNotOff); void startFrame(float deltaTime); @@ -221,6 +222,7 @@ private: void renderHRTF(); void renderITD(); void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2); + void renderLimiter(); std::vector m_hrtf_sample_locations; float *m_hrtf_data; From 62ca3305a64bd8fc02503c520d0ff4f6b2db4284 Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Tue, 14 Jan 2014 14:09:21 -0800 Subject: [PATCH 6/9] Made the audio mute function static (so it can be called from anywhere) --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index a39357c..550eaaf 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -133,7 +133,7 @@ public: KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index); - void mute(bool onNotOff); + static void mute(bool onNotOff); void startFrame(float deltaTime); From edbae68dc5286805f58b1b2b376e9d967ff0fb17 Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Tue, 14 Jan 2014 14:41:54 -0800 Subject: [PATCH 7/9] Little bug fix for the mute/unmute code --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index 8634bba..72aa05b 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -1983,7 +1983,7 @@ void audioLimit_Stereo(float *stereo_buffer, unsigned long framesize) // (1) get the limiting parameters for the incoming audio data float previouslimitvol = limit_value; float peak; - unsigned long attack_sample_position; + unsigned long attack_sample_position = framesize; // (1a) check for a mute or unmute state then get the next limit volume float nextlimitvol = 0.0; From ca1af8dd3e67b774d3a7f3301cba2c30492c06e8 Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Tue, 14 Jan 2014 15:51:32 -0800 Subject: [PATCH 8/9] Changed the buffer constants to decrease the number of drop outs (still needs some work) --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index 550eaaf..132e662 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -40,18 +40,27 @@ #include "KRMat4.h" #include "KRAudioSource.h" -const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32; -const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; // this is the buffer for our decoded audio (not the source file data) +const int KRENGINE_AUDIO_MAX_POOL_SIZE = 40; //32; + // for Circa we play a maximum of 7 mono audio streams at once + cross fading with ambient + // so we could safely say a maximum of 10 streams, which would be 33 buffers + +const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 5120; // in bytes + // this is the buffer for our decoded audio (not the source file data) + // it should be greater then 1152 samples (the size of an mp3 frame in samples) + // so it should be greater then 2304 bytes and also a multiple of 128 samples (to make + // the data flow efficient) but it shouldn't be too large or it will cause + // the render loop to stall out decoding large chunks of mp3 data. + // 2560 bytes would be the smallest size for mono sources, and 5120 would be smallest for stereo. + const int KRENGINE_AUDIO_BUFFERS_PER_SOURCE = 3; const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH - // 7 is 128, 8 -> 256, 9 -> 512, 10 -> 1024 (the size of the hardware (AUgraph) framebuffer) - // NOTE: the hrtf code use magic numbers everywhere and is hardcoded to 128 samples per frame + // 7 is 128 .. NOTE: the hrtf code uses magic numbers everywhere and is hardcoded to 128 samples per frame const int KRENGINE_AUDIO_BLOCK_LENGTH = 1 << KRENGINE_AUDIO_BLOCK_LOG2N; // Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution - // the AUGraph works in 1024 sample chunks. If we put a value of less then 1024 in here then we are making mutliple calls to our render functions without any - // improvement in latency and our audio render perfomance goes down significantly + // the AUGraph works in 1024 sample chunks. At 128 we are making 8 consecutive calls to the renderBlock method for each + // render initiated by the AUGraph. const int KRENGINE_REVERB_MAX_FFT_LOG2 = 15; const int KRENGINE_REVERB_WORKSPACE_SIZE = 1 << KRENGINE_REVERB_MAX_FFT_LOG2; From cae949c2596ce3a6db7aa7a01cdd1be3905b91e5 Mon Sep 17 00:00:00 2001 From: Peter Courtemanche Date: Tue, 14 Jan 2014 19:12:51 -0800 Subject: [PATCH 9/9] AudioManager - increased pool size to reduce dropouts. Change startFrame locks to non-blocking - improves FPS a bit and dropout rate goes down. --HG-- branch : nfb --- KREngine/kraken/KRAudioManager.cpp | 14 +++++++++++++- KREngine/kraken/KRAudioManager.h | 7 ++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index 72aa05b..9f8449a 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -1491,7 +1491,19 @@ void KRAudioManager::setGlobalAmbientGain(float gain) void KRAudioManager::startFrame(float deltaTime) { - m_mutex.lock(); + static unsigned long trackCount = 0; + static unsigned long trackMissed = 0; + trackCount++; + if (trackCount > 200) { +// printf("Missed %ld out of 200 try_lock attempts on audio startFrame\n", trackMissed); + trackCount = 0; + trackMissed = 0; + } + + if (!m_mutex.try_lock()) { + trackMissed++; + return; // if we are rendering audio don't update audio state + } // NOTE: this misses anywhere from 0 to to 30 times out of 200 on the iPad2 // ----====---- Determine Ambient Zone Contributions ----====---- m_ambient_zone_weights.clear(); diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index 132e662..c19697c 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -40,9 +40,10 @@ #include "KRMat4.h" #include "KRAudioSource.h" -const int KRENGINE_AUDIO_MAX_POOL_SIZE = 40; //32; - // for Circa we play a maximum of 7 mono audio streams at once + cross fading with ambient - // so we could safely say a maximum of 10 streams, which would be 33 buffers +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 + // so we could safely say a maximum of 12 or 13 streams, which would be 39 buffers + // do the WAV files for the reverb use the same buffer pool ??? const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 5120; // in bytes // this is the buffer for our decoded audio (not the source file data)