changeset 222:6a23c07d0fbb mergingClockSync

Working with UdpIoPlugin
author Giulio Moro <giuliomoro@yahoo.it>
date Sun, 14 Feb 2016 01:09:23 +0000
parents dbff109f64c2
children ec9425f728bc
files .cproject core/NetworkSend.cpp core/ReceiveAudioThread.cpp projects/basic_network/render.cpp
diffstat 4 files changed, 25 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/.cproject	Sat Feb 13 16:56:29 2016 +0000
+++ b/.cproject	Sun Feb 14 01:09:23 2016 +0000
@@ -123,7 +123,7 @@
 					<sourceEntries>
 						<entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/audio_in_FFT"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_network"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
@@ -240,7 +240,7 @@
 					<sourceEntries>
 						<entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/audio_in_FFT"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_network"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
--- a/core/NetworkSend.cpp	Sat Feb 13 16:56:29 2016 +0000
+++ b/core/NetworkSend.cpp	Sun Feb 14 01:09:23 2016 +0000
@@ -106,7 +106,7 @@
 #endif /* USE_JUCE */
 	cleanup();
 	int numSamples=blockSize*4>4*channel.bufferLength ? blockSize*4 : 4*channel.bufferLength;
-	channel.numBuffers= 1+numSamples/channel.bufferLength; //the +1 takes the ceil() of the division
+	channel.numBuffers= (1+numSamples/channel.bufferLength) * 3; //the +1 takes the ceil() of the division
 	channel.buffers=(float**)malloc(channel.numBuffers*sizeof(float*));
 	printf("NumBuffers: %d\n", channel.numBuffers);
 	if(channel.buffers==NULL)
@@ -143,7 +143,7 @@
 		channel.writePointer=channel.headerLength; //reset the writePointer
 		channel.writeBuffer=(channel.writeBuffer+1); //switch buffer
 		if(channel.writeBuffer==channel.numBuffers) // and wrap it
-			channel.writeBuffer=0;
+            channel.writeBuffer=0;
 //		printf("WriteBuffer:%d\n", channel.writeBuffer);
 		if(channel.doneOnTime[channel.writeBuffer]==false){ //check if this buffer's last sending has completed on time ...
 			printf("NetworkSend buffer underrun. timestamp: %d :-{\n",
--- a/core/ReceiveAudioThread.cpp	Sat Feb 13 16:56:29 2016 +0000
+++ b/core/ReceiveAudioThread.cpp	Sun Feb 14 01:09:23 2016 +0000
@@ -39,7 +39,7 @@
         //  for(int n=headerLength;n<lastValidPointer; n++){
             //  fprintf(fd2, "%f\n",buffer[n]); //DEBUG
         //  }
-        writePointer=0; //and reset to beginning of the buffer
+    	writePointer=0; //and reset to beginning of the buffer
     }
 }
 void ReceiveAudioThread::pushPayload(int startIndex){ //backup the payload samples that will be overwritten by the new header
@@ -54,17 +54,18 @@
 }
 
 int ReceiveAudioThread::readUdpToBuffer(){
-    if(listening==false || bufferReady==false)
+
+	if(listening==false || bufferReady==false)
         return 0;
     if(writePointer<0)
         return 0;
     if(socket.waitUntilReady(true, waitForSocketTime)){// TODO: if waitForSocketTime here is >>5, the
+    	// destructor (always or sometimes) never actually gets called, despite run() returns ...see issue #1381
 #ifdef USE_JUCE
 #else
 		lastTime=rt_timer_read();
 //        rt_printf("lastTimeread= %llu\n", lastTime);
 #endif /* USE_JUCE */
-    	// destructor (always or sometimes) never actually gets called, despite run() returns ...see issue #1381
         pushPayload(writePointer); //backup headerLength samples. This could be skipped if writePointer==0
         //read header+payload
         int numBytes=socket.read(buffer+writePointer, bytesToRead, true); //read without waiting.
@@ -150,7 +151,7 @@
   //  fprintf(fd,"var=["); //DEBUG
   headerLength=2;
   payloadLength=300; //TODO: make sure that payloadLength and headerLength are the same as the client is sending.
-  bufferLength=std::max(headerLength+(payloadLength*4), headerLength+(aSamplesPerBlock*4)); //there are many considerations that can be done here ...
+  bufferLength=10 * std::max(headerLength+(payloadLength*4), headerLength+(aSamplesPerBlock*4)); //there are many considerations that can be done here ...
                       //We keep a headerLength padding at the beginning of the array to allow full reads from the socket
   buffer=(float*)malloc(sizeof(float)*bufferLength);
   if(buffer==NULL) // something wrong
@@ -206,12 +207,15 @@
     if(writePointer<0 /*|| (numCalls&16383)==0*/){ //if writePointer has not been initalized yet ...
 #ifdef USE_JUCE
 #else //debug
-    	rt_printf("reinit the writePointer, readPointer: %f;\n",readPointer);
-    	readPointer=0;
+    	readPointer = headerLength;
 #endif /* USE_JUCE */
-        writePointer=2*length;  // do it, so that it starts writing at a safety margin from where we write.
+    	// this cumbersome line means: start writing at a position which is as close as possible
+    	// to the center of the buffer, but still is aligned to (payloadLength*x)+headerLength
+    	// thus allowing buffering to allow clock drift to go either way
+        writePointer = headerLength + ((bufferLength-headerLength)/payloadLength/2)*payloadLength;
                             // This will help keeping them in sync.
                             //TODO: handle what happens when the remote stream is interrupted and then restarted
+        printf("write pointer inited at: %d\n", writePointer);
     }
     numCalls++;
     if(length>lastValidPointer) { 
@@ -295,7 +299,6 @@
         sleep(sleepTime);
 #else
 		for(unsigned int n=0; n<ReceiveAudioThread::objAddrs.size(); n++){
-//			printf("%d\n", n);
 			ReceiveAudioThread::objAddrs[n]->readUdpToBuffer();
 		}
 		usleep(sleepTime); //TODO: use rt_task_sleep instead
--- a/projects/basic_network/render.cpp	Sat Feb 13 16:56:29 2016 +0000
+++ b/projects/basic_network/render.cpp	Sun Feb 14 01:09:23 2016 +0000
@@ -9,6 +9,7 @@
 //#include <rtdk.h>
 #include <cmath>
 #include <NetworkSend.h>
+#include <ReceiveAudioThread.h>
 #include <Utilities.h>
 
 // setup() is called once before the audio rendering starts.
@@ -21,6 +22,7 @@
 // Return true on success; returning false halts the program.
 
 NetworkSend networkSend;
+ReceiveAudioThread receive;
 float gFrequency;
 float gInverseSampleRate;
 float gPhase;
@@ -29,9 +31,11 @@
 	// Retrieve a parameter passed in from the initAudio() call
 	gFrequency = *(float *)userData;
 
-	networkSend.setup(context->audioSampleRate, context->audioFrames, 3, 9999, "192.168.7.1");
+	networkSend.setup(context->audioSampleRate, context->audioFrames, 0, 9999, "192.168.7.1");
+	receive.init(10000, context->audioFrames, 0);
+	receive.startThread();
 	gInverseSampleRate = 1.0 / context->audioSampleRate;
-	gPhase = 0.2132;
+	gPhase = 0;
 	return true;
 }
 
@@ -48,10 +52,12 @@
 		if(gPhase > 2.0 * M_PI)
 			gPhase -= 2.0 * M_PI;
 
+		networkSend.log(out);
+		float in;
+		int ret = receive.getSamplesSrc(&in, 1, 1);
 		for(unsigned int channel = 0; channel < context->audioChannels; channel++){
-			context->audioOut[n * context->audioChannels + channel] = out;
+			audioWriteFrame(context, n, channel, in);
 		}
-		networkSend.log(out);
 	}
 }