├── demo
├── test.mp3
├── MusicURI.jar
├── dependencies.zip
├── MusicURIReferences.db
└── README.txt
├── src
├── META-INF
│ └── MANIFEST.MF
├── it
│ └── univpm
│ │ └── deit
│ │ └── semedia
│ │ └── musicuri
│ │ ├── core
│ │ ├── Result.class
│ │ ├── Toolset.class
│ │ ├── Toolset.java
│ │ ├── MusicURIQuery.class
│ │ ├── MusicURISearch.class
│ │ ├── SearchStrategy.class
│ │ ├── MusicURIDatabase.class
│ │ ├── MusicURIReference.class
│ │ ├── MusicURIWebSource.class
│ │ ├── ResultRankingList.class
│ │ ├── MusicURIDataSource.class
│ │ ├── MusicURILocalSource.class
│ │ ├── MusicURIDataSource.java
│ │ ├── MusicURIWebSource.java
│ │ ├── MusicURILocalSource.java
│ │ ├── Result.java
│ │ ├── SearchStrategy.java
│ │ ├── ResultRankingList.java
│ │ ├── MusicURIQuery.java
│ │ ├── MusicURIReference.java
│ │ └── MusicURIDatabase.java
│ │ ├── statistics
│ │ ├── Test.class
│ │ ├── Stopwatch.class
│ │ ├── TestCaseCaller.class
│ │ ├── PerformanceStatistic.class
│ │ ├── Stopwatch.java
│ │ ├── Test.java
│ │ ├── PerformanceStatistic.java
│ │ └── TestCaseCaller.java
│ │ ├── utils
│ │ ├── dbadmin
│ │ │ ├── DbPopulator.class
│ │ │ ├── QueryObjectDbPopulator.class
│ │ │ ├── QueryObjectDbPopulator.java
│ │ │ └── DbPopulator.java
│ │ ├── misc
│ │ │ ├── MusicURILibraryDemo.class
│ │ │ ├── SoCProjectLineCounter.class
│ │ │ ├── SoCProjectLineCounter.java
│ │ │ └── MusicURILibraryDemo.java
│ │ └── experimental
│ │ │ ├── FilenameScrambler.class
│ │ │ ├── LambdaCalculator.class
│ │ │ ├── DbAverageDistanceCalculator.class
│ │ │ ├── Mpeg7XMAudioSignatureSearch.class
│ │ │ ├── Mpeg7XMAudioSignatureSearch.java
│ │ │ ├── DbAverageDistanceCalculator.java
│ │ │ ├── LambdaCalculator.java
│ │ │ └── FilenameScrambler.java
│ │ └── webservice
│ │ ├── client
│ │ ├── MusicURIWebSearch.class
│ │ ├── MusicURIWebSearchService.class
│ │ ├── MusicURIWebSearchServiceLocator.class
│ │ ├── MusicURIWebSearchSoapBindingStub.class
│ │ ├── MusicURIWebSearch.java
│ │ ├── MusicURIWebSearchService.java
│ │ ├── MusicURIWebSearchServiceLocator.java
│ │ └── MusicURIWebSearchSoapBindingStub.java
│ │ └── server
│ │ ├── MusicURIWebSearch.class
│ │ └── MusicURIWebSearch.java
├── .project
├── .classpath
├── README.txt
└── COPYING.txt
└── README.md
/demo/test.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/demo/test.mp3
--------------------------------------------------------------------------------
/demo/MusicURI.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/demo/MusicURI.jar
--------------------------------------------------------------------------------
/demo/dependencies.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/demo/dependencies.zip
--------------------------------------------------------------------------------
/demo/MusicURIReferences.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/demo/MusicURIReferences.db
--------------------------------------------------------------------------------
/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: it.univpm.deit.semedia.musicuri.utils.misc.MusicURILibrary
3 | Demo
4 |
5 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/Result.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/Result.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/Toolset.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/Toolset.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/Toolset.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/Toolset.java
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | musicuri
2 | ========
3 |
4 | A Java library for fingerprinting music files, assigning unique URIs to them, and matching them to unknown audio clips.
5 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/Test.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/statistics/Test.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIQuery.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURIQuery.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURISearch.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURISearch.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/SearchStrategy.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/SearchStrategy.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIDatabase.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURIDatabase.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIReference.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURIReference.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIWebSource.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURIWebSource.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/ResultRankingList.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/ResultRankingList.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/Stopwatch.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/statistics/Stopwatch.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIDataSource.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURIDataSource.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURILocalSource.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/core/MusicURILocalSource.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/TestCaseCaller.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/statistics/TestCaseCaller.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/dbadmin/DbPopulator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/dbadmin/DbPopulator.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/PerformanceStatistic.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/statistics/PerformanceStatistic.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/misc/MusicURILibraryDemo.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/misc/MusicURILibraryDemo.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/misc/SoCProjectLineCounter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/misc/SoCProjectLineCounter.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/dbadmin/QueryObjectDbPopulator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/dbadmin/QueryObjectDbPopulator.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/FilenameScrambler.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/experimental/FilenameScrambler.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/LambdaCalculator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/experimental/LambdaCalculator.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearch.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearch.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/server/MusicURIWebSearch.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/webservice/server/MusicURIWebSearch.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchService.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/DbAverageDistanceCalculator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/experimental/DbAverageDistanceCalculator.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/Mpeg7XMAudioSignatureSearch.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/utils/experimental/Mpeg7XMAudioSignatureSearch.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchServiceLocator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchServiceLocator.class
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchSoapBindingStub.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dkourtesis/musicuri/HEAD/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchSoapBindingStub.class
--------------------------------------------------------------------------------
/src/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | MusicURI
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIDataSource.java:
--------------------------------------------------------------------------------
1 | package it.univpm.deit.semedia.musicuri.core;
2 |
3 | import java.io.File;
4 | import java.net.URL;
5 |
6 | /**
7 | * @author Dimitrios Kourtesis
8 | */
9 | public interface MusicURIDataSource
10 | {
11 | public URL getDataSourceLocation();
12 | public void index(File musicItemToIndex);
13 | public void identify(File musicItemToIdentify);
14 | public void listMusicURIReferences();
15 | }
16 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearch.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MusicURIWebSearch.java
3 | *
4 | * This file was auto-generated from WSDL
5 | * by the Apache Axis 1.2.1 Jun 14, 2005 (09:15:57 EDT) WSDL2Java emitter.
6 | */
7 |
8 | package it.univpm.deit.semedia.musicuri.webservice.client;
9 |
10 | public interface MusicURIWebSearch extends java.rmi.Remote
11 | {
12 | public java.lang.String getMusicURIReferenceList() throws java.rmi.RemoteException;
13 | public int getNumOfMusicURIReferences() throws java.rmi.RemoteException;
14 | public java.lang.String performSearch(java.lang.String xmlAudioSignature, java.lang.String filename) throws java.rmi.RemoteException;
15 | }
16 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIWebSource.java:
--------------------------------------------------------------------------------
1 | package it.univpm.deit.semedia.musicuri.core;
2 |
3 | import java.io.File;
4 | import java.net.URL;
5 |
6 | /**
7 | * @author Dimitrios Kourtesis
8 | */
9 | public class MusicURIWebSource implements MusicURIDataSource
10 | {
11 | private URL dataSourceLocation;
12 |
13 | public URL getDataSourceLocation()
14 | {
15 | return dataSourceLocation;
16 | }
17 |
18 | public void index(File musicItemToIndex)
19 | {
20 | // TODO Auto-generated method stub
21 |
22 | }
23 |
24 | public void identify(File musicItemToIdentify)
25 | {
26 | // TODO Auto-generated method stub
27 |
28 | }
29 |
30 | public void listMusicURIReferences()
31 | {
32 | // TODO Auto-generated method stub
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURILocalSource.java:
--------------------------------------------------------------------------------
1 | package it.univpm.deit.semedia.musicuri.core;
2 |
3 | import java.io.File;
4 | import java.net.URL;
5 |
6 | /**
7 | * @author Dimitrios Kourtesis
8 | */
9 | public class MusicURILocalSource implements MusicURIDataSource
10 | {
11 | private URL dataSourceLocation;
12 |
13 | public URL getDataSourceLocation()
14 | {
15 | return dataSourceLocation;
16 | }
17 |
18 | public void index(File musicItemToIndex)
19 | {
20 | // TODO Auto-generated method stub
21 |
22 | }
23 |
24 | public void identify(File musicItemToIdentify)
25 | {
26 | // TODO Auto-generated method stub
27 |
28 | }
29 |
30 | public void listMusicURIReferences()
31 | {
32 | // TODO Auto-generated method stub
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchService.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MusicURIWebSearchService.java
3 | *
4 | * This file was auto-generated from WSDL
5 | * by the Apache Axis 1.2.1 Jun 14, 2005 (09:15:57 EDT) WSDL2Java emitter.
6 | */
7 |
8 | package it.univpm.deit.semedia.musicuri.webservice.client;
9 |
10 | public interface MusicURIWebSearchService extends javax.xml.rpc.Service {
11 | public java.lang.String getMusicURIWebSearchAddress();
12 |
13 | public it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearch getMusicURIWebSearch() throws javax.xml.rpc.ServiceException;
14 |
15 | public it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearch getMusicURIWebSearch(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
16 | }
17 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/misc/SoCProjectLineCounter.java:
--------------------------------------------------------------------------------
1 | package it.univpm.deit.semedia.musicuri.utils.misc;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileReader;
7 | import java.io.IOException;
8 |
9 |
10 | /**
11 | * Utility class used for calculating the SoC (Summer of Code) LOC (Lines Of Code) in a java source code directory
12 | */
13 | public class SoCProjectLineCounter
14 | {
15 | public static void main(String[] args) throws IOException
16 | {
17 | File directory = new File(args[0]);
18 | File[] allFiles = directory.listFiles();
19 | File currentFile;
20 | int totalLinesOfCode = 0;
21 |
22 | for (int i=0; i< allFiles.length; i++)
23 | {
24 | currentFile = allFiles[i];
25 | if (isJavaFile(currentFile)) totalLinesOfCode += countLines (currentFile);
26 | }
27 | System.out.println("Total Lines Of Java Code in Directory: " + directory.getName() + " - " + totalLinesOfCode);
28 | }
29 |
30 | private static int countLines(File file) throws IOException
31 | {
32 | BufferedReader br = new BufferedReader(new FileReader(file));
33 | int line = 0;
34 | while(br.readLine() != null) line++;
35 | return line;
36 | }
37 |
38 | private static boolean isJavaFile(File file)
39 | {
40 | String fname = file.getName();
41 | String extension = fname.substring(fname.lastIndexOf('.') + 1);
42 | if (extension.equalsIgnoreCase("java")) return true;
43 | else return false;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/Result.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.core;
23 |
24 | /**
25 | * @author Dimitrios Kourtesis
26 | */
27 | public class Result
28 | {
29 |
30 | /**
31 | * A generic double value denoting the distance of the specific result from the query used in comparison
32 | */
33 | public double distance;
34 |
35 | /**
36 | * The MD5 key contained in the MusicURIReference this result corresponds to
37 | */
38 | public String md5;
39 |
40 |
41 |
42 |
43 | /**
44 | * Constructs a Result object by setting its private attributes to the ones specified
45 | * @param dist the distance of the correponding reference from the query it was compared with
46 | * @param key the MD5 key contained in the MusicURIReference this result corresponds to
47 | */
48 | public Result (double dist, String key)
49 | {
50 | this.distance = dist;
51 | this.md5 = key;
52 | }
53 |
54 | /**
55 | * Compares a Result object with another by comparing their private attributes
56 | * (Experimental use only)
57 | * @param other the Result object to compare with
58 | */
59 | public boolean isSameWith(Result other)
60 | {
61 | if (other != null)
62 | {
63 |
64 | if ((other.distance == this.distance)
65 | && other.md5.equalsIgnoreCase(this.md5))
66 | {
67 | return true;
68 | }
69 | else return false;
70 | }
71 | else
72 | {
73 | System.out.println("other == null");
74 | return false;
75 | }
76 |
77 | }
78 |
79 |
80 | }//end class
81 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/Stopwatch.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, John O'Hanley, Canada
3 |
4 | Code for this class was taken from http://www.javapractices.com/
5 | */
6 |
7 | package it.univpm.deit.semedia.musicuri.statistics;
8 |
9 |
10 |
11 |
12 | /**
13 | * Allows timing of the execution of any block of code.
14 | */
15 |
16 | public final class Stopwatch
17 | {
18 |
19 | /**
20 | * Starts the stopwatch.
21 | * @throws IllegalStateException if the stopwatch is already running.
22 | */
23 | public void start(){
24 | if ( fIsRunning ) {
25 | throw new IllegalStateException("Must stop before calling start again.");
26 | }
27 | //reset both start and stop
28 | fStart = System.currentTimeMillis();
29 | fStop = 0;
30 | fIsRunning = true;
31 | fHasBeenUsedOnce = true;
32 | }
33 |
34 | /**
35 | * Stops the stopwatch.
36 | * @throws IllegalStateException if the stopwatch is not already running.
37 | */
38 | public void stop() {
39 | if ( !fIsRunning ) {
40 | throw new IllegalStateException("Cannot stop if not currently running.");
41 | }
42 | fStop = System.currentTimeMillis();
43 | fIsRunning = false;
44 | }
45 |
46 | /**
47 | * Expresses the "reading" on the stopwatch.
48 | * @throws IllegalStateException if the Stopwatch has never been used,
49 | * or if the stopwatch is still running.
50 | */
51 | public String toString() {
52 | validateIsReadable();
53 | StringBuffer result = new StringBuffer();
54 | result.append(fStop - fStart);
55 | result.append(" ms");
56 | return result.toString();
57 | }
58 |
59 | /**
60 | * Expresses the "reading" on the stopwatch as a numeric type.
61 | * @throws IllegalStateException if the Stopwatch has never been used,
62 | * or if the stopwatch is still running.
63 | */
64 | public long toValue() {
65 | validateIsReadable();
66 | return fStop - fStart;
67 | }
68 |
69 | // PRIVATE ////
70 | private long fStart;
71 | private long fStop;
72 |
73 | private boolean fIsRunning;
74 | private boolean fHasBeenUsedOnce;
75 |
76 | /**
77 | * @throws IllegalStateException if the watch has never been started,
78 | * or if the watch is still running.
79 | */
80 | private void validateIsReadable() {
81 | if ( fIsRunning ) {
82 | String message = "Cannot read a stopwatch which is still running.";
83 | throw new IllegalStateException(message);
84 | }
85 | if ( !fHasBeenUsedOnce ) {
86 | String message = "Cannot read a stopwatch which has never been started.";
87 | throw new IllegalStateException(message);
88 | }
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/src/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/dbadmin/QueryObjectDbPopulator.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.utils.dbadmin;
23 |
24 |
25 | import it.univpm.deit.semedia.musicuri.core.MusicURIQuery;
26 | import it.univpm.deit.semedia.musicuri.core.Toolset;
27 |
28 | import java.io.File;
29 | import java.io.FileWriter;
30 | import java.io.IOException;
31 |
32 | import com.thoughtworks.xstream.XStream;
33 |
34 |
35 | /**
36 | * Utility class used for experimenting with object serialization
37 | */
38 | public class QueryObjectDbPopulator
39 | {
40 |
41 | public static void main(String[] args) throws Exception
42 | {
43 | //System.out.println("Input: " + args[0]);
44 |
45 | if ((args.length == 1) && (new File (args[0]).exists()))
46 | {
47 | // get the file's canonical path
48 | File givenHandle = new File(args[0]);
49 | String queryAudioCanonicalPath = givenHandle.getCanonicalPath();
50 | System.out.println("New Query Source: " + queryAudioCanonicalPath);
51 |
52 | // for a naive mp3 format check
53 | final String MP3MASK = ".*\\." + "mp3";
54 | File[] list = null;
55 |
56 | if (givenHandle.isFile())
57 | {
58 | list = new File[1];
59 | list[0] = givenHandle;
60 | }
61 | if (givenHandle.isDirectory())
62 | {
63 | list = givenHandle.listFiles();
64 |
65 | if (list.length == 0)
66 | {
67 | System.out.println("No files in directory");
68 | return;
69 | }
70 | }
71 |
72 | MusicURIQuery newQuery;
73 | File mp3File;
74 | String parentDirectory;
75 |
76 | for (int i = 0; i < list.length; i++)
77 | {
78 | mp3File = list[i];
79 | parentDirectory = mp3File.getParent();
80 | try
81 | {
82 | if (mp3File.getName().matches(MP3MASK))
83 | {
84 | byte[] bytes = Toolset.createMD5Hash(mp3File);
85 | String md5 = Toolset.toHexString(bytes);
86 |
87 | if ((new File(parentDirectory + "/" + md5 + ".xml")).exists())
88 | {
89 | System.out.println("File : " + md5 + ".xml" + " already exists on disk");
90 | }
91 | else
92 | {
93 | System.out.print("MusicURIQuery for '" + mp3File.getName() + "' gets serialized to '" + md5 + ".xml' -- ");
94 | newQuery = new MusicURIQuery(mp3File);
95 | serializeToXmlFile(newQuery, parentDirectory + "/" + md5 + ".xml");
96 | }
97 | }
98 | else
99 | {
100 | if (mp3File.isDirectory())
101 | {
102 | String[] recursiveArgs = {mp3File.getCanonicalPath()};
103 | QueryObjectDbPopulator.main(recursiveArgs);
104 | }
105 | }
106 | }
107 | catch (Exception e)
108 | {
109 | e.printStackTrace();
110 | }
111 | }
112 | }
113 | else System.out.println("file or dir does not exist");
114 | if (args.length==0) System.out.println("no input given");
115 |
116 | }
117 |
118 | public static void serializeToXmlFile(Object object, String filename)
119 | {
120 | XStream xstream = new XStream();
121 | String xml = xstream.toXML(object);
122 | try
123 | {
124 | FileWriter fw = new FileWriter(filename);
125 | fw.write(xml);
126 | fw.close();
127 | }
128 | catch (IOException e)
129 | {
130 | e.printStackTrace();
131 | }
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/dbadmin/DbPopulator.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.utils.dbadmin;
23 |
24 |
25 | import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
26 | import it.univpm.deit.semedia.musicuri.core.MusicURIReference;
27 | import it.univpm.deit.semedia.musicuri.core.Toolset;
28 |
29 | import java.io.File;
30 |
31 |
32 | /**
33 | * Utility class used for adding audio files to the db
34 | */
35 | public class DbPopulator
36 | {
37 |
38 | public static void main(String[] args) throws Exception
39 | {
40 | if ((args.length == 1) && (new File (args[0]).exists()))
41 | {
42 | // get the file's canonical path
43 | File givenHandle = new File(args[0]);
44 | String queryAudioCanonicalPath = givenHandle.getCanonicalPath();
45 | System.out.println("New Reference Source: " + queryAudioCanonicalPath);
46 |
47 | // create reference db
48 | String databasePath = "D:/";
49 | //String databasePath = "C:/temp/";
50 | String databaseFileName = "MusicURIReferences.db";
51 | MusicURIDatabase db = new MusicURIDatabase(databasePath, databaseFileName);
52 |
53 | // for a naive mp3 format check
54 | final String MP3MASK = ".*\\." + "mp3";
55 | final String WAVMASK = ".*\\." + "wav";
56 |
57 | if (givenHandle.isDirectory())
58 | {
59 | File[] list = givenHandle.listFiles();
60 | if (list.length == 0)
61 | {
62 | System.out.println("no files in directory");
63 | return;
64 | }
65 | else
66 | {
67 | for (int i = 0; i < list.length; i++)
68 | {
69 | File file = list[i];
70 | try
71 | {
72 | if (file.getName().matches(MP3MASK) || file.getName().matches(WAVMASK))
73 | {
74 | byte[] bytes = Toolset.createMD5Hash(file);
75 | String md5 = Toolset.toHexString(bytes);
76 | System.out.println(md5 + " - " + file.getName());
77 |
78 | // if (md5.equalsIgnoreCase("d910f7ee9a7a0b23edeaaac20368eb1d"))
79 | // {
80 | // System.out.print("special add (d910f7ee9a7a0b23edeaaac20368eb1d) : " + file.getName());
81 | // MusicURIReference newref = new MusicURIReference(file);
82 | // db.addMusicURIReference(newref);
83 | // }
84 |
85 | File serializedMusicURIObject = new File(databasePath + md5 + ".xml");
86 | if (serializedMusicURIObject.exists())
87 | {
88 | System.out.print("the file " + databasePath + md5 + ".xml" + " exists on disk, ");
89 | if ((MusicURIReference) db.getMusicURIReference(md5)!=null)
90 | System.out.println("and in the db as well");
91 | else
92 | System.out.println("but not in the db");
93 | }
94 | else
95 | {
96 |
97 | System.out.print("the file " + databasePath + md5 + ".xml" + " gets added ");
98 | MusicURIReference newref = new MusicURIReference(file);
99 | db.addMusicURIReference(newref);
100 |
101 | }
102 |
103 | }
104 | }
105 | catch (Exception e)
106 | {
107 | e.printStackTrace();
108 | }
109 | }
110 | }
111 | }
112 | if (givenHandle.isFile())
113 | {
114 | if (givenHandle.getName().matches(MP3MASK)|| givenHandle.getName().matches(WAVMASK))
115 | {
116 | MusicURIReference newref = new MusicURIReference(givenHandle);
117 | db.addMusicURIReference(newref);
118 | }
119 | }
120 |
121 | }
122 | else System.out.println("file or dir does not exist");
123 | if (args.length==0) System.out.println("no param");
124 |
125 |
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/Mpeg7XMAudioSignatureSearch.java:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////
2 | //
3 | // This software module was originally developed by
4 | //
5 | // Thorsten Heinz
6 | // Fraunhofer IIS
7 | //
8 | // in the course of development of the MPEG-7 Experimentation Model.
9 | //
10 | // This software module is an implementation of a part of one or more MPEG-7
11 | // Experimentation Model tools as specified by the MPEG-7 Requirements.
12 | //
13 | // ISO/IEC gives users of MPEG-7 free license to this software module or
14 | // modifications thereof for use in hardware or software products claiming
15 | // conformance to MPEG-7.
16 | //
17 | // Those intending to use this software module in hardware or software products
18 | // are advised that its use may infringe existing patents. The original
19 | // developer of this software module and his/her company, the subsequent
20 | // editors and their companies, and ISO/IEC have no liability for use of this
21 | // software module or modifications thereof in an implementation.
22 | //
23 | // Copyright is not released for non MPEG-7 conforming products. The
24 | // organizations named above retain full right to use the code for their own
25 | // purpose, assign or donate the code to a third party and inhibit third
26 | // parties from using the code for non MPEG-7 conforming products.
27 | //
28 | // Copyright (c) 1998-1999.
29 | //
30 | // This notice must be included in all copies or derivative works.
31 | //
32 | // Applicable File Name: AudioSignatureSearch.cpp
33 | //
34 |
35 | package it.univpm.deit.semedia.musicuri.utils.experimental;
36 |
37 | public class Mpeg7XMAudioSignatureSearch
38 | {
39 |
40 | // Weighting vector for the mean vectors (unit variance)
41 | public static double meanWeight[] =
42 | {
43 | 11.933077, 11.103332, 10.464845, 10.231990, 9.743346, 9.645541, 9.644496, 9.672296,
44 | 8.791485, 8.741418, 8.613710, 8.741487, 8.126337, 8.257461, 8.053868, 8.387219
45 | };
46 |
47 | // Weighting vector for the variance vectors (unit variance)
48 | public static double varWeight[] =
49 | {
50 | 69.486160, 69.157463, 73.134132, 73.182343, 76.521751, 77.552032, 81.201492, 85.420212,
51 | 74.791885, 76.823540, 79.335228, 82.347801, 65.784485, 69.698914, 67.417160, 67.184540
52 | };
53 |
54 | // determines the weighted Euclidian distance between a reference and a query audio signature
55 | public static double WeightedEuclidianDistance ( double[] refMean,
56 | double[] refVar,
57 | int numRefVec,
58 | double[] queryMean,
59 | double[] queryVar,
60 | int numQueryVec,
61 | int vectorDim)
62 | {
63 | //--- Check whether the vector dimensions are compatible
64 | if(meanWeight.length != vectorDim)
65 | {
66 | System.out.println("Vector dimensions not identical");
67 | return -1.0f;
68 | }
69 |
70 | int i, j, k;
71 | double distance = 0.0f;
72 |
73 | //--- Loop over all query vectors (scalable series)
74 | for(i = 0; i < numQueryVec; ++i)
75 | {
76 | //System.out.println("query i: " + i);
77 |
78 | double minDistance = 9999.999;
79 |
80 | //--- Loop over reference fingerprint vectors (16-dimensional fingerprint vectors)
81 | for(j = 0; j < numRefVec; ++j) //eg 136 times for 136 seconds of query audio
82 | {
83 | //System.out.println("reference j: " + j);
84 | double tmpDistance = 0.0f;
85 | //--- Calculate distance of mean vector
86 | for(k = 0; k < vectorDim; ++k) //16 times == freq bands
87 | {
88 | //System.out.println("mean k: " + k);
89 | double v1 = queryMean[vectorDim*i + k] * meanWeight[k];
90 | double v2 = refMean[vectorDim*j + k] * meanWeight[k];
91 | tmpDistance += (v1-v2)*(v1-v2);
92 | }
93 |
94 | //--- Calculate distance of variance vector
95 | for(k = 0; k < vectorDim; ++k) //16 times == freq bands
96 | {
97 | //System.out.println("variance k: " + k);
98 | double v1 = queryVar[vectorDim*i + k] * varWeight[k];
99 | double v2 = refVar[vectorDim*j + k] * varWeight[k];
100 | tmpDistance += (v1-v2)*(v1-v2);
101 | }
102 |
103 | if(tmpDistance < minDistance) {minDistance = tmpDistance;}
104 | }
105 |
106 | //--- Cumulate overall distance for all query vectors
107 | distance += minDistance;
108 | }
109 |
110 | return Math.sqrt(distance/(vectorDim*numQueryVec));
111 | }
112 |
113 | }//end class
114 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/SearchStrategy.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package it.univpm.deit.semedia.musicuri.core;
5 |
6 | /**
7 | * @author Dimitrios Kourtesis
8 | */
9 | public interface SearchStrategy
10 | {
11 | /**
12 | * A perfect audio fingerprinting system would correctly match a query with
13 | * a known, previously indexed reference, 100% of the time, and reject an
14 | * unknown query, 100% of the time. However, audio fingerprints can be
15 | * extracted from a variety of audio signals (FM broadcasts, GSM telephony,
16 | * internet streams, mp3 files) which are captured under uncontrollable
17 | * conditions (cabling, speaker-microphone chains, AD conversions), and can
18 | * therefore be of questionable perceptual audio quality. This in turn leads
19 | * to matching of questionable accuracy. The overall accuracy of an audio
20 | * fingerprinting system is assessed by its tendency to produce either a
21 | * "false match" (false acceptance or false positive) or a "false non-match"
22 | * (false rejection or false negative). The point at which these two rates
23 | * intersect is called the equal error rate (EER). This indicates the rate
24 | * of errors (errors/attempts) occurring when a system's decision threshold
25 | * is set so that the number of false rejections will be approximately equal
26 | * to the number of false acceptances. The lower the equal error rate value,
27 | * the higher the accuracy of the system.
28 | *
29 | * The false acceptance rate, or FAR, is the measure of the likelihood that
30 | * the system will falsely accept a query as matching to a known reference,
31 | * while in fact the music item that the query actually belongs to, is
32 | * unknown to the system. Ie states the probability that the some irrelevant
33 | * reference will be wrongly selected. For example matching a sample from a
34 | * Metallica song, to a song by Madonna, while the database does not contain
35 | * any songs by Metallica. A system's FIR is stated as the ratio of the
36 | * number of false identifications divided by the number of identification
37 | * attempts.
38 | *
39 | * The false rejection rate, or FRR, is the measure of the likelihood that
40 | * the system will falsely reject a query as not matching to any known
41 | * reference, while the music item that the query actually belongs to, is
42 | * known to the system. Ie states the probability that the actual reference
43 | * will be wrongly rejected. For example refuse to match a sample from a
44 | * Metallica song, while the database contains every song ever produced by
45 | * Metallica. A system's FIR is stated as the ratio of the number of false
46 | * identifications divided by the number of identification attempts.
47 | *
48 | * This interface class is used to realize different implementations of
49 | * MusicURI search, reflecting the system's policy with regard to matching.
50 | * One of the questions is "what is the fine line separating acceptable from
51 | * non-acceptable matches?". In general, raising the decision threshold
52 | * leads to having less false acceptance or false-positive matches, but also
53 | * leads to having more false rejection or false-negative matches, and vice
54 | * versa. In a highly demanding application where the cost of a erroneous
55 | * identification could be high, system policy might prefer false-rejections
56 | * over false acceptances, and thus raise the decision threshold. In a
57 | * setting where the MusicURI service is provided at a "best-effort" basis,
58 | * and the cost of a erroneous identification is small, system policy might
59 | * favor a false-acceptance matching, in order not to over-reject queries,
60 | * and thereby under-utilize its reference database.
61 | *
62 | *
63 | * To fine tune the system and obtain the ERR, the FAR and FRR must
64 | * converge to an equal value:
65 | *
66 | * int numberOfQueries = 100;
67 | * float decision_threshold = 0.0f;
68 | * int falseAcceptances = 100;
69 | * int falseRejections = 0;
70 | *
71 | *
72 | * while (falseAcceptances > falseRejections)
73 | * {
74 | * decision_threshold += 0.01f;
75 | * stats = runQueriesBatch();
76 | * falseAcceptances = stats.getFalseAcceptances();
77 | * falseRejections = stats.getFalseRejections();
78 | * }
79 | *
80 | * float EER = falseAcceptances / numberOfQueries;
81 | *
82 | * Since it is true that the lower the equal error rate value, the higher
83 | * the accuracy of the system, we will use ERR as a benchmark to determine
84 | * the efficiency of different search strategies.
85 | *
86 | */
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/demo/README.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | ******************************************************************************
4 | ************************ Getting started with MusicURI ***********************
5 | ******************************************************************************
6 |
7 |
8 | I have put together some instructions to demonstrate the functionality that
9 | MusicURI offers at its current point of development. To get an idea of what is
10 | offered, please follow the instructions below.
11 |
12 |
13 |
14 | ******************************************************************************
15 | Step 1. Install the MusicURI package
16 | ******************************************************************************
17 |
18 | 1. Extract the contents of 'dependencies.zip'.
19 |
20 | 2. Add the .jar files to your CLASSPATH. One way to do this is to place them
21 | inside the extension directory of your Java Runtime Environment installation
22 | (JAVA_HOME/jre/lib/ext/).
23 |
24 | 3. Place the MusicURI.jar and MusicURIReferences.db somewhere in
25 | your system. The MusicURI.jar contains the executable you will use in the next
26 | step, and the MusicURIReferences.db is the actual database flat file.
27 |
28 |
29 |
30 | ******************************************************************************
31 | Step 2. Use the MusicURI package
32 | ******************************************************************************
33 |
34 | Execute the Music.jar as described below. The entry point for the MusicURI
35 | jar file is a demo application. It currently supports only local MusicURI data
36 | sources (ie working with local database files). Support for MusicURI data
37 | sources that are exposed as Web Services has been removed for now, but will
38 | be provided again shortly (i am currently doing some refactoring and redesign).
39 |
40 | The demo application intends to practically demonstrate the basic funcionality
41 | that MusicURI offers, which is to enable the mapping between a piece of music
42 | and a unique URI. The following operations are currently offered :
43 |
44 | a) Query a MusicURI local database with a music item, and retrieve a URI
45 | b) Add a reference music item to a local MusicURI database
46 | c) List all reference music items inside a local MusicURI database
47 |
48 | Explanation:
49 |
50 | a) Query the local MusicURI database file at the specified path, with the
51 | given audio file, to retrieve a URI. The -q switch is accompanied by the path
52 | to the local database, and the -f flag (optional) signals if the filename
53 | should be utilized as a reliable hint within search.
54 |
55 | Format: java -jar MusicURI.jar [] [<-q> ] [<-f>]
56 | example: "c:\demo\test.mp3" -q "c:\demo\MusicURIReferences.db" -f
57 |
58 |
59 | b) Add, to the local MusicURI database file at the specified path, the given
60 | audio file. The -a switch is accompanied by the path to the local database,
61 | into which the music item will be indexed.
62 |
63 |
64 | Format: java -jar MusicURI.jar [] [<-a> ]
65 | example: "c:\demo\test.mp3" -a "c:\demo\MusicURIReferences.db"
66 |
67 |
68 | c) List the URIs of all music items indexed in the local MusicURI database
69 | file, at the specified path.
70 |
71 | Format: java -jar MusicURI.jar [<-l> ]
72 | Example: -l "c:\demo\MusicURIReferences.db"
73 |
74 |
75 | Before proceeding with any of the aforementioned operations, the
76 | application verifies that any files that have been specified exist,
77 | and are valid.
78 |
79 | For query operations, the user has to specify Where, What and How to identify.
80 | I.e. the user must specify the URL where the MusicURI data source resides,
81 | the audio file containing the unknown piece of music, and whether the system
82 | should utilize the provided filename as a reliable hint within the search, or
83 | not (default is false). The filename should be taken into consideration only
84 | if the user is absolutely confident that it does not contain any misleading
85 | information about the artist and title of the respective piece of music. For
86 | example, this option could be safely used for a filename of the form:
87 | .
88 |
89 | @param Where: URL specifying the location of the MusicURI data source
90 | @param What : Audio file containing the piece of music to use as a query
91 | @param How : Flag determining whether to utilize the filename in search
92 |
93 |
94 | The MusicURIReferences.db database file is provided to be used as a starting
95 | point. It contains 14 MusicURIReference objects corresponding to 14 reference
96 | music items from the "Buena Vista Social Club" album that was released in 1997.
97 | The "test.mp3" file is a 6-second long excerpt from the album's 9th track.
98 |
99 |
100 | ******************************************************************************
101 | November 15, 2005
102 | Dimitrios Kourtesis
103 | d.kourtesis at gmail dot com
104 | ******************************************************************************
--------------------------------------------------------------------------------
/src/README.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | ******************************************************************************
4 | ************************ Getting started with MusicURI ***********************
5 | ******************************************************************************
6 |
7 |
8 | I have put together some instructions to demonstrate the functionality that
9 | MusicURI offers at its current point of development. To get an idea of what is
10 | offered, please follow the instructions below.
11 |
12 |
13 |
14 | ******************************************************************************
15 | Step 1. Install the MusicURI package
16 | ******************************************************************************
17 |
18 | 1. Extract the contents of 'dependencies.zip'.
19 |
20 | 2. Add the .jar files to your CLASSPATH. One way to do this is to place them
21 | inside the extension directory of your Java Runtime Environment installation
22 | (JAVA_HOME/jre/lib/ext/).
23 |
24 | 3. Place the MusicURI.jar and MusicURIReferences.db somewhere in
25 | your system. The MusicURI.jar contains the executable you will use in the next
26 | step, and the MusicURIReferences.db is the actual database flat file.
27 |
28 |
29 |
30 | ******************************************************************************
31 | Step 2. Use the MusicURI package
32 | ******************************************************************************
33 |
34 | Execute the Music.jar as described below. The entry point for the MusicURI
35 | jar file is a demo application. It currently supports only local MusicURI data
36 | sources (ie working with local database files). Support for MusicURI data
37 | sources that are exposed as Web Services has been removed for now, but will
38 | be provided again shortly (i am currently doing some refactoring and redesign).
39 |
40 | The demo application intends to practically demonstrate the basic funcionality
41 | that MusicURI offers, which is to enable the mapping between a piece of music
42 | and a unique URI. The following operations are currently offered :
43 |
44 | a) Query a MusicURI local database with a music item, and retrieve a URI
45 | b) Add a reference music item to a local MusicURI database
46 | c) List all reference music items inside a local MusicURI database
47 |
48 | Explanation:
49 |
50 | a) Query the local MusicURI database file at the specified path, with the
51 | given audio file, to retrieve a URI. The -q switch is accompanied by the path
52 | to the local database, and the -f flag (optional) signals if the filename
53 | should be utilized as a reliable hint within search.
54 |
55 | Format: java -jar MusicURI.jar [] [<-q> ] [<-f>]
56 | example: "c:\demo\test.mp3" -q "c:\demo\MusicURIReferences.db" -f
57 |
58 |
59 | b) Add, to the local MusicURI database file at the specified path, the given
60 | audio file. The -a switch is accompanied by the path to the local database,
61 | into which the music item will be indexed.
62 |
63 |
64 | Format: java -jar MusicURI.jar [] [<-a> ]
65 | example: "c:\demo\test.mp3" -a "c:\demo\MusicURIReferences.db"
66 |
67 |
68 | c) List the URIs of all music items indexed in the local MusicURI database
69 | file, at the specified path.
70 |
71 | Format: java -jar MusicURI.jar [<-l> ]
72 | Example: -l "c:\demo\MusicURIReferences.db"
73 |
74 |
75 | Before proceeding with any of the aforementioned operations, the
76 | application verifies that any files that have been specified exist,
77 | and are valid.
78 |
79 | For query operations, the user has to specify Where, What and How to identify.
80 | I.e. the user must specify the URL where the MusicURI data source resides,
81 | the audio file containing the unknown piece of music, and whether the system
82 | should utilize the provided filename as a reliable hint within the search, or
83 | not (default is false). The filename should be taken into consideration only
84 | if the user is absolutely confident that it does not contain any misleading
85 | information about the artist and title of the respective piece of music. For
86 | example, this option could be safely used for a filename of the form:
87 | .
88 |
89 | @param Where: URL specifying the location of the MusicURI data source
90 | @param What : Audio file containing the piece of music to use as a query
91 | @param How : Flag determining whether to utilize the filename in search
92 |
93 |
94 | The MusicURIReferences.db database file is provided to be used as a starting
95 | point. It contains 14 MusicURIReference objects corresponding to 14 reference
96 | music items from the "Buena Vista Social Club" album that was released in 1997.
97 | The "test.mp3" file is a 6-second long excerpt from the album's 9th track.
98 |
99 |
100 | ******************************************************************************
101 | November 15, 2005
102 | Dimitrios Kourtesis
103 | d.kourtesis at gmail dot com
104 | ******************************************************************************
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/server/MusicURIWebSearch.java:
--------------------------------------------------------------------------------
1 | package it.univpm.deit.semedia.musicuri.webservice.server;
2 |
3 | import java.io.BufferedWriter;
4 | import java.io.File;
5 | import java.io.FileWriter;
6 | import java.io.IOException;
7 | import java.net.URL;
8 | import java.util.ArrayList;
9 | import java.util.Iterator;
10 | import java.util.Set;
11 |
12 | import org.apache.axis.AxisProperties;
13 | import org.xml.sax.SAXException;
14 |
15 | import it.univpm.deit.database.datatypes.AudioLLDmeta;
16 | import it.univpm.deit.database.datatypes.Mp7ACT;
17 | import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
18 | import it.univpm.deit.semedia.musicuri.core.MusicURIQuery;
19 | import it.univpm.deit.semedia.musicuri.core.MusicURIReference;
20 | import it.univpm.deit.semedia.musicuri.core.MusicURISearch;
21 | import it.univpm.deit.semedia.musicuri.core.Result;
22 | import it.univpm.deit.semedia.musicuri.core.ResultRankingList;
23 | import it.univpm.deit.semedia.musicuri.core.Toolset;
24 | import it.univpm.deit.semedia.musicuri.statistics.PerformanceStatistic;
25 | import it.univpm.deit.semedia.musicuri.utils.misc.MusicURILibraryDemo;
26 |
27 | public class MusicURIWebSearch
28 | {
29 |
30 | private static MusicURIDatabase db = new MusicURIDatabase
31 | (getWebServiceDatabaseDirectory(), "\\MusicURIReferences.db"); // C:\WINDOWS\SYSTEM32
32 |
33 | private MusicURISearch engine = new MusicURISearch(db);
34 |
35 | public String performSearch(String xmlAudioSignature, String filename)
36 | {
37 | try
38 | {
39 | String returnString = "";
40 |
41 | String tempXMLFile = Toolset.getCWD() + "/temp.xml";
42 |
43 | BufferedWriter out = new BufferedWriter(new FileWriter(tempXMLFile));
44 | out.write(xmlAudioSignature);
45 | out.close();
46 |
47 | Mp7ACT act = new Mp7ACT();
48 | act.fromXML(tempXMLFile);
49 | MusicURIQuery query = new MusicURIQuery();
50 | query.setAudioCompactType(act);
51 |
52 | boolean usingPruningHeuristic;
53 | boolean usingCombinedDistance;
54 | boolean finalResortIsCombinedDistance;
55 | ResultRankingList finalDistanceRankingList;
56 | Result theBestResult = null;
57 | Result theSecondBestResult = null;
58 | float maximumThreshold = 0.9f;
59 |
60 |
61 | if (db == null)
62 | {
63 | returnString = "DB was not deserialized (null)";
64 | return returnString;
65 | }
66 | else
67 | {
68 | // if a filename has been provided, use it as a heuristic in search,
69 | // if not, perform a blind search, based on the audio signature only
70 | if (filename != null)
71 | {
72 | usingPruningHeuristic = true;
73 | usingCombinedDistance = true;
74 | finalResortIsCombinedDistance = true;
75 | query.setLabel(filename);
76 |
77 | returnString += queryDB(query, new Boolean(true));
78 | }
79 | else
80 | {
81 | usingPruningHeuristic = false;
82 | usingCombinedDistance = false;
83 | finalResortIsCombinedDistance = false;
84 | query.setLabel("unlabelled");
85 |
86 | returnString += queryDB(query, new Boolean(false));
87 | }
88 |
89 | return returnString;
90 |
91 | }
92 | } catch (Exception e)
93 | {
94 | e.printStackTrace();
95 | return (e.getMessage());
96 | }
97 |
98 | }
99 |
100 |
101 | public int getNumOfMusicURIReferences()
102 | {
103 | if (db == null)
104 | return (-1);
105 | else
106 | return db.getDbSize();
107 | }
108 |
109 | public String getMusicURIReferenceList()
110 | {
111 | if (db == null || db.getDbSize() == 0)
112 | return ("Database object could not be deserialized from "
113 | + getWebServiceDatabaseDirectory() );
114 | else
115 | return db.textFormattedSetOfMusicURIReferences();
116 | }
117 |
118 | private static String getWebServiceDatabaseDirectory()
119 | {
120 | // Get the "." file representing the cwd
121 | File cwd = new File(".");
122 | // Get the absolute path to the current working directory
123 | return cwd.getAbsolutePath();
124 | }
125 |
126 | private String queryDB(MusicURIQuery query, Boolean usefilenameValue)
127 | {
128 | String reply = "";
129 |
130 | ResultRankingList finalDistanceRankingList = engine.identify(query,
131 | usefilenameValue.booleanValue(),
132 | usefilenameValue.booleanValue(),
133 | 0.9f, //90% acceptable similarity rating
134 | usefilenameValue.booleanValue());
135 |
136 | if (finalDistanceRankingList.getSize() >= 1)
137 | {
138 | Result theBestResult = finalDistanceRankingList.getResultAtIndex(0);
139 | double bestMatchDistance = theBestResult.distance;
140 |
141 | reply += ("\nMatched with : " + (db.getMusicURIReference(theBestResult.md5)).getLabel());
142 | reply += ("\nScore : " + (float) (100 - (100*(theBestResult.distance))) + "%");
143 | }
144 | else
145 | {
146 | if (finalDistanceRankingList == null)
147 | reply += ("the ranking list was returned null");
148 | else
149 | reply += ("the ranking list has " + finalDistanceRankingList.getSize() + " items");
150 | }
151 | return reply;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.statistics;
23 |
24 | import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
25 |
26 | import java.io.File;
27 | import java.util.Arrays;
28 | import java.util.Collections;
29 | import java.util.Iterator;
30 | import java.util.List;
31 |
32 |
33 | import com.wcohen.secondstring.JaroWinkler;
34 | import com.wcohen.secondstring.MongeElkan;
35 | import com.wcohen.secondstring.StringDistance;
36 | import com.wcohen.secondstring.StringWrapper;
37 | import com.wcohen.secondstring.TFIDF;
38 | import com.wcohen.secondstring.tokens.SimpleTokenizer;
39 | import com.wcohen.secondstring.tokens.Token;
40 |
41 | /**
42 | * Utility class used for various tests
43 | */
44 | public class Test
45 | {
46 |
47 | public static void main(String[] args)
48 | {
49 |
50 | String databasePath = "D:/1000ReferenceDB/";
51 | String databaseFileName = "MusicURIReferences.db";
52 | System.out.println("Loading Database : " + databasePath + databaseFileName);
53 | MusicURIDatabase db = new MusicURIDatabase(databasePath, databaseFileName);
54 | System.out.println("db contains: "+ db.getDbSize());
55 |
56 | System.out.println(db.textFormattedSetOfMusicURIReferences());
57 |
58 |
59 | //StringDistance dist = new JaroWinkler().compare("frederic", "fredrick");
60 | // MongeElkan m = new MongeElkan();
61 | // String exp = m.explainScore("frederic", "fredrick");
62 | // System.out.println(exp);
63 |
64 | // StringWrapper w1 = new StringWrapper("tribe+called");
65 | // StringWrapper w2 = new StringWrapper("tribe called");
66 | // double res = m.score(w1, w2);
67 | // System.out.println(res);
68 |
69 |
70 | // SimpleTokenizer tk = new SimpleTokenizer(false, true);
71 | // Token[] tokens = tk.tokenize("tribe+Called");
72 | // for (int i = 0; i < tokens.length; i++)
73 | // {
74 | // System.out.println(tokens[i].getValue());
75 | // }
76 |
77 | // TFIDF test = new TFIDF();
78 | // w1 = test.prepare("tribe+Called");
79 | // w2 = test.prepare("tribe Called d");
80 | // float tfidfDist = (float) test.score(w1, w2);
81 | // float unit = 1.0f;
82 | // System.out.println("Distance: " + (tfidfDist));
83 | // System.out.println("Reverse : " + (unit - tfidfDist));
84 | //
85 |
86 | // ResultRankingList ranking = new ResultRankingList(4);
87 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
88 | // ranking.RankThis(new Result(2.1,"2.1"));
89 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
90 | // ranking.printContents();
91 | //
92 | // ranking.RankThis(new Result(1.1,"1.1"));
93 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
94 | // ranking.printContents();
95 | //
96 | // ranking.RankThis(new Result(3.1,"3.1"));
97 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
98 | // ranking.printContents();
99 | //
100 | // ranking.RankThis(new Result(2.0,"2.0"));
101 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
102 | // ranking.printContents();
103 | //
104 | // ranking.RankThis(new Result(0.9,"0.9"));
105 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
106 | // ranking.printContents();
107 | //
108 | // ranking.RankThis(new Result(0.7,"0.7"));
109 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
110 | // ranking.printContents();
111 | //
112 | // ranking.RankThis(new Result(3.7,"3.7"));
113 | // System.out.println("lastNullIndex: " + ranking.lastNullIndex);
114 | // ranking.printContents();
115 |
116 |
117 | // if (Toolset.getTestCaseIdentifier(currentReference.getLabel()) > 1035 )
118 | // {
119 | // int newId =0;
120 | //
121 | // if (Toolset.getTestCaseIdentifier(currentReference.getLabel()) < 1065)
122 | // newId = Toolset.getTestCaseIdentifier(currentReference.getLabel())-1;
123 | // else
124 | // newId = Toolset.getTestCaseIdentifier(currentReference.getLabel())-2;
125 | //
126 | // db.removeMusicURIReference(currentMD5);
127 | // System.out.print("replacing :" + currentReference.getLabel() );
128 | // String oldFilenameWithoutIdentifier = Toolset.removeIdentifier(currentReference.getLabel());
129 | // //System.out.print("oldFilenameWithoutIdentifier :" + oldFilenameWithoutIdentifier );
130 | // String newLabel = (newId + " " + oldFilenameWithoutIdentifier);
131 | // currentReference.setLabel(newLabel);
132 | // db.addMusicURIReference(currentReference);
133 | // System.out.println(" with " + newLabel);
134 | // //String appendedNonSenseFilename = scrambledTokenFilename.concat("#" + randomInteger +" - " + GeorgeOrwell1984[randomInteger]);
135 | //
136 | // }
137 |
138 | }
139 |
140 | }
141 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchServiceLocator.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MusicURIWebSearchServiceLocator.java
3 | *
4 | * This file was auto-generated from WSDL
5 | * by the Apache Axis 1.2.1 Jun 14, 2005 (09:15:57 EDT) WSDL2Java emitter.
6 | */
7 |
8 | package it.univpm.deit.semedia.musicuri.webservice.client;
9 |
10 | public class MusicURIWebSearchServiceLocator
11 | extends org.apache.axis.client.Service
12 | implements it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchService
13 | {
14 |
15 | public MusicURIWebSearchServiceLocator() {
16 | }
17 |
18 |
19 | public MusicURIWebSearchServiceLocator(org.apache.axis.EngineConfiguration config) {
20 | super(config);
21 | }
22 |
23 | public MusicURIWebSearchServiceLocator(java.lang.String wsdlLoc, javax.xml.namespace.QName sName) throws javax.xml.rpc.ServiceException {
24 | super(wsdlLoc, sName);
25 | }
26 |
27 | // Use to get a proxy class for MusicURIWebSearch
28 | private java.lang.String MusicURIWebSearch_address = "http://localhost:8080/axis/MusicURIWebSearch.jws";
29 |
30 | public java.lang.String getMusicURIWebSearchAddress() {
31 | return MusicURIWebSearch_address;
32 | }
33 |
34 | // The WSDD service name defaults to the port name.
35 | private java.lang.String MusicURIWebSearchWSDDServiceName = "MusicURIWebSearch";
36 |
37 | public java.lang.String getMusicURIWebSearchWSDDServiceName() {
38 | return MusicURIWebSearchWSDDServiceName;
39 | }
40 |
41 | public void setMusicURIWebSearchWSDDServiceName(java.lang.String name) {
42 | MusicURIWebSearchWSDDServiceName = name;
43 | }
44 |
45 | public it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearch getMusicURIWebSearch() throws javax.xml.rpc.ServiceException {
46 | java.net.URL endpoint;
47 | try {
48 | endpoint = new java.net.URL(MusicURIWebSearch_address);
49 | }
50 | catch (java.net.MalformedURLException e) {
51 | throw new javax.xml.rpc.ServiceException(e);
52 | }
53 | return getMusicURIWebSearch(endpoint);
54 | }
55 |
56 | public it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearch getMusicURIWebSearch(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
57 | try {
58 | it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchSoapBindingStub _stub = new it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchSoapBindingStub(portAddress, this);
59 | _stub.setPortName(getMusicURIWebSearchWSDDServiceName());
60 | return _stub;
61 | }
62 | catch (org.apache.axis.AxisFault e) {
63 | return null;
64 | }
65 | }
66 |
67 | public void setMusicURIWebSearchEndpointAddress(java.lang.String address) {
68 | MusicURIWebSearch_address = address;
69 | }
70 |
71 | /**
72 | * For the given interface, get the stub implementation.
73 | * If this service has no port for the given interface,
74 | * then ServiceException is thrown.
75 | */
76 | public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
77 | try {
78 | if (it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearch.class.isAssignableFrom(serviceEndpointInterface)) {
79 | it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchSoapBindingStub _stub = new it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchSoapBindingStub(new java.net.URL(MusicURIWebSearch_address), this);
80 | _stub.setPortName(getMusicURIWebSearchWSDDServiceName());
81 | return _stub;
82 | }
83 | }
84 | catch (java.lang.Throwable t) {
85 | throw new javax.xml.rpc.ServiceException(t);
86 | }
87 | throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface: " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
88 | }
89 |
90 | /**
91 | * For the given interface, get the stub implementation.
92 | * If this service has no port for the given interface,
93 | * then ServiceException is thrown.
94 | */
95 | public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
96 | if (portName == null) {
97 | return getPort(serviceEndpointInterface);
98 | }
99 | java.lang.String inputPortName = portName.getLocalPart();
100 | if ("MusicURIWebSearch".equals(inputPortName)) {
101 | return getMusicURIWebSearch();
102 | }
103 | else {
104 | java.rmi.Remote _stub = getPort(serviceEndpointInterface);
105 | ((org.apache.axis.client.Stub) _stub).setPortName(portName);
106 | return _stub;
107 | }
108 | }
109 |
110 | public javax.xml.namespace.QName getServiceName() {
111 | return new javax.xml.namespace.QName("http://kourtesis.homeip.net:8080/axis/MusicURIWebSearch.jws", "MusicURIWebSearchService");
112 | }
113 |
114 | private java.util.HashSet ports = null;
115 |
116 | public java.util.Iterator getPorts() {
117 | if (ports == null) {
118 | ports = new java.util.HashSet();
119 | ports.add(new javax.xml.namespace.QName("http://kourtesis.homeip.net:8080/axis/MusicURIWebSearch.jws", "MusicURIWebSearch"));
120 | }
121 | return ports.iterator();
122 | }
123 |
124 | /**
125 | * Set the endpoint address for the specified port name.
126 | */
127 | public void setEndpointAddress(java.lang.String portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
128 |
129 | if ("MusicURIWebSearch".equals(portName)) {
130 | setMusicURIWebSearchEndpointAddress(address);
131 | }
132 | else
133 | { // Unknown Port Name
134 | throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName);
135 | }
136 | }
137 |
138 | /**
139 | * Set the endpoint address for the specified port name.
140 | */
141 | public void setEndpointAddress(javax.xml.namespace.QName portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
142 | setEndpointAddress(portName.getLocalPart(), address);
143 | }
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/PerformanceStatistic.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.statistics;
23 |
24 |
25 | public class PerformanceStatistic
26 | {
27 | private int numOfReferenceFiles;
28 | private int numberOfComparisonsMade;
29 | private int numberOfRejections;
30 | private int totalReferenceSeconds;
31 | private long pruningTime;
32 | private long matchingTime;
33 | private float rejectionPercentage;
34 | private float speedPerRef;
35 | private boolean truePositive = false;
36 | private boolean falsePositive = false;
37 | private boolean trueNegative = false;
38 | private boolean falseNegative = false;
39 | private double bestMatchDistance;
40 | private double secondBestMatchDistance;
41 | private double worstMatchDistance;
42 |
43 | /**
44 | * Constructs a PerformanceStatistic object, calculates and assigns values to performance attibutes
45 | * @param numOfReferenceFiles the number of MusicURIReference objects in the db
46 | * @param numberOfComparisonsMade the number of comparisons made (certain MusicURIReference were rejected during db pruning)
47 | * @param totalReferenceSeconds the seconds of audio referenced by the db, (ie total playtime of all referenced audio files)
48 | * @param pruningTime the time spent during pruning the db
49 | * @param matchingTime the time spent for completing search and finding the match
50 | * @param identificationValidity an integer ranging [0..4] indincating wether the match was a true positive, false positive, true negative, false negative
51 | * @param bestMatchDistance the distance of the best match (ranked first) from the query
52 | * @param secondBestMatchDistance the distance of the second-best match (ranked second) from the query
53 | * @param worstMatchDistance the distance of the worst match (ranked last) from the query
54 | */
55 | public PerformanceStatistic(int numOfReferenceFiles,
56 | int numberOfComparisonsMade,
57 | int totalReferenceSeconds,
58 | long pruningTime,
59 | long matchingTime,
60 | int identificationValidity,
61 | double bestMatchDistance,
62 | double secondBestMatchDistance,
63 | double worstMatchDistance)
64 | {
65 | this.numOfReferenceFiles = numOfReferenceFiles;
66 | this.numberOfComparisonsMade = numberOfComparisonsMade;
67 | this.numberOfRejections = numOfReferenceFiles - numberOfComparisonsMade;
68 | this.totalReferenceSeconds = totalReferenceSeconds;
69 | this.pruningTime = pruningTime;
70 | this.matchingTime = matchingTime;
71 |
72 | double execTime = pruningTime + matchingTime;
73 |
74 | // Checking if the number of reference files exceeds 0
75 | if (numOfReferenceFiles > 0 && numOfReferenceFiles - numberOfRejections > 0)
76 | {
77 | rejectionPercentage = (float) (((float) 100/numOfReferenceFiles) * numberOfRejections);
78 | speedPerRef = (float)(((float) execTime/1000) /(numOfReferenceFiles - numberOfRejections));
79 | }
80 |
81 | if (identificationValidity == 1) truePositive = true;
82 | if (identificationValidity == 2) falsePositive = true;
83 | if (identificationValidity == 3) trueNegative = true;
84 | if (identificationValidity == 4) falseNegative = true;
85 |
86 | this.bestMatchDistance = bestMatchDistance;
87 | this.secondBestMatchDistance = secondBestMatchDistance;
88 | this.worstMatchDistance = worstMatchDistance;
89 | }
90 |
91 | /**
92 | * Prints some of the statistics related to speed and pruning efficiency
93 | */
94 | public void printStatistics()
95 | {
96 | System.out.println("Reference Files in DB : " + numOfReferenceFiles);
97 | System.out.println("Reference Files Processed : " + numberOfComparisonsMade);
98 | System.out.println("Reference Files Rejected : " + numberOfRejections + " (" + rejectionPercentage + " % of reference files)");
99 | // TODO: there probably is some error in how "Reference Audio Processed in Total" is calculated
100 | System.out.println("Reference Audio Processed in Total : " + totalReferenceSeconds + " audio sec (" + (float)totalReferenceSeconds/60 +" min / "+ (float)((float)(totalReferenceSeconds/60)/60) +" hrs)");
101 | System.out.println("Identification Completed in : " + ((float) (pruningTime + matchingTime)/1000) + " seconds"); //elapsed_time
102 | System.out.println("Average Search Speed (Per Reference): " + speedPerRef + " seconds per reference");
103 | }
104 |
105 | /**
106 | * @return the distance of the best match (ranked first) from the query
107 | */
108 | public double getBestMatchDistance()
109 | {
110 | return bestMatchDistance;
111 | }
112 |
113 | /**
114 | * @return the distance of the second-best match (ranked second) from the query
115 | */
116 | public double getSecondBestMatchDistance()
117 | {
118 | return secondBestMatchDistance;
119 | }
120 |
121 | /**
122 | * @return the distance of the worst match (ranked last) from the query
123 | */
124 | public double getWorstMatchDistance()
125 | {
126 | return worstMatchDistance;
127 | }
128 |
129 | /**
130 | * @return the time spent during pruning the db
131 | */
132 | public long getPruningTime()
133 | {
134 | return pruningTime;
135 | }
136 |
137 | /**
138 | * @return the time spent for completing search and finding the match
139 | */
140 | public long getMatchingTime()
141 | {
142 | return matchingTime;
143 | }
144 |
145 | /**
146 | * @return true if the MusicURIReference ranked first was a True Positive, false otherwise
147 | */
148 | public boolean isTruePositive()
149 | {
150 | return truePositive;
151 | }
152 |
153 | /**
154 | * @return true if the MusicURIReference ranked first was a False Positive, false otherwise
155 | */
156 | public boolean isFalsePositive()
157 | {
158 | return falsePositive;
159 | }
160 |
161 | /**
162 | * @return true if the MusicURIReference ranked first was a True Negative, false otherwise
163 | */
164 | public boolean isTrueNegative()
165 | {
166 | return trueNegative;
167 | }
168 |
169 | /**
170 | * @return true if the MusicURIReference ranked first was a False Negative, false otherwise
171 | */
172 | public boolean isFalseNegative()
173 | {
174 | return falseNegative;
175 | }
176 |
177 | }//end class
178 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/ResultRankingList.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.core;
23 |
24 |
25 | import java.util.ArrayList;
26 |
27 | /**
28 | * @author Dimitrios Kourtesis
29 | */
30 | public class ResultRankingList
31 | {
32 |
33 | /**
34 | * An array of Result objects
35 | */
36 | public Result[] rankList;
37 |
38 | /**
39 | * The last index in the rankList attribute, which is currently null
40 | */
41 | int lastNullIndex;
42 |
43 | /**
44 | * The maximum allowed size for the ranking list
45 | */
46 | int maxSize;
47 |
48 |
49 |
50 |
51 | /**
52 | * Constructs an empty ResultRankingList object having size equal to the one specified
53 | * @param size the maximum allowed size of the ranking list
54 | */
55 | public ResultRankingList(int size)
56 | {
57 | this.rankList = new Result[size];
58 | this.lastNullIndex = 0;
59 | this.maxSize = size;
60 | }
61 |
62 | /**
63 | * Adds the given Result object to its sorted position, according to distance,
64 | * and shifts all other results downwards. The worst result is removed, if the
65 | * maximum number of results in the list has been reached. If the given result
66 | * is not better than any other result in the list, and the max size has been
67 | * reached, the given result is ignored.
68 | * @param theNewResult the Result object to add to the list
69 | * @return the number of results currently in the list
70 | */
71 | public int RankThis(Result theNewResult)
72 | {
73 | Result currentResult;
74 |
75 | if (lastNullIndex == 0)
76 | {
77 | rankList[0] = theNewResult;
78 | lastNullIndex++;
79 | }
80 | else
81 | {
82 | for (int i = 0; i < maxSize; i++)
83 | {
84 | currentResult = (Result) rankList[i];
85 |
86 | if ( currentResult == null)
87 | {
88 | //shift all results downwards, deleting the last one
89 | for (int j = lastNullIndex-1; j > i; j--)
90 | {
91 | rankList[j] = rankList[j-1];
92 | }
93 | // insert into position i
94 | rankList[i] = theNewResult;
95 | lastNullIndex++;
96 | return lastNullIndex;
97 | }
98 | if ( currentResult != null && theNewResult.distance <= currentResult.distance )
99 | {
100 | if (lastNullIndex == maxSize)
101 | {
102 | for (int j = lastNullIndex-1; j > i; j--)
103 | {
104 | rankList[j] = rankList[j-1];
105 | }
106 | // insert into position i
107 | rankList[i] = theNewResult;
108 | }
109 | else
110 | {
111 | for (int j = lastNullIndex; j > i; j--)
112 | {
113 | rankList[j] = rankList[j-1];
114 | }
115 | // insert into position i
116 | rankList[i] = theNewResult;
117 | lastNullIndex++;
118 | }
119 | return lastNullIndex;
120 | }
121 | }
122 | }
123 | return lastNullIndex;
124 | }
125 |
126 | /**
127 | * Returns the ranking list
128 | * @return rankList the ranking list
129 | */
130 | public Result[] getRankList()
131 | {
132 | return rankList;
133 | }
134 |
135 | /**
136 | * Returns the size that the ranking list has been initialized to
137 | * @return the ranking list's initialization size
138 | */
139 | public int getSize()
140 | {
141 | return rankList.length;
142 | }
143 |
144 | /**
145 | * Returns an ArrayList object containing all MD5 keys of the
146 | * results currently contained in the ranking list
147 | * @return keyList the ArrayList object containing all MD5 keys
148 | */
149 | public ArrayList getRankListMd5Keys()
150 | {
151 | Result currentResult;
152 | String currentMD5;
153 | ArrayList keyList = new ArrayList();
154 |
155 | for (int i = 0; i < lastNullIndex; i++)
156 | {
157 | currentResult = (Result) rankList[i];
158 | currentMD5 = currentResult.md5;
159 | keyList.add(currentMD5);
160 | }
161 | return keyList;
162 | }
163 |
164 | /**
165 | * Returns the value of the distance atribute inside a Result object, that
166 | * has been added to the ranking list. If a Result object with the given
167 | * MD5 key does not exist in the ranking list, the return value is 1.0;
168 | * @param wantedKey the MD5 hash key of the wanted Result object
169 | * @return the value of the distance attribute in the Result object requested
170 | */
171 | public double getResultDistance(String wantedKey)
172 | {
173 | Result currentResult;
174 |
175 | for (int i = 0; i < lastNullIndex; i++)
176 | {
177 | currentResult = (Result) rankList[i];
178 | if (currentResult.md5.equalsIgnoreCase(wantedKey))
179 | return currentResult.distance;
180 | }
181 |
182 | return 1.0;
183 | }
184 |
185 | /**
186 | * Returns the ranking index of a Result object that has been added to
187 | * the ranking list. If a Result object with the given MD5 key does not
188 | * exist in the ranking list, the return value is the maximum raking list size;
189 | * @param wantedKey the MD5 hash key of the wanted Result object
190 | * @return the ranking index of the Result object requested
191 | */
192 | public int getRankingPositionOf(String wantedKey)
193 | {
194 | Result currentResult;
195 |
196 | for (int i = 0; i < maxSize; i++)
197 | {
198 | currentResult = (Result) rankList[i];
199 | if (currentResult.md5.equalsIgnoreCase(wantedKey))
200 | {
201 | return i+1;
202 | }
203 | }
204 | //System.out.println("returning " + position);
205 | return maxSize;
206 | }
207 |
208 | /**
209 | * Returns the Result object located in the given index. If the given index
210 | * is larger than the index of the last known valid entry, null is returned.
211 | * @param index the index (starting at zero) of the wanted Result object
212 | * @return the Result object stored in the ranking index specified
213 | */
214 | public Result getResultAtIndex(int index)
215 | {
216 | if (index <= lastNullIndex) return (Result) rankList[index];
217 | else return null;
218 | }
219 |
220 | /**
221 | * Prints some of the private attribute's values on screen (Experimental use only)
222 | */
223 | public void printContents()
224 | {
225 | for (int i = 0; i < lastNullIndex; i++)
226 | {
227 | if (rankList[i]==null)
228 | System.out.println("-");
229 | else
230 | {
231 | System.out.println(rankList[i].distance + " - " + rankList[i].md5);
232 | }
233 | }
234 | }
235 |
236 |
237 | }//end class
238 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/statistics/TestCaseCaller.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.statistics;
23 |
24 | import it.univpm.deit.semedia.musicuri.core.MusicURISearch;
25 |
26 | import java.sql.Date;
27 | import java.text.SimpleDateFormat;
28 |
29 |
30 | /**
31 | * Utility class used for various tests
32 | */
33 | public class TestCaseCaller
34 | {
35 |
36 | public static void main(String[] args) throws Exception
37 | {
38 | String[] argString = new String[2];
39 |
40 |
41 | SimpleDateFormat df = new SimpleDateFormat ("dd-MM-yyyy HH:mm:ss");
42 | // long time = System.currentTimeMillis();
43 |
44 | //known --high quality labelling
45 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
46 | // argString[0]="D:/NewBatch/Known/128kbps-FhG/TotallyAccurateLabelling"; argString[1]= "1"; MusicURISearch.main(argString); //combined distance final resort
47 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
48 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
49 | // argString[0]="D:/NewBatch/Known/64kbps-FhG/TotallyAccurateLabelling"; argString[1]= "1"; MusicURISearch.main(argString);
50 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
51 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
52 | // argString[0]="D:/NewBatch/Known/32kbps-FhG/TotallyAccurateLabelling"; argString[1]= "1"; MusicURISearch.main(argString);
53 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
54 | //
55 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
56 | // argString[0]="D:/NewBatch/Known/128kbps-FhG/TotallyAccurateLabelling"; argString[1]= "0"; MusicURISearch.main(argString);
57 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
58 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
59 | // argString[0]="D:/NewBatch/Known/64kbps-FhG/TotallyAccurateLabelling"; argString[1]= "0"; MusicURISearch.main(argString);
60 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
61 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
62 | // argString[0]="D:/NewBatch/Known/32kbps-FhG/TotallyAccurateLabelling"; argString[1]= "0"; MusicURISearch.main(argString);
63 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
64 |
65 | //known --mid quality labelling
66 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
67 | argString[0]="D:/NewBatch/Known/128kbps-FhG/BarelyReadable"; argString[1]= "1"; MusicURISearch.main(argString); //combined distance final resort
68 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
69 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
70 | argString[0]="D:/NewBatch/Known/64kbps-FhG/BarelyReadable"; argString[1]= "1"; MusicURISearch.main(argString);
71 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
72 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
73 | argString[0]="D:/NewBatch/Known/32kbps-FhG/BarelyReadable"; argString[1]= "1"; MusicURISearch.main(argString);
74 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
75 |
76 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
77 | // argString[0]="D:/NewBatch/Known/128kbps-FhG/BarelyReadable"; argString[1]= "0"; MusicURISearch.main(argString);
78 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
79 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
80 | // argString[0]="D:/NewBatch/Known/64kbps-FhG/BarelyReadable"; argString[1]= "0"; MusicURISearch.main(argString);
81 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
82 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
83 | // argString[0]="D:/NewBatch/Known/32kbps-FhG/BarelyReadable"; argString[1]= "0"; MusicURISearch.main(argString);
84 | // System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
85 |
86 |
87 | // //unknown
88 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
89 | argString[0]="D:/NewBatch/Unknown/128kbps"; argString[1]= "1"; MusicURISearch.main(argString);
90 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
91 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
92 | argString[0]="D:/NewBatch/Unknown/64kbps"; argString[1]= "1"; MusicURISearch.main(argString);
93 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
94 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
95 | argString[0]="D:/NewBatch/Unknown/32kbps"; argString[1]= "1"; MusicURISearch.main(argString);
96 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
97 |
98 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
99 | argString[0]="D:/NewBatch/Unknown/128kbps"; argString[1]= "0"; MusicURISearch.main(argString);
100 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
101 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
102 | argString[0]="D:/NewBatch/Unknown/64kbps"; argString[1]= "0"; MusicURISearch.main(argString);
103 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
104 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
105 | argString[0]="D:/NewBatch/Unknown/32kbps"; argString[1]= "0"; MusicURISearch.main(argString);
106 | System.out.println ("\n"); System.out.println (df.format(new Date(System.currentTimeMillis())));
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/DbAverageDistanceCalculator.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.utils.experimental;
23 |
24 |
25 | import it.univpm.deit.database.datatypes.AudioLLDmeta;
26 | import it.univpm.deit.database.datatypes.Mp7ACT;
27 | import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
28 | import it.univpm.deit.semedia.musicuri.core.MusicURIReference;
29 | import it.univpm.deit.semedia.musicuri.core.Toolset;
30 |
31 |
32 | import java.util.Iterator;
33 | import java.util.Set;
34 |
35 |
36 | /**
37 | * Utility class used for calculating the average distance of one MusicURIReference against the rest in the db
38 | */
39 | public class DbAverageDistanceCalculator
40 | {
41 | static String databasePath = "D:/100ReferenceDB/";
42 | static String databaseFileName = "MusicURIReferences.db";
43 | static MusicURIDatabase db = new MusicURIDatabase(databasePath, databaseFileName);
44 |
45 | public static void main(String[] args)
46 | {
47 |
48 | double overallAverageDistance = 0;
49 | double overallDistanceSum = 0;
50 |
51 | //*****************************************************************************
52 | //************ Q U E R Y D A T A P R E P A R A T I O N ****************
53 | //*****************************************************************************
54 |
55 | // gets the set of keys from the db hashmap
56 | Set queryIterator = db.getSetOfMusicURIReferences();
57 |
58 | for (Iterator iter = queryIterator.iterator(); iter.hasNext();)
59 | {
60 | // get the next md5 key
61 | String currentMD5 = (String) iter.next();
62 | MusicURIReference qqq = db.getMusicURIReference(currentMD5);
63 |
64 | Mp7ACT queryMp7 = qqq.getAudioCompactType();
65 |
66 | // if its null then there is some problem
67 | if (queryMp7 == null)
68 | System.out.println("Problem: queryMp7 is null");
69 |
70 | // read the required data from the AudioCompactType
71 | AudioLLDmeta queryMean = queryMp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.MEAN);
72 | AudioLLDmeta queryVariance = queryMp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.VARIANCE);
73 |
74 | // is audioSignatureType included in the act file?
75 | if (queryMean == null || queryVariance == null )
76 | {
77 | System.out.println("Problem: AudioSignatureType is not included in ACT or cannot be extracted from audio file. Aborting.");
78 | }
79 |
80 | int vectorSize = queryMean.vectorSize; // internal! stay out! read the matrix size instead
81 | float[][] queryMeanMatrix = queryMean.__rawVectors;
82 | float[][] queryVarianceMatrix = queryVariance.__rawVectors;
83 |
84 | // instantiate and initialize query data
85 | int QueryNumOfVectors = queryMeanMatrix.length; // ==number of vectors, seconds
86 | int QueryVectorDim = vectorSize; // ==number of dimensions, subbands
87 | double [] QueryMean = new double[QueryNumOfVectors * QueryVectorDim];
88 | double [] QueryVar = new double[QueryNumOfVectors * QueryVectorDim];
89 |
90 | // Copy the query data from the 2-d matrix of floats to a 1-d array of doubles
91 | QueryMean = Toolset.copyFloatMatrixToDoubleArray(queryMeanMatrix, vectorSize);
92 | QueryVar = Toolset.copyFloatMatrixToDoubleArray(queryVarianceMatrix, vectorSize);
93 |
94 |
95 |
96 | //*****************************************************************************
97 | //******************** D I S T A N C E S E A R C H *********************
98 | //*****************************************************************************
99 |
100 | // declare here, initialize inside the for loop
101 | int RefNumOfVectors = 0; // number of vectors, seconds
102 | int RefVectorDim = 0; // number of subbands, dimensions
103 | double[] RefMean;
104 | double[] RefVar;
105 |
106 | // something big
107 | double distance = 0;
108 |
109 | // flag used to skip entering the for loop
110 | boolean skipThis = false;
111 |
112 |
113 | // a counter used for display purposes
114 | int counter = 1;
115 |
116 |
117 | //System.out.print("Searching for " + numOfClosestMatches + " closest matches among " + db.getDbSize() + " reference signatures ");
118 |
119 | double currentQueryDistanceSum = 0;
120 | double currentQueryAverageDistance = 0;
121 | int numberOfComparisonsMade = 0;
122 |
123 |
124 | // gets the set of keys from the db hashmap
125 | Set keys = db.getSetOfMusicURIReferences();
126 | // beam me up scotty
127 | for (Iterator iter2 = keys.iterator(); iter2.hasNext();)
128 | {
129 | // get the next md5 key
130 | String currentMD52 = (String) iter2.next();
131 |
132 | // retrieve the MusicURIReference object corrsponding to this key
133 | MusicURIReference currentReference = db.getMusicURIReference(currentMD52);
134 |
135 | // retrieve the mp7act encapsulated in the MusicURIReference object
136 | Mp7ACT mp7 = currentReference.getAudioCompactType();
137 |
138 | // if it's null it shouldn't be
139 | if (mp7 == null)
140 | System.out.println("Problem: No mpeg7 exists for given uri");
141 |
142 | //System.out.print("[" + counter + "] "+ mp7.getLabel());
143 |
144 | // read the required data from the ACT
145 | AudioLLDmeta refMean = mp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.MEAN);
146 | AudioLLDmeta refVariance = mp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.VARIANCE);
147 |
148 | // if any of these are null there was some problem when extracting them, so skip them
149 | if ((refMean == null) || (refVariance == null))
150 | {
151 | System.out.println("Skipping: problematic mpeg7 description!!! - "+mp7.getLabel()+")");
152 | skipThis = true;
153 | }
154 |
155 | //System.out.println("if all goes well...");
156 | // if all goes well...
157 | if (!skipThis)
158 | {
159 | //System.out.println(" does well...");
160 | // instantiate and initialize reference data
161 | float[][] refMeanMatrix = refMean.__rawVectors;
162 | float[][] refVarianceMatrix = refVariance.__rawVectors;
163 | RefNumOfVectors = refMeanMatrix.length; // number of vectors-seconds
164 | RefVectorDim = vectorSize; // number of subbands
165 | RefMean = new double[RefNumOfVectors * RefVectorDim];
166 | RefVar = new double[RefNumOfVectors * RefVectorDim];
167 |
168 | // Copy the reference data from the 2-d matrix of floats to a 1-d array of doubles
169 | RefMean = Toolset.copyFloatMatrixToDoubleArray(refMeanMatrix, vectorSize);
170 | RefVar = Toolset.copyFloatMatrixToDoubleArray(refVarianceMatrix, vectorSize);
171 |
172 | // get the distance from query to reference
173 | distance = Mpeg7XMAudioSignatureSearch.WeightedEuclidianDistance(RefMean, RefVar, RefNumOfVectors, QueryMean, QueryVar, QueryNumOfVectors, QueryVectorDim);
174 | //distance = Toolset.getAlternativeDistance(refMeanMatrix, refVarianceMatrix, queryMeanMatrix, queryVarianceMatrix, QueryVectorDim);
175 |
176 |
177 | // print every reference in loop
178 | //System.out.println(distance + " \t" + currentReference.getLabel());
179 |
180 | currentQueryDistanceSum += distance;
181 | //get the average distance
182 |
183 | numberOfComparisonsMade++;
184 | }
185 | counter++;
186 | skipThis = false;
187 | }// for referenceIterator
188 |
189 | currentQueryAverageDistance = currentQueryDistanceSum / numberOfComparisonsMade;
190 | //System.out.println("currentQueryDistanceSum : " + currentQueryDistanceSum);
191 | //System.out.println("numberOfComparisonsMade : " + numberOfComparisonsMade);
192 | System.out.println(counter + "\tcurrentQueryAverageDistance: " + currentQueryAverageDistance);
193 |
194 | overallDistanceSum += currentQueryAverageDistance;
195 | }//for queryIterator
196 |
197 | overallAverageDistance = overallDistanceSum / db.getDbSize();
198 | System.out.println("overallDistanceSum : " + overallDistanceSum);
199 | System.out.println("db.getDbSize() : " + db.getDbSize());
200 | System.out.println("overallAverageDistance: " + overallAverageDistance);
201 | }
202 |
203 | }
204 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIQuery.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.core;
23 |
24 |
25 | import it.univpm.deit.database.datatypes.Mp7ACT;
26 | import it.univpm.deit.semedia.musicuri.core.Toolset;
27 | import java.io.File;
28 | import java.io.IOException;
29 | import java.io.StringReader;
30 | import java.util.ArrayList;
31 | import org.xml.sax.InputSource;
32 | import org.xml.sax.SAXException;
33 |
34 | /**
35 | * @author Dimitrios Kourtesis
36 | */
37 | public class MusicURIQuery
38 | {
39 |
40 | /**
41 | * An Audio Compact Type object as defined in the Mpeg7AudioDB library,
42 | * probably containing not only an AudioSignatureDS instance,
43 | * but the whole mpeg7-audio descriptor suite
44 | */
45 | private Mp7ACT audioCompactType;
46 |
47 | /**
48 | * The MD5 hash key of the original audiofile, produced by hashing
49 | * the actual binary file (and not the path to where it is located)
50 | */
51 | private String originalAudioFileMD5;
52 |
53 | /**
54 | * List of keywords taken from the original audiofile's filename and/or id3 tag
55 | * The keywords are currently extracted by tokenizing the filename
56 | * Experimental use only
57 | */
58 | private ArrayList keywords;
59 |
60 | /**
61 | * List of terms that are the metaphone equivalents of each keyword in the keywords list
62 | * The list of keywords was extracted from the original audiofile's filename and/or ID3 tag
63 | * The terms are generated using the double metaphone equivalent algorithm
64 | * Experimental use only
65 | */
66 | private ArrayList metaphones;
67 |
68 | /**
69 | * An informative label describing a piece of music (eg could be a filename)
70 | */
71 | private String label;
72 |
73 |
74 |
75 |
76 |
77 | /**
78 | * Constructs a MusicURIQuery object setting all its private atributes to null
79 | */
80 | public MusicURIQuery()
81 | {
82 | this.audioCompactType = null;
83 | this.originalAudioFileMD5 = null;
84 | this.keywords = null;
85 | this.metaphones = null;
86 | this.label = null;
87 | }
88 |
89 | /**
90 | * Constructs a MusicURIQuery object by creating the given audio file's MPEG-7
91 | * AudioCompactType, hashing its binary content to create an MD5 key, and
92 | * tokenizing its filename and/or ID3 tag to create a list of keywords and their
93 | * double metaphone equivalent terms.
94 | * @param musicFile the path to the source audio file
95 | */
96 | public MusicURIQuery(File musicFile) throws SAXException, IOException, Exception
97 | {
98 | File queryFile = musicFile;//.getCanonicalFile();
99 |
100 |
101 | //***************** AUDIO COMPACT TYPE *********************
102 | //System.out.println("Creating Audio Compact Type");
103 | //Create an empty Mp7ACT object
104 | Mp7ACT myNewMpeg7 = new Mp7ACT();
105 | // get an intermediary XML stream (String) containing the encoder-generated mpeg7 description
106 | // extracted from the given audio file, and copy the audiosignature data to our ACT
107 | myNewMpeg7.fromXML(new InputSource(new StringReader(Toolset.createMPEG7Description(queryFile))));
108 | this.audioCompactType = myNewMpeg7;
109 |
110 | //URI queryFileURI = queryFile.toURI();
111 | //String pathFromURI = queryFileURI.getPath();
112 | //URI md5DataURI = Toolset.generateMD5URI(queryFileURI);
113 | // initialize the two private attributes of class Mp7ACT (describedResource=uri describedFilePath=label)
114 | // describedResource :urn:md5:yVh5jeZOwRwwLqUUwEXUtQ==
115 | // describedFilePath: /C:/musicURI/queries/0001 A Tribe Called Quest - Can I Kick It_10sec.mp3
116 | //Mp7ACT myNewMpeg7 = new Mp7ACT(md5DataURI, pathFromURI);
117 | // get an intermediary XML stream (String) containing the encoder-generated mpeg7 description
118 | // (from the audio file specified in the URI), and copy the audiosignature data to our ACT
119 | //myNewMpeg7.fromXML(new InputSource(new StringReader(Toolset.retriveMP7(queryFileURI))));
120 | //this.audioCompactType = myNewMpeg7;
121 |
122 |
123 | //************************** MD-5 **************************
124 | //System.out.println("Creating MD5 hash key");
125 | // Hash the given audio file's binary contents to create the MD5 hash
126 | byte[] md = Toolset.createMD5Hash(queryFile);
127 | this.originalAudioFileMD5 = Toolset.toHexString(md);
128 | //System.out.println("hash: " + Utils.toHexString(md));
129 |
130 |
131 | //************************** KEYWORDS **************************
132 | //System.out.println("Extracting list of keywords");
133 | // Tokenize the audio file's name to create a list of keywords
134 | this.keywords = Toolset.ExtractKeywords(queryFile);
135 | //System.out.println("keywords size: " + keywords.size());
136 | //for (int i = 0; i < keywords.size(); i++) System.out.println(keywords.get(i).toString());
137 |
138 |
139 | // ************************ METAPHONES *************************
140 | //System.out.println("Extracting keywords' metaphone equivalents");
141 | // Convert the elements of the keywords list to their metaphone equivalents,
142 | // to enable fuzzy phonetic matching, and robustness against mispellings
143 | this.metaphones = Toolset.GenerateMetaphones(keywords);
144 | //System.out.println("metaphones size: " + metaphones.size());
145 | //for (int i = 0; i < metaphones.size(); i++) System.out.println(metaphones.get(i).toString());
146 |
147 |
148 | // ************************** LABEL ****************************
149 | //System.out.println("Extracting label");
150 | this.label = queryFile.getName();
151 | //System.out.println("label: " + label);
152 | }
153 |
154 | /**
155 | * Gets the Mp7ACT object that is encapsulated in this MusicURIQuery object
156 | * @return audioCompactType the Mp7ACT object
157 | */
158 | public Mp7ACT getAudioCompactType()
159 | {
160 | return audioCompactType;
161 | }
162 |
163 | /**
164 | * Sets the Mp7ACT object that is encapsulated in this MusicURIQuery object to the one specified
165 | * @param audioCompactType the Mp7ACT object to be set
166 | */
167 | public void setAudioCompactType(Mp7ACT audioCompactType)
168 | {
169 | this.audioCompactType = audioCompactType;
170 | }
171 |
172 | /**
173 | * Gets the MD5 key of the original audio file that this MusicURIQuery object was created from
174 | * @return originalAudioFileMD5 the MD5 hash key
175 | */
176 | public String getOriginalAudioFileMD5()
177 | {
178 | return originalAudioFileMD5;
179 | }
180 |
181 | /**
182 | * Sets the MD5 key of the original audio file that this MusicURIQuery corresponds to
183 | * @param originalAudioFileMD5 the MD5 hash key to set
184 | */
185 | public void setOriginalAudioFileMD5(String originalAudioFileMD5)
186 | {
187 | this.originalAudioFileMD5 = originalAudioFileMD5;
188 | }
189 |
190 | /**
191 | * Gets the list of keywords in this MusicURIQuery object
192 | * @return keywords the list of keywords
193 | */
194 | public ArrayList getKeywords()
195 | {
196 | return keywords;
197 | }
198 |
199 | /**
200 | * Sets the list of keywords in this MusicURIQuery object
201 | * @return keywords the list of keywords to set
202 | */
203 | public void setKeywords(ArrayList keywords)
204 | {
205 | this.keywords = keywords;
206 | }
207 |
208 | /**
209 | * Gets the list of metaphone equivalent terms that correspond to the keywords contained in the keywords list
210 | * @return metaphones the list of metaphones
211 | */
212 | public ArrayList getMetaphones()
213 | {
214 | return metaphones;
215 | }
216 |
217 | /**
218 | * Sets the list of metaphone equivalent terms that correspond to the keywords contained in the keywords list
219 | * @param metaphones the list of metaphones to set
220 | */
221 | public void setMetaphones(ArrayList metaphones)
222 | {
223 | this.metaphones = metaphones;
224 | }
225 |
226 | /**
227 | * Gets the label describing the audio file this MusicURIQuery has been created from
228 | * @return label the label describing the original audio file
229 | */
230 | public String getLabel()
231 | {
232 | return label;
233 | }
234 |
235 | /**
236 | * Sets the label describing the audio file this MusicURIQuery has been created from
237 | * @param label the label to be set, describing the original audio file
238 | */
239 | public void setLabel(String label)
240 | {
241 | this.label = label;
242 | }
243 |
244 |
245 | }//end class
246 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/webservice/client/MusicURIWebSearchSoapBindingStub.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MusicURIWebSearchSoapBindingStub.java
3 | *
4 | * This file was auto-generated from WSDL
5 | * by the Apache Axis 1.2.1 Jun 14, 2005 (09:15:57 EDT) WSDL2Java emitter.
6 | */
7 |
8 | package it.univpm.deit.semedia.musicuri.webservice.client;
9 |
10 | public class MusicURIWebSearchSoapBindingStub
11 | extends org.apache.axis.client.Stub
12 | implements it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearch
13 | {
14 | private java.util.Vector cachedSerClasses = new java.util.Vector();
15 |
16 | private java.util.Vector cachedSerQNames = new java.util.Vector();
17 |
18 | private java.util.Vector cachedSerFactories = new java.util.Vector();
19 |
20 | private java.util.Vector cachedDeserFactories = new java.util.Vector();
21 |
22 | static org.apache.axis.description.OperationDesc[] _operations;
23 |
24 | static
25 | {
26 | _operations = new org.apache.axis.description.OperationDesc[3];
27 | _initOperationDesc1();
28 | }
29 |
30 | private static void _initOperationDesc1()
31 | {
32 | org.apache.axis.description.OperationDesc oper;
33 | org.apache.axis.description.ParameterDesc param;
34 | oper = new org.apache.axis.description.OperationDesc();
35 | oper.setName("getMusicURIReferenceList");
36 | oper.setReturnType(new javax.xml.namespace.QName(
37 | "http://www.w3.org/2001/XMLSchema", "string"));
38 | oper.setReturnClass(java.lang.String.class);
39 | oper.setReturnQName(new javax.xml.namespace.QName("",
40 | "getMusicURIReferenceListReturn"));
41 | oper.setStyle(org.apache.axis.constants.Style.RPC);
42 | oper.setUse(org.apache.axis.constants.Use.ENCODED);
43 | _operations[0] = oper;
44 |
45 | oper = new org.apache.axis.description.OperationDesc();
46 | oper.setName("getNumOfMusicURIReferences");
47 | oper.setReturnType(new javax.xml.namespace.QName(
48 | "http://www.w3.org/2001/XMLSchema", "int"));
49 | oper.setReturnClass(int.class);
50 | oper.setReturnQName(new javax.xml.namespace.QName("",
51 | "getNumOfMusicURIReferencesReturn"));
52 | oper.setStyle(org.apache.axis.constants.Style.RPC);
53 | oper.setUse(org.apache.axis.constants.Use.ENCODED);
54 | _operations[1] = oper;
55 |
56 | oper = new org.apache.axis.description.OperationDesc();
57 | oper.setName("performSearch");
58 | param = new org.apache.axis.description.ParameterDesc(
59 | new javax.xml.namespace.QName("", "xmlAudioSignature"),
60 | org.apache.axis.description.ParameterDesc.IN,
61 | new javax.xml.namespace.QName(
62 | "http://www.w3.org/2001/XMLSchema", "string"),
63 | java.lang.String.class, false, false);
64 | oper.addParameter(param);
65 | param = new org.apache.axis.description.ParameterDesc(
66 | new javax.xml.namespace.QName("", "filename"),
67 | org.apache.axis.description.ParameterDesc.IN,
68 | new javax.xml.namespace.QName(
69 | "http://www.w3.org/2001/XMLSchema", "string"),
70 | java.lang.String.class, false, false);
71 | oper.addParameter(param);
72 | oper.setReturnType(new javax.xml.namespace.QName(
73 | "http://www.w3.org/2001/XMLSchema", "string"));
74 | oper.setReturnClass(java.lang.String.class);
75 | oper.setReturnQName(new javax.xml.namespace.QName("",
76 | "performSearchReturn"));
77 | oper.setStyle(org.apache.axis.constants.Style.RPC);
78 | oper.setUse(org.apache.axis.constants.Use.ENCODED);
79 | _operations[2] = oper;
80 |
81 | }
82 |
83 | public MusicURIWebSearchSoapBindingStub() throws org.apache.axis.AxisFault
84 | {
85 | this(null);
86 | }
87 |
88 | public MusicURIWebSearchSoapBindingStub(java.net.URL endpointURL,
89 | javax.xml.rpc.Service service) throws org.apache.axis.AxisFault
90 | {
91 | this(service);
92 | super.cachedEndpoint = endpointURL;
93 | }
94 |
95 | public MusicURIWebSearchSoapBindingStub(javax.xml.rpc.Service service)
96 | throws org.apache.axis.AxisFault
97 | {
98 | if (service == null)
99 | {
100 | super.service = new org.apache.axis.client.Service();
101 | } else
102 | {
103 | super.service = service;
104 | }
105 | ((org.apache.axis.client.Service) super.service)
106 | .setTypeMappingVersion("1.2");
107 | }
108 |
109 | protected org.apache.axis.client.Call createCall()
110 | throws java.rmi.RemoteException
111 | {
112 | try
113 | {
114 | org.apache.axis.client.Call _call = super._createCall();
115 | if (super.maintainSessionSet)
116 | {
117 | _call.setMaintainSession(super.maintainSession);
118 | }
119 | if (super.cachedUsername != null)
120 | {
121 | _call.setUsername(super.cachedUsername);
122 | }
123 | if (super.cachedPassword != null)
124 | {
125 | _call.setPassword(super.cachedPassword);
126 | }
127 | if (super.cachedEndpoint != null)
128 | {
129 | _call.setTargetEndpointAddress(super.cachedEndpoint);
130 | }
131 | if (super.cachedTimeout != null)
132 | {
133 | _call.setTimeout(super.cachedTimeout);
134 | }
135 | if (super.cachedPortName != null)
136 | {
137 | _call.setPortName(super.cachedPortName);
138 | }
139 | java.util.Enumeration keys = super.cachedProperties.keys();
140 | while (keys.hasMoreElements())
141 | {
142 | java.lang.String key = (java.lang.String) keys.nextElement();
143 | _call.setProperty(key, super.cachedProperties.get(key));
144 | }
145 | return _call;
146 | } catch (java.lang.Throwable _t)
147 | {
148 | throw new org.apache.axis.AxisFault(
149 | "Failure trying to get the Call object", _t);
150 | }
151 | }
152 |
153 | public java.lang.String getMusicURIReferenceList()
154 | throws java.rmi.RemoteException
155 | {
156 | if (super.cachedEndpoint == null)
157 | {
158 | throw new org.apache.axis.NoEndPointException();
159 | }
160 | org.apache.axis.client.Call _call = createCall();
161 | _call.setOperation(_operations[0]);
162 | _call.setUseSOAPAction(true);
163 | _call.setSOAPActionURI("");
164 | _call
165 | .setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
166 | _call.setOperationName(new javax.xml.namespace.QName(
167 | "http://DefaultNamespace", "getMusicURIReferenceList"));
168 |
169 | setRequestHeaders(_call);
170 | setAttachments(_call);
171 | try
172 | {
173 | java.lang.Object _resp = _call.invoke(new java.lang.Object[] {});
174 |
175 | if (_resp instanceof java.rmi.RemoteException)
176 | {
177 | throw (java.rmi.RemoteException) _resp;
178 | } else
179 | {
180 | extractAttachments(_call);
181 | try
182 | {
183 | return (java.lang.String) _resp;
184 | } catch (java.lang.Exception _exception)
185 | {
186 | return (java.lang.String) org.apache.axis.utils.JavaUtils
187 | .convert(_resp, java.lang.String.class);
188 | }
189 | }
190 | } catch (org.apache.axis.AxisFault axisFaultException)
191 | {
192 | throw axisFaultException;
193 | }
194 | }
195 |
196 | public int getNumOfMusicURIReferences() throws java.rmi.RemoteException
197 | {
198 | if (super.cachedEndpoint == null)
199 | {
200 | throw new org.apache.axis.NoEndPointException();
201 | }
202 | org.apache.axis.client.Call _call = createCall();
203 | _call.setOperation(_operations[1]);
204 | _call.setUseSOAPAction(true);
205 | _call.setSOAPActionURI("");
206 | _call
207 | .setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
208 | _call.setOperationName(new javax.xml.namespace.QName(
209 | "http://DefaultNamespace", "getNumOfMusicURIReferences"));
210 |
211 | setRequestHeaders(_call);
212 | setAttachments(_call);
213 | try
214 | {
215 | java.lang.Object _resp = _call.invoke(new java.lang.Object[] {});
216 |
217 | if (_resp instanceof java.rmi.RemoteException)
218 | {
219 | throw (java.rmi.RemoteException) _resp;
220 | } else
221 | {
222 | extractAttachments(_call);
223 | try
224 | {
225 | return ((java.lang.Integer) _resp).intValue();
226 | } catch (java.lang.Exception _exception)
227 | {
228 | return ((java.lang.Integer) org.apache.axis.utils.JavaUtils
229 | .convert(_resp, int.class)).intValue();
230 | }
231 | }
232 | } catch (org.apache.axis.AxisFault axisFaultException)
233 | {
234 | throw axisFaultException;
235 | }
236 | }
237 |
238 | public java.lang.String performSearch(java.lang.String xmlAudioSignature,
239 | java.lang.String filename) throws java.rmi.RemoteException
240 | {
241 | if (super.cachedEndpoint == null)
242 | {
243 | throw new org.apache.axis.NoEndPointException();
244 | }
245 | org.apache.axis.client.Call _call = createCall();
246 | _call.setOperation(_operations[2]);
247 | _call.setUseSOAPAction(true);
248 | _call.setSOAPActionURI("");
249 | _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
250 | _call.setOperationName(new javax.xml.namespace.QName(
251 | "http://DefaultNamespace", "performSearch"));
252 |
253 | setRequestHeaders(_call);
254 | setAttachments(_call);
255 | try
256 | {
257 | java.lang.Object _resp = _call.invoke(new java.lang.Object[]
258 | { xmlAudioSignature, filename });
259 |
260 | if (_resp instanceof java.rmi.RemoteException)
261 | {
262 | throw (java.rmi.RemoteException) _resp;
263 | } else
264 | {
265 | extractAttachments(_call);
266 | try
267 | {
268 | return (java.lang.String) _resp;
269 | } catch (java.lang.Exception _exception)
270 | {
271 | return (java.lang.String) org.apache.axis.utils.JavaUtils
272 | .convert(_resp, java.lang.String.class);
273 | }
274 | }
275 | } catch (org.apache.axis.AxisFault axisFaultException)
276 | {
277 | throw axisFaultException;
278 | }
279 | }
280 |
281 | }
282 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIReference.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.core;
23 |
24 |
25 | import it.univpm.deit.database.datatypes.Mp7ACT;
26 | import it.univpm.deit.semedia.musicuri.core.Toolset;
27 | import java.io.File;
28 | import java.io.Serializable;
29 | import java.io.StringReader;
30 | import java.net.URI;
31 | import java.util.ArrayList;
32 | import org.xml.sax.InputSource;
33 |
34 | /**
35 | * @author Dimitrios Kourtesis
36 | */
37 | public class MusicURIReference implements Serializable
38 | {
39 |
40 | /**
41 | * An Audio Compact Type object as defined in the Mpeg7AudioDB library,
42 | * probably containing not only an AudioSignatureDS instance,
43 | * but the whole mpeg7-audio descriptor suite
44 | */
45 | private Mp7ACT audioCompactType;
46 |
47 | /**
48 | * The MD5 hash key of the audiofile that is identified as a "representative" physical
49 | * resource containing a digitally encoded conceptual resource. For example, this could be
50 | * the MD5 key of the first mp3 file containing Eric Clapton's "Layla", that has been presented
51 | * to the system. Thereafter all digital audio files containing the same song will be collapsed
52 | * onto the specific musicURIReference containing the MD5 key of the first, original file.
53 | * the actual binary file (and not the path to where it is located)
54 | */
55 | private String originalAudioFileMD5;
56 |
57 | /**
58 | * List of keywords taken from the original audiofile's filename and/or id3 tag
59 | * The keywords are currently extracted by tokenizing the filename
60 | * Experimental use only
61 | */
62 | private ArrayList keywords;
63 |
64 | /**
65 | * List of terms that are the metaphone equivalents of each keyword in the keywords list
66 | * The list of keywords was extracted from the original audiofile's filename and/or ID3 tag
67 | * The terms are generated using the double metaphone equivalent algorithm
68 | * Experimental use only
69 | */
70 | private ArrayList metaphones;
71 |
72 | /**
73 | * An informative label describing a piece of music (eg could be a filename)
74 | */
75 | private String label;
76 |
77 | /**
78 | * The actual music URI that uniquely identifies the specific MusicURIReference,
79 | * and thus, the underlying conceptual resource, which is a song
80 | */
81 | private URI musicUri;
82 |
83 |
84 |
85 |
86 | /**
87 | * Constructs a MusicURIReference object by creating the given audio file's
88 | * MPEG-7 AudioCompactType, hashing its binary content to create an MD5 key, and
89 | * tokenizing its filename and/or ID3 tag to create a list of keywords and their
90 | * double metaphone equivalent terms.
91 | * @param musicFile the path to the source audio file
92 | */
93 | public MusicURIReference(File musicFile) throws Exception
94 | {
95 | File queryFile = musicFile.getCanonicalFile();
96 |
97 | //***************** AUDIO COMPACT TYPE *********************
98 | Mp7ACT myNewMpeg7 = new Mp7ACT();
99 | // get an intermediary XML stream (String) containing the encoder-generated mpeg7 description
100 | // extracted from the given audio file, and copy the audiosignature data to our ACT
101 | myNewMpeg7.fromXML(new InputSource(new StringReader(Toolset.createMPEG7Description(queryFile))));
102 | this.audioCompactType = myNewMpeg7;
103 |
104 |
105 | //************************** MD-5 **************************
106 | // Hash the given audio file's binary contents to create the MD5 hash
107 | byte[] md = Toolset.createMD5Hash(queryFile);
108 | this.originalAudioFileMD5 = Toolset.toHexString(md);
109 | //System.out.println("hash: " + Toolset.toHexString(md));
110 |
111 |
112 | //************************** KEYWORDS **************************
113 | // Tokenize the audio file's name to create a list of keywords
114 | this.keywords = Toolset.ExtractKeywords(queryFile);
115 | //System.out.println("keywords size: " + keywords.size());
116 | //for (int i = 0; i < keywords.size(); i++) System.out.println(keywords.get(i).toString());
117 |
118 |
119 | // ************************ METAPHONES *************************
120 | // Convert the elements of the keywords list to their metaphone equivalents,
121 | // to enable fuzzy phonetic matching, and robustness against mispellings
122 | this.metaphones = Toolset.GenerateMetaphones(keywords);
123 | //System.out.println("metaphones size: " + metaphones.size());
124 | //for (int i = 0; i < metaphones.size(); i++) System.out.println(metaphones.get(i).toString());
125 |
126 |
127 | // ************************ MUSIC URI **************************
128 | musicUri = new URI("http://musicuri.org/" + originalAudioFileMD5);
129 | //System.out.println("musicUri: " + musicUri.toString());
130 |
131 |
132 | // ************************** LABEL ****************************
133 | label = queryFile.getName();
134 | //System.out.println("label: " + label);
135 | }
136 |
137 | /**
138 | * Constructs a MusicURIReference object by setting its private attributes to the ones given
139 | * @param audioCompactType the Mp7ACT object extracted from the source audio file
140 | * @param originalAudioFileMD5 the MD5 hash key of the audio file
141 | * @param keywords the list of keywaords extracted from the source audio file
142 | * @param metaphones the list of metaphone equivalent terms generated from the keywords
143 | * @param musicUri the actual URI identifying this MusicURIReference
144 | * @param label the label describing the source audio file
145 | */
146 | MusicURIReference(Mp7ACT audioCompactType,
147 | String originalAudioFileMD5,
148 | ArrayList keywords,
149 | ArrayList metaphones,
150 | URI musicUri,
151 | String label)
152 | {
153 | this.audioCompactType = audioCompactType;
154 | this.originalAudioFileMD5 = originalAudioFileMD5;
155 | this.keywords = keywords;
156 | this.metaphones = metaphones;
157 | this.musicUri = musicUri;
158 | this.label = label;
159 | }
160 |
161 | /**
162 | * Gets the Mp7ACT object that is encapsulated in this MusicURIQuery object
163 | * @return audioCompactType the Mp7ACT object
164 | */
165 | public Mp7ACT getAudioCompactType()
166 | {
167 | return audioCompactType;
168 | }
169 |
170 | /**
171 | * Sets the Mp7ACT object that is encapsulated in this MusicURIQuery object to the one specified
172 | * @param audioCompactType the Mp7ACT object to be set
173 | */
174 | public void setAudioCompactType(Mp7ACT audioCompactType)
175 | {
176 | this.audioCompactType = audioCompactType;
177 | }
178 |
179 | /**
180 | * Gets the MD5 key of the original audio file that this MusicURIQuery object was created from
181 | * @return originalAudioFileMD5 the MD5 hash key
182 | */
183 | public String getOriginalAudioFileMD5()
184 | {
185 | return originalAudioFileMD5;
186 | }
187 |
188 | /**
189 | * Sets the MD5 key of the original audio file that this MusicURIQuery corresponds to
190 | * @param originalAudioFileMD5 the MD5 hash key to set
191 | */
192 | public void setOriginalAudioFileMD5(String originalAudioFileMD5)
193 | {
194 | this.originalAudioFileMD5 = originalAudioFileMD5;
195 | }
196 |
197 | /**
198 | * Gets the list of keywords in this MusicURIQuery object
199 | * @return keywords the list of keywords
200 | */
201 | public ArrayList getKeywords()
202 | {
203 | return keywords;
204 | }
205 |
206 | /**
207 | * Sets the list of keywords in this MusicURIQuery object
208 | * @return keywords the list of keywords to set
209 | */
210 | public void setKeywords(ArrayList keywords)
211 | {
212 | this.keywords = keywords;
213 | }
214 |
215 | /**
216 | * Gets the list of metaphone equivalent terms that correspond to the keywords contained in the keywords list
217 | * @return metaphones the list of metaphones
218 | */
219 | public ArrayList getMetaphones()
220 | {
221 | return metaphones;
222 | }
223 |
224 | /**
225 | * Sets the list of metaphone equivalent terms that correspond to the keywords contained in the keywords list
226 | * @param metaphones the list of metaphones to set
227 | */
228 | public void setMetaphones(ArrayList metaphones)
229 | {
230 | this.metaphones = metaphones;
231 | }
232 |
233 | /**
234 | * Gets the label describing the audio file this MusicURIQuery has been created from
235 | * @return label the label describing the original audio file
236 | */
237 | public String getLabel()
238 | {
239 | return label;
240 | }
241 |
242 | /**
243 | * Sets the label describing the audio file this MusicURIQuery has been created from
244 | * @param label the label to be set, describing the original audio file
245 | */
246 | public void setLabel(String label)
247 | {
248 | this.label = label;
249 | }
250 |
251 | /**
252 | * Gets the URI this MusicURIReference has been assigned to
253 | * @return musicUri the URI assigned to this reference
254 | */
255 | public URI getMusicUri()
256 | {
257 | return musicUri;
258 | }
259 |
260 | /**
261 | * Sets the URI this MusicURIReference should be assigned to
262 | * @param uri the URI to be set
263 | */
264 | public void setMusicUri(URI uri)
265 | {
266 | this.musicUri = uri;
267 | }
268 |
269 | /**
270 | * Prints some of the private attribute's values on screen (Experimental use only)
271 | */
272 | public void printToScreen()
273 | {
274 | System.out.println("MD5: " + getOriginalAudioFileMD5() + ", Label: "+ getLabel() + ", musicuri: " + getMusicUri());
275 |
276 | ArrayList keys = getKeywords();
277 | ArrayList metas = getMetaphones();
278 | for (int i = 0; i < keys.size(); i++)
279 | {
280 | System.out.println("keyword: "+ keys.get(i) + " metaphone: " + metas.get(i));
281 | }
282 | }
283 |
284 |
285 | }//end class
286 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/core/MusicURIDatabase.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.core;
23 |
24 |
25 | import java.io.File;
26 | import java.io.FileInputStream;
27 | import java.io.FileOutputStream;
28 | import java.io.FileWriter;
29 | import java.io.IOException;
30 | import java.io.InvalidClassException;
31 | import java.io.ObjectInputStream;
32 | import java.io.ObjectOutputStream;
33 | import java.io.Serializable;
34 | import java.net.URI;
35 | import java.net.URISyntaxException;
36 | import java.util.HashMap;
37 | import java.util.Iterator;
38 | import java.util.Map;
39 | import java.util.Set;
40 | import com.thoughtworks.xstream.XStream;
41 |
42 | /**
43 | * @author Dimitrios Kourtesis
44 | */
45 | public class MusicURIDatabase implements Serializable
46 | {
47 |
48 | private static final long serialVersionUID = 1L;
49 | /**
50 | * A HashMap object containing pairs of an MD5 String as key and a MusicURIReference object as value
51 | */
52 | private HashMap table;
53 | /**
54 | * The path to where the serialized HashMap database is located
55 | */
56 | private String databasePath;
57 | /**
58 | * The database file name
59 | */
60 | private String databaseFileName;
61 |
62 |
63 |
64 |
65 | /**
66 | * Constructs a MusicURIDatabase object by deserializing the HashMap specified by the path
67 | * @param databasePath the path to the directory containing the db
68 | * @param databaseFileName the filename of the serialized hashmap
69 | */
70 | public MusicURIDatabase(String databasePath, String databaseFileName)
71 | {
72 | table = new HashMap();
73 | this.databasePath = databasePath;
74 | this.databaseFileName = databaseFileName;
75 |
76 | try
77 | {
78 | table = (HashMap) deserialize(databasePath + databaseFileName);
79 | //System.out.println(table.size() + " references loaded from " + databaseFileName);
80 | }
81 | catch (ClassNotFoundException e)
82 | {
83 | e.toString();
84 | //System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
85 | }
86 | catch (InvalidClassException e)
87 | {
88 | e.toString();
89 | //System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
90 | }
91 | catch (IOException e)
92 | {
93 | e.toString();
94 | //System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
95 | }
96 | catch (Exception e)
97 | {
98 | e.toString();
99 | //System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
100 | }
101 | }
102 |
103 | /**
104 | * Creates and adds to the DB a MusicURIReference object for every audio file contained in the directory specified
105 | * @param directoryPath the path to the directory containing the audio files to be added to the DB
106 | */
107 | public void indexAudioFilesInDirectory(String directoryPath)
108 | {
109 | File path = new File(directoryPath);
110 | File[] list = path.listFiles();
111 | if (list.length == 0)
112 | {
113 | return;
114 | }
115 | else
116 | {
117 | for (int i = 0; i < list.length; i++)
118 | {
119 | File file = list[i];
120 | try
121 | {
122 | if (Toolset.isSupportedAudioFile(file))
123 | addMusicURIReference(new MusicURIReference(file));
124 | }
125 | catch (Exception e)
126 | {
127 | e.printStackTrace();
128 | }
129 | }
130 | }
131 | }
132 |
133 | /**
134 | * Adds the given MusicURIReference object to the DB, and also serializes it to xml
135 | * @param newReference the MusicURIReference object to add to the DB
136 | */
137 | public boolean addMusicURIReference(MusicURIReference newReference)
138 | {
139 |
140 | String md5 = newReference.getOriginalAudioFileMD5(); // MD5 used askey
141 | String filename = md5 + ".xml";
142 | File serializedObject = new File(databasePath + filename);
143 |
144 | // check if MD5 is already in use, and if the object serialized to xml exists on disk
145 | if (table.containsKey(md5))
146 | {
147 | //System.out.println("This MD5 is already in use");
148 | //if (serializedObject.exists()) System.out.println("XML file exists");
149 | //else System.out.println("XML file does not exist in DB directory");
150 | return false;
151 | }
152 | else
153 | {
154 | //although not required, also serialize to xml for easy debugging
155 | serializeToXmlFile(newReference, databasePath + filename);
156 | //add newReference to list with MD5 String as key, MusicURIReference object as value
157 | table.put(md5, newReference);
158 | saveDb();
159 | return true;
160 | }
161 | }
162 |
163 | /**
164 | * Serializes the HashMap table containing all references, saving its state
165 | */
166 | public void saveDb()
167 | {
168 | serialize(table, databasePath + databaseFileName);
169 | //System.out.println(table.keySet().size() + " references saved in " + databaseFileName);
170 | }
171 |
172 | /**
173 | * Removes a MusicURIReference object from the DB
174 | * @param md5 the MD5 key of the MusicURIReference object to remove
175 | */
176 | public boolean removeMusicURIReference (String md5)
177 | {
178 | if (!table.containsKey(md5)) // check if MD5 key exists in db
179 | {
180 | //System.out.println ("This MD5 key is not registered in the DB");
181 | return false;
182 | }
183 | else
184 | {
185 | //remove MD5 and associated MusicURIReference from db
186 | table.remove(md5);
187 | saveDb();
188 | return true;
189 | }
190 |
191 | }
192 |
193 | /**
194 | * Fetches a MusicURIReference object from the DB
195 | * @param md5 the MD5 key of the MusicURIReference object to fetch
196 | * @return the MusicURIReference that was fetched, if it exists, null otherwise
197 | */
198 | public MusicURIReference getMusicURIReference(String md5)
199 | {
200 | if (!table.containsKey(md5)) // check if MD5 key exists in db
201 | {
202 | //System.out.println ("This MD5 key is not registered in the DB");
203 | return null;
204 | }
205 | else
206 | {
207 | // get associated MusicURIReference
208 | return (MusicURIReference)table.get(md5);
209 | }
210 | }
211 |
212 | /**
213 | * Fetches the HashMap object that comprises the DB as a set view (object removals supported)
214 | * @return a set view of the keys contained in the HashMap
215 | */
216 | public Set getSetOfMusicURIReferences()
217 | {
218 | try
219 | {
220 | //HashMap tableClone = (HashMap) Cloner.cloneObject(table);
221 | //return tableClone.keySet();
222 | return table.keySet();
223 | }
224 | catch (Exception e)
225 | {
226 | e.printStackTrace();
227 | return null;
228 | }
229 | }
230 |
231 | /**
232 | * Returns a String containing a formatted list of all the audio files that have
233 | * been indexed as references in the DB (lists their titles and URIs).
234 | */
235 | public String textFormattedSetOfMusicURIReferences()
236 | {
237 | String text = "\nReference audio files indexed in the DB, and their assigned URIs:\n\n";
238 |
239 | Set set = table.entrySet();
240 | Iterator it = set.iterator();
241 | int index = 1;
242 | while (it.hasNext())
243 | {
244 | Map.Entry e = (Map.Entry)it.next();
245 | text = text.concat("["+ index + "]" + "\tTitle : " + ((MusicURIReference)e.getValue()).getLabel() + "\n");
246 | text = text.concat("\tURI : " + ((MusicURIReference)e.getValue()).getMusicUri() + "\n\n");
247 | index ++;
248 | }
249 | return text;
250 | }
251 |
252 | /**
253 | * Gets the number of entries in the HashMap object that comprises the DB
254 | * @return the size of the DB
255 | */
256 | public int getDbSize()
257 | {
258 | return table.size();
259 | }
260 |
261 | /**
262 | * Serializes any object to the filename specified
263 | * @param object the object to be serialized
264 | * @param fileName the filename of the serialized object
265 | */
266 | public void serialize(Object object,String fileName)
267 | {
268 | try
269 | {
270 | ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
271 | out.writeObject(object);
272 | out.flush();
273 | }
274 | catch (IOException e)
275 | {
276 | System.err.println("Unable to serialize object: " + e.toString());
277 | }
278 | }
279 |
280 | /**
281 | * Deserializes any object from the filename specified
282 | * @param filePath the filename of the serialized object
283 | * @return the object that was deserialized
284 | */
285 | public Object deserialize(String filePath) throws IOException, ClassNotFoundException
286 | {
287 | Object object = new Object();
288 | ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath));
289 | object = in.readObject();
290 | return object;
291 | }
292 |
293 | /**
294 | * Deserializes a HashMap object from the filename specified
295 | * @param filePath the filename of the serialized HashMap
296 | * @return the HashMap object that was deserialized
297 | */
298 | public HashMap deserializeHashMap(String filePath) throws IOException, ClassNotFoundException
299 | {
300 | HashMap object = new HashMap();
301 | ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath));
302 | object = (HashMap) in.readObject();
303 | return object;
304 | }
305 |
306 | /**
307 | * Serializes any object to an XML file with the filename specified
308 | * @param object the object to be serialized
309 | * @param filename the XML filename of the serialized object
310 | */
311 | public void serializeToXmlFile(Object object, String filename)
312 | {
313 | XStream xstream = new XStream();
314 | String xml = xstream.toXML(object);
315 | try
316 | {
317 | FileWriter fw = new FileWriter(filename);
318 | fw.write(xml);
319 | fw.close();
320 | }
321 | catch (IOException e)
322 | {
323 | e.printStackTrace();
324 | }
325 | }
326 |
327 |
328 | // /**
329 | // * Adds an Mp7ACT object to the DB
330 | // * @param act the Mp7ACT object to be added
331 | // * Experimental use only
332 | // */
333 | // private void ACT2ReferenceConverter(Mp7ACT act) throws NoSuchAlgorithmException, IOException, URISyntaxException
334 | // {
335 | // String label = act.getLabel();
336 | // File mp3File = new File(label);
337 | // byte[] md5bytes = Toolset.createMD5Hash(mp3File);
338 | // String md5 = Toolset.toHexString(md5bytes);
339 | // ArrayList keywords = Toolset.ExtractKeywords(mp3File);
340 | // ArrayList metaphones = Toolset.GenerateMetaphones(keywords);
341 | // URI musicUri = new URI ("file", label, null);
342 | //
343 | // MusicURIReference newref = new MusicURIReference(act, md5, keywords, metaphones, musicUri, label);
344 | // addMusicURIReference(newref);
345 | // }
346 |
347 |
348 |
349 | }
350 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/LambdaCalculator.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.utils.experimental;
23 |
24 |
25 | import it.univpm.deit.database.datatypes.AudioLLDmeta;
26 | import it.univpm.deit.database.datatypes.Mp7ACT;
27 | import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
28 | import it.univpm.deit.semedia.musicuri.core.MusicURIQuery;
29 | import it.univpm.deit.semedia.musicuri.core.MusicURIReference;
30 | import it.univpm.deit.semedia.musicuri.core.Toolset;
31 | import it.univpm.deit.semedia.musicuri.statistics.PerformanceStatistic;
32 |
33 | import java.io.File;
34 | import java.util.ArrayList;
35 | import java.util.Iterator;
36 | import java.util.Set;
37 |
38 |
39 | import org.apache.commons.math.stat.descriptive.SummaryStatistics;
40 |
41 |
42 | import com.wcohen.secondstring.JaroWinkler;
43 | import com.wcohen.secondstring.StringWrapper;
44 |
45 | /**
46 | * Utility class used for calculating the optimal lambda for a linear combination of heterogeneous distance metrics
47 | */
48 | public class LambdaCalculator
49 | {
50 | static String databasePath = "D:/1000ReferenceDB/";
51 | static String databaseFileName = "MusicURIReferences.db";
52 | static MusicURIDatabase db = new MusicURIDatabase(databasePath, databaseFileName);
53 |
54 | public static void main(String[] args) throws Exception
55 | {
56 |
57 | //*****************************************************************************
58 | //************************* F I L E I N P U T ***************************
59 | //*****************************************************************************
60 |
61 | if ((args.length == 1) && (new File (args[0]).exists()))
62 | {
63 | // get the file's canonical path
64 | File givenHandle = new File(args[0]);
65 | String queryAudioCanonicalPath = givenHandle.getCanonicalPath();
66 | System.out.println("Input: " + queryAudioCanonicalPath);
67 |
68 | //PerformanceStatistic tempStat;
69 | SummaryStatistics lambdaSummary = SummaryStatistics.newInstance();
70 |
71 | if (givenHandle.isDirectory())
72 | {
73 |
74 | File[] list = givenHandle.listFiles();
75 | if (list.length == 0)
76 | {
77 | System.out.println("Directory is empty");
78 | return;
79 | }
80 | else
81 | {
82 | ArrayList allStats = new ArrayList();
83 | File currentFile;
84 | for (int i = 0; i < list.length; i++)
85 | {
86 | currentFile = list[i];
87 | try
88 | {
89 | if (Toolset.isSupportedAudioFile(currentFile))
90 | {
91 | System.out.println("\nCalculating optimal lambda : " + currentFile.getName());
92 | lambdaSummary.addValue(getBestLambda (new MusicURIQuery(currentFile)));
93 | }
94 | }
95 | catch (Exception e)
96 | {
97 | e.printStackTrace();
98 | }
99 | }
100 | // System.out.println("\n\nStatistics for Test Case: " + queryAudioCanonicalPath);
101 | // mergeStatistics(allStats);
102 | }
103 | }
104 | if (givenHandle.isFile())
105 | {
106 | if (Toolset.isSupportedAudioFile(givenHandle))
107 | {
108 | // tempStat = getBestLambda (new MusicURIQuery(givenHandle));
109 | // if (tempStat!=null)
110 | // {
111 | // //tempStat.printStatistics();
112 | // ArrayList allStats = new ArrayList();
113 | // allStats.add(tempStat);
114 | // mergeStatistics(allStats);
115 | // }
116 | // else
117 | // System.out.println("Error in identification ");
118 | }
119 | }
120 |
121 | }//end if
122 | else
123 | {
124 | System.err.println("LambdaCalculator");
125 | System.err.println("Usage: java tester.LambdaCalculator {directory}");
126 | }
127 |
128 | }//end main method
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | public static double getBestLambda (MusicURIQuery query)
143 | {
144 |
145 | //*****************************************************************************
146 | //************ Q U E R Y D A T A P R E P A R A T I O N ****************
147 | //*****************************************************************************
148 |
149 | // get the act object encapsulated in the MusicURIQuery object
150 | Mp7ACT queryMp7 = query.getAudioCompactType();
151 | // if its null then there is some problem
152 | if (queryMp7 == null)
153 | System.out.println("Problem: queryMp7 is null");
154 | // read the required data from the AudioCompactType
155 | AudioLLDmeta queryMean = queryMp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.MEAN);
156 | AudioLLDmeta queryVariance = queryMp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.VARIANCE);
157 | // are audioSignatureType data included in the act file?
158 | if (queryMean == null || queryVariance == null )
159 | {
160 | System.out.println("Problem: AudioSignatureType is not included in ACT or cannot be extracted from audio file. Aborting.");
161 | }
162 | int vectorSize = queryMean.vectorSize; // internal! stay out! read the matrix size instead
163 | float[][] queryMeanMatrix = queryMean.__rawVectors;
164 | float[][] queryVarianceMatrix = queryVariance.__rawVectors;
165 | int QueryVectorDim = vectorSize; // ==number of dimensions, subbands
166 | String queryLabelling = query.getLabel();
167 | int queryIdentifier = Toolset.getTestCaseIdentifier(queryLabelling);
168 | StringWrapper queryWrapper = null;
169 | JaroWinkler test = new JaroWinkler();
170 | queryLabelling = Toolset.removeTestCaseIdentifier(queryLabelling);
171 | queryWrapper = test.prepare(queryLabelling);
172 |
173 | //*****************************************************************************
174 | //********* R E F E R E N C E D A T A P R E P A R A T I O N ***********
175 | //*****************************************************************************
176 |
177 | int RefVectorDim = 0; // number of subbands, dimensions
178 | double combinedDistance;
179 | double currentLabelDistance = 0.0;
180 | double currentSignatureDistance = 0.0;
181 | double normalizedSignatureDistance = 0.0;
182 | double confidence = 0.0;
183 | Mp7ACT mp7;
184 | String currentMD5;
185 | MusicURIReference currentReference;
186 | AudioLLDmeta refMean;
187 | AudioLLDmeta refVariance;
188 | float[][] refMeanMatrix;
189 | float[][] refVarianceMatrix;
190 |
191 | StringWrapper refWrapper = null;
192 | float editDistance;
193 | int referenceIdentifier;
194 | String referenceLabelling;
195 |
196 | double lambdaYeldingSmallestCombinedDistance = 0.0;
197 | double smallestCombinedDistanceYet = 0.0;
198 |
199 | Set allMusicURIReferenceKeys = db.getSetOfMusicURIReferences();
200 |
201 | //System.out.println("queryId: " + queryIdentifier);
202 |
203 | for (Iterator iter = allMusicURIReferenceKeys.iterator(); iter.hasNext();)
204 | {
205 | currentMD5 = (String) iter.next();
206 | currentReference = db.getMusicURIReference(currentMD5);
207 | referenceLabelling = currentReference.getLabel();
208 | referenceIdentifier = Toolset.getTestCaseIdentifier(referenceLabelling);
209 |
210 | if (referenceIdentifier == queryIdentifier)
211 | {
212 | mp7 = currentReference.getAudioCompactType();
213 | if (mp7 == null)
214 | {
215 | System.out.println("Problem: No mpeg7 exists for given uri");
216 | }
217 | refMean = mp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.MEAN);
218 | refVariance = mp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.VARIANCE);
219 | if ((refMean == null) || (refVariance == null))
220 | {
221 | System.out.println("Skipping: problematic mpeg7 description!!! - "+mp7.getLabel()+")");
222 | }
223 | refMeanMatrix = refMean.__rawVectors;
224 | refVarianceMatrix = refVariance.__rawVectors;
225 | RefVectorDim = vectorSize; // number of subbands
226 |
227 | currentSignatureDistance = Toolset.getEuclidianDistance(refMeanMatrix, refVarianceMatrix, queryMeanMatrix, queryVarianceMatrix, QueryVectorDim, false);
228 | double theoreticalMaximum = (RefVectorDim * Math.sqrt(1)) * queryMeanMatrix.length;
229 | normalizedSignatureDistance = currentSignatureDistance / theoreticalMaximum; //eg (16 * sqrootof(1) ) * 10 --to scale at 0-1
230 |
231 | String refname = currentReference.getLabel();
232 | refname = Toolset.removeTestCaseIdentifier(refname);
233 | refWrapper = test.prepare(refname);
234 | editDistance = 1 - (float) test.score(queryWrapper, refWrapper);
235 | currentLabelDistance = editDistance;
236 |
237 | System.out.println("currentLabelDistance: " + currentLabelDistance);
238 | System.out.println("normalizedSignatureDistance: " + normalizedSignatureDistance);
239 |
240 | //combinedDistance = (0.5 * currentLabelDistance) + (0.5 * normalizedSignatureDistance);
241 | //smallestCombinedDistanceYet = (0.5 * currentLabelDistance) + (0.5 * normalizedSignatureDistance);
242 | for (double lambda = 0.0; lambda < 1.0; lambda += 0.01)
243 | {
244 | combinedDistance = lambda * currentLabelDistance + (1-lambda) * normalizedSignatureDistance;
245 | if (combinedDistance < smallestCombinedDistanceYet)
246 | {
247 | smallestCombinedDistanceYet = combinedDistance;
248 | lambdaYeldingSmallestCombinedDistance = lambda;
249 | }
250 | }
251 | System.out.println("smallestCombinedDistanceYet: " + smallestCombinedDistanceYet);
252 | System.out.println("Best lambda: " + lambdaYeldingSmallestCombinedDistance);
253 | confidence = 100 - (100 * smallestCombinedDistanceYet);
254 | System.out.println("Best confidence: " + confidence);
255 | }
256 | }
257 | return lambdaYeldingSmallestCombinedDistance;
258 | }
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 | public static void mergeStatistics(ArrayList allStats)
270 | {
271 | PerformanceStatistic tempStat;
272 |
273 | int truePositives = 0;
274 | int falsePositives = 0;
275 | int trueNegatives = 0;
276 | int falseNegatives = 0;
277 |
278 | SummaryStatistics TPBestMatchSummary = SummaryStatistics.newInstance();
279 | SummaryStatistics TPSecondBestSummary = SummaryStatistics.newInstance();
280 |
281 | SummaryStatistics FPBestMatchSummary = SummaryStatistics.newInstance();
282 |
283 | SummaryStatistics BothTP_FPBestMatchSummary = SummaryStatistics.newInstance();
284 |
285 | SummaryStatistics TNSummary = SummaryStatistics.newInstance();
286 | SummaryStatistics FNSummary = SummaryStatistics.newInstance();
287 |
288 | SummaryStatistics pruningSpeedSummary = SummaryStatistics.newInstance();
289 | SummaryStatistics matchingSpeedSummary = SummaryStatistics.newInstance();
290 | SummaryStatistics totalSpeedSummary = SummaryStatistics.newInstance();
291 |
292 |
293 | for (int i = 0; i < allStats.size(); i++)
294 | {
295 | tempStat = (PerformanceStatistic) allStats.get(i);
296 |
297 | if (tempStat.isTruePositive()) truePositives++;
298 | if (tempStat.isFalsePositive()) falsePositives++;
299 | if (tempStat.isTrueNegative()) trueNegatives++;
300 | if (tempStat.isFalseNegative()) falseNegatives++;
301 |
302 | // accurate results only
303 | //if (tempStat.isTruePositive() || tempStat.isTrueNegative())
304 |
305 | pruningSpeedSummary.addValue(tempStat.getPruningTime());
306 | matchingSpeedSummary.addValue(tempStat.getMatchingTime());
307 | totalSpeedSummary.addValue(tempStat.getPruningTime() + tempStat.getMatchingTime());
308 |
309 | if (tempStat.isTruePositive())
310 | {
311 | TPBestMatchSummary.addValue(tempStat.getBestMatchDistance());
312 | TPSecondBestSummary.addValue(tempStat.getSecondBestMatchDistance());
313 | }
314 |
315 | if (tempStat.isFalsePositive())
316 | {
317 | FPBestMatchSummary.addValue(tempStat.getBestMatchDistance());
318 | }
319 |
320 | BothTP_FPBestMatchSummary.addValue(tempStat.getBestMatchDistance());
321 |
322 | }
323 |
324 | System.out.println("---------------------------------------------------------");
325 |
326 | System.out.println("\nTrue Positives : " + truePositives + "/" + allStats.size());
327 | System.out.println("False Positives : " + falsePositives + "/" + allStats.size());
328 | System.out.println("True Negatives : " + trueNegatives + "/" + allStats.size());
329 | System.out.println("False Negatives : " + falseNegatives + "/" + allStats.size());
330 |
331 | System.out.println("\nTrue Positive Best Match Statistics");
332 | System.out.println("Distance Min : " + TPBestMatchSummary.getMin());
333 | System.out.println("Distance Max : " + TPBestMatchSummary.getMax());
334 | System.out.println("Distance Mean : " + TPBestMatchSummary.getMean());
335 | System.out.println("Distance Variance : " + TPBestMatchSummary.getVariance());
336 | System.out.println("Distance StdDev : " + TPBestMatchSummary.getStandardDeviation());
337 | System.out.println("Confidence Mean : " + (100 - (100 * (TPBestMatchSummary.getMean())))+ " %");
338 |
339 | System.out.println("\nTrue Positive Second Best Statistics");
340 | System.out.println("Distance Min : " + TPSecondBestSummary.getMin());
341 | System.out.println("Distance Max : " + TPSecondBestSummary.getMax());
342 | System.out.println("Distance Mean : " + TPSecondBestSummary.getMean());
343 | System.out.println("Confidence Mean : " + (100 - (100 * (TPSecondBestSummary.getMean())))+ " %");
344 |
345 | System.out.println("\nFalse Positive Best Match Statistics");
346 | System.out.println("Distance Min : " + FPBestMatchSummary.getMin());
347 | System.out.println("Distance Max : " + FPBestMatchSummary.getMax());
348 | System.out.println("Distance Mean : " + FPBestMatchSummary.getMean());
349 | System.out.println("Distance Variance : " + FPBestMatchSummary.getVariance());
350 | System.out.println("Distance StdDev : " + FPBestMatchSummary.getStandardDeviation());
351 | System.out.println("Confidence Mean : " + (100 - (100 * (FPBestMatchSummary.getMean()))) + " %");
352 |
353 | System.out.println("\nBest Match Statistics (Regardless being False or True Positive) ");
354 | System.out.println("Distance Min : " + BothTP_FPBestMatchSummary.getMin());
355 | System.out.println("Distance Max : " + BothTP_FPBestMatchSummary.getMax());
356 | System.out.println("Distance Mean : " + BothTP_FPBestMatchSummary.getMean());
357 | System.out.println("Distance Variance : " + BothTP_FPBestMatchSummary.getVariance());
358 | System.out.println("Distance StdDev : " + BothTP_FPBestMatchSummary.getStandardDeviation());
359 | System.out.println("Confidence Mean : " + (100 - (100 * (BothTP_FPBestMatchSummary.getMean()))) + " %");
360 |
361 | System.out.println("\n\nPruning Speed Statistics");
362 | System.out.println("Speed Min : " + (pruningSpeedSummary.getMin()/1000) + " sec" );
363 | System.out.println("Speed Max : " + (pruningSpeedSummary.getMax()/1000) + " sec" );
364 | System.out.println("Speed Mean : " + (pruningSpeedSummary.getMean()/1000) + " sec" );
365 |
366 | System.out.println("\nMatching Speed Statistics");
367 | System.out.println("Speed Min : " + (matchingSpeedSummary.getMin()/1000) + " sec" );
368 | System.out.println("Speed Max : " + (matchingSpeedSummary.getMax()/1000) + " sec" );
369 | System.out.println("Speed Mean : " + (matchingSpeedSummary.getMean()/1000) + " sec" );
370 |
371 | System.out.println("\nOverall Speed Statistics");
372 | System.out.println("Speed Min : " + (totalSpeedSummary.getMin()/1000) + " sec" );
373 | System.out.println("Speed Max : " + (totalSpeedSummary.getMax()/1000) + " sec" );
374 | System.out.println("Speed Mean : " + (totalSpeedSummary.getMean()/1000) + " sec" );
375 |
376 |
377 | }
378 |
379 | }
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/experimental/FilenameScrambler.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2005, Dimitrios Kourtesis
3 |
4 | This file is part of MusicURI.
5 |
6 | MusicURI is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | MusicURI is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MPEG7AudioEnc; see the file COPYING. If not, write to
18 | the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 | MA 02111-1307 USA
20 | */
21 |
22 | package it.univpm.deit.semedia.musicuri.utils.experimental;
23 |
24 | import it.univpm.deit.semedia.musicuri.core.Toolset;
25 |
26 | import java.io.File;
27 | import java.util.ArrayList;
28 | import java.util.Random;
29 | import java.util.StringTokenizer;
30 |
31 |
32 | /**
33 | * Utility class used for scrambling the filenames of audio files in order to generate new test cases.
34 | * The srambling is done either using sentences generated by context-free grammars, or by inserting
35 | * random words and random character flips. This code was initially used to test the robustness
36 | * of various approximate string matching algorithms.
37 | */
38 | public class FilenameScrambler
39 | {
40 | // list of words to ignore
41 | private static ArrayList ignored = new ArrayList();
42 |
43 | // 100 non-existing band names, created using a context free grammar
44 | // taken from http://www.elsewhere.org/cgi-bin/bandname
45 | private static String[] ContextFreeGrammarBandNames =
46 | { "Order Of The Old Time Tree", "The Universal Ladies", "Four Creeks With Colors",
47 | "The Salamander Gambit", "Bob Stardust and the Telluride Buckaroos", "Still Clown",
48 | "Hammerbreeder", "The Venomous Badgers", "Donna Piro and the Jerusalem Police",
49 | "Stack of Creeks", "Large Dog", "The Famous Box Society", "Bob Lovlace and the Smokable Whiskey Session",
50 | "A Taste of Lakes", "Badgerbeagle", "Box of Wookiees", "Five Chains and Omega",
51 | "Six Good Ducks", "Frogbreeder", "The Moon Company", "The Metaphysical Alpha Session",
52 | "Donna Claypool and the Detroit Anteaters", "A Taste of Puppies", "A Sack of Guys",
53 | "The Ravenous Devil Headquarters", "The Venomous Flower Scheme", "Four Fellows and a Mouse",
54 | "Grace Badabing and the Venomous Motor Symphony", "Pink Color", "A Tower of Creeks",
55 | "Kamikaze Cholera", "Adam Banzai and the Screaming Carpenters", "Handful of Sounds",
56 | "Bumblebeewater", "Peter Tarantino and the Montgomery Daleks", "House of Fears",
57 | "Purityduck", "Box of Wookiees", "Screaming Bishop", "Four Ladies and a Thumb",
58 | "Crystal Cow", "The Flying Grrrl Trio", "Three Rasta Horses", "Peter Stallone and the Cleveland Crickets",
59 | "Buddy Johnson and the Still Oddities", "A Handful of Colors", "The Honey Group",
60 | "The Confederate River Symphony", "Bag of Ducks", "Leather Cat", "The Flying Temple Combo",
61 | "Metaphysical Milk", "The Amazing Delta Brotherhood", "Buckaroo Lovlace and the Large Juggler Gambit",
62 | "Box of Goats", "Four Womyn and a Axe", "Old Time Fear", "A Handful of Mice", "Puppyfennel",
63 | "Britney Summers and the Messiest Patrol", "Grace Stallone and the San Francisco All Stars",
64 | "Wall of Heads", "The Thick Star Factor", "Temple of Badgers", "Templebumblebee", "The Ganja Quintet",
65 | "Britney LaZonga and the Kamikaze Boingers", "Hamsterpurity", "A Stack of Oysters",
66 | "Buck Cooper and the Rasta Oddities", "Modern Hog", "A Tower of Anvils",
67 | "Buck and the Stellar Replicants", "The Garden Brotherhood", "Mothergun", "Starving Duck",
68 | "The Live Delta Incident", "Two Womyn and a Synth", "Taste of Horses", "A House of Hogs",
69 | "Linda Cornell and the Blindfolded Angels", "Les Claypool and the Heavenly All Stars",
70 | "Sylvester and the Stellar Leisurelies", "Six Clowns and a Woman", "The Liquid Gamma Company",
71 | "Temple of Ladies", "The Snout Conspiracy", "A Fistful of Beagles", "A Fistful of Fish",
72 | "Five Candles With Guns", "The Swollen Beagles", "Grace Turgidson and the Kamikaze Fulcrum Symphony",
73 | "Fabulous War", "The Live Ladies", "Two Venomous Sheep", "The Red Beagle Shrine", "A Temple of Heads",
74 | "The Abundant Badger Sound", "The Anvil Policy", "Quentin Phillips and the Seattle Plumbers" };
75 |
76 | // 123 words extracted from George Orwell's "1984"
77 | // taken from http://www.vocabulary.com/VUctnineteen.html
78 | private static String[] GeorgeOrwell1984 =
79 | {
80 | "depict", "simultaneously", "predicament", "interminable", "unorthodox", "renegade", "polysyllabic",
81 | "refute", "flog", "inscrutable", "discountenanced", "gamboling", "saboteur", "raspingly",
82 | "reverberate", "reproach", "fathom", "disdain", "annihilate", "repudiate", "shrewish", "orifice",
83 | "collate", "multifarious", "kaleidoscope", "denounce", "implicate", "hoard", "remorselessly",
84 | "venerate", "heretic", "catapult", "irrepressible", "proliferate", "debauchery", "promiscuity",
85 | "aquiline", "jostle", "flog", "listless", "incriminate", "posterity", "stratum", "balminess",
86 | "sordid", "altercation", "meditatively", "innumerable", "cumbersome", "officiousness", "unprocurable",
87 | "niggling", "hallucination", "malignant", "guise", "dapple", "swine", "strenuousness", "demeanor",
88 | "stagnant", "commodity", "chastity", "inconceivable", "eccentricity", "unendurable", "effigies",
89 | "rowdy", "indignation", "perish", "mutability", "invariably", "queue", "intermittent", "luminous",
90 | "scrounge", "pathos", "remonstrance", "proles", "intimidate", "wainscoting", "salutation", "allusion",
91 | "fretted", "voluptuous", "reprisal", "fecundity", "dilapidated", "ravage", "austere", "spurious",
92 | "preponderance", "tacitly", "ruminant", "plunder", "irrevocable", "irreconcilable", "recurrence",
93 | "hierarchy", "infallible", "oligarchical", "scrutinize", "dissipate", "repression", "supple",
94 | "reverence", "gnawing", "peddler", "timorously", "irony", "sabotage", "truncheon", "embezzlement",
95 | "inquisitor", "despicable", "bludgeon", "forlorn", "degradation", "taut", "improvisation",
96 | "interpose", "haggling", "digression", "tiddlywinks"
97 | };
98 |
99 |
100 | public static void main(String[] args) throws Exception
101 | {
102 |
103 | //*****************************************************************************
104 | //************************* F I L E I N P U T ***************************
105 | //*****************************************************************************
106 |
107 | if ((args.length == 1) && (new File (args[0]).exists()))
108 | {
109 | // get the file's canonical path
110 | File givenHandle = new File(args[0]);
111 | String queryAudioCanonicalPath = givenHandle.getCanonicalPath();
112 | System.out.println("Input: " + queryAudioCanonicalPath);
113 |
114 |
115 | if (givenHandle.isDirectory())
116 | {
117 | File[] list = givenHandle.listFiles();
118 | if (list.length == 0)
119 | {
120 | System.out.println("Directory is empty");
121 | return;
122 | }
123 | else
124 | {
125 | File currentFile;
126 | for (int i = 0; i < list.length; i++)
127 | {
128 | currentFile = list[i];
129 | if (Toolset.isSupportedAudioFile(currentFile))
130 | {
131 | String oldFilename = currentFile.getName();
132 | String newFilename = generateSubstitute(oldFilename);
133 | //String newFilename = generateBogusBandNameSubstitute(oldFilename, i);
134 | System.out.println("From : " + oldFilename);
135 | System.out.println("To : " + newFilename);
136 | String parent = currentFile.getParent();
137 | doRename(parent+"\\"+oldFilename, parent+"\\"+newFilename);
138 | }
139 |
140 | }
141 | }
142 | }
143 |
144 | if (givenHandle.isFile())
145 | {
146 | if (Toolset.isSupportedAudioFile(givenHandle))
147 | {
148 | String oldFilename = givenHandle.getName();
149 | String newFilename = generateSubstitute(oldFilename);
150 | //String newFilename = generateBogusBandNameSubstitute(oldFilename, 0);
151 | System.out.println("From : " + oldFilename);
152 | System.out.println("To : " + newFilename);
153 | String parent = givenHandle.getParent();
154 | doRename(parent+"\\"+oldFilename, parent+"\\"+newFilename);
155 | }
156 | }
157 |
158 | }//end if
159 |
160 |
161 | else
162 | {
163 | System.err.println("FilenameScrambler");
164 | System.err.println("Usage: java tester.FilenameScrambler {original.mp3}");
165 | }
166 |
167 | }//end main method
168 |
169 |
170 | public static String generateBogusBandNameSubstitute(String oldFilename, int index)
171 | {
172 | String band = ContextFreeGrammarBandNames[index];
173 | String newFilename = "";
174 |
175 | StringTokenizer chop = new StringTokenizer(oldFilename,"-");
176 | //System.out.println("num of tokens : " + chop.countTokens());
177 |
178 | int testCaseId = Toolset.getTestCaseIdentifier(oldFilename);
179 | String idPrePadding = "";
180 | if (testCaseId >= 1 )
181 | {
182 | if (testCaseId <10 )idPrePadding = "000";
183 | if (testCaseId >=10 && testCaseId < 100 )idPrePadding = "00";
184 | if (testCaseId >=100 && testCaseId < 1000 )idPrePadding = "0";
185 | }
186 |
187 | int i = 0;
188 | String token;
189 | int numOfToks = chop.countTokens();
190 | while (chop.hasMoreTokens())
191 | {
192 | token = chop.nextToken();
193 | //System.out.println(i + " token : " + token);
194 | if ( i == numOfToks-1 )
195 | {
196 | //System.out.println(i + "/ newFilename: " + newFilename);
197 | newFilename = newFilename.concat(idPrePadding + testCaseId + " " + band + " -" + token);
198 | //System.out.println(i + "/ newFilename: " + newFilename);
199 | }
200 | i++;
201 | }
202 |
203 |
204 | return newFilename;
205 | }
206 |
207 |
208 | public static void doRename (String oldname, String newname)
209 | {
210 | File file = new File(oldname);
211 | File file2 = new File(newname);
212 |
213 | // Rename file (or directory)
214 | boolean success = file.renameTo(file2);
215 | if (!success)
216 | {
217 | if (!file.exists()) System.out.println("File does not exist");
218 | if (!file.canWrite()) System.out.println("No write access");
219 | System.out.println("File could not be renamed");
220 | }
221 | }
222 |
223 |
224 | public static String generateSubstitute(String oldFilename)
225 | {
226 | // The 50 most common words in the english language
227 | // http://esl.about.com/library/vocabulary/bl1000_list1.htm
228 | // http://www.world-english.org/english500.htm
229 | // http://www.duboislc.org/EducationWatch/First100Words.html
230 |
231 | ignored.add("the"); ignored.add("of"); ignored.add("and");
232 | ignored.add("a"); ignored.add("to"); ignored.add("in");
233 | ignored.add("is"); ignored.add("you"); ignored.add("that");
234 | ignored.add("it"); ignored.add("he"); ignored.add("was");
235 | ignored.add("for"); ignored.add("on"); ignored.add("are");
236 | ignored.add("as"); ignored.add("with"); ignored.add("his");
237 | ignored.add("they"); ignored.add("i"); ignored.add("at");
238 | ignored.add("be"); ignored.add("this"); ignored.add("have");
239 | ignored.add("from"); ignored.add("or"); ignored.add("one");
240 | ignored.add("had"); ignored.add("by"); ignored.add("word");
241 | ignored.add("but"); ignored.add("not"); ignored.add("what");
242 | ignored.add("all"); ignored.add("were"); ignored.add("we");
243 | ignored.add("when"); ignored.add("your"); ignored.add("can");
244 | ignored.add("said"); ignored.add("there"); ignored.add("use");
245 | ignored.add("an"); ignored.add("each"); ignored.add("which");
246 | ignored.add("she"); ignored.add("do"); ignored.add("how");
247 | ignored.add("their"); ignored.add("if");
248 |
249 | // Some frequently occuring words related to music filenames
250 | ignored.add("mp3"); ignored.add("&"); ignored.add("featuring");
251 | ignored.add("+"); ignored.add("feat"); ignored.add("presenting");
252 | ignored.add("pres"); ignored.add("live"); ignored.add("track");
253 | ignored.add("album"); ignored.add("various"); ignored.add("artists");
254 | ignored.add("artist"); ignored.add("va"); ignored.add("collection");
255 | ignored.add("sampler"); ignored.add("mix"); ignored.add("complilation");
256 | ignored.add("mixed"); ignored.add("remix"); ignored.add("remixed");
257 | ignored.add("lp"); ignored.add("ep"); ignored.add("cd");
258 | ignored.add("");
259 |
260 | String identifier = "";
261 | int testCaseId = Toolset.getTestCaseIdentifier(oldFilename);
262 | if (testCaseId >= 1 )
263 | {
264 | if (testCaseId >=0 && testCaseId <10 )identifier = "000" + testCaseId + " ";
265 | if (testCaseId >=10 && testCaseId < 100 )identifier = "00" + testCaseId + " ";
266 | if (testCaseId >=100 && testCaseId < 1000 )identifier = "0" + testCaseId + " ";
267 | }
268 | String oldFilenameWithoutIdentifier = Toolset.removeTestCaseIdentifier(oldFilename);
269 | String extension = oldFilenameWithoutIdentifier.substring(oldFilenameWithoutIdentifier.lastIndexOf('.') + 1);
270 | String noId_noExtension = oldFilenameWithoutIdentifier.substring(0, oldFilenameWithoutIdentifier.lastIndexOf('.'));
271 | oldFilenameWithoutIdentifier.replaceAll(".mp3","");
272 | String scrambledTokenFilename = "";
273 | String whitespaceFreeFilename = "";
274 | String finalFilename = "";
275 |
276 | StringTokenizer tok = new StringTokenizer(noId_noExtension," `~!@#$%^&*()_-+={}[]|\\:;\"'<>,.?/\t\n\r");
277 |
278 | int numOfTokensInString = tok.countTokens();
279 | String[] tokens = new String[numOfTokensInString]; // list of tokens to return
280 | int i = 0;
281 |
282 | while (tok.hasMoreTokens())
283 | {
284 | String token = tok.nextToken();
285 | tokens[i] = token;
286 | i++;
287 | }
288 |
289 | boolean okToScramble = false;
290 | String selectedToken = "";
291 | int randomInteger = 0;
292 | Random rand = null;
293 |
294 | while (!okToScramble)
295 | {
296 | rand = new Random();
297 | // Random integer from from 0 to numOfTokensInString
298 | randomInteger = rand.nextInt(numOfTokensInString);
299 | selectedToken = tokens[randomInteger];
300 | if (!ignored.contains(selectedToken) //not a common english word
301 | && !isInteger(selectedToken) //not an integer
302 | //&& selectedToken.length() > 2
303 | ) //not a small word
304 | okToScramble = true;
305 | }
306 | okToScramble = false;
307 | int excludedAlreadyScrambledTokenNumber = randomInteger; //exclude this token from further mangling
308 | String scrambledToken = insertRandomAsciiFlip (selectedToken, 2);
309 | scrambledTokenFilename = noId_noExtension.replaceFirst(selectedToken, scrambledToken);
310 |
311 | while (!okToScramble)
312 | {
313 | rand = new Random();
314 | // Random integer from from 0 to numOfTokensInString
315 | randomInteger = rand.nextInt(numOfTokensInString);
316 | selectedToken = tokens[randomInteger];
317 | if (!ignored.contains(selectedToken) //not a common english word
318 | && !isInteger(selectedToken) //not an integer
319 | //&& selectedToken.length() > 2 //not a small word
320 | && randomInteger != excludedAlreadyScrambledTokenNumber) //not already scrambled
321 | okToScramble = true;
322 | }
323 | scrambledToken = insertRandomAsciiFlip (selectedToken, 2);
324 | scrambledTokenFilename = scrambledTokenFilename.replaceFirst(selectedToken, scrambledToken);
325 |
326 | rand = new Random();
327 | randomInteger = rand.nextInt(122); // Random integer from from 0 to 125
328 | String appendedNonSenseFilename = scrambledTokenFilename.concat("#" + randomInteger +" - " + GeorgeOrwell1984[randomInteger]);
329 |
330 | finalFilename = whitespaceFreeFilename.concat(identifier + removeSpaces(appendedNonSenseFilename) + "." + extension);
331 | return finalFilename;
332 | }
333 |
334 |
335 | // [JDK1.4] http://www.rgagnon.com/javadetails/java-0352.html
336 | public static String removeSpaces(String whitespacesIncluded)
337 | {
338 | StringTokenizer st = new StringTokenizer(whitespacesIncluded, " ", false);
339 | String whitespaceFree = "";
340 | while (st.hasMoreElements()) whitespaceFree += st.nextElement();
341 | return whitespaceFree;
342 | }
343 |
344 |
345 | public static String insertRandomAsciiFlip (String original, int numberOfFlips)
346 | {
347 | //System.out.println("Modified token : " + original);
348 | Random rand = new Random();
349 | Random rand2 = new Random();
350 | int randomInteger;
351 | int randomInteger2;
352 | char[] scrambledCharArray = original.toCharArray();
353 |
354 | for (int i = 0; i < numberOfFlips; i++)
355 | {
356 | randomInteger = rand.nextInt(original.length()); //random position
357 | randomInteger2 = 65 + rand2.nextInt(25); //result will be an integer ranging 65-90 (capital ascii characters)
358 | scrambledCharArray[randomInteger] = (char)randomInteger2;
359 | }
360 |
361 | String ret = new String(scrambledCharArray);
362 | return ret;
363 | }
364 |
365 |
366 | public static String replace(String str, String oldToken, String newToken)
367 | {
368 | //System.out.println("str: " + str);
369 | int s = 0;
370 | int e = 0;
371 | StringBuffer result = new StringBuffer();
372 |
373 | while ((e = str.indexOf(oldToken, s)) >= 0)
374 | {
375 | result.append(str.substring(s, e));
376 | result.append(newToken);
377 | s = e + oldToken.length();
378 | }
379 | result.append(str.substring(s));
380 |
381 | String tmp = result.toString();
382 | //System.out.println("str: " + tmp);
383 | return tmp;
384 | }
385 |
386 |
387 | public static boolean isInteger(String token)
388 | {
389 | try
390 | {
391 | Integer.parseInt(token);
392 | return true;
393 | }
394 | catch (NumberFormatException e)
395 | {
396 | // it wasn't
397 | return false;
398 | }
399 | }
400 |
401 | }
402 |
--------------------------------------------------------------------------------
/src/COPYING.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Library General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License
307 | along with this program; if not, write to the Free Software
308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
309 |
310 |
311 | Also add information on how to contact you by electronic and paper mail.
312 |
313 | If the program is interactive, make it output a short notice like this
314 | when it starts in an interactive mode:
315 |
316 | Gnomovision version 69, Copyright (C) year name of author
317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318 | This is free software, and you are welcome to redistribute it
319 | under certain conditions; type `show c' for details.
320 |
321 | The hypothetical commands `show w' and `show c' should show the appropriate
322 | parts of the General Public License. Of course, the commands you use may
323 | be called something other than `show w' and `show c'; they could even be
324 | mouse-clicks or menu items--whatever suits your program.
325 |
326 | You should also get your employer (if you work as a programmer) or your
327 | school, if any, to sign a "copyright disclaimer" for the program, if
328 | necessary. Here is a sample; alter the names:
329 |
330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
332 |
333 | , 1 April 1989
334 | Ty Coon, President of Vice
335 |
336 | This General Public License does not permit incorporating your program into
337 | proprietary programs. If your program is a subroutine library, you may
338 | consider it more useful to permit linking proprietary applications with the
339 | library. If this is what you want to do, use the GNU Library General
340 | Public License instead of this License.
341 |
--------------------------------------------------------------------------------
/src/it/univpm/deit/semedia/musicuri/utils/misc/MusicURILibraryDemo.java:
--------------------------------------------------------------------------------
1 | package it.univpm.deit.semedia.musicuri.utils.misc;
2 |
3 | import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
4 | import it.univpm.deit.semedia.musicuri.core.MusicURIQuery;
5 | import it.univpm.deit.semedia.musicuri.core.MusicURIReference;
6 | import it.univpm.deit.semedia.musicuri.core.MusicURISearch;
7 | import it.univpm.deit.semedia.musicuri.core.Result;
8 | import it.univpm.deit.semedia.musicuri.core.ResultRankingList;
9 | import it.univpm.deit.semedia.musicuri.core.Toolset;
10 | import it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchServiceLocator;
11 | import it.univpm.deit.semedia.musicuri.webservice.client.MusicURIWebSearchSoapBindingStub;
12 |
13 | import java.io.File;
14 | import java.net.URL;
15 | import java.net.HttpURLConnection;
16 | import java.net.MalformedURLException;
17 |
18 | import jargs.gnu.CmdLineParser;
19 |
20 | /**
21 | * @author Dimitrios Kourtesis
22 | */
23 | public class MusicURILibraryDemo
24 | {
25 |
26 |
27 | /**
28 | *
29 | * This application intends to practically demonstrate the basic
30 | * funcionality that MusicURI offers, which is to enable the mapping between
31 | * a piece of music and a unique URI.
32 | *
33 | * The demo application currently offers the following operations:
34 | *
35 | * a) Query a MusicURI local database with a music item, and retrieve a URI
36 | * b) Add a reference music item to a local MusicURI database
37 | * c) List all reference music items inside a local MusicURI database
38 | *
39 | * The main method in this class enables a user to:
40 | *
41 | * a) Query the local MusicURI database file at the specified path, with the
42 | * given audio file, to retrieve a URI. The -q switch is accompanied by the
43 | * path to the local database, and the -f flag (optional) signals if the
44 | * filename should be utilized as a reliable hint within search. Format:
45 | * java -jar MusicURI.jar [] [<-q> ] [<-f>] example:
46 | * "c:\test.wav" -q "C:\WINDOWS\system32\MusicURIReferences.db" -f
47 | *
48 | * b) Add, to the local MusicURI database file at the specified path, the
49 | * given audio file. The -a switch is accompanied by the path to the local
50 | * database, into which the music item will be indexed. Format: java -jar
51 | * MusicURI.jar [] [<-a> ] example: "c:\test.wav" -a
52 | * "C:\WINDOWS\system32\MusicURIReferences.db"
53 | *
54 | * c) List the URIs of all music items indexed in the local MusicURI
55 | * database file, at the specified path. Format: java -jar MusicURI.jar [<-l>
56 | * ] Example: -l "C:\WINDOWS\system32\MusicURIReferences.db"
57 | *
58 | * Before proceeding with any of the aforementioned operations, the
59 | * application verifies that any files that have been specified exist, and
60 | * are valid.
61 | *
62 | * For query operations, the user has to specify Where, What and How to
63 | * identify. I.e. the user must specify the URL where the MusicURI data
64 | * source resides, the audio file containing the unknown piece of music, and
65 | * whether the system should utilize the provided filename as a reliable
66 | * hint within the search, or not (default is false).
67 | *
68 | * The filename should be taken into consideration only if the user is
69 | * absolutely confident that it does not contain any misleading information
70 | * about the artist and title of the respective piece of music. For example,
71 | * this option could be safely used for a filename of the form
72 | * .
73 | *
74 | * Where: The URL specifying the location of the MusicURI data source
75 | * What : The audio file containing the piece of music to use as a query
76 | * How : A flag determining whether to utilize the filename in search
77 | */
78 |
79 |
80 | static MusicURIWebSearchSoapBindingStub stub;
81 |
82 | public static void main(String[] args)
83 | {
84 | if (args.length == 0)
85 | printUsage();
86 | else
87 | {
88 | /****************** ARGUMENT SETTING **************/
89 | // A command line parser to handle all options and arguments.
90 | CmdLineParser parser = new CmdLineParser();
91 |
92 | // The -f option is a flag determining whether to use or not use the filename
93 | // within the search. No value follows, the flag is either present, or not.
94 | CmdLineParser.Option usefilename = parser.addBooleanOption('f', "usefilename");
95 |
96 | // The -q option is followed by a String value specifying the path
97 | // of the database file to be queried.
98 | CmdLineParser.Option queryOption = parser.addStringOption('q', "query");
99 |
100 | // The -a switch is followed by a String value specifying the path to the
101 | // local database, into which a given audio file will be indexed.
102 | CmdLineParser.Option addReferenceOption = parser.addStringOption('a', "addReference");
103 |
104 | // The -l switch is followed by a String value specifying the path to the
105 | // local database, the contents of which will be listed.
106 | CmdLineParser.Option listReferencesOption = parser.addStringOption('l', "listReferences");
107 |
108 |
109 |
110 | /****************** ARGUMENT PARSING **************/
111 |
112 | // Parse the user-provided command line arguments, and catch any errors
113 | try
114 | {
115 | parser.parse(args);
116 | }
117 | catch (CmdLineParser.OptionException e)
118 | {
119 | System.err.println(e.getMessage());
120 | printUsage();
121 | System.exit(1);
122 | }
123 |
124 |
125 |
126 | // The location of the MusicURI data source defaults to the loopback address.
127 | //String queryValue = (String) parser.getOptionValue(queryWS, "http://localhost:8080/axis/MusicURIWebSearch.jws?wsdl");
128 |
129 | String queryValue = (String) parser.getOptionValue(queryOption);
130 | String addReferenceValue = (String) parser.getOptionValue(addReferenceOption);
131 | String listReferencesValue = (String) parser.getOptionValue(listReferencesOption);
132 |
133 |
134 |
135 |
136 | /****************** PERFORM OPERATION **************/
137 | String audiofileValue = null;
138 |
139 | // At any time only one option value should be selected, and therefore be non-null,
140 | // while the rest must be null. If any two option values are found to be non-null,
141 | // at the same time, print usage and abort.
142 | if ( ((queryValue != null) && (addReferenceValue != null)) ||
143 | ((queryValue != null) && (listReferencesValue != null)) ||
144 | ((addReferenceValue != null) && (listReferencesValue != null)) )
145 | {
146 | printUsage();
147 | System.exit(1);
148 | }
149 | else
150 | {
151 | /****************** QUERY OPERATION **************/
152 | // The requested operation was a query to a Web Service or local database file
153 | if (queryValue != null)
154 | {
155 | // The flag determining whether to use the filename within search, defaults to false.
156 | Boolean usefilenameValue = (Boolean) parser.getOptionValue(usefilename, Boolean.FALSE);
157 |
158 | // There should remain only one free argument (not preceeded by a switch);
159 | // the one specifying the filename of the audio file.
160 | if (parser.getRemainingArgs().length == 1)
161 | {
162 | audiofileValue = parser.getRemainingArgs()[0];
163 | }
164 | if (!isValidAudioFile(audiofileValue))
165 | {
166 | printUsage();
167 | System.exit(1);
168 | }
169 |
170 | boolean done = false;
171 | String musicURIDataSource = queryValue;
172 |
173 | // if the given MusicURI data source is a valid web service URL, query it.
174 | if (isValidWebServiceURL(musicURIDataSource))
175 | {
176 | // Set the done flag, to signal that the MusicURI data source
177 | // has been identified as a Web Service
178 | done = true;
179 | try
180 | {
181 | queryWS(new URL(musicURIDataSource), new File(audiofileValue), usefilenameValue);
182 | }
183 | catch (MalformedURLException e)
184 | {
185 | //impossible to reach here, the URL has already been checked
186 | }
187 | }
188 |
189 | // if the given MusicURI data source is a valid local database file, query it.
190 | if (!done && isValidDatabaseFile(musicURIDataSource))
191 | {
192 | // Set the done flag, to signal that the MusicURI data source
193 | // has been identified as a local database file
194 | done = true;
195 | queryDB(new File (musicURIDataSource), new File(audiofileValue), usefilenameValue);
196 | }
197 | // if the given MusicURI data source is non of the above, abort.
198 | if (!done)
199 | {
200 | printUsage();
201 | System.exit(1);
202 | }
203 | }
204 |
205 | /****************** ADDITION OPERATION **************/
206 | // The requested operation was a MusicURI reference addition to a
207 | // Web Service or local database file
208 | if (addReferenceValue != null)
209 | {
210 | // There should remain only one free argument (not preceded by a switch);
211 | // the one specifying the filename of the audio file.
212 | if (parser.getRemainingArgs().length == 1)
213 | {
214 | audiofileValue = parser.getRemainingArgs()[0];
215 | }
216 |
217 | if (!isValidAudioFile(audiofileValue))
218 | {
219 | printUsage();
220 | System.exit(1);
221 | }
222 |
223 | boolean done = false;
224 | String musicURIDataSource = addReferenceValue;
225 |
226 | // if the given MusicURI data source is a valid web service URL, query it.
227 | if (isValidWebServiceURL(musicURIDataSource))
228 | {
229 | // Set the done flag, to signal that the MusicURI data source
230 | // has been identified as a Web Service
231 | done = true;
232 | try
233 | {
234 | addReferenceToWS(new URL(musicURIDataSource), new File(audiofileValue));
235 | }
236 | catch (MalformedURLException e)
237 | {
238 | //impossible to reach here, the URL has already been checked
239 | }
240 | }
241 |
242 |
243 | // if the given MusicURI data source is a valid local database file, query it.
244 | if (!done && isValidDatabaseFile(musicURIDataSource))
245 | {
246 | // Set the done flag, to signal that the MusicURI data source
247 | // has been identified as a local database file
248 | done = true;
249 | addReferenceToDB(new File (musicURIDataSource), new File(audiofileValue));
250 | }
251 | // if the given MusicURI data source is non of the above, abort.
252 | if (!done)
253 | {
254 | printUsage();
255 | System.exit(1);
256 | }
257 | }
258 |
259 | /****************** LIST OPERATION **************/
260 | // The requested operation was a listing of all the MusicURI references
261 | // that reside on a Web Service or local database file
262 | if (listReferencesValue != null)
263 | {
264 | boolean done = false;
265 | String musicURIDataSource = listReferencesValue;
266 |
267 | // if the given MusicURI data source is a valid web service URL, query it.
268 | if (isValidWebServiceURL(musicURIDataSource))
269 | {
270 | // Set the done flag, to signal that the MusicURI data source
271 | // has been identified as a Web Service
272 | done = true;
273 | try
274 | {
275 | listWSReferences(new URL(musicURIDataSource));
276 | }
277 | catch (MalformedURLException e)
278 | {
279 | //impossible to reach here, the URL has already been checked
280 | }
281 | }
282 |
283 | // if the given MusicURI data source is a valid local database file, query it.
284 | if (!done && isValidDatabaseFile(musicURIDataSource))
285 | {
286 | // Set the done flag, to signal that the MusicURI data source
287 | // has been identified as a local database file
288 | done = true;
289 | listDBReferences(new File (musicURIDataSource));
290 | }
291 | // if the given MusicURI data source is non of the above, abort.
292 | if (!done)
293 | {
294 | printUsage();
295 | System.exit(1);
296 | }
297 | }
298 | }
299 |
300 | }
301 | }// end main method
302 |
303 | private static void printUsage()
304 | {
305 | System.out.println("USAGE: This MusicURI demo currently supports the following operations: ");
306 | System.out.println("");
307 | System.out.println("1) To query a MusicURI local database with a music item, and retrieve a URI:");
308 | System.out.println(" The -f flag signals if the filename should be considered as a hint in search.");
309 | System.out.println(" The -q switch is followed by the local database file's path");
310 | System.out.println("");
311 | System.out.println(" - java -jar MusicURI.jar [audiofile] [-f] [-q localDB]");
312 | System.out.println(" ");
313 | System.out.println("2) To add a reference music item into a local MusicURI database file ");
314 | System.out.println(" The -a switch is followed by the local database file's path]");
315 | System.out.println(" ");
316 | System.out.println(" - java -jar MusicURI.jar [audiofile] [-a localDB]");
317 | System.out.println(" ");
318 | System.out.println("3) To list all reference music items indexed inside a local MusicURI database");
319 | System.out.println(" The -l switch is followed by the local database file's path]");
320 | System.out.println(" ");
321 | System.out.println(" - java -jar MusicURI.jar [-l localDB]");
322 | }
323 |
324 |
325 |
326 |
327 |
328 | private static void queryWS(URL webServiceURL, File audioFile, Boolean usefilenameValue)
329 | {
330 | System.out.println("Starting MusicURI Demo: Query a MusicURI Web Service Data Source");
331 |
332 | String response = null;
333 | try
334 | {
335 | //the object that will be our proxy
336 | stub = new MusicURIWebSearchSoapBindingStub(webServiceURL, new MusicURIWebSearchServiceLocator());
337 |
338 | if (audioFile.exists())
339 | {
340 | System.out.println("Creating query for : " + audioFile.getName());
341 | String xmlAudioSignature = Toolset.createMPEG7Description(audioFile);
342 |
343 | String filename = audioFile.getName();
344 |
345 | System.out.println("Waiting for Web Service to return results...");
346 |
347 | // If the useFileName flag has been set to true, the filename should be provided
348 | // and used within the search. If not, don't the provide the filename at all.
349 | if (usefilenameValue.booleanValue())
350 | {
351 | response = stub.performSearch(xmlAudioSignature, filename);
352 | }
353 | else
354 | {
355 | response = stub.performSearch(xmlAudioSignature, null);
356 | }
357 | System.out.println("Web Service response: ");
358 | System.out.println(response);
359 | }
360 | }
361 | catch (Exception e)
362 | {
363 | System.err.println("An error occured while querying the Web Service");
364 | e.printStackTrace();
365 | }
366 |
367 | }
368 |
369 |
370 | private static void addReferenceToWS(URL webServiceURL, File audioFile)
371 | {
372 | System.out.println("Starting MusicURI Demo: Add a MusicURI reference to a MusicURI Web Service Data Source");
373 | System.out.println("Not implemented yet");
374 | }
375 |
376 | private static void listWSReferences(URL webServiceURL)
377 | {
378 | System.out.println("Starting MusicURI Demo: List the MusicURI references of a MusicURI Web Service Data Source");
379 |
380 |
381 |
382 |
383 | String response = null;
384 | try
385 | {
386 | //the object that will be our proxy
387 | stub = new MusicURIWebSearchSoapBindingStub(webServiceURL, new MusicURIWebSearchServiceLocator());
388 |
389 | System.out.println("Waiting for Web Service to return results...");
390 |
391 | response = stub.getMusicURIReferenceList();
392 | System.out.println("Web Service response: ");
393 | System.out.println(response);
394 | }
395 | catch (Exception ex)
396 | {
397 | ex.printStackTrace();
398 | response = "An error occured while querying the Web Service";
399 | }
400 |
401 |
402 |
403 |
404 | }
405 |
406 |
407 |
408 | private static void queryDB(File databaseFile, File audioFile, Boolean usefilenameValue)
409 | {
410 | System.out.println("Starting MusicURI Demo: Query a local MusicURI Data Source");
411 |
412 | String databasePath = databaseFile.getParent() + "\\";
413 | String databaseFileName = databaseFile.getName();
414 | MusicURIDatabase db = new MusicURIDatabase (databasePath, databaseFileName);
415 | MusicURISearch engine = new MusicURISearch (db);
416 |
417 | try
418 | {
419 | ResultRankingList finalDistanceRankingList = engine.identify(new MusicURIQuery(audioFile),
420 | usefilenameValue.booleanValue(),
421 | usefilenameValue.booleanValue(),
422 | 0.9f, //90% acceptable similarity rating
423 | usefilenameValue.booleanValue());
424 |
425 | if (finalDistanceRankingList.getSize() >= 1)
426 | {
427 | Result theBestResult = finalDistanceRankingList.getResultAtIndex(0);
428 | double bestMatchDistance = theBestResult.distance;
429 |
430 | System.out.println("Matched with : " + (db.getMusicURIReference(theBestResult.md5)).getLabel());
431 | System.out.println("Score : " + (float) (100 - (100*(theBestResult.distance))) + "%");
432 | }
433 | }
434 | catch (Exception e)
435 | {
436 | e.printStackTrace();
437 | }
438 |
439 | }
440 |
441 | private static void addReferenceToDB(File databaseFile, File audioFile)
442 | {
443 | System.out.println("Starting MusicURI Demo: Add a MusicURI reference to a local MusicURI Data Source");
444 |
445 | String databasePath = databaseFile.getParent() + "\\";
446 | String databaseFileName = databaseFile.getName();
447 | MusicURIDatabase db = new MusicURIDatabase (databasePath, databaseFileName);
448 |
449 | boolean success = false;
450 |
451 | MusicURIReference newref = null;
452 | try
453 | {
454 | newref = new MusicURIReference(audioFile);
455 | success = db.addMusicURIReference(newref);
456 | }
457 | catch (Exception e)
458 | {
459 | e.printStackTrace();
460 | }
461 |
462 | if (success)
463 | {
464 | System.out.println("The MusicURI reference was added successfully.");
465 | System.out.println("The local MusicURI Data Source now holds " + db.getDbSize() + " references.");
466 | }
467 | else
468 | System.out.println("The MusicURI reference could not be added");
469 | }
470 |
471 | private static void listDBReferences(File databaseFile)
472 | {
473 | System.out.println("Starting MusicURI Demo: List the MusicURI references of a local MusicURI Data Source");
474 |
475 | String databasePath = databaseFile.getParent() + "\\";
476 | String databaseFileName = databaseFile.getName();
477 | MusicURIDatabase db = new MusicURIDatabase (databasePath, databaseFileName);
478 |
479 | String list = db.textFormattedSetOfMusicURIReferences();
480 | System.out.println(list);
481 | }
482 |
483 |
484 |
485 |
486 |
487 | public static boolean isValidAudioFile(String audiofileValue)
488 | {
489 | if (audiofileValue != null)
490 | {
491 | // Verify that the specified file exists, and it is not a directory
492 | File audioFile = new File(audiofileValue);
493 | if (!audioFile.exists())
494 | {
495 | System.err.println("The specified file does not exist");
496 | return false;
497 | }
498 |
499 | if (!audioFile.isFile())
500 | {
501 | System.err.println("The specified file is a directory");
502 | return false;
503 | }
504 |
505 | // Verify that the specified file is of a supported type
506 | if (!Toolset.isSupportedAudioFile(audioFile))
507 | {
508 | System.err.println("The specified file is not a supported audio file");
509 | return false;
510 | }
511 | return true;
512 | }
513 | else
514 | {
515 | System.out.println("Unspecified audiofileValue");
516 | return false;
517 | }
518 | }
519 |
520 |
521 | public static boolean isValidWebServiceURL(String queryValue)
522 | {
523 | if (queryValue != null)
524 | {
525 | // Verify that the URL is well-formed and valid (both host and
526 | // resource exist)
527 | URL webServiceURL = null;
528 | try
529 | {
530 | webServiceURL = new URL(queryValue);
531 | HttpURLConnection urlConn = (HttpURLConnection) webServiceURL
532 | .openConnection();
533 | // Try to connect. If the URL is malformed throw a
534 | // MalformedURLException.
535 | urlConn.connect();
536 |
537 | // To take care of the chance of having an invalid, although
538 | // well-formed URL, check the HTTP Status Code. If it's not
539 | // 200 (HTTP_OK), throw an Exception.
540 | if (urlConn.getResponseCode() != 200)
541 | throw new Exception();
542 |
543 | }
544 | catch (MalformedURLException e)
545 | {
546 | return false;
547 | }
548 | catch (Exception e)
549 | {
550 | return false;
551 | }
552 | return true;
553 | }
554 | else
555 | return false;
556 | }
557 |
558 | public static boolean isValidDatabaseFile(String musicURIDataSource)
559 | {
560 | if (musicURIDataSource != null)
561 | {
562 | // Verify that the specified file exists, and it is not a directory
563 | File databaseFile = new File(musicURIDataSource);
564 | if (!databaseFile.exists() || !databaseFile.isFile())
565 | {
566 | return false;
567 | }
568 |
569 | // Verify that the specified file is a valid MusicURI Hashmap flatfile
570 | // (ends with .db, and can be deserialized into a Java Hashmap object)
571 | if (!isDBFile(databaseFile))
572 | {
573 | System.err.println("The specified file is not a valid MusicURI database file");
574 | return false;
575 | }
576 | // else
577 | // System.out.println("file ends with .db");
578 | // try
579 | // {
580 | // HashMap object = new HashMap();
581 | // ObjectInputStream in = new ObjectInputStream(new FileInputStream(musicURIDataSource));
582 | // object = (HashMap) in.readObject();
583 | // System.out.println("file can be deserialized");
584 | // }
585 | // catch (Exception e)
586 | // {
587 | // e.toString();
588 | // System.out.println("Can't load database file (" + musicURIDataSource + ")");
589 | // return false;
590 | // }
591 | return true;
592 | }
593 | else
594 | {
595 | System.out.println("Unspecified musicURIDataSource");
596 | return false;
597 | }
598 | }
599 |
600 | /**
601 | * Reports if the filename of the given file ends with ".db"
602 | * @param file the file to check
603 | * @return true if the filename ends with a ".db" extension, false otherwise
604 | */
605 | public static boolean isDBFile(File file)
606 | {
607 | String fname = file.getName();
608 | String extension = fname.substring(fname.lastIndexOf('.') + 1);
609 | if (extension.equalsIgnoreCase("db")) return true;
610 | else return false;
611 | }
612 |
613 |
614 | }
615 |
--------------------------------------------------------------------------------