[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] SF.net SVN: supercollider: [7364] trunk



Revision: 7364
          http://svn.sourceforge.net/supercollider/?rev=7364&view=rev
Author:   joshpar
Date:     2008-02-19 20:46:10 -0800 (Tue, 19 Feb 2008)

Log Message:
-----------
re-commit Win changes

Modified Paths:
--------------
    trunk/Headers/server/SC_CoreAudio.h
    trunk/Source/server/SC_CoreAudio.cpp

Modified: trunk/Headers/server/SC_CoreAudio.h
===================================================================
--- trunk/Headers/server/SC_CoreAudio.h	2008-02-20 04:42:13 UTC (rev 7363)
+++ trunk/Headers/server/SC_CoreAudio.h	2008-02-20 04:46:10 UTC (rev 7364)
@@ -221,6 +221,8 @@
 
     int mInputChannelCount, mOutputChannelCount;
     PaStream *mStream;
+	PaTime mPaStreamStartupTime;
+	int64 mPaStreamStartupTimeOSC;
 
 protected:
     // Driver interface methods
@@ -280,4 +282,4 @@
 }
 #endif // SC_AUDIO_API == SC_AUDIO_API_INNERSC_VST
 
-#endif
\ No newline at end of file
+#endif

Modified: trunk/Source/server/SC_CoreAudio.cpp
===================================================================
--- trunk/Source/server/SC_CoreAudio.cpp	2008-02-20 04:42:13 UTC (rev 7363)
+++ trunk/Source/server/SC_CoreAudio.cpp	2008-02-20 04:46:10 UTC (rev 7364)
@@ -155,6 +155,14 @@
 	return GetCurrentOSCTime();
 }
 
+int64 PaStreamTimeToOSC(PaTime pa_time) {
+	uint64 s, f;
+	s = (uint64)pa_time;
+	f = (uint64)((pa_time - s) * 1000000 * kMicrosToOSCunits);
+
+	return (s << 32) + f;
+}
+
 void initializeScheduler()
 {
 	gOSCoffset = GetCurrentOSCTime(); 
@@ -198,7 +206,7 @@
 
 int PerformOSCMessage(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
 {
-	//scprintf("->PerformOSCMessage %d\n", inData[0]);
+	// scprintf("->PerformOSCMessage %d\n", inData[0]);
 	SC_LibCmd *cmdObj;
 	int cmdNameLen;
 	if (inData[0] == 0) {
@@ -266,7 +274,6 @@
 	
 		// in real time engine, schedule the packet
 		int64 time = OSCtime(packet->mData + 8);
-
 		if (time == 0 || time == 1) {
 			PerformOSCBundle(world, packet);
 		} else {
@@ -277,6 +284,11 @@
 				
 				//ReportLateness(packet->mReply, seconds)
 			}
+			// DEBUG
+			// else	
+				//scprintf("scheduled in %.6f at time %.6f\n", 
+				//	(time-driver->mOSCbuftime)*kOSCtoSecs, 
+				//	(time-gStartupOSCTime)*kOSCtoSecs);
 			
 			SC_ScheduledEvent event(world, time, packet);
 			driver->AddEvent(event);
@@ -1561,15 +1573,16 @@
             PaStreamCallbackFlags statusFlags )
 {
     World *world = mWorld;
+    (void) frameCount, timeInfo, statusFlags; // suppress unused parameter warnings
 
-    (void) frameCount, timeInfo, statusFlags; // suppress unused parameter warnings
-    
 	try {
-		int64 oscTime = GetCurrentOSCTime();
-		int64 temptime = oscTime;
+		// synchronise against the output buffer - timeInfo->currentTime is 0.0 bug in PA?
+		if (mPaStreamStartupTime==0 && mPaStreamStartupTimeOSC==0) {
+			mPaStreamStartupTimeOSC = GetCurrentOSCTime();
+			mPaStreamStartupTime = timeInfo->outputBufferDacTime;
+		}
+		mOSCbuftime = PaStreamTimeToOSC(timeInfo->outputBufferDacTime - mPaStreamStartupTime) + mPaStreamStartupTimeOSC;
 		
-		mOSCbuftime = oscTime;
-		
 		mFromEngine.Free();
 		mToEngine.Perform();
 		mOscPacketsToEngine.Perform();
@@ -1578,7 +1591,7 @@
 		int numOutputs = mOutputChannelCount;
 		const float **inBuffers = (const float**)input;
 		float **outBuffers = (float**)output;
-
+		
 		int numSamples = NumSamplesPerCallback();
 		int bufFrames = mWorld->mBufLength;
 		int numBufs = numSamples / bufFrames;
@@ -1593,6 +1606,7 @@
 
 		int bufFramePos = 0;
 
+		int64 oscTime = mOSCbuftime;
 		int64 oscInc = mOSCincrement;
 		double oscToSamples = mOSCtoSamples;
 	
@@ -1612,17 +1626,30 @@
 				*tch++ = bufCounter;
 			}
 
-
 			// run engine
-
 			int64 schedTime;
 			int64 nextTime = oscTime + oscInc;
+			// DEBUG
+			/*
+			if (mScheduler.Ready(nextTime)) {
+				double diff = (mScheduler.NextTime() - mOSCbuftime)*kOSCtoSecs; 
+				scprintf("rdy %.6f %.6f %.6f %.6f \n", (mScheduler.NextTime()-gStartupOSCTime) * kOSCtoSecs, (mOSCbuftime-gStartupOSCTime)*kOSCtoSecs, diff, (nextTime-gStartupOSCTime)*kOSCtoSecs);
+			}
+			*/
 			while ((schedTime = mScheduler.NextTime()) <= nextTime) {
-				world->mSampleOffset = (int)((double)(schedTime - oscTime) * oscToSamples);
+				float diffTime = (float)(schedTime - oscTime) * oscToSamples + 0.5;
+				float diffTimeFloor = floor(diffTime);
+				world->mSampleOffset = (int)diffTimeFloor;
+				world->mSubsampleOffset = diffTime - diffTimeFloor;
+				
+				if (world->mSampleOffset < 0) world->mSampleOffset = 0;
+				else if (world->mSampleOffset >= world->mBufLength) world->mSampleOffset = world->mBufLength-1;
+				
 				SC_ScheduledEvent event = mScheduler.Remove();
 				event.Perform();
-				world->mSampleOffset = 0;
 			}
+			world->mSampleOffset = 0;
+			world->mSubsampleOffset = 0.f;
 
 			World_Run(world);
 
@@ -1639,7 +1666,7 @@
 			}
 
 			// update buffer time
-			mOSCbuftime = nextTime;
+			oscTime = mOSCbuftime = nextTime;
 		}
 	} catch (std::exception& exc) {
 		scprintf("SC_PortAudioDriver: exception in real time: %s\n", exc.what());
@@ -1729,6 +1756,7 @@
 		inStreamParams.channelCount = mInputChannelCount;
 		inStreamParams.sampleFormat = fmt;
 		inStreamParams.suggestedLatency = Pa_GetDeviceInfo( mDeviceInOut[0] )->defaultLowInputLatency; //$$$todo : allow user to choose latency instead of this
+		scprintf("suggestedLatency used: %.3f\n", Pa_GetDeviceInfo( mDeviceInOut[0] )->defaultLowInputLatency);
 		inStreamParams.hostApiSpecificStreamInfo = NULL;
 
 		PaStreamParameters outStreamParams;
@@ -1761,6 +1789,13 @@
     if( paerror != paNoError )
         PRINT_PORTAUDIO_ERROR( Pa_StartStream, paerror );
 
+	// sync times
+	mPaStreamStartupTimeOSC = 0;
+	mPaStreamStartupTime = 0;
+	// it would be better to do the sync here, but the timeInfo in the callback is incomplete
+	//mPaStreamStartupTimeOSC = GetCurrentOSCTime();
+	//mPaStreamStartupTime = Pa_GetStreamTime(mStream);
+
 	return paerror == paNoError;
 }
 
@@ -1955,4 +1990,4 @@
 {
 }
 
-#endif // SC_AUDIO_API_INNERSC_VST
\ No newline at end of file
+#endif // SC_AUDIO_API_INNERSC_VST


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.