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