# HG changeset patch # User Giulio Moro # Date 1440168757 -3600 # Node ID cdd441a304a9dd02050c6d11aec2f85923f54537 # Parent c692827083e13150776693701916b13e4ad0cd77 Added read to interleaved buffer diff -r c692827083e1 -r cdd441a304a9 core/NetworkSend.cpp --- a/core/NetworkSend.cpp Fri Aug 21 15:21:34 2015 +0100 +++ b/core/NetworkSend.cpp Fri Aug 21 15:52:37 2015 +0100 @@ -47,7 +47,6 @@ void NetworkSend::setup(float aSampleRate){ setup(aSampleRate, 0, 9999, "192.168.7.1");//channelNumber=0 } - void NetworkSend::setup(float aSampleRate, int aChannelNumber, int aPort, const char *aServer){ staticConstructor(); //FIXME: ideally this should be in the constructor, but this is not currently possible //because of limitations in BeagleRT_createAuxiliaryTask() @@ -59,7 +58,7 @@ setChannelNumber(aChannelNumber); setPort(aPort); setServer(aServer); - printf("Channel %d is sending messages to : %s:%d at %fHz\n", getChannelNumber(), aServer, aPort, aSampleRate); + printf("Channel %d is sending messages to: %s:%d at %fHz\n", getChannelNumber(), aServer, aPort, aSampleRate); } void NetworkSend::log(float value){ //TODO: add a vectorized version of this method @@ -72,7 +71,12 @@ channel.activeBuffer=!channel.activeBuffer; //switch buffer channel.doneOnTime=false; BeagleRT_scheduleAuxiliaryTask(NetworkSend::sendDataTask); //send the buffer - //TODO: maybe we should have transmitAudioTask running in a loop instead of scheduling it multiple times? + // TODO: maybe we should have transmitAudioTask running in a loop instead of scheduling it multiple times? + // The current solution allows to minimize latency when a single channel is used, as there is no inherent + // rt_task_sleep in the thread, as we are signaling it every time. + // Although, there is a possible race condition: if the auxiliaryTask is scheduled by channel 0, + // it might still be executing when channel 1 schedules it. But if the AuxTask has already skipped + // over channel 1, then we are at risk that channel 1 never gets sent. } if(channel.index==channel.headerLength){ channel.buffers[channel.activeBuffer][0] = (float)channel.channelNumber; //TODO: this could actually be done just once in setup() @@ -138,8 +142,9 @@ channels[n].setPort(port); } } -void Scope::setPort(int channel, int port){ - channels[channel].setPort(port); +void Scope::setPort(int channel, int aPort){ + channels[channel].setPort(aPort); + printf("Channel %d is now sending to port %d\n", channel, aPort); } int Scope::getNumChannels(){ diff -r c692827083e1 -r cdd441a304a9 core/ReceiveAudioThread.cpp --- a/core/ReceiveAudioThread.cpp Fri Aug 21 15:21:34 2015 +0100 +++ b/core/ReceiveAudioThread.cpp Fri Aug 21 15:52:37 2015 +0100 @@ -132,6 +132,7 @@ #endif bindToPort(aPort); channel=aChannel; + printf("Channel %d is receiving on port %d\n",aChannel, aPort); // fd=fopen("output.m","w"); //DEBUG // fprintf(fd,"var=["); //DEBUG headerLength=2; @@ -147,7 +148,7 @@ stackBuffer=(float*)malloc(sizeof(float)*headerLength); bytesToRead=sizeof(float)*(payloadLength + headerLength); writePointer=-1; - readPointer=0; //TODO: this *4 is sortof a security margin + readPointer=0; sleepTime=payloadLength/(float)44100 /4.0; //set sleepTime so that you do not check too often or too infrequently //JUCE startThread(threadPriority); } @@ -173,7 +174,10 @@ } return buffer+(int)readPointer; }; -int ReceiveAudioThread::getSamplesSrc(float *destination, int length, float samplingRateRatio){//TODO: add interleaved version +int ReceiveAudioThread::getSamplesSrc(float *destination, int length, + float samplingRateRatio, int numChannelsInDestination, + int channelToWriteTo) +{ if (!(samplingRateRatio>0 && samplingRateRatio<=2)) return -2; if(isListening()==false) @@ -194,7 +198,7 @@ return 0; } for(int n=0; n=lastValidPointer){ @@ -203,7 +207,11 @@ } return readPointer; } - +int ReceiveAudioThread::getSamplesSrc(float *destination, int length, float samplingRateRatio){ + return getSamplesSrc(destination, length, samplingRateRatio, 1,0); + // TODO: rewriting this so that it does not call the override method we can save a multiply and add + // for each sample. +} bool ReceiveAudioThread::isBufferReady(){ return bufferReady; } diff -r c692827083e1 -r cdd441a304a9 include/ReceiveAudioThread.h --- a/include/ReceiveAudioThread.h Fri Aug 21 15:21:34 2015 +0100 +++ b/include/ReceiveAudioThread.h Fri Aug 21 15:52:37 2015 +0100 @@ -58,7 +58,16 @@ void bindToPort(int aPort); bool isListening(); float* getCurrentBuffer(int length); + /** + * Copies the samples to a non-interleaved buffer. + */ int getSamplesSrc(float *destination, int length, float samplingRateRatio); + /** + * Copies the samples to an interleaved buffer. + */ + int getSamplesSrc(float *destination, int length, + float samplingRateRatio, int numChannelsInDestination, + int channelToWriteTo); bool isBufferReady(); #ifdef JUCE // if we are in Juce, then we run a separate thread for each receiver // (as each of them are typically receiving on a mono or stereo track) diff -r c692827083e1 -r cdd441a304a9 projects/scope/render.cpp --- a/projects/scope/render.cpp Fri Aug 21 15:21:34 2015 +0100 +++ b/projects/scope/render.cpp Fri Aug 21 15:52:37 2015 +0100 @@ -84,17 +84,9 @@ gPhase2 -= 2.0 * M_PI; } - static float buffer[2][32]; //this should be context->audioFrames - if(count==0){ - memset(buffer,2*32*sizeof(float),0); - } if(count>0){ - int readPointer0=receiveAudio0.getSamplesSrc(buffer[0], context->audioFrames, 1); - int readPointer1=receiveAudio1.getSamplesSrc(buffer[1], context->audioFrames, 1); - for(unsigned int n=0; naudioFrames; n++){ - context->audioOut[n*2]=buffer[0][n]; - context->audioOut[n*2+1]=buffer[1][n]; - } + int readPointer0=receiveAudio0.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 0); + int readPointer1=receiveAudio1.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 1); } count++; }