comparison projects/cape_test/render.cpp @ 55:41d24dba6b74 newapi

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