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