Merge
--HG-- branch : nfb
This commit is contained in:
@@ -406,6 +406,9 @@ void KRAudioManager::renderBlock()
|
|||||||
|
|
||||||
// ----====---- Render Ambient Sound ----====----
|
// ----====---- Render Ambient Sound ----====----
|
||||||
renderAmbient();
|
renderAmbient();
|
||||||
|
|
||||||
|
// ----====---- Render Ambient Sound ----====----
|
||||||
|
renderLimiter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----====---- Advance audio sources ----====----
|
// ----====---- Advance audio sources ----====----
|
||||||
@@ -1488,7 +1491,19 @@ void KRAudioManager::setGlobalAmbientGain(float gain)
|
|||||||
|
|
||||||
void KRAudioManager::startFrame(float deltaTime)
|
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 ----====----
|
// ----====---- Determine Ambient Zone Contributions ----====----
|
||||||
m_ambient_zone_weights.clear();
|
m_ambient_zone_weights.clear();
|
||||||
@@ -1932,3 +1947,113 @@ void KRAudioManager::renderITD()
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = framesize;
|
||||||
|
|
||||||
|
// (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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,13 +40,28 @@
|
|||||||
#include "KRMat4.h"
|
#include "KRMat4.h"
|
||||||
#include "KRAudioSource.h"
|
#include "KRAudioSource.h"
|
||||||
|
|
||||||
const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32;
|
const int KRENGINE_AUDIO_MAX_POOL_SIZE = 60; //32;
|
||||||
const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024;
|
// 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)
|
||||||
|
// 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_BUFFERS_PER_SOURCE = 3;
|
||||||
|
|
||||||
const int KRENGINE_AUDIO_BLOCK_LENGTH = 128; // 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
|
const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH
|
||||||
|
// 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. 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_MAX_FFT_LOG2 = 15;
|
||||||
const int KRENGINE_REVERB_WORKSPACE_SIZE = 1 << KRENGINE_REVERB_MAX_FFT_LOG2;
|
const int KRENGINE_REVERB_WORKSPACE_SIZE = 1 << KRENGINE_REVERB_MAX_FFT_LOG2;
|
||||||
@@ -128,6 +143,7 @@ public:
|
|||||||
|
|
||||||
KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index);
|
KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index);
|
||||||
|
|
||||||
|
static void mute(bool onNotOff);
|
||||||
|
|
||||||
void startFrame(float deltaTime);
|
void startFrame(float deltaTime);
|
||||||
|
|
||||||
@@ -216,6 +232,7 @@ private:
|
|||||||
void renderHRTF();
|
void renderHRTF();
|
||||||
void renderITD();
|
void renderITD();
|
||||||
void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2);
|
void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2);
|
||||||
|
void renderLimiter();
|
||||||
|
|
||||||
std::vector<KRVector2> m_hrtf_sample_locations;
|
std::vector<KRVector2> m_hrtf_sample_locations;
|
||||||
float *m_hrtf_data;
|
float *m_hrtf_data;
|
||||||
|
|||||||
@@ -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
|
// Resize active textures to balance the memory usage and mipmap levels
|
||||||
for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
|
for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
|
||||||
KRTexture *activeTexture = *itr;
|
KRTexture *activeTexture = *itr;
|
||||||
|
|||||||
Reference in New Issue
Block a user