Mercurial > hg > beaglert
changeset 120:cdd441a304a9 scope-refactoring
Added read to interleaved buffer
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Fri, 21 Aug 2015 15:52:37 +0100 |
parents | c692827083e1 |
children | 2197435e8fb4 |
files | core/NetworkSend.cpp core/ReceiveAudioThread.cpp include/ReceiveAudioThread.h projects/scope/render.cpp |
diffstat | 4 files changed, 33 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- 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(){
--- 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<length; n++){ - destination[n]=buffer[(int)(0.5+readPointer)];//simple ZOH non-interpolation (nearest neighbour) + destination[n*numChannelsInDestination+channelToWriteTo]=buffer[(int)(0.5+readPointer)];//simple ZOH non-interpolation (nearest neighbour) // fprintf(fd,"%f, %d, %f;\n",readPointer,writePointer,destination[n]); //DEBUG readPointer+=samplingRateRatio; if((int)(0.5+readPointer)>=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; }
--- 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)
--- 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; n<context->audioFrames; 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++; }