Skip to content

Commit 8c0ab6b

Browse files
committed
Restrict Synchronizer sample rate updates to minimum interval
1 parent 24abc97 commit 8c0ab6b

2 files changed

Lines changed: 102 additions & 35 deletions

File tree

Source/Processors/Synchronizer/Synchronizer.cpp

Lines changed: 92 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ void SyncStream::reset (String mainStreamKey)
3636
isMainStream = (streamKey == mainStreamKey);
3737

3838
pulses.clear();
39-
firstMatchingPulse = SyncPulse();
39+
baselineMatchingPulse = SyncPulse();
40+
nextMatchingPulse = SyncPulse();
4041

4142
latestSyncSampleNumber = 0;
4243
latestGlobalSyncTime = 0.0;
@@ -64,7 +65,7 @@ void SyncStream::addEvent (int64 sampleNumber, bool state)
6465
{
6566
SyncPulse latestPulse;
6667
latestPulse.localSampleNumber = sampleNumber;
67-
latestPulse.localTimestamp = sampleNumber / expectedSampleRate;
68+
latestPulse.localTimestamp = double(sampleNumber) / expectedSampleRate;
6869
latestPulse.computerTimeMillis = Time::currentTimeMillis();
6970

7071
pulses.insert (pulses.begin(), latestPulse);
@@ -77,7 +78,7 @@ void SyncStream::addEvent (int64 sampleNumber, bool state)
7778

7879
latestPulse.complete = true;
7980
latestPulse.duration =
80-
(sampleNumber / expectedSampleRate) - latestPulse.localTimestamp;
81+
double(sampleNumber) / expectedSampleRate - latestPulse.localTimestamp;
8182

8283
if (pulses.size() > 1)
8384
{
@@ -122,7 +123,13 @@ double SyncStream::getSyncAccuracy()
122123
//LOGD ("latestGlobalSyncTime: ", latestGlobalSyncTime);
123124
//LOGD ("globalStartTime: ", globalStartTime);
124125
//LOGD ("actualSampleRate: ", actualSampleRate);
125-
double estimatedGlobalTime = latestSyncSampleNumber / actualSampleRate + globalStartTime;
126+
// ORIGINAL CALCULATION:
127+
//double estimatedGlobalTime = latestSyncSampleNumber / actualSampleRate + globalStartTime;
128+
129+
// NEW CALCULATION:
130+
double estimatedGlobalTime = double(latestSyncSampleNumber - baselineMatchingPulse.localSampleNumber)
131+
/ actualSampleRate
132+
+ (baselineMatchingPulse.globalTimestamp);
126133
//LOGD ("estimatedGlobalTime: ", estimatedGlobalTime);
127134
//LOGD ("difference: ", latestGlobalSyncTime - estimatedGlobalTime);
128135

@@ -136,11 +143,11 @@ double SyncStream::getSyncAccuracy()
136143

137144
void SyncStream::syncWith (const SyncStream* mainStream)
138145
{
139-
//LOGD ("Synchronizing ", streamKey, " with ", mainStream->streamKey, "...")
146+
//LOGC ("Synchronizing ", streamKey, " with ", mainStream->streamKey, "...")
140147

141148
if (mainStream->pulses.size() < 2 || pulses.size() < 2)
142149
{
143-
//LOGD ("Not enough pulses to synchronize.");
150+
//LOGC ("Not enough pulses to synchronize.");
144151
return;
145152
}
146153

@@ -174,14 +181,59 @@ void SyncStream::syncWith (const SyncStream* mainStream)
174181
//LOGD ("latestSyncSampleNumber: ", latestSyncSampleNumber, ", latestGlobalSyncTime: ", latestGlobalSyncTime);
175182

176183

177-
if (firstMatchingPulse.complete == false)
184+
if (baselineMatchingPulse.complete == false)
185+
{
186+
baselineMatchingPulse.localTimestamp = pulse.localTimestamp;
187+
baselineMatchingPulse.globalTimestamp = mainPulse.localTimestamp;
188+
baselineMatchingPulse.localSampleNumber = pulse.localSampleNumber;
189+
baselineMatchingPulse.complete = true;
190+
//LOGC ("Time of first matching pulse: ", baselineMatchingPulse.localTimestamp, " (local), ", baselineMatchingPulse.globalTimestamp, " (global)");
191+
}
192+
else
178193
{
179-
firstMatchingPulse.localTimestamp = pulse.localTimestamp;
180-
firstMatchingPulse.globalTimestamp = mainPulse.localTimestamp;
181-
firstMatchingPulse.localSampleNumber = pulse.localSampleNumber;
182-
firstMatchingPulse.complete = true;
183-
//LOGD ("Time of first matching pulse: ", firstMatchingPulse.localTimestamp, " (local), ", firstMatchingPulse.globalTimestamp, " (global)");
194+
if (pulse.localTimestamp - baselineMatchingPulse.localTimestamp > BASELINE_UPDATE_INTERVAL_S)
195+
{
196+
197+
if (nextMatchingPulse.complete == false)
198+
{
199+
nextMatchingPulse.localTimestamp = pulse.localTimestamp;
200+
nextMatchingPulse.globalTimestamp = mainPulse.localTimestamp;
201+
nextMatchingPulse.localSampleNumber = pulse.localSampleNumber;
202+
nextMatchingPulse.complete = true;
203+
}
204+
else
205+
{
206+
if (pulse.localTimestamp - nextMatchingPulse.localTimestamp > BASELINE_UPDATE_INTERVAL_S)
207+
{
208+
209+
double estimatedActualSampleRate = double (nextMatchingPulse.localSampleNumber - baselineMatchingPulse.localSampleNumber)
210+
/ double (nextMatchingPulse.globalTimestamp - baselineMatchingPulse.globalTimestamp);
211+
212+
if (std::abs (estimatedActualSampleRate - expectedSampleRate) / expectedSampleRate < 0.001)
213+
{
214+
std::cout << ">>> UPDATING SAMPLE RATE TO " << estimatedActualSampleRate << std::endl;
215+
actualSampleRate = estimatedActualSampleRate;
216+
}
217+
218+
//baselineMatchingPulse = nextMatchingPulse;
219+
220+
LOGC ("Time of new matching pulse: ",
221+
nextMatchingPulse.localTimestamp,
222+
" (local), ",
223+
nextMatchingPulse.globalTimestamp,
224+
" (global)");
225+
226+
nextMatchingPulse.localTimestamp = pulse.localTimestamp;
227+
nextMatchingPulse.globalTimestamp = mainPulse.localTimestamp;
228+
nextMatchingPulse.localSampleNumber = pulse.localSampleNumber;
229+
}
230+
231+
}
232+
233+
234+
}
184235
}
236+
185237
}
186238
}
187239

@@ -204,35 +256,40 @@ void SyncStream::syncWith (const SyncStream* mainStream)
204256

205257
if (foundMatchingPulse)
206258
{
207-
if (firstMatchingPulse.complete && (pulses[localIndex].localTimestamp - firstMatchingPulse.localTimestamp) > 1.0)
259+
if (baselineMatchingPulse.complete && (pulses[localIndex].localTimestamp - baselineMatchingPulse.localTimestamp) > 1.0)
208260
{
209-
//LOGD ("pulses[localIndex].localSampleNumber: ", pulses[localIndex].localSampleNumber, ", firstMatchingPulse.localSampleNumber: ", firstMatchingPulse.localSampleNumber);
210-
//LOGD ("pulses[localIndex].localTimestamp: ", pulses[localIndex].localTimestamp, ", firstMatchingPulse.localTimestamp: ", firstMatchingPulse.localTimestamp);
211-
//LOGD ("pulses[localIndex].globalTimestamp: ", pulses[localIndex].globalTimestamp, ", firstMatchingPulse.globalTimestamp: ", firstMatchingPulse.globalTimestamp);
261+
//LOGD ("pulses[localIndex].localSampleNumber: ", pulses[localIndex].localSampleNumber, ", baselineMatchingPulse.localSampleNumber: ", baselineMatchingPulse.localSampleNumber);
262+
//LOGD ("pulses[localIndex].localTimestamp: ", pulses[localIndex].localTimestamp, ", baselineMatchingPulse.localTimestamp: ", baselineMatchingPulse.localTimestamp);
263+
//LOGD ("pulses[localIndex].globalTimestamp: ", pulses[localIndex].globalTimestamp, ", baselineMatchingPulse.globalTimestamp: ", baselineMatchingPulse.globalTimestamp);
212264

213-
float estimatedActualSampleRate = (pulses[localIndex].localSampleNumber - firstMatchingPulse.localSampleNumber) / (pulses[localIndex].globalTimestamp - firstMatchingPulse.globalTimestamp);
265+
double estimatedActualSampleRate = double(pulses[localIndex].localSampleNumber - baselineMatchingPulse.localSampleNumber)
266+
/ double(pulses[localIndex].globalTimestamp - baselineMatchingPulse.globalTimestamp);
214267

215-
double estimatedGlobalStartTime = pulses[localIndex].globalTimestamp - pulses[localIndex].localSampleNumber / actualSampleRate;
268+
double estimatedGlobalStartTime = pulses[localIndex].globalTimestamp
269+
- double (pulses[localIndex].localSampleNumber) / estimatedActualSampleRate;
216270

217271
if (std::abs (estimatedActualSampleRate - expectedSampleRate) / expectedSampleRate < 0.001)
218272
{
219-
actualSampleRate = estimatedActualSampleRate;
220-
221-
if (std::abs(estimatedGlobalStartTime) < 1.0)
273+
if (actualSampleRate == -1.0)
222274
{
223-
if (! isSynchronized)
275+
std::cout << "!!! INITIAL UPDATING SAMPLE RATE TO " << estimatedActualSampleRate << std::endl;
276+
actualSampleRate = estimatedActualSampleRate;
277+
278+
if (std::abs (estimatedGlobalStartTime) < 1.0)
279+
{
280+
if (! isSynchronized)
224281

282+
{
283+
globalStartTime = estimatedGlobalStartTime;
284+
isSynchronized = true;
285+
}
286+
}
287+
else
225288
{
226-
globalStartTime = estimatedGlobalStartTime;
227-
isSynchronized = true;
289+
//LOGD ("Estimated global start time of ", estimatedGlobalStartTime, " is out of bounds. Ignoring.");
228290
}
229291
}
230-
else
231-
{
232-
//LOGD ("Estimated global start time of ", estimatedGlobalStartTime, " is out of bounds. Ignoring.");
233-
}
234292

235-
236293
}
237294
else
238295
{
@@ -381,7 +438,9 @@ double Synchronizer::convertSampleNumberToTimestamp (String streamKey, int64 sam
381438
{
382439
if (streams[streamKey]->isSynchronized)
383440
{
384-
return (double) sampleNumber / streams[streamKey]->actualSampleRate + streams[streamKey]->globalStartTime;
441+
return double(sampleNumber - streams[streamKey]->baselineMatchingPulse.localSampleNumber)
442+
/ streams[streamKey]->actualSampleRate
443+
+ streams[streamKey]->baselineMatchingPulse.globalTimestamp;
385444
}
386445
else
387446
{
@@ -393,7 +452,9 @@ int64 Synchronizer::convertTimestampToSampleNumber (String streamKey, double tim
393452
{
394453
if (streams[streamKey]->isSynchronized)
395454
{
396-
double t = (timestamp - streams[streamKey]->globalStartTime) * streams[streamKey]->actualSampleRate;
455+
double t = (timestamp - streams[streamKey]->baselineMatchingPulse.globalTimestamp)
456+
* streams[streamKey]->actualSampleRate
457+
+ double(streams[streamKey]->baselineMatchingPulse.localSampleNumber);
397458

398459
return (int64) t;
399460
}

Source/Processors/Synchronizer/Synchronizer.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ class SyncStream
104104
bool comparePulses (const SyncPulse& pulse1, const SyncPulse& pulse2);
105105

106106
/** Stated sample rate for this stream */
107-
float expectedSampleRate;
107+
double expectedSampleRate;
108108

109109
/** Computed sample rate for this stream */
110-
float actualSampleRate;
110+
double actualSampleRate;
111111

112112
/** TTL line to use for synchronization */
113113
int syncLine;
@@ -128,8 +128,14 @@ class SyncStream
128128
*/
129129
std::vector<SyncPulse> pulses;
130130

131-
/** First pulse matching the global stream */
132-
SyncPulse firstMatchingPulse;
131+
/** Baseline matching the global stream */
132+
SyncPulse baselineMatchingPulse;
133+
134+
/** Next pulse to become the baseline matching pulse */
135+
SyncPulse nextMatchingPulse;
136+
137+
/** Time interval (in seconds) for updating baseline pulse */
138+
const float BASELINE_UPDATE_INTERVAL_S = 10;
133139

134140
/** Determines the maximum size of the sync pulse buffer */
135141
const int MAX_PULSES_IN_BUFFER = 10;

0 commit comments

Comments
 (0)