giuliomoro@94
|
1 #include <BeagleRT.h>
|
giuliomoro@112
|
2 #include <NetworkSend.h>
|
giuliomoro@117
|
3 #include <ReceiveAudioThread.h>
|
giuliomoro@132
|
4 #include <ClockSynchronizer.h>
|
giuliomoro@94
|
5 #include <cmath>
|
giuliomoro@135
|
6 #include <ClockSyncThread.h>
|
giuliomoro@94
|
7
|
giuliomoro@94
|
8 float gPhase1, gPhase2;
|
giuliomoro@94
|
9 float gFrequency1, gFrequency2;
|
giuliomoro@94
|
10 float gInverseSampleRate;
|
giuliomoro@94
|
11
|
giuliomoro@128
|
12 //Scope scope(2); //create a scope object with 2 channels
|
giuliomoro@135
|
13 //NetworkSend networkSend;
|
giuliomoro@94
|
14
|
giuliomoro@94
|
15 // initialise_render() is called once before the audio rendering starts.
|
giuliomoro@94
|
16 // Use it to perform any initialisation and allocation which is dependent
|
giuliomoro@94
|
17 // on the period size or sample rate.
|
giuliomoro@94
|
18 //
|
giuliomoro@94
|
19 // userData holds an opaque pointer to a data structure that was passed
|
giuliomoro@94
|
20 // in from the call to initAudio().
|
giuliomoro@94
|
21 //
|
giuliomoro@94
|
22 // Return true on success; returning false halts the program.
|
giuliomoro@135
|
23 //ReceiveAudioThread receiveAudio0;
|
giuliomoro@128
|
24 //ReceiveAudioThread receiveAudio1;
|
giuliomoro@132
|
25 ClockSynchronizer clockSynchronizer;
|
giuliomoro@132
|
26 extern I2c_Codec* gAudioCodec;
|
giuliomoro@135
|
27 VirtualClock virtualClock;
|
giuliomoro@135
|
28 ClockSyncThread clockSyncThread;
|
giuliomoro@94
|
29 bool setup(BeagleRTContext *context, void *userData)
|
giuliomoro@94
|
30 {
|
giuliomoro@135
|
31 // receiveAudio0.init(10000, context->audioFrames, 0);
|
giuliomoro@128
|
32 // receiveAudio1.init(10000, context->audioFrames, 1);
|
giuliomoro@131
|
33
|
giuliomoro@128
|
34 // scope.setup(); //call this once in setup to initialise the scope
|
giuliomoro@128
|
35 // scope.setPort(0, 9999);
|
giuliomoro@128
|
36 // scope.setPort(1, 10000);
|
giuliomoro@135
|
37 // networkSend.setup(context->audioSampleRate, context->audioFrames, 0, 9999, "192.168.7.1");
|
giuliomoro@132
|
38 clockSynchronizer.setup();
|
giuliomoro@135
|
39 virtualClock.init();
|
giuliomoro@135
|
40 clockSyncThread.init(true, 5000, virtualClock); //start as slave
|
giuliomoro@94
|
41 gInverseSampleRate = 1.0/context->audioSampleRate;
|
giuliomoro@94
|
42
|
giuliomoro@94
|
43 gPhase1 = 0.0;
|
giuliomoro@94
|
44 gPhase2 = 0.0;
|
giuliomoro@94
|
45
|
giuliomoro@94
|
46 gFrequency1 = 200.0;
|
giuliomoro@94
|
47 gFrequency2 = 201.0;
|
giuliomoro@111
|
48
|
giuliomoro@94
|
49 return true;
|
giuliomoro@94
|
50 }
|
giuliomoro@94
|
51
|
giuliomoro@94
|
52 // render() is called regularly at the highest priority by the audio engine.
|
giuliomoro@94
|
53 // Input and output are given from the audio hardware and the other
|
giuliomoro@94
|
54 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
|
giuliomoro@94
|
55 // will be 0.
|
giuliomoro@94
|
56
|
giuliomoro@94
|
57 void render(BeagleRTContext *context, void *userData)
|
giuliomoro@94
|
58 {
|
giuliomoro@135
|
59 virtualClock.sync(context->audioFrames);
|
giuliomoro@109
|
60 static int count=0;
|
giuliomoro@135
|
61 if(count==0)
|
giuliomoro@135
|
62 clockSyncThread.startThread();
|
giuliomoro@135
|
63 static float phase=0;
|
giuliomoro@135
|
64 float phaseInc=200.0/44100.0*2*M_PI;
|
giuliomoro@135
|
65 // rt_printf("phaseInc: %f, phase: %f\n",phaseInc,phase);
|
giuliomoro@135
|
66 for(unsigned int n=0; n<context->audioFrames; n++){
|
giuliomoro@135
|
67 context->audioOut[n*2]=sinf(phaseInc);//context->audioIn[n*2];
|
giuliomoro@135
|
68 context->audioOut[n*2+1]=sinf(phaseInc);//context->audioIn[n*2];
|
giuliomoro@135
|
69 phase+=200.0/44100.0*2*M_PI;
|
giuliomoro@135
|
70 if(phase>=2*M_PI)
|
giuliomoro@135
|
71 phase-=2*M_PI;
|
giuliomoro@135
|
72 // context->audioOut[n*2+1]=rand()/(float)RAND_MAX;context->audioIn[n*2];
|
giuliomoro@135
|
73 }
|
giuliomoro@135
|
74 count++;
|
giuliomoro@135
|
75 /*
|
giuliomoro@132
|
76 // if((count&262143)==0){
|
giuliomoro@132
|
77 // static int nextCall=160000;
|
giuliomoro@135
|
78 if( ((count&(2047))==0)){
|
giuliomoro@132
|
79 // rt_printf("b %d\n", count);
|
giuliomoro@132
|
80 clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
|
giuliomoro@132
|
81 // nextCall=count+100000;
|
giuliomoro@132
|
82 // rt_printf("a %d\n", count);
|
giuliomoro@132
|
83 }
|
giuliomoro@132
|
84 // if(count == nextCall){
|
giuliomoro@132
|
85 // clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
|
giuliomoro@132
|
86 // }
|
giuliomoro@131
|
87 if(count==0){
|
giuliomoro@135
|
88 gAudioCodec->setAudioSamplingRate( 44100);
|
giuliomoro@133
|
89 rt_printf("startHread\n");
|
giuliomoro@131
|
90 ReceiveAudioThread::startThread();
|
giuliomoro@131
|
91 }
|
giuliomoro@94
|
92 for(unsigned int n = 0; n < context->audioFrames; n++) {
|
giuliomoro@94
|
93
|
giuliomoro@111
|
94 float chn0 = sinf(gPhase1);
|
giuliomoro@131
|
95 // float chn1 = sinf(gPhase2);
|
giuliomoro@111
|
96
|
giuliomoro@118
|
97 // float chn2 = context->audioIn[n*2 + 0];
|
giuliomoro@118
|
98 // float chn3 = context->audioIn[n*2 + 1];
|
giuliomoro@111
|
99
|
giuliomoro@118
|
100 // float chn4 = context->analogIn[(int)n/2*8 + 0];
|
giuliomoro@118
|
101 // float chn5 = context->analogIn[(int)n/2*8 + 1];
|
giuliomoro@132
|
102 // networkSend.log(context->audioIn[n]);
|
giuliomoro@132
|
103 networkSend.log(chn0);
|
giuliomoro@131
|
104 // scope.log(0, chn0);
|
giuliomoro@131
|
105 // scope.log(1, chn1);
|
giuliomoro@118
|
106 // scope.log(2, chn2);
|
giuliomoro@118
|
107 // scope.log(3, chn3);
|
giuliomoro@118
|
108 // scope.log(4, chn4);
|
giuliomoro@118
|
109 // scope.log(5, chn5);
|
giuliomoro@94
|
110
|
giuliomoro@94
|
111 // scope.log(chn1, chn2, chn3, chn4, chn5, chn6);
|
giuliomoro@94
|
112 //call this once every audio frame
|
giuliomoro@94
|
113 //takes six or fewer floats as parameters
|
giuliomoro@94
|
114 //first parameter becomes channel 1 etc
|
giuliomoro@94
|
115 //to view, click the 'oscilloscope' button on the toolbar while BeagleRT is NOT running
|
giuliomoro@94
|
116 //then click the big red button on the toolbar on this page
|
giuliomoro@94
|
117
|
giuliomoro@132
|
118 gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate * ((count&65535)/65535.0+1);
|
giuliomoro@118
|
119 gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate;
|
giuliomoro@94
|
120 if(gPhase1 > 2.0 * M_PI)
|
giuliomoro@94
|
121 gPhase1 -= 2.0 * M_PI;
|
giuliomoro@94
|
122 if(gPhase2 > 2.0 * M_PI)
|
giuliomoro@94
|
123 gPhase2 -= 2.0 * M_PI;
|
giuliomoro@135
|
124 int value=count%1000;
|
giuliomoro@135
|
125 context->audioOut[n*2]=value>=500 ? 1 : -1;
|
giuliomoro@135
|
126 context->audioOut[n*2+1]=context->audioOut[n*2];
|
giuliomoro@132
|
127 count++;
|
giuliomoro@94
|
128 }
|
giuliomoro@118
|
129 if(count>0){
|
giuliomoro@131
|
130 float samplingRateRatio=1;
|
giuliomoro@131
|
131 int channelsInDestinationBuffer=2;
|
giuliomoro@135
|
132 int channelToWriteTo=1;
|
giuliomoro@131
|
133 int length=receiveAudio0.getSamplesSrc(context->audioOut, context->audioFrames,
|
giuliomoro@131
|
134 samplingRateRatio, channelsInDestinationBuffer, channelToWriteTo);
|
giuliomoro@132
|
135 if((unsigned int)length!=context->audioFrames){
|
giuliomoro@131
|
136 rt_printf("Length mismatch: %d\n", length);
|
giuliomoro@131
|
137 }
|
giuliomoro@128
|
138 // int readPointer1=receiveAudio1.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 1);
|
giuliomoro@119
|
139 }
|
giuliomoro@132
|
140 for(unsigned int n=0; n<context->audioFrames; n++){
|
giuliomoro@135
|
141 // context->audioOut[n*2+1]=context->audioOut[n*2];
|
giuliomoro@131
|
142 }
|
giuliomoro@135
|
143 */
|
giuliomoro@135
|
144
|
giuliomoro@94
|
145 }
|
giuliomoro@94
|
146
|
giuliomoro@94
|
147 // cleanup_render() is called once at the end, after the audio has stopped.
|
giuliomoro@94
|
148 // Release any resources that were allocated in initialise_render().
|
giuliomoro@94
|
149
|
giuliomoro@94
|
150 void cleanup(BeagleRTContext *context, void *userData)
|
giuliomoro@94
|
151 {
|
giuliomoro@94
|
152
|
giuliomoro@94
|
153 }
|