annotate projects/basic_network/render.cpp @ 180:07cfd337ad18

Updated examples with new audioWrite macros
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 02 Jan 2016 13:55:01 +0100
parents a55dcdcebdcd
children 3068421c0737 dbff109f64c2
rev   line source
giuliomoro@24 1 /*
giuliomoro@24 2 * render.cpp
giuliomoro@24 3 *
giuliomoro@24 4 * Created on: Oct 24, 2014
giuliomoro@24 5 * Author: parallels
giuliomoro@24 6 */
giuliomoro@24 7
andrewm@56 8 #include <BeagleRT.h>
giuliomoro@92 9 //#include <rtdk.h>
giuliomoro@24 10 #include <cmath>
giuliomoro@92 11 #include <UdpClient.h>
giuliomoro@92 12 #include <Utilities.h>
giuliomoro@92 13
giuliomoro@92 14 AuxiliaryTask transmitReceiveDataTask;
giuliomoro@92 15
giuliomoro@92 16 #define NETWORK_AUDIO_BUFFER_SIZE 400 //1400/4 //maximum payload for a UDP datagram over ethernet is 1472 bytes, I leave some headroom and divide by 4 to get the number of floats
giuliomoro@92 17 struct networkAudio{
giuliomoro@92 18 int timestamp;
giuliomoro@92 19 int currentBuffer;
giuliomoro@92 20 int index;
giuliomoro@92 21 float buffers[2][NETWORK_AUDIO_BUFFER_SIZE];
giuliomoro@92 22 int doneOnTime;
giuliomoro@92 23 bool toBeSent;
giuliomoro@92 24 UdpClient udpClient;
giuliomoro@92 25 };
andrewm@56 26
giuliomoro@24 27 float gFrequency;
giuliomoro@24 28 float gPhase;
giuliomoro@24 29 float gInverseSampleRate;
giuliomoro@24 30 int gCount=0;
giuliomoro@92 31 //networkData networkObject;
giuliomoro@92 32 #define numNetAudio 3
giuliomoro@92 33 networkAudio netAudio[numNetAudio];
giuliomoro@92 34 AuxiliaryTask printIntervalTask;
giuliomoro@92 35 AuxiliaryTask transmitReceiveAudioTask;
giuliomoro@24 36
giuliomoro@92 37 void transmitReceiveAudio(){ //transmit and receive audio buffers
giuliomoro@92 38 for(int n=0;n<numNetAudio; n++){
giuliomoro@92 39 if(netAudio[n].toBeSent){
giuliomoro@92 40 netAudio[n].toBeSent=false;
giuliomoro@92 41 netAudio[n].udpClient.send(netAudio[n].buffers[!netAudio[n].currentBuffer],NETWORK_AUDIO_BUFFER_SIZE*sizeof(float));
giuliomoro@92 42 netAudio[n].doneOnTime=1;
giuliomoro@92 43 }
giuliomoro@24 44 }
giuliomoro@24 45 }
giuliomoro@24 46
andrewm@56 47 // setup() is called once before the audio rendering starts.
giuliomoro@24 48 // Use it to perform any initialisation and allocation which is dependent
giuliomoro@24 49 // on the period size or sample rate.
giuliomoro@24 50 //
giuliomoro@24 51 // userData holds an opaque pointer to a data structure that was passed
giuliomoro@24 52 // in from the call to initAudio().
giuliomoro@24 53 //
giuliomoro@24 54 // Return true on success; returning false halts the program.
andrewm@56 55 bool setup(BeagleRTContext *context, void *userData)
giuliomoro@24 56 {
giuliomoro@24 57 // Retrieve a parameter passed in from the initAudio() call
giuliomoro@24 58 gFrequency = *(float *)userData;
giuliomoro@24 59
andrewm@56 60 gInverseSampleRate = 1.0 / context->audioSampleRate;
giuliomoro@24 61 gPhase = 0.0;
giuliomoro@24 62
giuliomoro@92 63 // networkObject.counter=&gCount;
giuliomoro@92 64 // networkObject.variables[0]=&gFrequency;
giuliomoro@92 65 // networkObject.variables[1]=&gPhase;
giuliomoro@92 66 // networkObject.numVariables=2;
giuliomoro@92 67 for(int n=0; n<numNetAudio; n++){
giuliomoro@92 68 netAudio[n].doneOnTime=1;
giuliomoro@92 69 netAudio[n].index=0;
giuliomoro@92 70 netAudio[n].currentBuffer=0;
giuliomoro@92 71 netAudio[n].toBeSent=false;
giuliomoro@92 72 // netAudio[n].udpClient.setPort(settings->transmitPort+n);
giuliomoro@92 73 // netAudio[n].udpClient.setServer(settings->serverName);
giuliomoro@92 74 netAudio[n].udpClient.setPort(9999+n);
giuliomoro@92 75 netAudio[n].udpClient.setServer("192.168.7.1");
giuliomoro@92 76 }
giuliomoro@92 77 // setupSockets(settings->receivePort, settings->transmitPort, settings->serverName);
giuliomoro@92 78
giuliomoro@92 79 // transmitReceiveDataTask=createAuxiliaryTask(*transmitReceiveData, 10, "transmit-receive-data");
giuliomoro@92 80 // scheduleAuxiliaryTask(transmitReceiveDataTask); //here it does not work
giuliomoro@92 81 transmitReceiveAudioTask=BeagleRT_createAuxiliaryTask(*transmitReceiveAudio, 98, "transmit-receive-audio");
giuliomoro@24 82 return true;
giuliomoro@24 83 }
giuliomoro@24 84
giuliomoro@24 85 // render() is called regularly at the highest priority by the audio engine.
giuliomoro@24 86 // Input and output are given from the audio hardware and the other
giuliomoro@24 87 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
giuliomoro@24 88 // will be 0.
giuliomoro@24 89
andrewm@56 90 void render(BeagleRTContext *context, void *userData)
giuliomoro@92 91 {/*
andrewm@56 92 for(unsigned int n = 0; n < context->audioFrames; n++) {
giuliomoro@24 93 float out = 0.7f * sinf(gPhase);
giuliomoro@24 94 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
giuliomoro@24 95 if(gPhase > 2.0 * M_PI)
giuliomoro@24 96 gPhase -= 2.0 * M_PI;
giuliomoro@24 97
andrewm@56 98 for(unsigned int channel = 0; channel < context->audioChannels; channel++)
andrewm@56 99 context->audioOut[n * context->audioChannels + channel] = out;
andrewm@56 100
andrewm@56 101 if(gCount == 0){
andrewm@56 102 BeagleRT_scheduleAuxiliaryTask(transmitReceiveDataTask);
giuliomoro@24 103 }
giuliomoro@24 104 gCount++;
giuliomoro@24 105 }
giuliomoro@92 106
giuliomoro@92 107
giuliomoro@92 108 */
giuliomoro@92 109 for(int n = 0; n < context->audioFrames; n++) {
giuliomoro@92 110 float out = 0.7f * sinf(gPhase);
giuliomoro@92 111 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
giuliomoro@92 112 if(gPhase > 2.0 * M_PI)
giuliomoro@92 113 gPhase -= 2.0 * M_PI;
giuliomoro@92 114
giuliomoro@92 115 // for(int channel = 0; channel < context->audioChannels; channel++)
giuliomoro@92 116 // context->audioOut[n * context->audioChannels + channel] = context->audioIn[n * context->audioChannels + 0]+context->audioIn[n * context->audioChannels + 1];
giuliomoro@92 117 context->audioOut[n * context->audioChannels] = context->audioIn[n*context->audioChannels+0];
giuliomoro@92 118 context->audioOut[n * context->audioChannels+1]=out;
giuliomoro@92 119 if(0==gCount){
giuliomoro@92 120 // scheduleAuxiliaryTask(transmitReceiveDataTask);
giuliomoro@92 121 }
giuliomoro@92 122 for(int j=0; j<numNetAudio; j++){
giuliomoro@92 123 if(netAudio[j].index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ...
giuliomoro@92 124 netAudio[j].toBeSent=true;
giuliomoro@92 125 netAudio[j].index=0; //reset the counter
giuliomoro@92 126 if(netAudio[j].doneOnTime==0)
giuliomoro@92 127 rt_printf("Network buffer underrun :-{\n");
giuliomoro@92 128 netAudio[j].timestamp=gCount;
giuliomoro@92 129 netAudio[j].currentBuffer=!netAudio[j].currentBuffer; //switch buffer
giuliomoro@92 130 netAudio[j].doneOnTime=0;
giuliomoro@92 131 BeagleRT_scheduleAuxiliaryTask(transmitReceiveAudioTask); //send the buffer
giuliomoro@92 132 }
giuliomoro@92 133 }
giuliomoro@92 134 if((gCount&1)==0){
giuliomoro@92 135 netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=analogReadFrame(context,n/2,0)+context->audioOut[n*context->audioChannels + 0];
giuliomoro@92 136 netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=analogReadFrame(context,n/2,1)+context->audioOut[n*context->audioChannels + 0];
giuliomoro@92 137 }
giuliomoro@92 138 netAudio[0].buffers[netAudio[0].currentBuffer][netAudio[0].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]);//copy channel 0 to the buffer
giuliomoro@92 139 // netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]);
giuliomoro@92 140 // netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]);
giuliomoro@92 141 gCount++;
giuliomoro@92 142 }
giuliomoro@24 143 }
giuliomoro@24 144
andrewm@56 145 // cleanup() is called once at the end, after the audio has stopped.
andrewm@56 146 // Release any resources that were allocated in setup().
giuliomoro@24 147
andrewm@56 148 void cleanup(BeagleRTContext *context, void *userData)
giuliomoro@24 149 {
giuliomoro@24 150 }