comparison audioDB.cpp @ 20:0519fc406b29

New major version, mostly tested: both sequence queries (-Q seq --pointnn N and -Q seq --radius R) now work, all reported distances are Euclidean.
author mas01mc
date Mon, 13 Aug 2007 23:25:16 +0000
parents 999c9c216565
children 95f1f4a42257
comparison
equal deleted inserted replaced
19:0c5884204732 20:0519fc406b29
943 case O2_FLAG_POINT_QUERY: 943 case O2_FLAG_POINT_QUERY:
944 pointQuery(dbName, inFile, adbQueryResult); 944 pointQuery(dbName, inFile, adbQueryResult);
945 break; 945 break;
946 case O2_FLAG_SEQUENCE_QUERY: 946 case O2_FLAG_SEQUENCE_QUERY:
947 if(radius==0) 947 if(radius==0)
948 trackSequenceQuery(dbName, inFile, adbQueryResult); 948 trackSequenceQueryNN(dbName, inFile, adbQueryResult);
949 else 949 else
950 trackSequenceQueryEuc(dbName, inFile, adbQueryResult); 950 trackSequenceQueryRad(dbName, inFile, adbQueryResult);
951 break; 951 break;
952 case O2_FLAG_TRACK_QUERY: 952 case O2_FLAG_TRACK_QUERY:
953 trackPointQuery(dbName, inFile, adbQueryResult); 953 trackPointQuery(dbName, inFile, adbQueryResult);
954 break; 954 break;
955 default: 955 default:
1136 delete qNorm; 1136 delete qNorm;
1137 if(timesdata) 1137 if(timesdata)
1138 delete timesdata; 1138 delete timesdata;
1139 if(dbdurs) 1139 if(dbdurs)
1140 delete dbdurs; 1140 delete dbdurs;
1141 }
1142
1143 void audioDB::sequenceQuery(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){
1144
1145 } 1141 }
1146 1142
1147 // trackPointQuery 1143 // trackPointQuery
1148 // return the trackNN closest tracks to the query track 1144 // return the trackNN closest tracks to the query track
1149 // uses average of pointNN points per track 1145 // uses average of pointNN points per track
1389 delete timesdata; 1385 delete timesdata;
1390 if(meanDBdur) 1386 if(meanDBdur)
1391 delete meanDBdur; 1387 delete meanDBdur;
1392 1388
1393 } 1389 }
1394 1390
1395 void audioDB::deleteDB(const char* dbName, const char* inFile){ 1391
1396 1392 // k nearest-neighbor (k-NN) search between query and target tracks
1397 } 1393 // efficient implementation based on matched filter
1398 1394 // assumes normed shingles
1399 // NBest matched filter distance between query and target tracks 1395 // outputs distances of retrieved shingles, max retreived = pointNN shingles per per track
1400 // efficient implementation 1396 void audioDB::trackSequenceQueryNN(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){
1401 // outputs average of N minimum matched filter distances
1402 void audioDB::trackSequenceQuery(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){
1403 1397
1404 initTables(dbName, inFile); 1398 initTables(dbName, inFile);
1405 1399
1406 // For each input vector, find the closest pointNN matching output vectors and report 1400 // For each input vector, find the closest pointNN matching output vectors and report
1407 // we use stdout in this stub version 1401 // we use stdout in this stub version
1423 error("Database must be L2 normed for sequence query","use -l2norm"); 1417 error("Database must be L2 normed for sequence query","use -l2norm");
1424 1418
1425 if(verbosity>1) 1419 if(verbosity>1)
1426 cerr << "performing norms ... "; cerr.flush(); 1420 cerr << "performing norms ... "; cerr.flush();
1427 unsigned dbVectors = dbH->length/(sizeof(double)*dbH->dim); 1421 unsigned dbVectors = dbH->length/(sizeof(double)*dbH->dim);
1422
1428 // Make a copy of the query 1423 // Make a copy of the query
1429 queryCopy = new double[numVectors*dbH->dim]; 1424 queryCopy = new double[numVectors*dbH->dim];
1430 memcpy(queryCopy, query, numVectors*dbH->dim*sizeof(double)); 1425 memcpy(queryCopy, query, numVectors*dbH->dim*sizeof(double));
1431 qNorm = new double[numVectors]; 1426 qNorm = new double[numVectors];
1432 sNorm = new double[dbVectors]; 1427 sNorm = new double[dbVectors];
1433 sMeanL2=new double[dbH->numFiles]; 1428 sMeanL2=new double[dbH->numFiles];
1434 assert(qNorm&&sNorm&&queryCopy&&sMeanL2&&sequenceLength); 1429 assert(qNorm&&sNorm&&queryCopy&&sMeanL2&&sequenceLength);
1435 unitNorm(queryCopy, dbH->dim, numVectors, qNorm); 1430 unitNorm(queryCopy, dbH->dim, numVectors, qNorm);
1436 query = queryCopy; 1431 query = queryCopy;
1432
1437 // Make norm measurements relative to sequenceLength 1433 // Make norm measurements relative to sequenceLength
1438 unsigned w = sequenceLength-1; 1434 unsigned w = sequenceLength-1;
1439 unsigned i,j; 1435 unsigned i,j;
1440 double* ps; 1436 double* ps;
1441 double tmp1,tmp2; 1437 double tmp1,tmp2;
1438
1442 // Copy the L2 norm values to core to avoid disk random access later on 1439 // Copy the L2 norm values to core to avoid disk random access later on
1443 memcpy(sNorm, l2normTable, dbVectors*sizeof(double)); 1440 memcpy(sNorm, l2normTable, dbVectors*sizeof(double));
1444 double* snPtr = sNorm; 1441 double* snPtr = sNorm;
1445 for(i=0; i<dbH->numFiles; i++){ 1442 for(i=0; i<dbH->numFiles; i++){
1446 if(trackTable[i]>sequenceLength){ 1443 if(trackTable[i]>=sequenceLength){
1447 tmp1=*snPtr; 1444 tmp1=*snPtr;
1448 j=1; 1445 j=1;
1449 w=sequenceLength-1; 1446 w=sequenceLength-1;
1450 while(w--) 1447 while(w--)
1451 *snPtr+=snPtr[j++]; 1448 *snPtr+=snPtr[j++];
1452 ps = snPtr+1; 1449 ps = snPtr+1;
1453 w=trackTable[i]-sequenceLength; // +1 - 1 1450 w=trackTable[i]-sequenceLength; // +1 - 1
1454 while(w--){ 1451 while(w--){
1455 tmp2=*ps; 1452 tmp2=*ps;
1456 *ps=*(ps-1)-tmp1+*(ps+sequenceLength); 1453 *ps=*(ps-1)-tmp1+*(ps+sequenceLength-1);
1457 tmp1=tmp2; 1454 tmp1=tmp2;
1455 ps++;
1456 }
1457 ps = snPtr;
1458 w=trackTable[i]-sequenceLength+1;
1459 while(w--){
1460 *ps=sqrt(*ps);
1458 ps++; 1461 ps++;
1459 } 1462 }
1460 } 1463 }
1461 snPtr+=trackTable[i]; 1464 snPtr+=trackTable[i];
1462 } 1465 }
1467 *pn++=0.0; 1470 *pn++=0.0;
1468 ps=sNorm; 1471 ps=sNorm;
1469 unsigned processedTracks=0; 1472 unsigned processedTracks=0;
1470 for(i=0; i<dbH->numFiles; i++){ 1473 for(i=0; i<dbH->numFiles; i++){
1471 if(trackTable[i]>sequenceLength-1){ 1474 if(trackTable[i]>sequenceLength-1){
1472 w = trackTable[i]-sequenceLength+1; 1475 w = trackTable[i]-sequenceLength;
1473 pn = sMeanL2+i; 1476 pn = sMeanL2+i;
1477 *pn=0;
1474 while(w--) 1478 while(w--)
1475 *pn+=*ps++; 1479 if(*ps>0)
1476 *pn/=trackTable[i]-sequenceLength+1; 1480 *pn+=*ps++;
1481 *pn/=trackTable[i]-sequenceLength;
1477 SILENCE_THRESH+=*pn; 1482 SILENCE_THRESH+=*pn;
1478 processedTracks++; 1483 processedTracks++;
1479 } 1484 }
1480 ps = sNorm + trackTable[i]; 1485 ps = sNorm + trackTable[i];
1481 } 1486 }
1482 if(verbosity>1) 1487 if(verbosity>1)
1483 cerr << "processedTracks: " << processedTracks << endl; 1488 cerr << "processedTracks: " << processedTracks << endl;
1489
1490
1484 SILENCE_THRESH/=processedTracks; 1491 SILENCE_THRESH/=processedTracks;
1485 USE_THRESH=1; // Turn thresholding on 1492 USE_THRESH=1; // Turn thresholding on
1486 DIFF_THRESH=SILENCE_THRESH/2; // 50% of the mean shingle power 1493 DIFF_THRESH=SILENCE_THRESH; // mean shingle power
1487 SILENCE_THRESH/=10; // 10% of the mean shingle power is SILENCE 1494 SILENCE_THRESH/=5; // 20% of the mean shingle power is SILENCE
1488 1495 if(verbosity>4)
1496 cerr << "silence thresh: " << SILENCE_THRESH;
1489 w=sequenceLength-1; 1497 w=sequenceLength-1;
1490 i=1; 1498 i=1;
1491 tmp1=*qNorm; 1499 tmp1=*qNorm;
1492 while(w--) 1500 while(w--)
1493 *qNorm+=qNorm[i++]; 1501 *qNorm+=qNorm[i++];
1494 ps = qNorm+1; 1502 ps = qNorm+1;
1495 qMeanL2 = *qNorm; 1503 w=numVectors-sequenceLength; // +1 -1
1496 w=numVectors-sequenceLength;
1497 while(w--){ 1504 while(w--){
1498 tmp2=*ps; 1505 tmp2=*ps;
1499 *ps=*(ps-1)-tmp1+*(ps+sequenceLength); 1506 *ps=*(ps-1)-tmp1+*(ps+sequenceLength-1);
1500 tmp1=tmp2; 1507 tmp1=tmp2;
1501 qMeanL2+=*ps; 1508 ps++;
1502 *ps++; 1509 }
1510 ps = qNorm;
1511 qMeanL2 = 0;
1512 w=numVectors-sequenceLength+1;
1513 while(w--){
1514 *ps=sqrt(*ps);
1515 qMeanL2+=*ps++;
1503 } 1516 }
1504 qMeanL2 /= numVectors-sequenceLength+1; 1517 qMeanL2 /= numVectors-sequenceLength+1;
1518
1505 if(verbosity>1) 1519 if(verbosity>1)
1506 cerr << "done." << endl; 1520 cerr << "done." << endl;
1507 1521
1508 1522
1509 if(verbosity>1) 1523 if(verbosity>1)
1526 unsigned k,l,m,n,track,trackOffset=0, HOP_SIZE=sequenceHop, wL=sequenceLength; 1540 unsigned k,l,m,n,track,trackOffset=0, HOP_SIZE=sequenceHop, wL=sequenceLength;
1527 double thisDist; 1541 double thisDist;
1528 double oneOverWL=1.0/wL; 1542 double oneOverWL=1.0/wL;
1529 1543
1530 for(k=0; k<pointNN; k++){ 1544 for(k=0; k<pointNN; k++){
1531 distances[k]=0.0; 1545 distances[k]=1.0e6;
1532 qIndexes[k]=~0; 1546 qIndexes[k]=~0;
1533 sIndexes[k]=~0; 1547 sIndexes[k]=~0;
1534 } 1548 }
1535 1549
1536 for(k=0; k<trackNN; k++){ 1550 for(k=0; k<trackNN; k++){
1537 trackDistances[k]=0.0; 1551 trackDistances[k]=1.0e6;
1538 trackQIndexes[k]=~0; 1552 trackQIndexes[k]=~0;
1539 trackSIndexes[k]=~0; 1553 trackSIndexes[k]=~0;
1540 trackIDs[k]=~0; 1554 trackIDs[k]=~0;
1541 } 1555 }
1542 1556
1584 query=query+queryPoint*dbH->dim; 1598 query=query+queryPoint*dbH->dim;
1585 qNorm=qNorm+queryPoint; 1599 qNorm=qNorm+queryPoint;
1586 numVectors=wL; 1600 numVectors=wL;
1587 } 1601 }
1588 1602
1589 double ** D = 0; // Cross-correlation between query and target 1603 double ** D = 0; // Differences query and target
1590 double ** DD = 0; // Matched filter distance 1604 double ** DD = 0; // Matched filter distance
1591 1605
1592 D = new double*[numVectors]; 1606 D = new double*[numVectors];
1593 assert(D); 1607 assert(D);
1594 DD = new double*[numVectors]; 1608 DD = new double*[numVectors];
1611 trackOffsetTable[k]=cumTrack; 1625 trackOffsetTable[k]=cumTrack;
1612 cumTrack+=trackTable[k]*dbH->dim; 1626 cumTrack+=trackTable[k]*dbH->dim;
1613 } 1627 }
1614 1628
1615 char nextKey [MAXSTR]; 1629 char nextKey [MAXSTR];
1630
1631 // chi^2 statistics
1632 double sampleCount = 0;
1633 double sampleSum = 0;
1634 double logSampleSum = 0;
1635 double minSample = 1e9;
1636 double maxSample = 0;
1637
1638 // Track loop
1616 for(processedTracks=0, track=0 ; processedTracks < dbH->numFiles ; track++, processedTracks++){ 1639 for(processedTracks=0, track=0 ; processedTracks < dbH->numFiles ; track++, processedTracks++){
1617 1640
1618 // get trackID from file if using a control file 1641 // get trackID from file if using a control file
1619 if(trackFile){ 1642 if(trackFile){
1620 if(!trackFile->eof()){ 1643 if(!trackFile->eof()){
1631 if(sequenceLength<trackTable[track]){ // test for short sequences 1654 if(sequenceLength<trackTable[track]){ // test for short sequences
1632 1655
1633 if(verbosity>7) 1656 if(verbosity>7)
1634 cerr << track << "." << trackIndexOffset << "." << trackTable[track] << " | ";cerr.flush(); 1657 cerr << track << "." << trackIndexOffset << "." << trackTable[track] << " | ";cerr.flush();
1635 1658
1636 // Cross-correlation matrix 1659 // Sum products matrix
1637 for(j=0; j<numVectors;j++){ 1660 for(j=0; j<numVectors;j++){
1638 D[j]=new double[trackTable[track]]; 1661 D[j]=new double[trackTable[track]];
1639 assert(D[j]); 1662 assert(D[j]);
1640 1663
1641 } 1664 }
1644 for(j=0; j<numVectors;j++){ 1667 for(j=0; j<numVectors;j++){
1645 DD[j]=new double[trackTable[track]]; 1668 DD[j]=new double[trackTable[track]];
1646 assert(DD[j]); 1669 assert(DD[j]);
1647 } 1670 }
1648 1671
1649 // Cross Correlation 1672 double tmp;
1673 // Dot product
1650 for(j=0; j<numVectors; j++) 1674 for(j=0; j<numVectors; j++)
1651 for(k=0; k<trackTable[track]; k++){ 1675 for(k=0; k<trackTable[track]; k++){
1652 qp=query+j*dbH->dim; 1676 qp=query+j*dbH->dim;
1653 sp=dataBuf+trackOffset+k*dbH->dim; 1677 sp=dataBuf+trackOffset+k*dbH->dim;
1654 DD[j][k]=0.0; // Initialize matched filter array 1678 DD[j][k]=0.0; // Initialize matched filter array
1670 k=trackTable[track]-w; 1694 k=trackTable[track]-w;
1671 while(k--) 1695 while(k--)
1672 *sp+++=*spd++; 1696 *sp+++=*spd++;
1673 } 1697 }
1674 } 1698 }
1699
1675 else{ // HOP_SIZE != 1 1700 else{ // HOP_SIZE != 1
1676 for(w=0; w<wL; w++) 1701 for(w=0; w<wL; w++)
1677 for(j=0; j<numVectors-w; j+=HOP_SIZE){ 1702 for(j=0; j<numVectors-w; j+=HOP_SIZE){
1678 sp=DD[j]; 1703 sp=DD[j];
1679 spd=D[j+w]+w; 1704 spd=D[j+w]+w;
1698 cerr << "within duration tolerance." << endl; 1723 cerr << "within duration tolerance." << endl;
1699 cerr.flush(); 1724 cerr.flush();
1700 } 1725 }
1701 1726
1702 // Search for minimum distance by shingles (concatenated vectors) 1727 // Search for minimum distance by shingles (concatenated vectors)
1703 for(j=0;j<numVectors-wL+1;j+=HOP_SIZE) 1728 for(j=0;j<numVectors-wL;j+=HOP_SIZE)
1704 for(k=0;k<trackTable[track]-wL+1;k+=HOP_SIZE){ 1729 for(k=0;k<trackTable[track]-wL;k+=HOP_SIZE){
1705 1730 thisDist=2-(2/(qNorm[j]*sNorm[trackIndexOffset+k]))*DD[j][k];
1706 diffL2 = fabs(qNorm[j] - sNorm[k]); 1731 if(verbosity>10)
1732 cerr << thisDist << " " << qNorm[j] << " " << sNorm[trackIndexOffset+k] << endl;
1733 // Gather chi^2 statistics
1734 if(thisDist<minSample)
1735 minSample=thisDist;
1736 else if(thisDist>maxSample)
1737 maxSample=thisDist;
1738 if(thisDist>1e-9){
1739 sampleCount++;
1740 sampleSum+=thisDist;
1741 logSampleSum+=log(thisDist);
1742 }
1743
1744 // diffL2 = fabs(qNorm[j] - sNorm[trackIndexOffset+k]);
1707 // Power test 1745 // Power test
1708 if(!USE_THRESH || 1746 if(!USE_THRESH ||
1709 // Threshold on mean L2 of Q and S sequences 1747 // Threshold on mean L2 of Q and S sequences
1710 (USE_THRESH && qNorm[j]>SILENCE_THRESH && sNorm[k]>SILENCE_THRESH && 1748 (USE_THRESH && qNorm[j]>SILENCE_THRESH && sNorm[trackIndexOffset+k]>SILENCE_THRESH &&
1711 // Are both query and target windows above mean energy? 1749 // Are both query and target windows above mean energy?
1712 (qNorm[j]>qMeanL2 && sNorm[k]>sMeanL2[track] && diffL2 < DIFF_THRESH ))) 1750 (qNorm[j]>qMeanL2*.25 && sNorm[trackIndexOffset+k]>sMeanL2[track]*.25))) // && diffL2 < DIFF_THRESH )))
1713 thisDist=DD[j][k]*oneOverWL; 1751 thisDist=thisDist; // Computed above
1714 else 1752 else
1715 thisDist=0.0; 1753 thisDist=1000000.0;
1716 1754
1717 // NBest match algorithm 1755 // k-NN match algorithm
1718 for(m=0; m<pointNN; m++){ 1756 m=pointNN;
1719 if(thisDist>=distances[m]){ 1757 while(m--){
1758 if(thisDist<=distances[m])
1759 if(m==0 || thisDist>=distances[m-1]){
1720 // Shuffle distances up the list 1760 // Shuffle distances up the list
1721 for(l=pointNN-1; l>m; l--){ 1761 for(l=pointNN-1; l>m; l--){
1722 distances[l]=distances[l-1]; 1762 distances[l]=distances[l-1];
1723 qIndexes[l]=qIndexes[l-1]; 1763 qIndexes[l]=qIndexes[l-1];
1724 sIndexes[l]=sIndexes[l-1]; 1764 sIndexes[l]=sIndexes[l-1];
1728 qIndexes[m]=queryPoint; 1768 qIndexes[m]=queryPoint;
1729 else 1769 else
1730 qIndexes[m]=j; 1770 qIndexes[m]=j;
1731 sIndexes[m]=k; 1771 sIndexes[m]=k;
1732 break; 1772 break;
1733 } 1773 }
1734 } 1774 }
1735 } 1775 }
1736 // Calculate the mean of the N-Best matches 1776 // Calculate the mean of the N-Best matches
1737 thisDist=0.0; 1777 thisDist=0.0;
1738 for(m=0; m<pointNN; m++) 1778 for(m=0; m<pointNN; m++)
1739 if(distances[m]<0.000001){ // Stop rubbish songs getting good scores 1779 thisDist+=distances[m];
1740 thisDist=0.0;
1741 break;
1742 }
1743 else
1744 thisDist+=distances[m];
1745 thisDist/=pointNN; 1780 thisDist/=pointNN;
1746 1781
1747 // Let's see the distances then... 1782 // Let's see the distances then...
1748 if(verbosity>3) 1783 if(verbosity>3)
1749 cerr << fileTable+track*O2_FILETABLESIZE << " " << thisDist << endl; 1784 cerr << fileTable+track*O2_FILETABLESIZE << " " << thisDist << endl;
1750 1785
1786
1751 // All the track stuff goes here 1787 // All the track stuff goes here
1752 n=trackNN; 1788 n=trackNN;
1753 while(n--){ 1789 while(n--){
1754 if(thisDist>=trackDistances[n]){ 1790 if(thisDist<=trackDistances[n]){
1755 if((n==0 || thisDist<=trackDistances[n-1])){ 1791 if((n==0 || thisDist>=trackDistances[n-1])){
1756 // Copy all values above up the queue 1792 // Copy all values above up the queue
1757 for( l=trackNN-1 ; l > n ; l--){ 1793 for( l=trackNN-1 ; l > n ; l--){
1758 trackDistances[l]=trackDistances[l-1]; 1794 trackDistances[l]=trackDistances[l-1];
1759 trackQIndexes[l]=trackQIndexes[l-1]; 1795 trackQIndexes[l]=trackQIndexes[l-1];
1760 trackSIndexes[l]=trackSIndexes[l-1]; 1796 trackSIndexes[l]=trackSIndexes[l-1];
1770 } 1806 }
1771 else 1807 else
1772 break; 1808 break;
1773 } 1809 }
1774 } // Duration match 1810 } // Duration match
1775 1811
1776 // per-track reset array values
1777 for(unsigned k=0; k<pointNN; k++){
1778 distances[k]=0.0;
1779 qIndexes[k]=~0;
1780 sIndexes[k]=~0;
1781 }
1782
1783 // Clean up current track 1812 // Clean up current track
1784 if(D!=NULL){ 1813 if(D!=NULL){
1785 for(j=0; j<numVectors; j++) 1814 for(j=0; j<numVectors; j++)
1786 delete[] D[j]; 1815 delete[] D[j];
1787 } 1816 }
1789 if(DD!=NULL){ 1818 if(DD!=NULL){
1790 for(j=0; j<numVectors; j++) 1819 for(j=0; j<numVectors; j++)
1791 delete[] DD[j]; 1820 delete[] DD[j];
1792 } 1821 }
1793 } 1822 }
1823 // per-track reset array values
1824 for(unsigned k=0; k<pointNN; k++){
1825 distances[k]=1.0e6;
1826 qIndexes[k]=~0;
1827 sIndexes[k]=~0;
1828 }
1794 } 1829 }
1795 1830
1796 gettimeofday(&tv2,NULL); 1831 gettimeofday(&tv2,NULL);
1797 if(verbosity>1) 1832 if(verbosity>1){
1798 cerr << endl << "processed tracks :" << processedTracks << " matched tracks: " << successfulTracks << " elapsed time:" 1833 cerr << endl << "processed tracks :" << processedTracks << " matched tracks: " << successfulTracks << " elapsed time:"
1799 << ( tv2.tv_sec*1000 + tv2.tv_usec/1000 ) - ( tv1.tv_sec*1000+tv1.tv_usec/1000 ) << " msec" << endl; 1834 << ( tv2.tv_sec*1000 + tv2.tv_usec/1000 ) - ( tv1.tv_sec*1000+tv1.tv_usec/1000 ) << " msec" << endl;
1800 1835 cerr << "sampleCount: " << sampleCount << " sampleSum: " << sampleSum << " logSampleSum: " << logSampleSum
1836 << " minSample: " << minSample << " maxSample: " << maxSample << endl;
1837 }
1801 if(adbQueryResult==0){ 1838 if(adbQueryResult==0){
1802 if(verbosity>1) 1839 if(verbosity>1)
1803 cerr<<endl; 1840 cerr<<endl;
1804 // Output answer 1841 // Output answer
1805 // Loop over nearest neighbours 1842 // Loop over nearest neighbours
1806 for(k=0; k < min(trackNN,successfulTracks); k++) 1843 for(k=0; k < min(trackNN,successfulTracks); k++)
1807 cout << fileTable+trackIDs[k]*O2_FILETABLESIZE << " " << trackDistances[k] << " " << trackQIndexes[k] << " " << trackSIndexes[k] << endl; 1844 cout << fileTable+trackIDs[k]*O2_FILETABLESIZE << " " << trackDistances[k] << " "
1845 << trackQIndexes[k] << " " << trackSIndexes[k] << endl;
1808 } 1846 }
1809 else{ // Process Web Services Query 1847 else{ // Process Web Services Query
1810 int listLen = min(trackNN, processedTracks); 1848 int listLen = min(trackNN, processedTracks);
1811 adbQueryResult->__sizeRlist=listLen; 1849 adbQueryResult->__sizeRlist=listLen;
1812 adbQueryResult->__sizeDist=listLen; 1850 adbQueryResult->__sizeDist=listLen;
1826 } 1864 }
1827 1865
1828 1866
1829 // Clean up 1867 // Clean up
1830 if(trackOffsetTable) 1868 if(trackOffsetTable)
1831 delete trackOffsetTable; 1869 delete[] trackOffsetTable;
1832 if(queryCopy) 1870 if(queryCopy)
1833 delete queryCopy; 1871 delete[] queryCopy;
1834 //if(qNorm) 1872 //if(qNorm)
1835 //delete qNorm; 1873 //delete qNorm;
1836 if(D) 1874 if(D)
1837 delete[] D; 1875 delete[] D;
1838 if(DD) 1876 if(DD)
1839 delete[] DD; 1877 delete[] DD;
1840 if(timesdata) 1878 if(timesdata)
1841 delete timesdata; 1879 delete[] timesdata;
1842 if(meanDBdur) 1880 if(meanDBdur)
1843 delete meanDBdur; 1881 delete[] meanDBdur;
1844 1882
1845 1883
1846 } 1884 }
1847 1885
1848 // NBest matched filter distance between query and target tracks 1886 // Radius search between query and target tracks
1849 // efficient implementation 1887 // efficient implementation based on matched filter
1850 // outputs average of N minimum matched filter distances 1888 // assumes normed shingles
1851 void audioDB::trackSequenceQueryEuc(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){ 1889 // outputs count of retrieved shingles, max retreived = one shingle per query shingle per track
1890 void audioDB::trackSequenceQueryRad(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){
1852 1891
1853 initTables(dbName, inFile); 1892 initTables(dbName, inFile);
1854 1893
1855 // For each input vector, find the closest pointNN matching output vectors and report 1894 // For each input vector, find the closest pointNN matching output vectors and report
1856 // we use stdout in this stub version 1895 // we use stdout in this stub version