Mercurial > hg > beaglert
comparison projects/basic_network/render.cpp @ 108:3068421c0737 ultra-staging
Merged default into ultra-staging
| author | Giulio Moro <giuliomoro@yahoo.it> |
|---|---|
| date | Tue, 18 Aug 2015 00:35:15 +0100 |
| parents | d3f869b98147 a55dcdcebdcd |
| children |
comparison
equal
deleted
inserted
replaced
| 54:d3f869b98147 | 108:3068421c0737 |
|---|---|
| 3 * | 3 * |
| 4 * Created on: Oct 24, 2014 | 4 * Created on: Oct 24, 2014 |
| 5 * Author: parallels | 5 * Author: parallels |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "../../include/RTAudioSettings.h" | 8 #include <BeagleRT.h> |
| 9 #include "../../include/render.h" | 9 //#include <rtdk.h> |
| 10 #include <cmath> | 10 #include <cmath> |
| 11 //#include "../../include/client.h" | 11 #include <UdpClient.h> |
| 12 #include "../../include/RTAudio.h" // to schedule lower prio parallel process | 12 #include <Utilities.h> |
| 13 #include <rtdk.h> | 13 |
| 14 #include <native/timer.h> | 14 AuxiliaryTask transmitReceiveDataTask; |
| 15 #include "../../include/PRU.h" | |
| 16 #include "../../include/UdpClient.h" | |
| 17 | 15 |
| 18 #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 | 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 |
| 19 struct networkAudio{ | 17 struct networkAudio{ |
| 20 int timestamp; | 18 int timestamp; |
| 21 int currentBuffer; | 19 int currentBuffer; |
| 31 float gInverseSampleRate; | 29 float gInverseSampleRate; |
| 32 int gCount=0; | 30 int gCount=0; |
| 33 //networkData networkObject; | 31 //networkData networkObject; |
| 34 #define numNetAudio 3 | 32 #define numNetAudio 3 |
| 35 networkAudio netAudio[numNetAudio]; | 33 networkAudio netAudio[numNetAudio]; |
| 36 extern PRU *gPRU; | |
| 37 AuxiliaryTask printIntervalTask; | 34 AuxiliaryTask printIntervalTask; |
| 38 AuxiliaryTask transmitReceiveAudioTask; | 35 AuxiliaryTask transmitReceiveAudioTask; |
| 39 void transmitReceiveData(){ //transmit and receive asynchronous messages | |
| 40 // printf("transmitReceiveData auxiliary task has started\n"); | |
| 41 // while(!gShouldStop){ | |
| 42 // sendMessage(&networkObject); | |
| 43 // receiveMessage(networkObject); | |
| 44 // usleep(1000); | |
| 45 // } | |
| 46 // closeSockets(); | |
| 47 } | |
| 48 | 36 |
| 49 void transmitReceiveAudio(){ //transmit and receive audio buffers | 37 void transmitReceiveAudio(){ //transmit and receive audio buffers |
| 50 for(int n=0;n<numNetAudio; n++){ | 38 for(int n=0;n<numNetAudio; n++){ |
| 51 if(netAudio[n].toBeSent){ | 39 if(netAudio[n].toBeSent){ |
| 52 netAudio[n].toBeSent=false; | 40 netAudio[n].toBeSent=false; |
| 54 netAudio[n].doneOnTime=1; | 42 netAudio[n].doneOnTime=1; |
| 55 } | 43 } |
| 56 } | 44 } |
| 57 } | 45 } |
| 58 | 46 |
| 59 | 47 // setup() is called once before the audio rendering starts. |
| 60 // initialise_render() is called once before the audio rendering starts. | |
| 61 // Use it to perform any initialisation and allocation which is dependent | 48 // Use it to perform any initialisation and allocation which is dependent |
| 62 // on the period size or sample rate. | 49 // on the period size or sample rate. |
| 63 // | 50 // |
| 64 // userData holds an opaque pointer to a data structure that was passed | 51 // userData holds an opaque pointer to a data structure that was passed |
| 65 // in from the call to initAudio(). | 52 // in from the call to initAudio(). |
| 66 // | 53 // |
| 67 // Return true on success; returning false halts the program. | 54 // Return true on success; returning false halts the program. |
| 68 bool initialise_render(int numMatrixChannels, int numDigitalChannels, int numAudioChannels, | 55 bool setup(BeagleRTContext *context, void *userData) |
| 69 int numMatrixFramesPerPeriod, | |
| 70 int numAudioFramesPerPeriod, | |
| 71 float matrixSampleRate, float audioSampleRate, | |
| 72 void *userData, RTAudioSettings *settings) | |
| 73 { | 56 { |
| 74 // Retrieve a parameter passed in from the initAudio() call | 57 // Retrieve a parameter passed in from the initAudio() call |
| 75 gFrequency = *(float *)userData; | 58 gFrequency = *(float *)userData; |
| 76 | 59 |
| 77 gInverseSampleRate = 1.0 / audioSampleRate; | 60 gInverseSampleRate = 1.0 / context->audioSampleRate; |
| 78 gPhase = 0.0; | 61 gPhase = 0.0; |
| 79 | 62 |
| 80 // networkObject.counter=&gCount; | 63 // networkObject.counter=&gCount; |
| 81 // networkObject.variables[0]=&gFrequency; | 64 // networkObject.variables[0]=&gFrequency; |
| 82 // networkObject.variables[1]=&gPhase; | 65 // networkObject.variables[1]=&gPhase; |
| 84 for(int n=0; n<numNetAudio; n++){ | 67 for(int n=0; n<numNetAudio; n++){ |
| 85 netAudio[n].doneOnTime=1; | 68 netAudio[n].doneOnTime=1; |
| 86 netAudio[n].index=0; | 69 netAudio[n].index=0; |
| 87 netAudio[n].currentBuffer=0; | 70 netAudio[n].currentBuffer=0; |
| 88 netAudio[n].toBeSent=false; | 71 netAudio[n].toBeSent=false; |
| 89 netAudio[n].udpClient.setPort(settings->transmitPort+n); | 72 // netAudio[n].udpClient.setPort(settings->transmitPort+n); |
| 90 netAudio[n].udpClient.setServer(settings->serverName); | 73 // netAudio[n].udpClient.setServer(settings->serverName); |
| 74 netAudio[n].udpClient.setPort(9999+n); | |
| 75 netAudio[n].udpClient.setServer("192.168.7.1"); | |
| 91 } | 76 } |
| 92 // setupSockets(settings->receivePort, settings->transmitPort, settings->serverName); | 77 // setupSockets(settings->receivePort, settings->transmitPort, settings->serverName); |
| 93 | 78 |
| 94 // transmitReceiveDataTask=createAuxiliaryTaskLoop(*transmitReceiveData, 10, "transmit-receive-data"); | 79 // transmitReceiveDataTask=createAuxiliaryTask(*transmitReceiveData, 10, "transmit-receive-data"); |
| 95 // scheduleAuxiliaryTask(transmitReceiveDataTask); //here it does not work | 80 // scheduleAuxiliaryTask(transmitReceiveDataTask); //here it does not work |
| 96 transmitReceiveAudioTask=createAuxiliaryTaskLoop(*transmitReceiveAudio, 98, "transmit-receive-audio"); | 81 transmitReceiveAudioTask=BeagleRT_createAuxiliaryTask(*transmitReceiveAudio, 98, "transmit-receive-audio"); |
| 97 return true; | 82 return true; |
| 98 } | 83 } |
| 99 | 84 |
| 100 // render() is called regularly at the highest priority by the audio engine. | 85 // render() is called regularly at the highest priority by the audio engine. |
| 101 // Input and output are given from the audio hardware and the other | 86 // Input and output are given from the audio hardware and the other |
| 102 // ADCs and DACs (if available). If only audio is available, numMatrixFrames | 87 // ADCs and DACs (if available). If only audio is available, numMatrixFrames |
| 103 // will be 0. | 88 // will be 0. |
| 104 | 89 |
| 105 void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, | 90 void render(BeagleRTContext *context, void *userData) |
| 106 float *analogIn, float *analogOut, uint32_t *digital) | 91 {/* |
| 107 { | 92 for(unsigned int n = 0; n < context->audioFrames; n++) { |
| 108 for(int n = 0; n < numAudioFrames; n++) { | |
| 109 float out = 0.7f * sinf(gPhase); | 93 float out = 0.7f * sinf(gPhase); |
| 110 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; | 94 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; |
| 111 if(gPhase > 2.0 * M_PI) | 95 if(gPhase > 2.0 * M_PI) |
| 112 gPhase -= 2.0 * M_PI; | 96 gPhase -= 2.0 * M_PI; |
| 113 | 97 |
| 114 // for(int channel = 0; channel < gNumAudioChannels; channel++) | 98 for(unsigned int channel = 0; channel < context->audioChannels; channel++) |
| 115 // audioOut[n * gNumAudioChannels + channel] = audioIn[n * gNumAudioChannels + 0]+audioIn[n * gNumAudioChannels + 1]; | 99 context->audioOut[n * context->audioChannels + channel] = out; |
| 116 audioOut[n * gNumAudioChannels] = audioIn[n*gNumAudioChannels+0]; | 100 |
| 117 audioOut[n * gNumAudioChannels+1]=out; | 101 if(gCount == 0){ |
| 102 BeagleRT_scheduleAuxiliaryTask(transmitReceiveDataTask); | |
| 103 } | |
| 104 gCount++; | |
| 105 } | |
| 106 | |
| 107 | |
| 108 */ | |
| 109 for(int n = 0; n < context->audioFrames; n++) { | |
| 110 float out = 0.7f * sinf(gPhase); | |
| 111 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; | |
| 112 if(gPhase > 2.0 * M_PI) | |
| 113 gPhase -= 2.0 * M_PI; | |
| 114 | |
| 115 // for(int channel = 0; channel < context->audioChannels; channel++) | |
| 116 // context->audioOut[n * context->audioChannels + channel] = context->audioIn[n * context->audioChannels + 0]+context->audioIn[n * context->audioChannels + 1]; | |
| 117 context->audioOut[n * context->audioChannels] = context->audioIn[n*context->audioChannels+0]; | |
| 118 context->audioOut[n * context->audioChannels+1]=out; | |
| 118 if(0==gCount){ | 119 if(0==gCount){ |
| 119 // scheduleAuxiliaryTask(transmitReceiveDataTask); | 120 // scheduleAuxiliaryTask(transmitReceiveDataTask); |
| 120 } | 121 } |
| 121 for(int j=0; j<numNetAudio; j++){ | 122 for(int j=0; j<numNetAudio; j++){ |
| 122 if(netAudio[j].index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ... | 123 if(netAudio[j].index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ... |
| 125 if(netAudio[j].doneOnTime==0) | 126 if(netAudio[j].doneOnTime==0) |
| 126 rt_printf("Network buffer underrun :-{\n"); | 127 rt_printf("Network buffer underrun :-{\n"); |
| 127 netAudio[j].timestamp=gCount; | 128 netAudio[j].timestamp=gCount; |
| 128 netAudio[j].currentBuffer=!netAudio[j].currentBuffer; //switch buffer | 129 netAudio[j].currentBuffer=!netAudio[j].currentBuffer; //switch buffer |
| 129 netAudio[j].doneOnTime=0; | 130 netAudio[j].doneOnTime=0; |
| 130 scheduleAuxiliaryTask(transmitReceiveAudioTask); //send the buffer | 131 BeagleRT_scheduleAuxiliaryTask(transmitReceiveAudioTask); //send the buffer |
| 131 } | 132 } |
| 132 } | 133 } |
| 133 if((gCount&1)==0){ | 134 if((gCount&1)==0){ |
| 134 netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=analogRead(0,n/2)+audioOut[n*gNumAudioChannels + 0]; | 135 netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=analogReadFrame(context,n/2,0)+context->audioOut[n*context->audioChannels + 0]; |
| 135 netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=analogRead(1,n/2)+audioOut[n*gNumAudioChannels + 0]; | 136 netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=analogReadFrame(context,n/2,1)+context->audioOut[n*context->audioChannels + 0]; |
| 136 } | 137 } |
| 137 netAudio[0].buffers[netAudio[0].currentBuffer][netAudio[0].index++]=0.5*(out+audioOut[n*gNumAudioChannels + 0]);//copy channel 0 to the buffer | 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 |
| 138 // netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=0.5*(out+audioOut[n*gNumAudioChannels + 0]); | 139 // netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]); |
| 139 // netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=0.5*(out+audioOut[n*gNumAudioChannels + 0]); | 140 // netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]); |
| 140 gCount++; | 141 gCount++; |
| 141 } | 142 } |
| 142 } | 143 } |
| 143 | 144 |
| 144 // cleanup_render() is called once at the end, after the audio has stopped. | 145 // cleanup() is called once at the end, after the audio has stopped. |
| 145 // Release any resources that were allocated in initialise_render(). | 146 // Release any resources that were allocated in setup(). |
| 146 | 147 |
| 147 void cleanup_render() | 148 void cleanup(BeagleRTContext *context, void *userData) |
| 148 { | 149 { |
| 149 // closeSockets(); | |
| 150 } | 150 } |
