Skip to content

Commit 4ec8ce5

Browse files
committed
Add autocorrelation for sub item scale with rounding error compensation.
1 parent f7ee55e commit 4ec8ce5

1 file changed

Lines changed: 67 additions & 20 deletions

File tree

src/musicbrainz/chromaprinter.cpp

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ namespace
6060
(x<<24) + ... */
6161
}
6262

63+
bool compareBit(uint32_t a, uint32_t b, int bit) {
64+
return ((a >> bit) & 1) == ((b >> bit) & 1);
65+
}
66+
6367
float matchFingerprints(uint32_t* a, int aSize, uint32_t* b, int bSize, int maxoffset) {
6468
int biterror;
6569
int numcounts = aSize + bSize + 1;
@@ -82,11 +86,6 @@ namespace
8286

8387
int topcount = 0;
8488
int topoffset = 0;
85-
int topcount2 = 0;
86-
int topoffset2 = 0;
87-
int topcount3 = 0;
88-
int topoffset3 = 0;
89-
9089
// 16384 steps
9190
for (int i = 0; i < MATCH_MASK; i++) {
9291
if (aOffsets[i] && bOffsets[i]) {
@@ -95,26 +94,67 @@ namespace
9594
offset += bSize;
9695
counts[offset]++;
9796
if (counts[offset] > topcount) {
98-
if (topoffset != offset) {
99-
if (topoffset2 != topoffset) {
100-
topcount3 = topcount2;
101-
topoffset3 = topoffset2;
102-
}
103-
topcount2 = topcount;
104-
topoffset2 = topoffset;
105-
}
10697
topcount = counts[offset];
10798
topoffset = offset;
10899
}
109100
}
110101
}
111102
}
112103

113-
qDebug() << "topOffset" << topoffset << topcount << " # " << topoffset2
114-
<< topcount2 << " # " << topoffset3 << topcount3;
115-
116104
topoffset -= bSize;
117105

106+
qDebug() << topoffset;
107+
108+
int count_r = 0;
109+
int count_c = 0;
110+
int count_l = 0;
111+
112+
int corr_size = std::min(aSize, bSize);
113+
114+
if (topoffset > 0) {
115+
for (int i = 1 + topoffset; i < corr_size - (1 + topoffset); i++) {
116+
for (int k = 0; k < 32; k++) {
117+
if (compareBit(a[i - (-1 - topoffset)], b[i], k)) {
118+
count_r++;
119+
}
120+
if (compareBit(a[i - (0 - topoffset)], b[i], k)) {
121+
count_c++;
122+
}
123+
if (compareBit(a[i - (1 - topoffset)], b[i], k)) {
124+
count_l++;
125+
}
126+
}
127+
}
128+
} else {
129+
for (int i = 1 - topoffset; i < corr_size - (1 - topoffset); i++) {
130+
for (int k = 0; k < 32; k++) {
131+
if (compareBit(a[i], b[i - (1 + topoffset)], k)) {
132+
count_r++;
133+
}
134+
if (compareBit(a[i], b[i - (0 + topoffset)], k)) {
135+
count_c++;
136+
}
137+
if (compareBit(a[i], b[i - (-1 + topoffset)], k)) {
138+
count_l++;
139+
}
140+
}
141+
}
142+
}
143+
144+
qDebug() << count_r << count_c << count_l;
145+
146+
int count_min = std::min(std::min(count_r, count_c), count_l);
147+
148+
count_r -= count_min;
149+
count_c -= count_min;
150+
count_l -= count_min;
151+
152+
float fract = ((float)count_r * 1 + float(count_l) * -1) / (count_r + count_c + count_l);
153+
154+
const double A = 0.06;
155+
float correction = static_cast<float>(A * std::sin(2.0 * M_PI * fract));
156+
qDebug() << "fine offset" << topoffset + fract - correction << correction;
157+
118158
int minSize = std::min(aSize, bSize) & ~1;
119159
if (topoffset < 0) {
120160
b -= topoffset;
@@ -249,7 +289,12 @@ QString calcFingerprint(
249289
uint32_t simHash;
250290
chromaprint_hash_fingerprint(fprint, size, &simHash);
251291

252-
qDebug() << "similar" << matchFingerprints(fprint, size, old.data(), old.size(), 120);
292+
qDebug() << "similar"
293+
<< matchFingerprints(fprint,
294+
size,
295+
old.data(),
296+
static_cast<int>(old.size()),
297+
120);
253298

254299
QByteArray hash =
255300
QCryptographicHash::hash(QByteArray(reinterpret_cast<char*>(fprint),
@@ -266,7 +311,7 @@ QString calcFingerprint(
266311
while (item.length() < 32) {
267312
item.prepend(' ');
268313
}
269-
qDebug() << item << i;
314+
// qDebug() << item << i;
270315
old.push_back(fprint[i]);
271316
}
272317
#endif
@@ -293,6 +338,8 @@ QString calcFingerprint(
293338
qDebug() << "generating fingerprint took"
294339
<< timerGeneratingFingerprint.elapsed().debugMillisWithUnit();
295340

341+
qDebug() << fingerprint;
342+
296343
return fingerprint;
297344
}
298345

@@ -314,7 +361,7 @@ QString ChromaPrinter::getFingerprint(TrackPointer pTrack) {
314361
return QString();
315362
}
316363

317-
const SINT startFrame = 0;
364+
const SINT startFrame = static_cast<SINT>(5944 * 2.25); // 5944 item size for 48 kHz Tracks
318365
mixxx::IndexRange fingerprintRange = intersect(
319366
pAudioSource->frameIndexRange(),
320367
mixxx::IndexRange::forward(
@@ -329,7 +376,7 @@ QString ChromaPrinter::getFingerprint(TrackPointer pTrack) {
329376
fingerprintRange = intersect(
330377
pAudioSource->frameIndexRange(),
331378
mixxx::IndexRange::forward(
332-
pAudioSource->frameIndexMin() + 0, // 5904/2,
379+
pAudioSource->frameIndexMin(),
333380
kFingerprintDuration * pAudioSource->getSignalInfo().getSampleRate()));
334381

335382
return calcFingerprint(audioSourceProxy, fingerprintRange);

0 commit comments

Comments
 (0)