Revision

View differences:

Source/ClockSync.cpp
44 44
	((myClock_t*)((char*)buffer+sizeof(int)))[0]=timestamp;
45 45
}
46 46
void ClockSync::print(){
47
	 printf("type: %d, timestamp: %lld\n",*((int*)buffer),*((myClock_t*)(((int*)buffer)+1)));
47
	 //printf("type: %d, timestamp: %lld\n",*((int*)buffer),*((myClock_t*)(((int*)buffer)+1)));
48 48
}
49 49
void ClockSync::setPort(int aPort){
50 50
	if(aPort>0){
......
52 52
		int outPort=isSlave() ? aPort+1: aPort;
53 53
		server.bindToPort(inPort);
54 54
		client.setPort(outPort);
55
		printf("Receiving on port %d\n", inPort);
56
		printf("Sending to port %d\n", outPort);    
55
		//printf("Receiving on port %d\n", inPort);
56
		//printf("Sending to port %d\n", outPort);
57 57
	}
58 58
}
59 59
/** 
......
89 89
	ret=server.read(buffer, bufferLength, false);
90 90
	myClock_t timestamp=(myClock_t)virtualClock->getNow();
91 91
	if(timestamp==0){
92
		printf("The virtualClock period is <=0\n");
92
		//printf("The virtualClock period is <=0\n");
93 93
		return -3;
94 94
	}
95 95
	if(ret==-1){
......
97 97
		return -1;
98 98
	}
99 99
	if(ret!=bufferLength){
100
		printf("Received a clockSync of the wrong size: %d\n", ret);
100
		//printf("Received a clockSync of the wrong size: %d\n", ret);
101 101
		return -2;
102 102
	}
103 103
	//  print();
......
106 106

  
107 107
int ClockSync::masterSendSync(){
108 108
	//let's send a sync clockSync!
109
	printf("Sending a sync clockSync\n");
109
	//printf("Sending a sync clockSync\n");
110 110
	setType(kSync);
111 111
	setTimestamp(-1);//do not care about sending the timestamp, a more accurate one will be sent in the follow up
112 112
	localTimestamp=send();
113 113
	if(localTimestamp<0){
114
		printf("Could not send sync clockSync\n");
114
		//printf("Could not send sync clockSync\n");
115 115
		return -1; //error, don't retry, start over
116 116
	}
117 117
	//let's send a followUp
118
	printf("sent a sync clockSync\n");
118
	//printf("sent a sync clockSync\n");
119 119
	setType(kFollowUp);
120 120
	setTimestamp(localTimestamp);
121 121
	if(localTimestamp<0){
122
		printf("Could not send followup clockSync\n");
122
		//printf("Could not send followup clockSync\n");
123 123
		return -2; //error, don't retry, start over
124 124
	}
125 125
	int ret=send();
126 126
	if(ret<0){
127
		printf("Error while sending followup\n");
127
		//printf("Error while sending followup\n");
128 128
		return -3;
129 129
	}
130
	printf("sent a followUp clockSync\n");
130
	//printf("sent a followUp clockSync\n");
131 131
	expectedClockSyncType=kDelayReq;
132 132
	return 1;
133 133
}
134
#ifdef USE_JUCE
135
#define NOTGSHOULDSTOP 1
136
#else
137
extern bool gShouldStop;
138
#define NOTGSHOULDSTOP (!gShouldStop)
139
#endif /* USE_JUCE */
134 140
int ClockSync::receiveLoop(){
135 141
	int receiveLoopElapsed=0;
136
	while(isSlave() || (receiveLoopElapsed<receiveLoopTimeout)){ //when slave, does not timeout!
142
	while( NOTGSHOULDSTOP && (isSlave() || (receiveLoopElapsed<receiveLoopTimeout))){ //when slave, does not timeout!
137 143
		receiveLoopElapsed+=receiveLoopSleepUs;
138 144
		usleep(receiveLoopSleepUs); //how often to check for new clockSyncs;
139
		//   printf("waiting for clockSyncs\n");
145
		//   //printf("waiting for clockSyncs\n");
140 146
		localTimestamp=receive();
141 147
		if(localTimestamp<=0){
142 148
			if(localTimestamp==0){
143
				//  printf("Socket not ready to be read: %lld\n", localTimestamp);
149
				//  //printf("Socket not ready to be read: %lld\n", localTimestamp);
144 150
			}
145
			else if(localTimestamp==-1)
146
				printf("Error while receiving: %lld\n", localTimestamp);
151
			else if(localTimestamp==-1){
152
				//printf("Error while receiving: %lld\n", localTimestamp);
153
			}
147 154
			else if(localTimestamp==-2){
148
				//  printf("Wrong size of the received clockSync: %lld\n", localTimestamp);
155
				//  //printf("Wrong size of the received clockSync: %lld\n", localTimestamp);
149 156
			}
150 157
			continue ; //keep waiting
151 158
		}
152 159
		clockSyncType=getType();
153 160
		clockSyncTimestamp=getTimestamp();
154 161
		if(clockSyncType!=expectedClockSyncType){
155
			printf("Wrong clockSync type: %d, expected: %d\n",clockSyncType, expectedClockSyncType);
162
			//printf("Wrong clockSync type: %d, expected: %d\n",clockSyncType, expectedClockSyncType);
156 163
			return -2; //start over
157 164
		}
158
		printf("Received clockSync type: %d, clockSyncTimestamp: %lld\n", clockSyncType, clockSyncTimestamp);
165
		//printf("Received clockSync type: %d, clockSyncTimestamp: %lld\n", clockSyncType, clockSyncTimestamp);
159 166
		if(isSlave()==true){
160 167
			int ret=slaveHandleMessage();
161 168
			if(ret==1 && clockSyncType==kDelayResp){ //we are done, end of a cycle!
......
175 182
			}
176 183
		}
177 184
	}
178
	printf("Receive loop timeout\n");
185
	//printf("Receive loop timeout\n");
179 186
	return -1;
180 187
}
181 188

  
......
192 199
			setTimestamp(-1);
193 200
			T2=send();
194 201
			if(T2<0){
195
				printf("Error while sending delayReq\n");
202
				//printf("Error while sending delayReq\n");
196 203
				return -1;
197 204
			}
198 205
			expectedClockSyncType=kDelayResp;
......
206 213
			break;
207 214
		}
208 215
		default:
209
			printf("Unexpected message type\n"); // we should never get here
216
			//printf("Unexpected message type\n"); // we should never get here
210 217
			return -1;
211 218
	}
212 219
	return 1;
......
227 234

  
228 235
int ClockSync::sendReceiveLoop(){
229 236
	if(isSlave()==true){
230
		 printf("Waiting for a sync clockSync\n");
237
		 //printf("Waiting for a sync clockSync\n");
231 238
	} else { //if this is master
232
		usleep(1000000); //this times (roughly) how often sync clockSyncs are being sent.
239
		usleep(100000); //this times (roughly) how often sync clockSyncs are being sent.
233 240
		int ret=masterSendSync();
234 241
		if(ret<=0)
235 242
			return -1;
Source/ClockSyncThread.cpp
1 1
#include "ClockSyncThread.h"
2

  
2
#ifdef USE_JUCE
3
#else //declare static members TODO: rather refactor this similar to other threads so that only run and clockSyncTask are static
4
	myClock_t ClockSyncThread::lastTime; // Used for clock synchronization
5
	bool ClockSyncThread::listening;
6
	ClockSync ClockSyncThread::clockSync;
7
	VirtualClock* ClockSyncThread::virtualClock;
8
	bool ClockSyncThread::threadIsExiting;
9
	AuxiliaryTask ClockSyncThread::clockSyncTask;
10
#endif
3 11
#ifdef USE_JUCE
4 12
ClockSyncThread::ClockSyncThread(const String &threadName) :
5 13
			Thread(threadName)
......
15 23
	stopThread();
16 24
#endif /* USE_JUCE */
17 25
}
18
void ClockSyncThread::init(int aPort, int aBlockSize, VirtualClock &aVirtualClock){
26
void ClockSyncThread::init(bool isSlave, int aPort, VirtualClock &aVirtualClock){
19 27
	setVirtualClock(aVirtualClock);
20 28
	listening=false;
21
	clockSync.init(false, aPort, *virtualClock);
29
	clockSync.init(isSlave, aPort, *virtualClock);
22 30
#ifdef USE_JUCE
23 31
	startThread(5);
24 32
#else
33
	threadIsExiting=false;
34
	clockSyncTask=BeagleRT_createAuxiliaryTask(&ClockSyncThread::run,98, "clockSyncTask");
25 35
	//TODO: the thread cannot be started here at the moment because init() is called in setup(), where tasks cannot be scheduled
26 36
#endif /* USE_JUCE */
27 37
}
......
29 39
#ifdef USE_JUCE
30 40
#else
31 41
void ClockSyncThread::startThread(){
32
	BeagleRT_scheduleAuxiliaryTask(receiveDataTask);
42
	printf("starting\n");
43
	BeagleRT_scheduleAuxiliaryTask(clockSyncTask);
44
	printf("started\n");
33 45
}
34 46
void ClockSyncThread::stopThread(){
35 47
	threadIsExiting=true;
......
45 57

  
46 58
void ClockSyncThread::run(){
47 59
	while(!threadShouldExit()){
48
		//  usleep(100000);
49 60
		clockSync.sendReceiveLoop();
50
		double now=virtualClock->getNow();
51
		//  printf("now: %f\n", now*blockSize/44100.0f);
61
		usleep(5000);
62
//		double now=virtualClock->getNow();
63
//		printf("th(end+1)=%f;\n", now/44100.0f);
64
//		printf("act(end+1)=%lld;\n", Clock::getTimeUs());
52 65
	}
53 66
	printf("Thread is not running \n");
54
}
67
}
Source/ClockSyncThread.h
3 3

  
4 4
#ifdef USE_JUCE
5 5
#include <JuceHeader.h>
6
#define IS_STATIC
6 7
#else
8
#define IS_STATIC static
9
#include <BeagleRT.h>
7 10
#endif /*USE_JUCE*/
8 11

  
9 12
#include "ClockSync.h"
......
14 17
class ClockSyncThread {
15 18
#endif /* USE_JUCE */
16 19
private:
17
	myClock_t lastTime; // Used for clock synchronization
18
	bool listening;
19
	ClockSync clockSync;
20
	int blockSize;
21
	VirtualClock *virtualClock;
20
	IS_STATIC myClock_t lastTime; // Used for clock synchronization
21
	IS_STATIC bool listening;
22
	IS_STATIC ClockSync clockSync;
23
	IS_STATIC VirtualClock *virtualClock;
24
#ifdef USE_JUCE
25
#else
26
	IS_STATIC bool threadIsExiting;
27
	IS_STATIC AuxiliaryTask clockSyncTask;
28
#endif /* USE_JUCE */
29

  
22 30
public:
23 31
#ifdef USE_JUCE
24 32
    ClockSyncThread(const String &threadName);
25 33
#else
26 34
    ClockSyncThread();
27
#endif
35
#endif /* USE_JUCE */
28 36
    ~ClockSyncThread();
29
    void init(int aPort, int aBlockSize, VirtualClock &aVirtualClock);
30
	void setVirtualClock(VirtualClock &aVirtualClock);
37
    IS_STATIC void init(bool isSlave, int aPort, VirtualClock &aVirtualClock);
38
    IS_STATIC void setVirtualClock(VirtualClock &aVirtualClock);
31 39

  
32
    void run();
40
    IS_STATIC void run();
33 41
#ifdef USE_JUCE
34 42
#else
35
    void startThread();
36
    void stopThread();
43
    IS_STATIC void startThread();
44
    IS_STATIC void stopThread();
45
    IS_STATIC bool threadShouldExit();
37 46
#endif // USE_JUCE
38 47
};
39 48
#endif  // CLOCK_SYNC_THREAD_H_INCLUDED
Source/PluginProcessor.cpp
130 130
	// Use this method as the place to do any pre-playback
131 131
	// initialisation that you need..
132 132
	virtualClock.init();
133
	clockSyncThread.init(5000, samplesPerBlock, virtualClock);
133
	clockSyncThread.init(false, 5000, virtualClock);
134
	_samplesPerBlock=samplesPerBlock;
134 135
}
135 136

  
136 137
void ClockSyncAudioProcessor::releaseResources()
......
142 143
void ClockSyncAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
143 144
{
144 145
	//  printf("period: %lld\n",virtualClock.getPeriod());
145
	virtualClock.sync();  
146
	virtualClock.sync(_samplesPerBlock);  
147
	double now=virtualClock.getNow();
148
	//  printf("now(end+1)=%f;\n", now);
146 149
	// In case we have more outputs than inputs, this code clears any output
147 150
	// channels that didn't contain input data, (because these aren't
148 151
	// guaranteed to be empty - they may contain garbage).
Source/PluginProcessor.h
66 66
    void getStateInformation (MemoryBlock& destData) override;
67 67
    void setStateInformation (const void* data, int sizeInBytes) override;
68 68
private:
69
	int _samplesPerBlock;
69 70
    VirtualClock virtualClock;
70 71
    ClockSyncThread clockSyncThread;
71 72
    //==============================================================================
Source/VirtualClock.cpp
9 9
	init();
10 10
}
11 11
void VirtualClock::sync(){
12
	sync(1);
13
}
14
void VirtualClock::sync(double count){
12 15
	myClock_t currentTime=Clock::getTimeUs();
13 16
	if(firstRun==true){
14 17
		firstRun=false;
15 18
		startTime=currentTime;
16 19
	} else {
17
		period=movingAverage.add(currentTime-lastSync); //TODO: replace with Kalman filter
20
		period=movingAverage.add((currentTime-lastSync)/count); //TODO: replace with Kalman filter
18 21
	}
19
	//  printf("lastPeriod(end+1)= %lld;\n", currentTime-lastSync);
20 22
	lastSync=currentTime;
21 23
}
22 24

  
23 25
double VirtualClock::getNow(){
24
	myClock_t now=Clock::getTimeUs(); 
26
	myClock_t now=Clock::getTimeUs();
25 27
	if(period<=0){
26 28
		return now;
27 29
	}
28
	double beginningOfPeriod=lastSync; // TODO: if sync() does not get called every time (but e.g. only every so often),
30
	//  double beginningOfPeriod=lastSync; // TODO: if sync() does not get called every time (but e.g. only every so often),
29 31
													 // then this line (and the class) needs editing
30 32
	myClock_t elapsed=(now-startTime);
31 33
	double frac=elapsed/(double)period;
......
33 35
	return frac;
34 36
}
35 37

  
36
myClock_t VirtualClock::getPeriod(){
38
double VirtualClock::getPeriod(){
37 39
	return period;
38
}
40
}
Source/VirtualClock.h
9 9
	myClock_t startTime;
10 10
	myClock_t lastSync;
11 11
	bool firstRun;
12
	myClock_t period;
13
	MovingAverage<myClock_t> movingAverage;
12
	double period;
13
	MovingAverage<double> movingAverage;
14 14
public:
15 15
	void init();
16 16
	VirtualClock();
......
21 21
/**
22 22
	Call this method asynchronously, passing a number of equally spaced events that have elapsed since the last call.
23 23
*/
24
	void sync(long long int count);
24
	void sync(double count);
25 25
/**
26 26
	Get the current time according to the VirtualClock.
27 27
	
......
33 33
	
34 34
	Get the length of the period (difference between calls to sync() after various filtering operations)
35 35
*/
36
	myClock_t getPeriod();
36
	double getPeriod();
37 37
};
38 38

  
39
#endif /* VIRTUAL_CLOCK_H_INCLUDED */
39
#endif /* VIRTUAL_CLOCK_H_INCLUDED */

Also available in: Unified diff