comparison examples/measure_noisefloor/render.cpp @ 300:dbeed520b014 prerelease

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