annotate projects/cape_test/render.cpp @ 151:e9c9404e3d1f ClockSync

Pff partially working. No PID. When setting the audio clock on the bbb to 44098 the master and slave clock keep diverging instead of converging ...
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 22 Sep 2015 04:10:07 +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 }