annotate examples/measure_noisefloor/render.cpp @ 380:9dc5a0ccad25 prerelease

Fixed missing ) in Makefile, and removed unnecessary Utilities.h includes
author andrewm
date Sun, 12 Jun 2016 23:03:57 +0100
parents 421a69d42943
children
rev   line source
andrewm@89 1 /*
andrewm@89 2 * render.cpp
andrewm@89 3 *
andrewm@89 4 * Created on: Oct 24, 2014
andrewm@89 5 * Author: parallels
andrewm@89 6 */
andrewm@89 7
andrewm@89 8
giuliomoro@301 9 #include <Bela.h>
andrewm@89 10 #include <cmath>
andrewm@89 11
andrewm@89 12 int gBufferSize = 8192;
andrewm@89 13
andrewm@91 14 // Double buffers to hold samples for noise analysis
andrewm@91 15 float *gReadBuffers[10], *gWriteBuffers[10];
andrewm@91 16 float *gBuffers0[10], *gBuffers1[10];
andrewm@89 17
andrewm@91 18 int gWriteBufferPointers[10], gReadBufferPointers[10];
andrewm@89 19
andrewm@91 20 // Task to analyse and print results which would otherwise be too slow for render()
andrewm@91 21 AuxiliaryTask gAnalysisTask;
andrewm@89 22
andrewm@91 23 void analyseResults();
andrewm@89 24
andrewm@89 25 // setup() is called once before the audio rendering starts.
andrewm@89 26 // Use it to perform any initialisation and allocation which is dependent
andrewm@89 27 // on the period size or sample rate.
andrewm@89 28 //
andrewm@89 29 // userData holds an opaque pointer to a data structure that was passed
andrewm@89 30 // in from the call to initAudio().
andrewm@89 31 //
andrewm@89 32 // Return true on success; returning false halts the program.
andrewm@89 33
giuliomoro@301 34 bool setup(BelaContext *context, void *userData)
andrewm@89 35 {
andrewm@89 36 // Clear the filter data structures
andrewm@89 37 for(int i = 0; i < 10; i++) {
andrewm@91 38 gReadBufferPointers[i] = gWriteBufferPointers[i] = 0;
andrewm@91 39 gBuffers0[i] = new float[gBufferSize];
andrewm@91 40 gBuffers1[i] = new float[gBufferSize];
andrewm@91 41 gWriteBuffers[i] = gBuffers0[i];
andrewm@91 42 gReadBuffers[i] = gBuffers1[i];
andrewm@91 43 if(gBuffers0[i] == 0 || gBuffers1[i] == 0) {
andrewm@89 44 rt_printf("Error allocating buffer %d\n", i);
andrewm@89 45 return false;
andrewm@89 46 }
andrewm@89 47 }
andrewm@89 48
andrewm@303 49 gAnalysisTask = Bela_createAuxiliaryTask(analyseResults, 50, "bela-analyse-results");
andrewm@89 50
andrewm@89 51 return true;
andrewm@89 52 }
andrewm@89 53
andrewm@89 54 // render() is called regularly at the highest priority by the audio engine.
andrewm@89 55 // Input and output are given from the audio hardware and the other
andrewm@89 56 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
andrewm@89 57 // will be 0.
andrewm@89 58
giuliomoro@301 59 void render(BelaContext *context, void *userData)
andrewm@89 60 {
andrewm@89 61 bool bufferIsFull = false; // Whether at least one buffer has filled
andrewm@89 62
andrewm@89 63 for(unsigned int n = 0; n < context->audioFrames; n++) {
andrewm@89 64 // Store audio inputs in buffer
andrewm@89 65 for(unsigned int ch = 0; ch < context->audioChannels; ch++) {
andrewm@91 66 if(gWriteBufferPointers[ch] < gBufferSize) {
andrewm@91 67 gWriteBuffers[ch][gWriteBufferPointers[ch]] =
andrewm@89 68 context->audioIn[n * context->audioChannels + ch];
andrewm@91 69 gWriteBufferPointers[ch]++;
andrewm@91 70 if(gWriteBufferPointers[ch] >= gBufferSize)
andrewm@89 71 bufferIsFull = true;
andrewm@89 72 }
andrewm@89 73 }
andrewm@89 74 }
andrewm@89 75
andrewm@89 76 if(context->analogChannels != 0) {
andrewm@89 77 for(unsigned int n = 0; n < context->analogFrames; n++) {
andrewm@89 78 // Store analog inputs in buffer, starting at channel 2
andrewm@89 79 for(unsigned int ch = 0; ch < context->analogChannels; ch++) {
andrewm@91 80 if(gWriteBufferPointers[ch + 2] < gBufferSize) {
andrewm@91 81 gWriteBuffers[ch + 2][gWriteBufferPointers[ch + 2]] =
andrewm@89 82 context->analogIn[n * context->analogChannels + ch];
andrewm@91 83 gWriteBufferPointers[ch + 2]++;
andrewm@91 84 if(gWriteBufferPointers[ch + 2] >= gBufferSize)
andrewm@89 85 bufferIsFull = true;
andrewm@89 86 }
andrewm@91 87
andrewm@91 88 // Set all analog outputs to halfway point so they can be more
andrewm@91 89 // easily measured for noise
andrewm@91 90 context->analogOut[n * context->analogChannels + ch] = 0.5;
andrewm@89 91 }
andrewm@89 92 }
andrewm@89 93 }
andrewm@91 94
andrewm@89 95
andrewm@89 96 if(bufferIsFull) {
andrewm@91 97 // Swap buffers and reset write pointers
andrewm@89 98 for(int ch = 0; ch < 10; ch++) {
andrewm@91 99 gReadBufferPointers[ch] = gWriteBufferPointers[ch];
andrewm@91 100 gWriteBufferPointers[ch] = 0;
andrewm@89 101
andrewm@91 102 if(gReadBuffers[ch] == gBuffers0[ch]) {
andrewm@91 103 gReadBuffers[ch] = gBuffers1[ch];
andrewm@91 104 gWriteBuffers[ch] = gBuffers0[ch];
andrewm@89 105 }
andrewm@91 106 else {
andrewm@91 107 gReadBuffers[ch] = gBuffers0[ch];
andrewm@91 108 gWriteBuffers[ch] = gBuffers1[ch];
andrewm@91 109 }
andrewm@89 110 }
andrewm@89 111
giuliomoro@301 112 Bela_scheduleAuxiliaryTask(gAnalysisTask);
andrewm@89 113 }
andrewm@89 114 }
andrewm@89 115
andrewm@91 116 void analyseResults()
andrewm@89 117 {
andrewm@89 118 rt_printf("\e[1;1H\e[2J"); // Command to clear the screen
andrewm@91 119
andrewm@89 120 // Print the analysis results. channels 0-1 are audio, channels 2-9 are analog
andrewm@89 121 for(int ch = 0; ch < 10; ch++) {
andrewm@91 122 // Skip unused channels
andrewm@91 123 if(gReadBufferPointers[ch] == 0)
andrewm@89 124 continue;
andrewm@89 125
andrewm@91 126 float mean = 0;
andrewm@91 127 for(int n = 0; n < gReadBufferPointers[ch]; n++) {
andrewm@91 128 mean += gReadBuffers[ch][n];
andrewm@91 129 }
andrewm@91 130 mean /= (float)gReadBufferPointers[ch];
andrewm@91 131
andrewm@91 132 float rms = 0;
andrewm@91 133 for(int n = 0; n < gReadBufferPointers[ch]; n++) {
andrewm@91 134 rms += (gReadBuffers[ch][n] - mean) * (gReadBuffers[ch][n] - mean);
andrewm@91 135 }
andrewm@91 136 rms = sqrtf(rms / (float)gReadBufferPointers[ch]);
andrewm@91 137
andrewm@89 138 if(ch == 0)
andrewm@89 139 rt_printf("Audio In L: ");
andrewm@89 140 else if(ch == 1)
andrewm@89 141 rt_printf("Audio In R: ");
andrewm@89 142 else
andrewm@89 143 rt_printf("Analog In %d: ", ch - 2);
andrewm@89 144
andrewm@89 145 rt_printf("Noise %6.1fdB DC offset %6.4f (%6.1fdB) window size: %d\n",
andrewm@91 146 20.0f * log10f(rms),
andrewm@91 147 mean,
andrewm@91 148 20.0f * log10f(fabsf(mean)),
andrewm@91 149 gReadBufferPointers[ch]);
andrewm@89 150 }
andrewm@89 151 }
andrewm@89 152
andrewm@89 153 // cleanup() is called once at the end, after the audio has stopped.
andrewm@89 154 // Release any resources that were allocated in setup().
andrewm@89 155
giuliomoro@301 156 void cleanup(BelaContext *context, void *userData)
andrewm@89 157 {
andrewm@91 158 for(int i = 0; i < 10; i++) {
andrewm@91 159 delete gBuffers0[i];
andrewm@91 160 delete gBuffers1[i];
andrewm@91 161 }
andrewm@89 162 }