Mercurial > hg > beaglert
changeset 91:241d4d5df929
Double buffered the noise floor project; works without glitches now
author | andrewm |
---|---|
date | Sun, 19 Jul 2015 23:19:27 +0100 |
parents | c74006ef86ca |
children | a55dcdcebdcd |
files | projects/measure_noisefloor/render.cpp |
diffstat | 1 files changed, 62 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/projects/measure_noisefloor/render.cpp Sun Jul 19 16:42:51 2015 +0100 +++ b/projects/measure_noisefloor/render.cpp Sun Jul 19 23:19:27 2015 +0100 @@ -12,19 +12,16 @@ int gBufferSize = 8192; -// Buffers to hold samples for noise analysis -float* gBuffers[10]; -int gBufferPointers[10]; +// Double buffers to hold samples for noise analysis +float *gReadBuffers[10], *gWriteBuffers[10]; +float *gBuffers0[10], *gBuffers1[10]; -// Outputs to display -float gDCLevels[10]; -float gNoiseLevels[10]; -float gNumSamplesAnalysed[10]; +int gWriteBufferPointers[10], gReadBufferPointers[10]; -// Task to print results which would otherwise be too slow for render() -AuxiliaryTask gPrintTask; +// Task to analyse and print results which would otherwise be too slow for render() +AuxiliaryTask gAnalysisTask; -void printResults(); +void analyseResults(); // setup() is called once before the audio rendering starts. // Use it to perform any initialisation and allocation which is dependent @@ -39,15 +36,18 @@ { // Clear the filter data structures for(int i = 0; i < 10; i++) { - gBufferPointers[i] = 0; - gBuffers[i] = new float[gBufferSize]; - if(gBuffers[i] == 0) { + gReadBufferPointers[i] = gWriteBufferPointers[i] = 0; + gBuffers0[i] = new float[gBufferSize]; + gBuffers1[i] = new float[gBufferSize]; + gWriteBuffers[i] = gBuffers0[i]; + gReadBuffers[i] = gBuffers1[i]; + if(gBuffers0[i] == 0 || gBuffers1[i] == 0) { rt_printf("Error allocating buffer %d\n", i); return false; } } - gPrintTask = BeagleRT_createAuxiliaryTask(printResults, 50, "beaglert-print-results"); + gAnalysisTask = BeagleRT_createAuxiliaryTask(analyseResults, 50, "beaglert-analyse-results"); return true; } @@ -64,11 +64,11 @@ for(unsigned int n = 0; n < context->audioFrames; n++) { // Store audio inputs in buffer for(unsigned int ch = 0; ch < context->audioChannels; ch++) { - if(gBufferPointers[ch] < gBufferSize) { - gBuffers[ch][gBufferPointers[ch]] = + if(gWriteBufferPointers[ch] < gBufferSize) { + gWriteBuffers[ch][gWriteBufferPointers[ch]] = context->audioIn[n * context->audioChannels + ch]; - gBufferPointers[ch]++; - if(gBufferPointers[ch] >= gBufferSize) + gWriteBufferPointers[ch]++; + if(gWriteBufferPointers[ch] >= gBufferSize) bufferIsFull = true; } } @@ -78,58 +78,64 @@ for(unsigned int n = 0; n < context->analogFrames; n++) { // Store analog inputs in buffer, starting at channel 2 for(unsigned int ch = 0; ch < context->analogChannels; ch++) { - if(gBufferPointers[ch + 2] < gBufferSize) { - gBuffers[ch + 2][gBufferPointers[ch + 2]] = + if(gWriteBufferPointers[ch + 2] < gBufferSize) { + gWriteBuffers[ch + 2][gWriteBufferPointers[ch + 2]] = context->analogIn[n * context->analogChannels + ch]; - gBufferPointers[ch + 2]++; - if(gBufferPointers[ch + 2] >= gBufferSize) + gWriteBufferPointers[ch + 2]++; + if(gWriteBufferPointers[ch + 2] >= gBufferSize) bufferIsFull = true; } + + // Set all analog outputs to halfway point so they can be more + // easily measured for noise + context->analogOut[n * context->analogChannels + ch] = 0.5; } } } + if(bufferIsFull) { - // Analyse all active channels at once + // Swap buffers and reset write pointers for(int ch = 0; ch < 10; ch++) { - // gBufferPointers[ch] tells us how many samples were stored in the buffer - gNumSamplesAnalysed[ch] = gBufferPointers[ch]; + gReadBufferPointers[ch] = gWriteBufferPointers[ch]; + gWriteBufferPointers[ch] = 0; - if(gBufferPointers[ch] != 0) { - float mean = 0; - for(int n = 0; n < gBufferPointers[ch]; n++) { - mean += gBuffers[ch][n]; - } - mean /= (float)gBufferPointers[ch]; - - float rms = 0; - for(int n = 0; n < gBufferPointers[ch]; n++) { - rms += (gBuffers[ch][n] - mean) * (gBuffers[ch][n] - mean); - } - rms = sqrtf(rms / (float)gBufferPointers[ch]); - - gDCLevels[ch] = mean; - gNoiseLevels[ch] = rms; + if(gReadBuffers[ch] == gBuffers0[ch]) { + gReadBuffers[ch] = gBuffers1[ch]; + gWriteBuffers[ch] = gBuffers0[ch]; } - - // Reset pointer to 0 for next time - gBufferPointers[ch] = 0; + else { + gReadBuffers[ch] = gBuffers0[ch]; + gWriteBuffers[ch] = gBuffers1[ch]; + } } - BeagleRT_scheduleAuxiliaryTask(gPrintTask); + BeagleRT_scheduleAuxiliaryTask(gAnalysisTask); } } -void printResults() +void analyseResults() { rt_printf("\e[1;1H\e[2J"); // Command to clear the screen - + // Print the analysis results. channels 0-1 are audio, channels 2-9 are analog for(int ch = 0; ch < 10; ch++) { - int samples = gNumSamplesAnalysed[ch]; - if(samples == 0) + // Skip unused channels + if(gReadBufferPointers[ch] == 0) continue; + float mean = 0; + for(int n = 0; n < gReadBufferPointers[ch]; n++) { + mean += gReadBuffers[ch][n]; + } + mean /= (float)gReadBufferPointers[ch]; + + float rms = 0; + for(int n = 0; n < gReadBufferPointers[ch]; n++) { + rms += (gReadBuffers[ch][n] - mean) * (gReadBuffers[ch][n] - mean); + } + rms = sqrtf(rms / (float)gReadBufferPointers[ch]); + if(ch == 0) rt_printf("Audio In L: "); else if(ch == 1) @@ -138,10 +144,10 @@ rt_printf("Analog In %d: ", ch - 2); rt_printf("Noise %6.1fdB DC offset %6.4f (%6.1fdB) window size: %d\n", - 20.0f * log10f(gNoiseLevels[ch]), - gDCLevels[ch], - 20.0f * log10f(fabsf(gDCLevels[ch])), - samples); + 20.0f * log10f(rms), + mean, + 20.0f * log10f(fabsf(mean)), + gReadBufferPointers[ch]); } } @@ -150,6 +156,8 @@ void cleanup(BeagleRTContext *context, void *userData) { - for(int i = 0; i < 10; i++) - delete gBuffers[i]; + for(int i = 0; i < 10; i++) { + delete gBuffers0[i]; + delete gBuffers1[i]; + } }