annotate projects/scope/render.cpp @ 152:8f98b32d0e23 ClockSync

Last commit on this branch for a while. Overall not very succesful
author Giulio Moro <giuliomoro@yahoo.it>
date Mon, 05 Oct 2015 13:06:14 +0100
parents e9c9404e3d1f
children
rev   line source
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@152 7 #include <Pid.h>
giuliomoro@94 8
giuliomoro@94 9 float gPhase1, gPhase2;
giuliomoro@94 10 float gFrequency1, gFrequency2;
giuliomoro@94 11 float gInverseSampleRate;
giuliomoro@94 12
giuliomoro@128 13 //Scope scope(2); //create a scope object with 2 channels
giuliomoro@135 14 //NetworkSend networkSend;
giuliomoro@94 15
giuliomoro@94 16 // initialise_render() is called once before the audio rendering starts.
giuliomoro@94 17 // Use it to perform any initialisation and allocation which is dependent
giuliomoro@94 18 // on the period size or sample rate.
giuliomoro@94 19 //
giuliomoro@94 20 // userData holds an opaque pointer to a data structure that was passed
giuliomoro@94 21 // in from the call to initAudio().
giuliomoro@94 22 //
giuliomoro@94 23 // Return true on success; returning false halts the program.
giuliomoro@135 24 //ReceiveAudioThread receiveAudio0;
giuliomoro@128 25 //ReceiveAudioThread receiveAudio1;
giuliomoro@132 26 ClockSynchronizer clockSynchronizer;
giuliomoro@132 27 extern I2c_Codec* gAudioCodec;
giuliomoro@135 28 VirtualClock virtualClock;
giuliomoro@135 29 ClockSyncThread clockSyncThread;
giuliomoro@141 30 AuxiliaryTask testTime;
giuliomoro@141 31 void testTimeFunction(){
giuliomoro@141 32 rt_printf("time=[");
giuliomoro@141 33 while(!gShouldStop){
giuliomoro@141 34 rt_task_sleep(50000*1e3);
giuliomoro@141 35 rt_printf("%f, ", virtualClock.getNow());
giuliomoro@141 36 rt_printf("%f, ", virtualClock.getPeriod());
giuliomoro@141 37 rt_task_sleep(20000);
giuliomoro@141 38 rt_printf("%f,", virtualClock.getNow());
giuliomoro@141 39 rt_printf("%f\n", virtualClock.getPeriod());
giuliomoro@141 40 }
giuliomoro@141 41 rt_printf("];");
giuliomoro@141 42 }
giuliomoro@94 43 bool setup(BeagleRTContext *context, void *userData)
giuliomoro@94 44 {
giuliomoro@135 45 // receiveAudio0.init(10000, context->audioFrames, 0);
giuliomoro@128 46 // receiveAudio1.init(10000, context->audioFrames, 1);
giuliomoro@131 47
giuliomoro@128 48 // scope.setup(); //call this once in setup to initialise the scope
giuliomoro@128 49 // scope.setPort(0, 9999);
giuliomoro@128 50 // scope.setPort(1, 10000);
giuliomoro@135 51 // networkSend.setup(context->audioSampleRate, context->audioFrames, 0, 9999, "192.168.7.1");
giuliomoro@141 52 // clockSynchronizer.setup();
giuliomoro@149 53 virtualClock.init(context->audioFrames / context->audioSampleRate * 1e6);
giuliomoro@135 54 clockSyncThread.init(true, 5000, virtualClock); //start as slave
giuliomoro@94 55 gInverseSampleRate = 1.0/context->audioSampleRate;
giuliomoro@94 56
giuliomoro@94 57 gPhase1 = 0.0;
giuliomoro@94 58 gPhase2 = 0.0;
giuliomoro@94 59
giuliomoro@152 60 gFrequency1 = 441.0;
giuliomoro@94 61 gFrequency2 = 201.0;
giuliomoro@111 62
giuliomoro@141 63 // testTime=BeagleRT_createAuxiliaryTask(testTimeFunction, 80, "testTimeTask");
giuliomoro@94 64 return true;
giuliomoro@94 65 }
giuliomoro@94 66
giuliomoro@94 67 // render() is called regularly at the highest priority by the audio engine.
giuliomoro@94 68 // Input and output are given from the audio hardware and the other
giuliomoro@94 69 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
giuliomoro@94 70 // will be 0.
giuliomoro@152 71 extern Pid* gClockSyncPid;
giuliomoro@152 72 extern ClockSync* gClockSync;
giuliomoro@94 73 void render(BeagleRTContext *context, void *userData)
giuliomoro@94 74 {
giuliomoro@135 75 virtualClock.sync(context->audioFrames);
giuliomoro@109 76 static int count=0;
giuliomoro@141 77 if(count==0){
giuliomoro@141 78 // BeagleRT_scheduleAuxiliaryTask(testTime);
giuliomoro@141 79 clockSyncThread.startThread(); //make sure you uncomment .init in setup()
giuliomoro@141 80 }
giuliomoro@151 81 /*
giuliomoro@151 82 switch (count){
giuliomoro@151 83 case 5000:
giuliomoro@151 84 gAudioCodec->setAudioSamplingRate(44101);
giuliomoro@151 85 printf("0 0 0\n");
giuliomoro@151 86 break;
giuliomoro@151 87 case 10000:
giuliomoro@151 88 gAudioCodec->setAudioSamplingRate(44100);
giuliomoro@151 89 printf("0 0 0\n");
giuliomoro@151 90 break;
giuliomoro@151 91 case 15000:
giuliomoro@151 92 gAudioCodec->setAudioSamplingRate(44099);
giuliomoro@151 93 printf("0 0 0\n");
giuliomoro@151 94 break;
giuliomoro@151 95 case 20000:
giuliomoro@151 96 gAudioCodec->setAudioSamplingRate(44100);
giuliomoro@151 97 printf("0 0 0\n");
giuliomoro@151 98 count = 0;
giuliomoro@151 99 break;
giuliomoro@151 100 }
giuliomoro@151 101 */
giuliomoro@135 102 static float phase=0;
giuliomoro@144 103 float phaseInc=gFrequency1/44100.0*2*M_PI;
giuliomoro@135 104 // rt_printf("phaseInc: %f, phase: %f\n",phaseInc,phase);
giuliomoro@135 105 for(unsigned int n=0; n<context->audioFrames; n++){
giuliomoro@152 106 context->audioOut[n*2]=sinf(phase) > 0 ? 1 : -1;
giuliomoro@152 107 context->audioOut[n*2+1]=sinf(phase) > 0 ? 1 : -1;
giuliomoro@152 108 // context->audioOut[n*2]= context->audioIn[n*2];
giuliomoro@152 109 // context->audioOut[n*2+1]= context->audioIn[n*2+1];
giuliomoro@152 110 phase+=phaseInc;
giuliomoro@135 111 if(phase>=2*M_PI)
giuliomoro@135 112 phase-=2*M_PI;
giuliomoro@152 113 // context->audioOut[n*2+1]=rand()/(float)RAND_MAX;//context->audioIn[n*2];
giuliomoro@135 114 }
giuliomoro@152 115 gClockSyncPid->setProportionalGain(context->analogIn[0]*10);
giuliomoro@152 116 // gClockSyncPid->setIntegralGain(context->analogIn[1]);
giuliomoro@152 117 gClockSyncPid->setIntegralGain(0);
giuliomoro@152 118 // gClockSyncPid->setDerivativeGain(context->analogIn[2]);
giuliomoro@152 119 gClockSyncPid->setDerivativeGain(0);
giuliomoro@152 120 gClockSyncPid->setGlobalGain(context->analogIn[3]*1/0.828);
giuliomoro@152 121 for (int n = 0; n < context->analogFrames; n++){
giuliomoro@152 122 context->analogOut[n*context->analogChannels + 0] = (gClockSync->getOffset() )/ 100 + 0.5;
giuliomoro@152 123 context->analogOut[n*context->analogChannels + 1] = (gAudioCodec->getAudioSamplingRate()-44100)/20 + 0.5;
giuliomoro@152 124 }
giuliomoro@152 125 static bool pastSwitch = false;
giuliomoro@152 126 bool thisSwitch = context->analogIn[4]>0.5;
giuliomoro@152 127 if(thisSwitch && pastSwitch == false){
giuliomoro@152 128 rt_printf("--------------reset offset\n");
giuliomoro@152 129 virtualClock.addOffset(gClockSync->getIirOffset());
giuliomoro@152 130 }
giuliomoro@152 131 pastSwitch = thisSwitch;
giuliomoro@135 132 count++;
giuliomoro@135 133 /*
giuliomoro@132 134 // if((count&262143)==0){
giuliomoro@132 135 // static int nextCall=160000;
giuliomoro@135 136 if( ((count&(2047))==0)){
giuliomoro@132 137 // rt_printf("b %d\n", count);
giuliomoro@132 138 clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
giuliomoro@132 139 // nextCall=count+100000;
giuliomoro@132 140 // rt_printf("a %d\n", count);
giuliomoro@132 141 }
giuliomoro@132 142 // if(count == nextCall){
giuliomoro@132 143 // clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
giuliomoro@132 144 // }
giuliomoro@131 145 if(count==0){
giuliomoro@135 146 gAudioCodec->setAudioSamplingRate( 44100);
giuliomoro@133 147 rt_printf("startHread\n");
giuliomoro@131 148 ReceiveAudioThread::startThread();
giuliomoro@131 149 }
giuliomoro@94 150 for(unsigned int n = 0; n < context->audioFrames; n++) {
giuliomoro@94 151
giuliomoro@111 152 float chn0 = sinf(gPhase1);
giuliomoro@131 153 // float chn1 = sinf(gPhase2);
giuliomoro@111 154
giuliomoro@118 155 // float chn2 = context->audioIn[n*2 + 0];
giuliomoro@118 156 // float chn3 = context->audioIn[n*2 + 1];
giuliomoro@111 157
giuliomoro@118 158 // float chn4 = context->analogIn[(int)n/2*8 + 0];
giuliomoro@118 159 // float chn5 = context->analogIn[(int)n/2*8 + 1];
giuliomoro@132 160 // networkSend.log(context->audioIn[n]);
giuliomoro@132 161 networkSend.log(chn0);
giuliomoro@131 162 // scope.log(0, chn0);
giuliomoro@131 163 // scope.log(1, chn1);
giuliomoro@118 164 // scope.log(2, chn2);
giuliomoro@118 165 // scope.log(3, chn3);
giuliomoro@118 166 // scope.log(4, chn4);
giuliomoro@118 167 // scope.log(5, chn5);
giuliomoro@94 168
giuliomoro@94 169 // scope.log(chn1, chn2, chn3, chn4, chn5, chn6);
giuliomoro@94 170 //call this once every audio frame
giuliomoro@94 171 //takes six or fewer floats as parameters
giuliomoro@94 172 //first parameter becomes channel 1 etc
giuliomoro@94 173 //to view, click the 'oscilloscope' button on the toolbar while BeagleRT is NOT running
giuliomoro@94 174 //then click the big red button on the toolbar on this page
giuliomoro@94 175
giuliomoro@132 176 gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate * ((count&65535)/65535.0+1);
giuliomoro@118 177 gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate;
giuliomoro@94 178 if(gPhase1 > 2.0 * M_PI)
giuliomoro@94 179 gPhase1 -= 2.0 * M_PI;
giuliomoro@94 180 if(gPhase2 > 2.0 * M_PI)
giuliomoro@94 181 gPhase2 -= 2.0 * M_PI;
giuliomoro@135 182 int value=count%1000;
giuliomoro@135 183 context->audioOut[n*2]=value>=500 ? 1 : -1;
giuliomoro@135 184 context->audioOut[n*2+1]=context->audioOut[n*2];
giuliomoro@132 185 count++;
giuliomoro@94 186 }
giuliomoro@118 187 if(count>0){
giuliomoro@131 188 float samplingRateRatio=1;
giuliomoro@131 189 int channelsInDestinationBuffer=2;
giuliomoro@135 190 int channelToWriteTo=1;
giuliomoro@131 191 int length=receiveAudio0.getSamplesSrc(context->audioOut, context->audioFrames,
giuliomoro@131 192 samplingRateRatio, channelsInDestinationBuffer, channelToWriteTo);
giuliomoro@132 193 if((unsigned int)length!=context->audioFrames){
giuliomoro@131 194 rt_printf("Length mismatch: %d\n", length);
giuliomoro@131 195 }
giuliomoro@128 196 // int readPointer1=receiveAudio1.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 1);
giuliomoro@119 197 }
giuliomoro@132 198 for(unsigned int n=0; n<context->audioFrames; n++){
giuliomoro@135 199 // context->audioOut[n*2+1]=context->audioOut[n*2];
giuliomoro@131 200 }
giuliomoro@135 201 */
giuliomoro@135 202
giuliomoro@94 203 }
giuliomoro@94 204
giuliomoro@94 205 // cleanup_render() is called once at the end, after the audio has stopped.
giuliomoro@94 206 // Release any resources that were allocated in initialise_render().
giuliomoro@94 207
giuliomoro@94 208 void cleanup(BeagleRTContext *context, void *userData)
giuliomoro@94 209 {
giuliomoro@94 210
giuliomoro@94 211 }