annotate projects/scope/render.cpp @ 135:e77e2e712fbc ClockSync

To work with the ClockSync plugin
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 12 Sep 2015 20:05:55 +0100
parents 04b1678614c9
children 44d07fa9bd03
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@94 29 bool setup(BeagleRTContext *context, void *userData)
giuliomoro@94 30 {
giuliomoro@135 31 // receiveAudio0.init(10000, context->audioFrames, 0);
giuliomoro@128 32 // receiveAudio1.init(10000, context->audioFrames, 1);
giuliomoro@131 33
giuliomoro@128 34 // scope.setup(); //call this once in setup to initialise the scope
giuliomoro@128 35 // scope.setPort(0, 9999);
giuliomoro@128 36 // scope.setPort(1, 10000);
giuliomoro@135 37 // networkSend.setup(context->audioSampleRate, context->audioFrames, 0, 9999, "192.168.7.1");
giuliomoro@132 38 clockSynchronizer.setup();
giuliomoro@135 39 virtualClock.init();
giuliomoro@135 40 clockSyncThread.init(true, 5000, virtualClock); //start as slave
giuliomoro@94 41 gInverseSampleRate = 1.0/context->audioSampleRate;
giuliomoro@94 42
giuliomoro@94 43 gPhase1 = 0.0;
giuliomoro@94 44 gPhase2 = 0.0;
giuliomoro@94 45
giuliomoro@94 46 gFrequency1 = 200.0;
giuliomoro@94 47 gFrequency2 = 201.0;
giuliomoro@111 48
giuliomoro@94 49 return true;
giuliomoro@94 50 }
giuliomoro@94 51
giuliomoro@94 52 // render() is called regularly at the highest priority by the audio engine.
giuliomoro@94 53 // Input and output are given from the audio hardware and the other
giuliomoro@94 54 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
giuliomoro@94 55 // will be 0.
giuliomoro@94 56
giuliomoro@94 57 void render(BeagleRTContext *context, void *userData)
giuliomoro@94 58 {
giuliomoro@135 59 virtualClock.sync(context->audioFrames);
giuliomoro@109 60 static int count=0;
giuliomoro@135 61 if(count==0)
giuliomoro@135 62 clockSyncThread.startThread();
giuliomoro@135 63 static float phase=0;
giuliomoro@135 64 float phaseInc=200.0/44100.0*2*M_PI;
giuliomoro@135 65 // rt_printf("phaseInc: %f, phase: %f\n",phaseInc,phase);
giuliomoro@135 66 for(unsigned int n=0; n<context->audioFrames; n++){
giuliomoro@135 67 context->audioOut[n*2]=sinf(phaseInc);//context->audioIn[n*2];
giuliomoro@135 68 context->audioOut[n*2+1]=sinf(phaseInc);//context->audioIn[n*2];
giuliomoro@135 69 phase+=200.0/44100.0*2*M_PI;
giuliomoro@135 70 if(phase>=2*M_PI)
giuliomoro@135 71 phase-=2*M_PI;
giuliomoro@135 72 // context->audioOut[n*2+1]=rand()/(float)RAND_MAX;context->audioIn[n*2];
giuliomoro@135 73 }
giuliomoro@135 74 count++;
giuliomoro@135 75 /*
giuliomoro@132 76 // if((count&262143)==0){
giuliomoro@132 77 // static int nextCall=160000;
giuliomoro@135 78 if( ((count&(2047))==0)){
giuliomoro@132 79 // rt_printf("b %d\n", count);
giuliomoro@132 80 clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
giuliomoro@132 81 // nextCall=count+100000;
giuliomoro@132 82 // rt_printf("a %d\n", count);
giuliomoro@132 83 }
giuliomoro@132 84 // if(count == nextCall){
giuliomoro@132 85 // clockSynchronizer.update(networkSend.getTimestamp(), receiveAudio0.getTimestamp(), receiveAudio0.getLastTime());
giuliomoro@132 86 // }
giuliomoro@131 87 if(count==0){
giuliomoro@135 88 gAudioCodec->setAudioSamplingRate( 44100);
giuliomoro@133 89 rt_printf("startHread\n");
giuliomoro@131 90 ReceiveAudioThread::startThread();
giuliomoro@131 91 }
giuliomoro@94 92 for(unsigned int n = 0; n < context->audioFrames; n++) {
giuliomoro@94 93
giuliomoro@111 94 float chn0 = sinf(gPhase1);
giuliomoro@131 95 // float chn1 = sinf(gPhase2);
giuliomoro@111 96
giuliomoro@118 97 // float chn2 = context->audioIn[n*2 + 0];
giuliomoro@118 98 // float chn3 = context->audioIn[n*2 + 1];
giuliomoro@111 99
giuliomoro@118 100 // float chn4 = context->analogIn[(int)n/2*8 + 0];
giuliomoro@118 101 // float chn5 = context->analogIn[(int)n/2*8 + 1];
giuliomoro@132 102 // networkSend.log(context->audioIn[n]);
giuliomoro@132 103 networkSend.log(chn0);
giuliomoro@131 104 // scope.log(0, chn0);
giuliomoro@131 105 // scope.log(1, chn1);
giuliomoro@118 106 // scope.log(2, chn2);
giuliomoro@118 107 // scope.log(3, chn3);
giuliomoro@118 108 // scope.log(4, chn4);
giuliomoro@118 109 // scope.log(5, chn5);
giuliomoro@94 110
giuliomoro@94 111 // scope.log(chn1, chn2, chn3, chn4, chn5, chn6);
giuliomoro@94 112 //call this once every audio frame
giuliomoro@94 113 //takes six or fewer floats as parameters
giuliomoro@94 114 //first parameter becomes channel 1 etc
giuliomoro@94 115 //to view, click the 'oscilloscope' button on the toolbar while BeagleRT is NOT running
giuliomoro@94 116 //then click the big red button on the toolbar on this page
giuliomoro@94 117
giuliomoro@132 118 gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate * ((count&65535)/65535.0+1);
giuliomoro@118 119 gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate;
giuliomoro@94 120 if(gPhase1 > 2.0 * M_PI)
giuliomoro@94 121 gPhase1 -= 2.0 * M_PI;
giuliomoro@94 122 if(gPhase2 > 2.0 * M_PI)
giuliomoro@94 123 gPhase2 -= 2.0 * M_PI;
giuliomoro@135 124 int value=count%1000;
giuliomoro@135 125 context->audioOut[n*2]=value>=500 ? 1 : -1;
giuliomoro@135 126 context->audioOut[n*2+1]=context->audioOut[n*2];
giuliomoro@132 127 count++;
giuliomoro@94 128 }
giuliomoro@118 129 if(count>0){
giuliomoro@131 130 float samplingRateRatio=1;
giuliomoro@131 131 int channelsInDestinationBuffer=2;
giuliomoro@135 132 int channelToWriteTo=1;
giuliomoro@131 133 int length=receiveAudio0.getSamplesSrc(context->audioOut, context->audioFrames,
giuliomoro@131 134 samplingRateRatio, channelsInDestinationBuffer, channelToWriteTo);
giuliomoro@132 135 if((unsigned int)length!=context->audioFrames){
giuliomoro@131 136 rt_printf("Length mismatch: %d\n", length);
giuliomoro@131 137 }
giuliomoro@128 138 // int readPointer1=receiveAudio1.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 1);
giuliomoro@119 139 }
giuliomoro@132 140 for(unsigned int n=0; n<context->audioFrames; n++){
giuliomoro@135 141 // context->audioOut[n*2+1]=context->audioOut[n*2];
giuliomoro@131 142 }
giuliomoro@135 143 */
giuliomoro@135 144
giuliomoro@94 145 }
giuliomoro@94 146
giuliomoro@94 147 // cleanup_render() is called once at the end, after the audio has stopped.
giuliomoro@94 148 // Release any resources that were allocated in initialise_render().
giuliomoro@94 149
giuliomoro@94 150 void cleanup(BeagleRTContext *context, void *userData)
giuliomoro@94 151 {
giuliomoro@94 152
giuliomoro@94 153 }