source: gs3-extensions/audioDB/trunk/src/src/java/org/greenstone/gsdl3/util/AudioDBWrapper.java@ 26290

Last change on this file since 26290 was 26290, checked in by davidb, 12 years ago

Addition of single quotes on file names to help it play more nicely in a Windows environment

  • Property svn:executable set to *
File size: 6.6 KB
Line 
1/*
2 * AudioDBWrapper.java
3 * Copyright (C) 2011 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import java.io.*;
22import java.util.Vector;
23import java.util.Collections;
24
25import org.apache.log4j.*;
26
27/** java wrapper class for access to the audioDB executable
28 *
29 * Inspired by MGSearchWrapper.java
30 */
31
32public class AudioDBWrapper
33{
34 /** the query result, filled in by runQuery */
35 protected Vector query_result_;
36
37 protected int offset_ = 100;
38 protected int length_ = 20;
39
40 // Approximate matching not yet utilized
41 protected double radius_;
42
43 protected int max_docs_;
44
45 static Logger logger = Logger.getLogger (org.greenstone.gsdl3.util.AudioDBWrapper.class.getName ());
46
47 public AudioDBWrapper() {
48 query_result_ = null;
49 }
50
51 // query param methods
52
53 /** start point (offset) into the array of feature vectors for a track
54 - 100 by default which equals 10 seconds (assuming 0.1 frame size) */
55 public void setOffset(int offset) {
56 offset_ = offset;
57 }
58
59 /** the number of consecutive frames used in match
60 - 20 by default which equals 2 seconds (assuming 0.1 frame size) */
61 public void setLength(int length) {
62 length_ = length;
63 }
64
65 /** distance used in approximate matching support - default is 50 */
66 public void setRadius(double radius) {
67 radius_ = radius;
68 }
69
70 public void setMaxDocs(int max_docs) {
71 max_docs_ = max_docs;
72 }
73
74 /** returns a string with all the current query param settings */
75 // the following was in MG version, do we need this in audioDB version?
76 //public String getQueryParams() {}
77
78
79 protected boolean addQueryResult(boolean first_entry, String doc_id,
80 Vector<Double> rankVector, Vector<Integer> offsetVector)
81 {
82
83 if (first_entry) {
84 AudioDBDocInfo audioDB_doc_info = new AudioDBDocInfo(doc_id,rankVector,offsetVector);
85 query_result_.add(audioDB_doc_info);
86 first_entry = false;
87 }
88 else {
89 double rank = rankVector.get(0);
90 int offset = offsetVector.get(0);
91 AudioDBDocInfo audioDB_doc_info = new AudioDBDocInfo(doc_id,rank,offset);
92
93 query_result_.add(audioDB_doc_info);
94 }
95
96 return first_entry;
97 }
98
99
100 /** actually carry out the query.
101 Use the set methods to set query results.
102 Writes the result to query_result.
103 * - maintains state between requests as can be slow
104 * base_dir and index_path should join together to provide
105 * the absolute location of the mg index files eg ..../index/dtx/demo
106 * base_dir must end with a file separator (OS dependant)
107 */
108 public void runQuery(String audioDB_index_dir, String adb_file,
109 String assoc_index_dir, String query_string) {
110
111 // combine index_dir with audiodb fileanem
112
113 String full_adb_filename = audioDB_index_dir + File.separatorChar + adb_file;
114 String full_chr12_filename = assoc_index_dir + File.separatorChar
115 + query_string + File.separatorChar + "doc.chr12";
116
117 int num_matches_within_track = 6;
118
119 String cmd = "audioDB"
120 + " -d " + "'" + full_adb_filename + "'"
121 + " -Q nsequence"
122 + " -p " + offset_
123 + " -n " + num_matches_within_track
124 + " -l " + length_
125 + " -r " + max_docs_
126 + " -f " + "'" + full_chr12_filename + "'";
127
128 System.err.println("**** cmd = " + cmd);
129
130 Runtime runtime = Runtime.getRuntime();
131 try {
132 Process audioDB_proc = runtime.exec(cmd);
133 InputStream ais = audioDB_proc.getInputStream();
134 InputStreamReader aisr = new InputStreamReader(ais);
135 BufferedReader abr = new BufferedReader(aisr);
136
137 query_result_ = new Vector();
138
139 boolean first_entry = true;
140 int line_count = 0;
141
142 String root_doc_id = null;
143 Vector<Double> rankVector = new Vector<Double>();
144 Vector<Integer> offsetVector = new Vector<Integer>();
145
146 // Example output
147 // D8 0.00105175
148 // 1.69786e-16 392 392
149 // 0.00113568 392 673
150 // 0.00127239 392 910
151 // 0.00139736 392 481
152 // 0.00145331 392 303
153 // D2 0.00429758
154 // 0.00403335 392 865
155 // 0.00411288 392 458
156 // 0.00442461 392 866
157 // 0.00444272 392 864
158 // 0.00447434 392 424
159 // ...
160
161 String line;
162 while ((line = abr.readLine()) != null) {
163 String[] tokens = line.split("\\s+");
164 line_count++;
165
166 if (tokens.length==2) {
167 // processing a top-level doc line
168
169 if (line_count>1) {
170 // struck new top-level entry => store vector vals for previous block
171 first_entry = addQueryResult(first_entry,root_doc_id,rankVector,offsetVector);
172 // and now reset vectors to empty to be ready for next chain of values
173 rankVector = new Vector<Double>();
174 offsetVector = new Vector<Integer>();
175 }
176
177 root_doc_id = tokens[0];
178 }
179 else {
180 // should be 3 items
181 double euclidean_dist = Double.parseDouble(tokens[0]);
182 int src_frame = Integer.parseInt(tokens[1]);
183 int target_frame = Integer.parseInt(tokens[2]);
184
185 // enforce 1.0 as upper limit due to rounding errors
186 // in audioDB distance calculations
187 double rank = Math.min(1.0 - euclidean_dist,1.0);
188
189 if ((line_count==2) && (src_frame==target_frame)) {
190 // Found match with self
191 continue;
192 }
193
194 rankVector.add(rank);
195 offsetVector.add(target_frame);
196 }
197
198 }
199
200 addQueryResult(first_entry,root_doc_id,rankVector,offsetVector);
201
202 abr.close();
203
204 // sort query_result_ on 'rank' field
205 // note: compareTo() method impelemented to sort into descending order
206
207 Collections.sort(query_result_);
208
209
210 }
211 catch (Exception e) {
212 logger.error("Failed to execute the following command: " + cmd);
213 e.printStackTrace();
214 }
215
216 }
217
218
219 /** get the result out of the wrapper */
220 public Vector getQueryResult()
221 {
222 return query_result_;
223 }
224}
225
Note: See TracBrowser for help on using the repository browser.