-//printf("%d: ", swLen);
- for(uint32_t i=0; i<num; i++)
- {
-//printf("[%d->%d]", syncSave[i], syncPt[i]);
- if (syncSave[i] != syncPt[i])
- {
- done2 = false;
-// break;
- }
- }
-//printf("\n");
-
- while (!done2)
- {
- float amplitude = ampStep;
- uint32_t smallestIdx = SmallestIdx(currentRow, num);
- uint32_t cnt = 1;
- a[0] = currentRow[smallestIdx];
-//printf("a[0]=%.2lf: ", a[0]);
-
- for(uint32_t i=0; i<num; i++)
- {
- // Make sure we haven't gone beyond the end of any of the streams we're looking at
- if (syncSave[i] >= Global::streamLen[i])
- return swLen;
-
- if (i == smallestIdx)
- {
- currentRow[i] = 0;
- StepAndAddForward(syncSave[i], currentRow[i], i);
-//printf("<%.2lf>", currentRow[i]);
-
- // Make sure no spurious signals are looked at
- if ((syncSave[i] < syncPt[i]) && (currentRow[i] < 24.0))
- StepAndAddForward(syncSave[i], currentRow[i], i);
-
- continue;
- }
-
- double crSave = currentRow[i];
- currentRow[i] -= a[0];
-
- // Don't bother with stuff that's out of range! :-P
- if (syncSave[i] == syncPt[i])
- continue;
-
- // Try to find correlates
- a[cnt] = crSave;//currentRow[i];
- cnt++;
- sigma = StdDeviation(a, cnt, &mean);
-//for(uint32_t j=1; j<cnt; j++)
-// printf("[%.2lf]", a[j]);
-
-//relaxed sigma...
- if (sigma <= 5.5)//SIGMA_THRESHOLD)
- {
- currentRow[i] = 0;
- StepAndAddForward(syncSave[i], currentRow[i], i);
-//printf("{%.2lf}", currentRow[i]);
- amplitude += ampStep;
-
- // Make sure no spurious signals are looked at
- if ((syncSave[i] < syncPt[i]) && (currentRow[i] < 24.0))
- StepAndAddForward(syncSave[i], currentRow[i], i);
- }
- else
- {
- cnt--;
- }
-//printf(" ==> %.2lf\n\t", sigma);
- }
-
- sigma = StdDeviation(a, cnt, &mean);
- synthWave[swLen] = (uint32_t)(mean + 0.5);
- swAmplitude[swLen] = amplitude;
- swLen++;
- done2 = true;
-
-//printf("%d: ", swLen);
- for(uint32_t i=0; i<num; i++)
- {
-//printf("[%d->%d]", syncSave[i], syncPt[i]);
- if (syncSave[i] != syncPt[i])
- {
- done2 = false;
-// break;
- }
- }
-//printf("\n");
- }
-
- sigma = StdDeviation(currentRow, num, &mean);
- synthWave[swLen] = mean;
- swAmplitude[swLen] = 1.0f;
- swLen++;
- }
- }
-
- return swLen;
-}
-
-
-//
-// Attempt to find the sync point for the passed in stream #s. If found, set
-// sync1 & sync2 to the spots where sync was found (typically, one or the other
-// will be zero) and return true, otherwise return false.
-//
-bool FindSync(uint32_t stream1, uint32_t stream2, uint32_t & sync1, uint32_t & sync2)
-{
- sync1 = sync2 = 0;
-
- // We *should* be able to synchronize within around 80 fluxes or so. If not, then there's bigger problems.
- for(uint32_t offset=0; offset<80; offset++)
- {
- uint32_t strmLen = Uint32LE(Global::stream[stream1]->dataLength);
- bool found = true;
-
- // How many bits should we consider as synchronized? All of them?
- for(uint32_t i=1, i2=1; i<strmLen; i++, i2++)
- {
- double time1 = (double)Global::stream[stream1]->data[i];
- double time2 = (double)Global::stream[stream2]->data[i2 + offset];
-
- while (Global::stream[stream1]->data[i] == 0xFF)
- {
- i++;
- time1 += (double)Global::stream[stream1]->data[i];
- }
-
- while (Global::stream[stream2]->data[i2] == 0xFF)
- {
- i2++;
- time2 += (double)Global::stream[stream2]->data[i2 + offset];
- }
-
- double mean = (time1 + time2) * 0.5;
- double sigma = sqrt(0.5 * (((time1 - mean) * (time1 - mean))
- + ((time2 - mean) * (time2 - mean))));
-
- if (sigma > 2.50)
- {
- // How many bits is enough to say we found it?
-/*
-N.B.: This (1,000) is fine for Apple Panic (which has shitty captures with junk in between sectors), but not for Championship Lode Runner which doesn't have any sync bytes for a loooooooooooong time
-*/
- if (i < 10000)
- found = false;
-
- break;
- }
- }
-
- if (found)
- {
- sync2 = offset;
- return true;
- }
- }
-
- // Since we didn't find sync moving stream 2 forward, let's try stream 1
- for(uint32_t offset=0; offset<80; offset++)
- {
- uint32_t strmLen = Uint32LE(Global::stream[stream2]->dataLength);
- bool found = true;
-
- // How many bits should we consider as synchronized? All of them?
- for(uint32_t i=1, i2=1; i<strmLen; i++, i2++)
- {
- double time1 = (double)Global::stream[stream2]->data[i];
- double time2 = (double)Global::stream[stream1]->data[i2 + offset];
-
- while (Global::stream[stream2]->data[i] == 0xFF)
- {
- i++;
- time1 += (double)Global::stream[stream2]->data[i];
- }
-
- while (Global::stream[stream1]->data[i2] == 0xFF)
- {
- i2++;
- time2 += (double)Global::stream[stream1]->data[i2 + offset];
- }
-
- double mean = (time1 + time2) * 0.5;
- double sigma = sqrt(0.5 * (((time1 - mean) * (time1 - mean))
- + ((time2 - mean) * (time2 - mean))));
-
- if (sigma > 2.50)
- {
- // How many bits is enough to say we found it?
- if (i < 10000)
- found = false;
-
- break;
- }
- }
-
- if (found)
- {
- sync1 = offset;
- return true;
- }
- }
-
- return false;
-}
-
-
-void FindSyncForStreams(uint32_t * syncPt, uint32_t num)
-{
-// uint32_t syncPt[10] = { 0 };
- uint32_t base = 0;
- syncPt[0] = 0;
-
- for(uint32_t i=1; i<num; i++)
- {
- if (FindSync(sNum[base], sNum[i], syncPt[base], syncPt[i]) == true)
- {
- // Check to see which stream has to move. If it's not the current base, then we don't have to do anything but check the next one; otherwise, we have to shift everything done prior by the amount of the shift and set the new base to be the one that didn't move.
- if (syncPt[base] != 0)
- {
- for(uint32_t j=0; j<i; j++)
- {
- if (j != base)
- syncPt[j] += syncPt[base];
- }
-
- base = i;
- }
- }
- else
- {
- // should we do this? or just set a flag that we couldn't sync this one?
- syncPt[i] = -1;
-// return;
- }
- }
-
- // If there was no sync for any of the other tracks, signal this by counting the number of non-sync tracks and checking against the total # of tracks - 1.
- uint32_t nonSync = 0;
-
- for(uint32_t i=1; i<num; i++)
- {
- if (syncPt[i] == (uint32_t)-1)
- nonSync++;
- }
-
- // Signal that sync failed
- if (nonSync == (num - 1))
- syncPt[0] = -1;
-/*
-v v
-0 0 0 0 0 base = 0, i = 1
-
-0 1
-0, 10
-
-v v
-0 10 0 0 0 base = 0, i = 2
-5 10 0 0 0
-
-0 2
-5, 0
-
- v v
-5 15 0 0 0 base = 2, i = 3
-5 15 0 7 0
-
-2 3
-0, 7
-
- v v
-5 15 0 7 0 base = 2, i = 4
-5 15 8 7 0
-
-2 4
-8, 0
-
-13 23 8 15 0 base = 4
-
- if (FindSync(sNum[0], sNum[1], syncPt[0], syncPt[1]) == false)
- {
- // give up, we couldn't sync stream 0 & 1... :-/
- }
-
- // check to see which one had to move, and use the other to check against the rest...
- uint32_t base = (syncPt[0] == 0 ? 0 : 1);
-
- if (FindSync(sNum[base], sNum[2], syncPt[base], syncPt[2]) == false)
- {
- // give up, we couldn't sync stream 0 & 1... :-/
- }
-
- // check again, to see which one moved and the other...
- uint32_t base2 = (syncPt[base] == 0 ? base, 2);
-
- // & so on...
-
-
-*/
-}
-
-
-void FindInitialSyncForStreams(uint32_t * sync, uint32_t num)
-{
-/*
-What we need to do is find the FF. or FF.. or FE..s, then find the first non-zero trailing byte after that to be our sync point. If we don't, we run the risk of getting bad starts because some bitstreams might have some sync starts that start with the wrong number of 1 bits, and thus walking back will fail.
-*/
- // Let's try aligning samples to each other by counting to a short stream
- // of FF.(.)s...
- uint64_t bitPat0 = 0;
-
- for(uint32_t i=0; i<num; i++)
- {
- sync[i] = 0;
- uint64_t bitPat = 0;
- initSyncTime[i] = 0;
-
- // We'll use a naïve window to scan for the bit patterns
- for(int32_t j=0; j<Uint32LE(Global::stream[sNum[i]]->dataLength); j++)
- {
- uint32_t timeToNext = Global::streamData[i][j];
-
- while (Global::streamData[i][j] == 0xFF)
- {
- j++;
- timeToNext += Global::streamData[i][j];
- }
-
- initSyncTime[i] += (double)timeToNext;
-
- if ((timeToNext >= 24) && (timeToNext <= 49))
- bitPat = (bitPat << 1) | 1;
- else if ((timeToNext >= 50) && (timeToNext <= 80))
- bitPat = (bitPat << 2) | 1;
- else if ((timeToNext >= 81) && (timeToNext <= 112))
- bitPat = (bitPat << 3) | 1;
- else
- {
- while (timeToNext > 32)
- {
- bitPat <<= 1;
- timeToNext -= 32;
- }
- }
-
- if (i == 0)
- bitPat0 = bitPat;
-
- // Search for first instance of 3 FF. or 3 FF.. in bitstream
- // Might need to look for FE.. as well
- // 0 1111 1111 0111 1111 1011 1111 1101
- // 0111 1111 1001 1111 1110 0111 1111 1001
-// if (((bitPat & 0x1FFFFFFF) == 0x0FF7FBFD)
-// || (bitPat & 0xFFFFFFFF) == 0x7F9FE7F9)
- // Need to see at least two regular bytes after as well:
- // 0 1111 1111 0111 1111 1011 1111 1101 xxxx xxx1 xxxx xxx1
- // 0111 1111 1001 1111 1110 0111 1111 1001 xxxx xxx1 xxxx xxx1
- if ((bitPat & 0x1FFFFFFF0101) == 0x0FF7FBFD0101)
- {
- if ((i != 0) && (bitPat != bitPat0))
- continue;
-
- sync[i] = j - (j - 25 >= 0 ? 25 : 0);
- break;
- }
- else if ((bitPat & 0xFFFFFFFF0101) == 0x7F9FE7F90101)
- {
- if ((i != 0) && (bitPat != bitPat0))
- continue;
-
- sync[i] = j - (j - 25 >= 0 ? 25 : 0);
- break;
- }
- }
- }
-}
-
-
-//
-// Walk through the streams backwards until we hit the zero point on one of them. This assumes the sync point we found initially is a good one (it might not be!).
-//
-void BacktrackInitialSync(uint32_t * syncPt, uint32_t num)
-{
-// uint32_t count = 0;
- double a[10];
-// uint32_t syncSave[10];
-
- // Save the original sync points (do we need to?)
-// for(uint32_t i=0; i<num; i++)
-// syncSave[i] = syncPt[i];
-
- uint32_t minSlip = (uint32_t)-1;
-
- for(uint32_t i=0; i<num; i++)
- {
- if (syncPt[i] < minSlip)
- minSlip = syncPt[i];
- }
-
- while (minSlip > 0)
- {
- // Get the time for this step into a[]
- for(uint32_t i=0; i<num; i++)
- {
- // We scale the time by a factor of the measured RPM to 300 RPM, which should get us closer to a "normal" time for all streams
- a[i] = (double)Global::stream[sNum[i]]->data[syncPt[i]];// * ratio[i];
-
- while ((syncPt[i] > 0)
- && (Global::stream[sNum[i]]->data[syncPt[i] - 1] == 0xFF))
- {
- syncPt[i]--;
- a[i] += (double)Global::stream[sNum[i]]->data[syncPt[i]];// * ratio[i];
- }
- }
-
- double sigma = StdDeviation(a, num);
-// count++;
-
- if (sigma > SIGMA_THRESHOLD)
- {
- printf("\n");
-
- for(uint32_t i=0; i<num; i++)
-// printf("<%6.2lf>", (double)Global::stream[sNum[i]]->data[syncPt[i]]);// * ratio[j]);
- printf("<%6.2lf>", a[i]);// * ratio[j]);
-
- printf(" --> %.2lf\n", sigma);
-
- uint32_t syncCount = 0;
-
- // Save sync origins for later analysis
-// for(uint32_t j=0; j<num; j++)
-// syncSave[j] = syncPt[j];
-
- // It may turn out that this is too large too...
- while (sigma > 3.30)//SIGMA_THRESHOLD)
- {
- // Deal with the problem. The heuristic is find the largest value in the set, then advance the other streams by one step until they are "close" to the largest. If the std. deviation is too large, try again; eventually it should be within good limits.
- uint32_t largestIdx = LargestIdx(a, num);
-
- for(uint32_t i=0; i<num; i++)
- {
- if (i == largestIdx)
- {
- printf(" ~~~~ ");
- continue;
- }
-
- int32_t walkBack = syncPt[i] - 1;
- double ttn = (double)Global::stream[sNum[i]]->data[walkBack];
-
- while ((walkBack > 0)
- && (Global::stream[sNum[i]]->data[walkBack - 1] == 0xFF))
- {
- walkBack--;
- ttn += (double)Global::stream[sNum[i]]->data[walkBack];// * ratio[i];
- }
-
- // If the difference between the highest and this is over 5, add the next time interval and let the sync counter, uh, slip (backwards!) :-)
- if ((a[largestIdx] - a[i]) > 5.0)
- {
- syncPt[i] = walkBack;
- a[i] += ttn;
- printf(" %6.2lf ", ttn);
- }
- else
- printf(" ");
- }
-
- printf("\n");
-
- for(uint32_t i=0; i<num; i++)
- printf("<%6.2lf>", a[i]);
-
- sigma = StdDeviation(a, num);
- printf(" ==> %.2lf\n", sigma);
-
- syncCount++;
-
- if (syncCount > 20)
- {
- // Back up the train
- for(uint32_t i=0; i<num; i++)
- {
- syncPt[i] -= (syncPt[i] >= 40 ? 40 : 0);
-
- if ((int32_t)syncPt[i] < 0)
- syncPt[i] = 0;
- }
-
- minSlip = 0;
- printf("Could not synchronize streams...\n");
- break;
- }
- }
- }
-
- // Point as the next time step and see where the minimum sync point is now...
- for(uint32_t i=0; i<num; i++)
- {
- syncPt[i]--;
-
- if (syncPt[i] < minSlip)
- minSlip = syncPt[i];
- }
- }
-}
-
-
-//
-// Walk through the streams backwards until we hit the zero point on one of them. This assumes the sync point we found initially is a good one (it might not be!). [We've found that sometimes, the initial sync point is *really* bad.]
-//
-void BacktrackInitialSync2(uint32_t * syncPt, uint32_t num)
-{
- double a[10];
- uint32_t syncSave[10];
- uint32_t minSlip = Smallest(syncPt, num);
-
- while (minSlip > 0)
- {
- // Get the time for this step into a[]
- for(uint32_t i=0; i<num; i++)
- {
- // We scale the time by a factor of the measured RPM to 300 RPM, which should get us closer to a "normal" time for all streams
- a[i] = (double)Global::stream[sNum[i]]->data[syncPt[i]];// * ratio[i];
-
- while ((syncPt[i] > 0)
- && (Global::stream[sNum[i]]->data[syncPt[i] - 1] == 0xFF))
- {
- syncPt[i]--;
- a[i] += (double)Global::stream[sNum[i]]->data[syncPt[i]];// * ratio[i];
- }
- }
-
- double sigma = StdDeviation(a, num);
-
- if (sigma > SIGMA_THRESHOLD)
- {
- uint32_t syncCount = 0;
-
- // Save sync origins for later analysis
- memcpy(syncSave, syncPt, sizeof(syncSave));
-
- // It may turn out that this is too large too...
- while (sigma > SIGMA_THRESHOLD)
- {
- // Deal with the problem. The heuristic is find the largest value in the set, then advance the other streams by one step until they are "close" to the largest. If the std. deviation is too large, try again; eventually it should be within good limits.
- uint32_t largestIdx = LargestIdx(a, num);
-
- // We now pull all streams "forward" until they are within 7
- // underneath the largest or past it.
- for(uint32_t i=0; i<num; i++)
- {
- if (i == largestIdx)
- continue;
-
- double ttn = 0;
- int32_t walkback = syncPt[i];
-
- while((a[largestIdx] - (a[i] + ttn)) > 7.0)
- {
- if (walkback <= 0)
- {
- memcpy(syncPt, syncSave, sizeof(syncSave));
- printf("Synchronized as far back as possible...\n");
- return;
- }
-
- walkback--;
- ttn += (double)Global::stream[sNum[i]]->data[walkback];// * ratio[i];
-
- while ((walkback > 0)
- && (Global::stream[sNum[i]]->data[walkback - 1] == 0xFF))
- {
- walkback--;
- ttn += (double)Global::stream[sNum[i]]->data[walkback];// * ratio[i];
- }
- }
-
- syncPt[i] = walkback;
- a[i] += ttn;
- }
-
- sigma = StdDeviation(a, num);
-
- syncCount++;
-
- if (syncCount > 20)
- {
- // Back up the train
- for(uint32_t i=0; i<num; i++)
- {
- syncPt[i] -= (syncPt[i] >= 40 ? 40 : 0);
-
- if ((int32_t)syncPt[i] < 0)
- syncPt[i] = 0;
- }
-
- minSlip = 0;
- printf("Could not synchronize streams...\n");
- break;
- }
- }
- }
-
- // Point as the next time step and see where the minimum sync point is now...
- for(uint32_t i=0; i<num; i++)
- {
- syncPt[i]--;
-
- if (syncPt[i] < minSlip)
- minSlip = syncPt[i];
- }
- }
-}
-
-
-//
-// Walk through the streams backwards until we hit the zero point on one of them. This assumes the sync point we found initially is a good one (it might not be!). [We've found that sometimes, the initial sync point is *really* bad.]
-//
-void BacktrackInitialSync3(uint32_t * sync, uint32_t num)
-{
- double a[9];
- uint32_t syncSave[9];
-
- while (true)
- {
- uint32_t minSlip = Smallest(sync, num);
-
- if (minSlip == 0)
- break;
-
- // Save sync origins for later analysis if necessary
- memcpy(syncSave, sync, sizeof(syncSave));
-
- // Get the time for this step into a[]
- StepBack(sync, a, num);
- double sigma = StdDeviation(a, num);
-
- if (sigma > SIGMA_THRESHOLD)
- {
- uint32_t syncCount = 0;
- bool pulled;
-
- do
- {
- syncCount++;
-
- if (syncCount > 20)
- {
- // Back up the train
- for(uint32_t i=0; i<num; i++)
- {
- sync[i] -= (sync[i] >= 40 ? 40 : 0);
-
- if ((int32_t)sync[i] < 0)
- sync[i] = 0;
- }
-
- printf("Could not synchronize streams...\n");
- return;
- }
-
- // Deal with the problem. The heuristic is find the largest value in the set, then advance the other streams by one step until they are "close" to the largest. If the std. deviation is too large, try again; eventually it should be within good limits.
- uint32_t largestIdx = LargestIdx(a, num);
- pulled = false;
-
- // We now pull all streams "forward" until they are within 7
- // underneath the largest or past it.
- for(uint32_t i=0; i<num; i++)
- {
- if (i == largestIdx)
- continue;
-
- double ttn = 0;
- uint32_t walkback = sync[i];
-
- while((a[largestIdx] - (a[i] + ttn)) > 7.0)
- {
- pulled = true;
-
- if ((int32_t)walkback <= 0)
- {
- memcpy(sync, syncSave, sizeof(syncSave));
- printf("Synchronized as far back as possible...\n");
- return;
- }
-
- StepAndAddBack(walkback, ttn, i);
- }
-
- sync[i] = walkback;
- a[i] += ttn;
- }
-
- // Calculate the standard deviation at this new point
- sigma = StdDeviation(a, num);
-
- // Heuristic: see if we're stuck with a bad sigma and can't pull any more forward; if so, pull forward one step and see if that gets us any traction...
- if ((sigma > SIGMA_THRESHOLD) && !pulled)
- {
- for(uint32_t i=0; i<num; i++)
- StepAndAddBack(sync[i], a[i], i);
-
- sigma = StdDeviation(a, num);//, &mean);
- pulled = true;
- }
- }
- while ((sigma > SIGMA_THRESHOLD) && pulled);
- }
- }
-}
-
-
-void BacktrackInitialSync4(uint32_t * sync, uint32_t num)
-{
- double a[9], a2[9];
- uint32_t syncSave[9];
-
- while (true)
- {
- uint32_t minSlip = Smallest(sync, num);
-
- if (minSlip == 0)
- break;
-
- // Save sync origins for later analysis if necessary
- memcpy(syncSave, sync, sizeof(syncSave));
-
- // Get the time for this step into a[]
- StepBack(sync, a, num);
- double sigma = StdDeviation(a, num);
-
- if (sigma > SIGMA_THRESHOLD)
- {
-printf("\n");
-for(uint32_t i=0; i<num; i++) { printf("<%6.2lf>", a[i]); }
-printf(" --> %.2lf\n", sigma);
- // Let's see if we can re-sync through this rough patch
- int result = Resync(sync, a, num, -1);
-
- // Well, we failed to find synchronization... :-(
- if (result == -1)
- {
- memcpy(sync, syncSave, sizeof(syncSave));
- return;
- }
-
- // OK, we have a good result, but what kind (1=end, 0=sync OK)?
- if (result == 0)
- StepBack(sync, a2, num);
- else if (result == 1)
- {
-for(uint32_t j=0; j<num; j++) { printf("{%d} ", sync[j]); }
-printf("\n");
- memcpy(sync, syncSave, sizeof(syncSave));
-for(uint32_t j=0; j<num; j++) { printf("<%d> ", sync[j]); }
-printf("\n");
- StepBack(sync, a2, num);
- return;
- }
- }
- }
-}
-
-
-void StepBackUntilBad(uint32_t * sync, double * a, uint32_t num)
-{
- while (true)
- {
- // See where the minimum sync point is now...
- uint32_t minSlip = Smallest(sync, num);
-
- if (minSlip == 0)
- break;
-
- // Get the time for this step into a[]
- StepBack(sync, a, num);
- double sigma = StdDeviation(a, num);
-
- if (sigma > SIGMA_THRESHOLD)
- {
- printf("\n");
-
- for(uint32_t i=0; i<num; i++)
- printf("<%6.2lf>", a[i]);
-
- printf(" --> %.2lf\n", sigma);
- return;
- }
- }
-
- printf("---------------------------------------------------\nAT START\n\n");
-}
-
-
-bool StepBackThruBad(uint32_t * sync, double * a, uint32_t num)
-{
- // Deal with the problem. The heuristic is find the largest value in the set, then advance the other streams by one step until they are "close" to the largest. If the std. deviation is too large, try again; eventually it should be within good limits.
- uint32_t largestIdx = LargestIdx(a, num);
-
-/*
-New heuristic to try here: advance each stream until it comes within 7 on the bottom end or passes it altogether; check the sigma then.
-
-2nd heuristic: attempt to pull the next 'num' time all at once and *add* it to the current step, check the sigma to see if it's in tolerance (*and* check the lookahead).
-*/
- for(uint32_t i=0; i<num; i++)
- {
- if (i == largestIdx)
- {
- printf(" ~~~~ ");
- continue;
- }
-
- // heuristic 1
- bool seen = false;
- double ttn = 0;
- uint32_t walkback = sync[i];
-
- // If the difference between the highest and this is over 7, add the next time interval and let the sync counter, uh, slip (backwards!) :-)
- while ((a[largestIdx] - (a[i] + ttn)) > 7.0)
- {
- seen = true;
- StepAndAddBack(walkback, ttn, i);
- }
-
- sync[i] = walkback;
- a[i] += ttn;
-
- if (seen)
- printf(" %6.2lf ", ttn);
- else
- printf(" ");
- }
-
- printf("\n");
-
- for(uint32_t i=0; i<num; i++)
- printf("<%6.2lf>", a[i]);
-
- double sigma = StdDeviation(a, num);
- printf(" ==> %.2lf%s", sigma, (sigma <= SIGMA_THRESHOLD ? " (OK)" : ""));
-
-double lookahead[9];
-for(uint32_t i=0; i<num; i++)
- lookahead[i] = (double)Global::streamData[i][sync[i] - 1] * ratio[i];
-printf(" (lookahead=%.2lf, %d)\n", StdDeviation(lookahead, num), Lookahead(sync, num, -1));
-for(uint32_t j=0; j<num; j++) { printf("{%d}%s", sync[j], (j < num - 1 ? "-" : "")); }
-printf("\n");
-
- if (sigma < SIGMA_THRESHOLD)
- {
- // If we're out of the woods, make sure to step to the next step...
- double b[9];
- StepBack(sync, b, num);
- return false;
- }
-
- return true;
-}
-
-
-void StepBack(uint32_t * sync, double * a, uint32_t num)
-{
- for(uint32_t i=0; i<num; i++)
- {
- int32_t walkback = sync[i] - 1;
- a[i] = (double)Global::streamData[i][walkback] * ratio[i];
-
- while ((walkback > 0)
- && (Global::streamData[i][walkback - 1] == 0xFF))
- {
- walkback--;
- a[i] += (double)Global::streamData[i][walkback] * ratio[i];
- }
-
- sync[i] = walkback;
- }
-}
-
-
-void StepAndAddBack(uint32_t * sync, double * a, uint32_t num)
-{
- for(uint32_t i=0; i<num; i++)
- {
- int32_t walkback = sync[i] - 1;
- a[i] += (double)Global::streamData[i][walkback] * ratio[i];
-
- while ((walkback > 0)
- && (Global::streamData[i][walkback - 1] == 0xFF))
- {
- walkback--;
- a[i] += (double)Global::streamData[i][walkback] * ratio[i];
- }
-
- sync[i] = walkback;
- }
-}
-
-
-void StepAndAddBack(uint32_t & loc, double & a, uint32_t i)
-{
- int32_t walkback = loc - 1;
- a += (double)Global::streamData[i][walkback] * ratio[i];
-
- while ((walkback > 0)
- && (Global::streamData[i][walkback - 1] == 0xFF))
- {
- walkback--;
- a += (double)Global::streamData[i][walkback] * ratio[i];
- }
-
- loc = (uint32_t)walkback;
-}
-
-
-//
-// Move every stream forward by one step
-//
-void StepForward(uint32_t * sync, double * a, uint32_t num)
-{
- for(uint32_t i=0; i<num; i++)
- {
- uint32_t walkahead = sync[i] + 1;
- a[i] = (double)Global::streamData[i][walkahead] * ratio[i];
-
- while ((walkahead < Global::streamLen[i])
- && (Global::streamData[i][walkahead] == 0xFF))
- {
- walkahead++;
- a[i] += (double)Global::streamData[i][walkahead] * ratio[i];
- }
-
- sync[i] = walkahead;
- }
-}
-
-
-//
-// Move every stream forward by one step
-//
-void StepAndAddForward(uint32_t * sync, double * a, uint32_t num)
-{
- for(uint32_t i=0; i<num; i++)
- {
- uint32_t walkahead = sync[i] + 1;
- a[i] += (double)Global::streamData[i][walkahead] * ratio[i];
-
- while ((walkahead < Global::streamLen[i])
- && (Global::streamData[i][walkahead] == 0xFF))
- {
- walkahead++;
- a[i] += (double)Global::streamData[i][walkahead] * ratio[i];
- }
-
- sync[i] = walkahead;
- }
-}
-
-
-//
-// Move just *this* stream forward by one step
-//
-void StepAndAddForward(uint32_t & loc, double & a, uint32_t i)
-{
- loc++;
- a += (double)Global::streamData[i][loc] * ratio[i];
-
- while ((loc < Global::streamLen[i])
- && (Global::streamData[i][loc] == 0xFF))
- {
- loc++;
- a += (double)Global::streamData[i][loc] * ratio[i];
- }
-}
-
-
-//
-// Return the number of times with good correlation in the specified direction
-// (1 for forward, -1 for backwards)
-//
-uint32_t Lookahead(uint32_t * syncPt, uint32_t num, int32_t dir /*= 1*/)
-{
- uint32_t tSync[10];
- double a[10];
- uint32_t count = 0;
-
- // Use temporary sync array instead of the one passed in
- memcpy(tSync, syncPt, sizeof(tSync));
-
- if (dir == -1)
- {
- uint32_t smallestIdx = SmallestIdx(tSync, num);
-
- while (tSync[smallestIdx] > 0)
- {
- StepBack(tSync, a, num);
- double sigma = StdDeviation(a, num);
-
- if (sigma > SIGMA_THRESHOLD)
- break;
-
- count++;
- smallestIdx = SmallestIdx(tSync, num);
- }
- }
- else
- {
- uint32_t largestIdx = LargestIdx(tSync, num);
-
- while (tSync[largestIdx] < Global::streamLen[largestIdx])
- {
- StepForward(tSync, a, num);
- double sigma = StdDeviation(a, num);
-
- if (sigma > SIGMA_THRESHOLD)
- break;
-
- count++;
- largestIdx = LargestIdx(tSync, num);
- }
- }
-
- return count;
-}
-
-
-//
-// Attempt to resynchronize the current streams
-// N.B.: When we get here, we're already at the point *after* where it blew up
-// the sigma (the times for that step are passed-in in "a")
-//
-// Returns -1 on failure, 0 is sync was successful, or 1 if reached end of
-// stream before finding sync
-//
-int Resync(uint32_t * sync, double * a, uint32_t num, int32_t dir/*= 1*/)
-{
- uint32_t syncCount = 0;
- bool pulled;
- double sigma = 0;
-
-for(uint32_t j=0; j<num; j++) { printf("{%d} ", sync[j]); }
-printf("\n");
- do
- {
- syncCount++;
-
- if (syncCount > 20)
- {
- // Back up the train
- printf("Could not synchronize streams...\n");
- return -1;
- }
-
- // Deal with the problem. The heuristic is find the largest value in the set, then advance the other streams by one step until they are "close" to the largest. If the std. deviation is too large, try again; eventually it should be within good limits.
- uint32_t largestIdx = LargestIdx(a, num);
- pulled = false;
-
- // We now pull all streams "forward" until they are within 7
- // underneath the largest or past it.
- for(uint32_t i=0; i<num; i++)
- {
- if (i == largestIdx)
- {
- printf(" ~~~~ ");
- continue;
- }
-
- double ttn = 0;
- uint32_t walkback = sync[i];
-
- while ((a[largestIdx] - (a[i] + ttn)) > 7.0)
- {
- pulled = true;
-
- if (((dir == 1) && (walkback >= Global::streamLen[i]))
- || ((dir == -1) && ((int32_t)walkback <= 0)))
- {
-// memcpy(sync, syncSave, sizeof(syncSave));
- printf("\nSynchronized as far back as possible...\n");
-for(uint32_t j=0; j<num; j++) { printf("{%d} ", sync[j]); }
-printf("\n");
- return 1;
- }
-
- if (dir == 1)
- StepAndAddForward(walkback, ttn, i);
- else
- StepAndAddBack(walkback, ttn, i);
- }
-
- sync[i] = walkback;
- a[i] += ttn;
-
- if (pulled)
- printf(" %6.2lf ", ttn);
- else
- printf(" ");
- }
-
- printf("\n");
-
- for(uint32_t i=0; i<num; i++)
- printf("<%6.2lf>", a[i]);
-
- // Calculate the standard deviation at this new point
- sigma = StdDeviation(a, num);
-printf(" ==> %.2lf%s", sigma, (sigma <= SIGMA_THRESHOLD ? " (OK)" : (!pulled ? "(STEP)" : "")));
-
-double lookahead[9];
-uint32_t minSyncIdx = SmallestIdx(sync, num);
-if (sync[minSyncIdx] > 0 && dir == -1)
-{
-for(uint32_t i=0; i<num; i++)
-{ lookahead[i] = (double)Global::streamData[i][sync[i] + dir] * ratio[i]; }
-printf(" (lookahead=%.2lf, %d)\n", StdDeviation(lookahead, num), Lookahead(sync, num, dir));
-}
- // Heuristic: see if we're stuck with a bad sigma and can't pull any more forward; if so, pull forward one step and see if that gets us any traction...
- if ((sigma > SIGMA_THRESHOLD) && !pulled)
- {
- if (dir == 1)
- StepAndAddForward(sync, a, num);
- else
- StepAndAddBack(sync, a, num);
-
- sigma = StdDeviation(a, num);//, &mean);
- pulled = true;
- }
- }
- while ((sigma > SIGMA_THRESHOLD) && pulled);
-
-// double a2[9];
-// StepBack(sync, a2, num);
-
- return 0;
-}
-
-#endif
-
-
-//
-// Compare two arrays to see if they are equal
-//
-bool Equal(uint32_t * a1, uint32_t * a2, uint32_t num)
-{
- for(uint32_t i=0; i<num; i++)
- {
- if (a1[i] != a2[i])
- return false;
- }
-
- return true;
-}
-
-
-uint32_t LookaheadWave(uint32_t * passedInSync, uint32_t num, int8_t dir = 1);
-uint32_t LookaheadWave(uint32_t * passedInSync, uint32_t num, int8_t dir/*= 1*/)
-{
- uint32_t sync[6];
- uint32_t count = 0;
- memcpy(sync, passedInSync, sizeof(sync));
-
- while (true)
- {
- if (StdDeviationWave(sync, num) > 2.50)
- break;
-
- for(uint32_t i=0; i<num; i++)
- {
- if (((dir == 1) && (sync[i] >= Global::waveLen[sNum[i]]))
- || ((dir == -1) && (sync[i] == 0)))
- return count;
-
- sync[i] += dir;
- }
-
- count++;
- }
-
- return count;
-}
-
-
-uint32_t FindSyncBetweenFirstTwo(uint32_t * sync)
-{
- uint32_t bestSync[2], bestLA = 0, syncSave = sync[0];
-
- // Move the first stream first...
- for(uint32_t i=0; i<200; i++)
- {
- uint32_t la = LookaheadWave(sync, 2);
-
- // See if the sync we've found is the best so far...
- if (la > bestLA)
- {
- bestLA = la;
- memcpy(bestSync, sync, sizeof(bestSync));
- }
-
- sync[0]++;
- }
-
- // Otherwise, reset the first stream and move the 2nd
- sync[0] = syncSave;
-
- for(uint32_t i=0; i<200; i++)
- {
- // We can bump this first since we already checked the [0][0] case above
- sync[1]++;
- uint32_t la = LookaheadWave(sync, 2);
-
- // See if the sync we've found is the best so far...
- if (la > bestLA)
- {
- bestLA = la;
- memcpy(bestSync, sync, sizeof(bestSync));
- }
- }
-
- // Set sync to the best we found & return the best lookahead count
- memcpy(sync, bestSync, sizeof(bestSync));
-
- return bestLA;
-}