annotate projects/cape_test/render.cpp @ 269:ac8eb07afcf5

Oxygen text added to each render.cpp file for the default projects. Text includes project explanation from Wiki, edited in places. Empty project added as a default project. Doxyfile updated. Each of the project locations added to INPUT configuration option. Consider just watching the whole project file so all new projects are automatically pulled through.
author Robert Jack <robert.h.jack@gmail.com>
date Tue, 17 May 2016 15:40:16 +0100
parents 3c3a1357657d
children 8d80eda512cd
rev   line source
andrewm@55 1 /*
andrewm@55 2 * render.cpp
andrewm@55 3 *
andrewm@55 4 * Created on: Oct 24, 2014
andrewm@55 5 * Author: parallels
andrewm@55 6 */
andrewm@55 7
andrewm@55 8
andrewm@56 9 #include <BeagleRT.h>
andrewm@55 10 #include <cmath>
andrewm@55 11
andrewm@55 12 #define ANALOG_LOW (2048.0 / 65536.0)
andrewm@55 13 #define ANALOG_HIGH (50000.0 / 65536.0)
andrewm@55 14
andrewm@55 15 const int gDACPinOrder[] = {6, 4, 2, 0, 1, 3, 5, 7};
andrewm@55 16
andrewm@55 17 uint64_t gLastErrorFrame = 0;
andrewm@55 18 uint32_t gEnvelopeSampleCount = 0;
andrewm@55 19 float gEnvelopeValue = 0.5;
andrewm@55 20 float gEnvelopeDecayRate = 0.9995;
andrewm@55 21
andrewm@56 22 // setup() is called once before the audio rendering starts.
andrewm@55 23 // Use it to perform any initialisation and allocation which is dependent
andrewm@55 24 // on the period size or sample rate.
andrewm@55 25 //
andrewm@55 26 // userData holds an opaque pointer to a data structure that was passed
andrewm@55 27 // in from the call to initAudio().
andrewm@55 28 //
andrewm@55 29 // Return true on success; returning false halts the program.
andrewm@55 30
andrewm@56 31 bool setup(BeagleRTContext *context, void *userData)
andrewm@55 32 {
andrewm@55 33 return true;
andrewm@55 34 }
andrewm@55 35
andrewm@55 36 // render() is called regularly at the highest priority by the audio engine.
andrewm@55 37 // Input and output are given from the audio hardware and the other
andrewm@55 38 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
andrewm@55 39 // will be 0.
andrewm@55 40
andrewm@55 41 void render(BeagleRTContext *context, void *userData)
andrewm@55 42 {
andrewm@55 43 static float phase = 0.0;
andrewm@55 44 static int sampleCounter = 0;
andrewm@55 45 static int invertChannel = 0;
andrewm@55 46 float frequency = 0;
andrewm@55 47
andrewm@55 48 // Play a sine wave on the audio output
andrewm@55 49 for(unsigned int n = 0; n < context->audioFrames; n++) {
andrewm@55 50 context->audioOut[2*n] = context->audioOut[2*n + 1] = gEnvelopeValue * sinf(phase);
andrewm@55 51
andrewm@55 52 // If one second has gone by with no error, play one sound, else
andrewm@55 53 // play another
andrewm@55 54 if(context->audioSampleCount + n - gLastErrorFrame > 44100) {
andrewm@55 55 gEnvelopeValue *= gEnvelopeDecayRate;
andrewm@55 56 gEnvelopeSampleCount++;
andrewm@55 57 if(gEnvelopeSampleCount > 22050) {
andrewm@55 58 gEnvelopeValue = 0.5;
andrewm@55 59 gEnvelopeSampleCount = 0;
andrewm@55 60 }
andrewm@55 61 frequency = 880.0;
andrewm@55 62 }
andrewm@55 63 else {
andrewm@55 64 gEnvelopeValue = 0.5;
andrewm@55 65 frequency = 220.0;
andrewm@55 66 }
andrewm@55 67
andrewm@55 68 phase += 2.0 * M_PI * frequency / 44100.0;
andrewm@55 69 if(phase >= 2.0 * M_PI)
andrewm@55 70 phase -= 2.0 * M_PI;
andrewm@55 71 }
andrewm@55 72
andrewm@55 73 for(unsigned int n = 0; n < context->analogFrames; n++) {
andrewm@55 74 // Change outputs every 512 samples
andrewm@55 75 if(sampleCounter < 512) {
andrewm@55 76 for(int k = 0; k < 8; k++) {
andrewm@55 77 if(k == invertChannel)
andrewm@55 78 context->analogOut[n*8 + gDACPinOrder[k]] = ANALOG_HIGH;
andrewm@55 79 else
andrewm@55 80 context->analogOut[n*8 + gDACPinOrder[k]] = 0;
andrewm@55 81 }
andrewm@55 82 }
andrewm@55 83 else {
andrewm@55 84 for(int k = 0; k < 8; k++) {
andrewm@55 85 if(k == invertChannel)
andrewm@55 86 context->analogOut[n*8 + gDACPinOrder[k]] = 0;
andrewm@55 87 else
andrewm@55 88 context->analogOut[n*8 + gDACPinOrder[k]] = ANALOG_HIGH;
andrewm@55 89 }
andrewm@55 90 }
andrewm@55 91
andrewm@55 92 // Read after 256 samples: input should be low
andrewm@55 93 if(sampleCounter == 256) {
andrewm@55 94 for(int k = 0; k < 8; k++) {
andrewm@55 95 if(k == invertChannel) {
andrewm@55 96 if(context->analogIn[n*8 + k] < ANALOG_HIGH) {
andrewm@55 97 rt_printf("FAIL [output %d, input %d] -- output HIGH input %f (inverted)\n", gDACPinOrder[k], k, context->analogIn[n*8 + k]);
andrewm@55 98 gLastErrorFrame = context->audioSampleCount + n;
andrewm@55 99 }
andrewm@55 100 }
andrewm@55 101 else {
andrewm@55 102 if(context->analogIn[n*8 + k] > ANALOG_LOW) {
andrewm@55 103 rt_printf("FAIL [output %d, input %d] -- output LOW --> input %f\n", gDACPinOrder[k], k, context->analogIn[n*8 + k]);
andrewm@55 104 gLastErrorFrame = context->audioSampleCount + n;
andrewm@55 105 }
andrewm@55 106 }
andrewm@55 107 }
andrewm@55 108 }
andrewm@55 109 else if(sampleCounter == 768) {
andrewm@55 110 for(int k = 0; k < 8; k++) {
andrewm@55 111 if(k == invertChannel) {
andrewm@55 112 if(context->analogIn[n*8 + k] > ANALOG_LOW) {
andrewm@55 113 rt_printf("FAIL [output %d, input %d] -- output LOW input %f (inverted)\n", gDACPinOrder[k], k, context->analogIn[n*8 + k]);
andrewm@55 114 gLastErrorFrame = context->audioSampleCount + n;
andrewm@55 115 }
andrewm@55 116 }
andrewm@55 117 else {
andrewm@55 118 if(context->analogIn[n*8 + k] < ANALOG_HIGH) {
andrewm@55 119 rt_printf("FAIL [output %d, input %d] -- output HIGH input %f\n", gDACPinOrder[k], k, context->analogIn[n*8 + k]);
andrewm@55 120 gLastErrorFrame = context->audioSampleCount + n;
andrewm@55 121 }
andrewm@55 122 }
andrewm@55 123 }
andrewm@55 124 }
andrewm@55 125
andrewm@55 126 if(++sampleCounter >= 1024) {
andrewm@55 127 sampleCounter = 0;
andrewm@55 128 invertChannel++;
andrewm@55 129 if(invertChannel >= 8)
andrewm@55 130 invertChannel = 0;
andrewm@55 131 }
andrewm@55 132 }
andrewm@55 133 }
andrewm@55 134
andrewm@56 135 // cleanup() is called once at the end, after the audio has stopped.
andrewm@56 136 // Release any resources that were allocated in setup().
andrewm@55 137
andrewm@56 138 void cleanup(BeagleRTContext *context, void *userData)
andrewm@55 139 {
andrewm@55 140
andrewm@55 141 }