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

Last change on this file since 24398 was 24398, checked in by davidb, 13 years ago

Latest round of changes to code, in preparing for demo to Goldsmiths

  • 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.