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@141
|
29 AuxiliaryTask testTime;
|
giuliomoro@141
|
30 void testTimeFunction(){
|
giuliomoro@141
|
31 rt_printf("time=[");
|
giuliomoro@141
|
32 while(!gShouldStop){
|
giuliomoro@141
|
33 rt_task_sleep(50000*1e3);
|
giuliomoro@141
|
34 rt_printf("%f, ", virtualClock.getNow());
|
giuliomoro@141
|
35 rt_printf("%f, ", virtualClock.getPeriod());
|
giuliomoro@141
|
36 rt_task_sleep(20000);
|
giuliomoro@141
|
37 rt_printf("%f,", virtualClock.getNow());
|
giuliomoro@141
|
38 rt_printf("%f\n", virtualClock.getPeriod());
|
giuliomoro@141
|
39 }
|
giuliomoro@141
|
40 rt_printf("];");
|
giuliomoro@141
|
41 }
|
giuliomoro@94
|
42 bool setup(BeagleRTContext *context, void *userData)
|
giuliomoro@94
|
43 {
|
giuliomoro@135
|
44 // receiveAudio0.init(10000, context->audioFrames, 0);
|
giuliomoro@128
|
45 // receiveAudio1.init(10000, context->audioFrames, 1);
|
giuliomoro@131
|
46
|
giuliomoro@128
|
47 // scope.setup(); //call this once in setup to initialise the scope
|
giuliomoro@128
|
48 // scope.setPort(0, 9999);
|
giuliomoro@128
|
49 // scope.setPort(1, 10000);
|
giuliomoro@135
|
50 // networkSend.setup(context->audioSampleRate, context->audioFrames, 0, 9999, "192.168.7.1");
|
giuliomoro@141
|
51 // clockSynchronizer.setup();
|
giuliomoro@149
|
52 virtualClock.init(context->audioFrames / context->audioSampleRate * 1e6);
|
giuliomoro@135
|
53 clockSyncThread.init(true, 5000, virtualClock); //start as slave
|
giuliomoro@94
|
54 gInverseSampleRate = 1.0/context->audioSampleRate;
|
giuliomoro@94
|
55
|
giuliomoro@94
|
56 gPhase1 = 0.0;
|
giuliomoro@94
|
57 gPhase2 = 0.0;
|
giuliomoro@94
|
58
|
giuliomoro@94
|
59 gFrequency1 = 200.0;
|
giuliomoro@94
|
60 gFrequency2 = 201.0;
|
giuliomoro@111
|
61
|
giuliomoro@141
|
62 // testTime=BeagleRT_createAuxiliaryTask(testTimeFunction, 80, "testTimeTask");
|
giuliomoro@94
|
63 return true;
|
giuliomoro@94
|
64 }
|
giuliomoro@94
|
65
|
giuliomoro@94
|
66 // render() is called regularly at the highest priority by the audio engine.
|
giuliomoro@94
|
67 // Input and output are given from the audio hardware and the other
|
giuliomoro@94
|
68 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
|
giuliomoro@94
|
69 // will be 0.
|
giuliomoro@94
|
70
|
giuliomoro@94
|
71 void render(BeagleRTContext *context, void *userData)
|
giuliomoro@94
|
72 {
|
giuliomoro@135
|
73 virtualClock.sync(context->audioFrames);
|
giuliomoro@109
|
74 static int count=0;
|
giuliomoro@141
|
75 if(count==0){
|
giuliomoro@141
|
76 // BeagleRT_scheduleAuxiliaryTask(testTime);
|
giuliomoro@141
|
77 clockSyncThread.startThread(); //make sure you uncomment .init in setup()
|
giuliomoro@141
|
78 }
|
giuliomoro@151
|
79 /*
|
giuliomoro@151
|
80 switch (count){
|
giuliomoro@151
|
81 case 5000:
|
giuliomoro@151
|
82 gAudioCodec->setAudioSamplingRate(44101);
|
giuliomoro@151
|
83 printf("0 0 0\n");
|
giuliomoro@151
|
84 break;
|
giuliomoro@151
|
85 case 10000:
|
giuliomoro@151
|
86 gAudioCodec->setAudioSamplingRate(44100);
|
giuliomoro@151
|
87 printf("0 0 0\n");
|
giuliomoro@151
|
88 break;
|
giuliomoro@151
|
89 case 15000:
|
giuliomoro@151
|
90 gAudioCodec->setAudioSamplingRate(44099);
|
giuliomoro@151
|
91 printf("0 0 0\n");
|
giuliomoro@151
|
92 break;
|
giuliomoro@151
|
93 case 20000:
|
giuliomoro@151
|
94 gAudioCodec->setAudioSamplingRate(44100);
|
giuliomoro@151
|
95 printf("0 0 0\n");
|
giuliomoro@151
|
96 count = 0;
|
giuliomoro@151
|
97 break;
|
giuliomoro@151
|
98 }
|
giuliomoro@151
|
99 */
|
giuliomoro@135
|
100 static float phase=0;
|
giuliomoro@144
|
101 float phaseInc=gFrequency1/44100.0*2*M_PI;
|
giuliomoro@135
|
102 // rt_printf("phaseInc: %f, phase: %f\n",phaseInc,phase);
|
giuliomoro@135
|
103 for(unsigned int n=0; n<context->audioFrames; n++){
|
giuliomoro@144
|
104 context->audioOut[n*2]=sinf(phase);//context->audioIn[n*2];
|
giuliomoro@135
|
105 phase+=200.0/44100.0*2*M_PI;
|
giuliomoro@135
|
106 if(phase>=2*M_PI)
|
giuliomoro@135
|
107 phase-=2*M_PI;
|
giuliomoro@149
|
108 context->audioOut[n*2+1]=rand()/(float)RAND_MAX;//context->audioIn[n*2];
|
giuliomoro@135
|
109 }
|
giuliomoro@135
|
110 count++;
|
giuliomoro@135
|
111 /*
|
giuliomoro@132
|
112 // if((count&262143)==0){
|
giuliomoro@132
|
113 // static int nextCall=160000;
|
giuliomoro@135
|
114 if( ((count&(2047))==0)){
|
giuliomoro@132
|
115 // rt_printf("b %d\n", count);
|
giuliomoro@132
|
116 clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
|
giuliomoro@132
|
117 // nextCall=count+100000;
|
giuliomoro@132
|
118 // rt_printf("a %d\n", count);
|
giuliomoro@132
|
119 }
|
giuliomoro@132
|
120 // if(count == nextCall){
|
giuliomoro@132
|
121 // clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
|
giuliomoro@132
|
122 // }
|
giuliomoro@131
|
123 if(count==0){
|
giuliomoro@135
|
124 gAudioCodec->setAudioSamplingRate( 44100);
|
giuliomoro@133
|
125 rt_printf("startHread\n");
|
giuliomoro@131
|
126 ReceiveAudioThread::startThread();
|
giuliomoro@131
|
127 }
|
giuliomoro@94
|
128 for(unsigned int n = 0; n < context->audioFrames; n++) {
|
giuliomoro@94
|
129
|
giuliomoro@111
|
130 float chn0 = sinf(gPhase1);
|
giuliomoro@131
|
131 // float chn1 = sinf(gPhase2);
|
giuliomoro@111
|
132
|
giuliomoro@118
|
133 // float chn2 = context->audioIn[n*2 + 0];
|
giuliomoro@118
|
134 // float chn3 = context->audioIn[n*2 + 1];
|
giuliomoro@111
|
135
|
giuliomoro@118
|
136 // float chn4 = context->analogIn[(int)n/2*8 + 0];
|
giuliomoro@118
|
137 // float chn5 = context->analogIn[(int)n/2*8 + 1];
|
giuliomoro@132
|
138 // networkSend.log(context->audioIn[n]);
|
giuliomoro@132
|
139 networkSend.log(chn0);
|
giuliomoro@131
|
140 // scope.log(0, chn0);
|
giuliomoro@131
|
141 // scope.log(1, chn1);
|
giuliomoro@118
|
142 // scope.log(2, chn2);
|
giuliomoro@118
|
143 // scope.log(3, chn3);
|
giuliomoro@118
|
144 // scope.log(4, chn4);
|
giuliomoro@118
|
145 // scope.log(5, chn5);
|
giuliomoro@94
|
146
|
giuliomoro@94
|
147 // scope.log(chn1, chn2, chn3, chn4, chn5, chn6);
|
giuliomoro@94
|
148 //call this once every audio frame
|
giuliomoro@94
|
149 //takes six or fewer floats as parameters
|
giuliomoro@94
|
150 //first parameter becomes channel 1 etc
|
giuliomoro@94
|
151 //to view, click the 'oscilloscope' button on the toolbar while BeagleRT is NOT running
|
giuliomoro@94
|
152 //then click the big red button on the toolbar on this page
|
giuliomoro@94
|
153
|
giuliomoro@132
|
154 gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate * ((count&65535)/65535.0+1);
|
giuliomoro@118
|
155 gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate;
|
giuliomoro@94
|
156 if(gPhase1 > 2.0 * M_PI)
|
giuliomoro@94
|
157 gPhase1 -= 2.0 * M_PI;
|
giuliomoro@94
|
158 if(gPhase2 > 2.0 * M_PI)
|
giuliomoro@94
|
159 gPhase2 -= 2.0 * M_PI;
|
giuliomoro@135
|
160 int value=count%1000;
|
giuliomoro@135
|
161 context->audioOut[n*2]=value>=500 ? 1 : -1;
|
giuliomoro@135
|
162 context->audioOut[n*2+1]=context->audioOut[n*2];
|
giuliomoro@132
|
163 count++;
|
giuliomoro@94
|
164 }
|
giuliomoro@118
|
165 if(count>0){
|
giuliomoro@131
|
166 float samplingRateRatio=1;
|
giuliomoro@131
|
167 int channelsInDestinationBuffer=2;
|
giuliomoro@135
|
168 int channelToWriteTo=1;
|
giuliomoro@131
|
169 int length=receiveAudio0.getSamplesSrc(context->audioOut, context->audioFrames,
|
giuliomoro@131
|
170 samplingRateRatio, channelsInDestinationBuffer, channelToWriteTo);
|
giuliomoro@132
|
171 if((unsigned int)length!=context->audioFrames){
|
giuliomoro@131
|
172 rt_printf("Length mismatch: %d\n", length);
|
giuliomoro@131
|
173 }
|
giuliomoro@128
|
174 // int readPointer1=receiveAudio1.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 1);
|
giuliomoro@119
|
175 }
|
giuliomoro@132
|
176 for(unsigned int n=0; n<context->audioFrames; n++){
|
giuliomoro@135
|
177 // context->audioOut[n*2+1]=context->audioOut[n*2];
|
giuliomoro@131
|
178 }
|
giuliomoro@135
|
179 */
|
giuliomoro@135
|
180
|
giuliomoro@94
|
181 }
|
giuliomoro@94
|
182
|
giuliomoro@94
|
183 // cleanup_render() is called once at the end, after the audio has stopped.
|
giuliomoro@94
|
184 // Release any resources that were allocated in initialise_render().
|
giuliomoro@94
|
185
|
giuliomoro@94
|
186 void cleanup(BeagleRTContext *context, void *userData)
|
giuliomoro@94
|
187 {
|
giuliomoro@94
|
188
|
giuliomoro@94
|
189 }
|