annotate projects/scope/render.cpp @ 151:e9c9404e3d1f ClockSync

Pff partially working. No PID. When setting the audio clock on the bbb to 44098 the master and slave clock keep diverging instead of converging ...
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 22 Sep 2015 04:10:07 +0100
parents 134bff10e561
children 8f98b32d0e23
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@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 }