annotate projects/scope/render.cpp @ 133:04b1678614c9 scope-refactoring

Using moving average for clock detection during synchronization seems to be working better but audio gets worse and worse
author Giulio Moro <giuliomoro@yahoo.it>
date Thu, 27 Aug 2015 03:33:32 +0100
parents e24c531220ee
children e77e2e712fbc
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@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 }