source: trunk/src/org/apollo/meldex/MeldexMatch.java

Last change on this file was 315, checked in by bjn8, 16 years ago

Apollo spin-off added

  • Property svn:executable set to *
File size: 7.6 KB
Line 
1package org.apollo.meldex;
2
3import java.io.ByteArrayInputStream;
4import java.io.ByteArrayOutputStream;
5import java.io.File;
6import java.io.IOException;
7
8import javax.sound.sampled.AudioFormat;
9import javax.sound.sampled.AudioInputStream;
10import javax.sound.sampled.AudioSystem;
11import javax.sound.sampled.DataLine;
12import javax.sound.sampled.TargetDataLine;
13
14/**
15 * Calculates a "Score" on how well two given
16 *
17 */
18class MeldexMatch {
19
20 final protected int MIC_FREQUENCY = 8;
21
22 protected DataLine.Info micInfo_;
23
24 protected AudioFormat micFormat_;
25
26 protected TargetDataLine micLine_;
27
28 protected Transcriber transcriber_ = null;
29
30 public MeldexMatch() {
31 transcriber_ = new Transcriber();
32 }
33
34 protected void establishMicInfo() {
35 AudioFormat micFormat22050, micFormat11025, micFormat8000, micFormat8096;
36 DataLine.Info micInfo22050, micInfo11025, micInfo8000, micInfo8096;
37
38 // Define the format for our microphone data line
39 AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_UNSIGNED;
40 int sampleSize = 8;
41 int channels = 1;
42 boolean bigEndian = false;
43 float rate;
44
45 // Define a variety of formats, each with a different sampling rate
46 rate = 22050F;
47 micFormat22050 = new AudioFormat(encoding, rate, sampleSize, channels,
48 (sampleSize / 8) * channels, rate, bigEndian);
49 rate = 11025F;
50 micFormat11025 = new AudioFormat(encoding, rate, sampleSize, channels,
51 (sampleSize / 8) * channels, rate, bigEndian);
52 rate = 8000F;
53 micFormat8000 = new AudioFormat(encoding, rate, sampleSize, channels,
54 (sampleSize / 8) * channels, rate, bigEndian);
55 rate = 8096F;
56 micFormat8096 = new AudioFormat(encoding, rate, sampleSize, channels,
57 (sampleSize / 8) * channels, rate, bigEndian);
58
59 // Describe a variety of data lines, each with a different sampling rate
60 micInfo22050 = new DataLine.Info(TargetDataLine.class, micFormat22050);
61 micInfo11025 = new DataLine.Info(TargetDataLine.class, micFormat11025);
62 micInfo8000 = new DataLine.Info(TargetDataLine.class, micFormat8000);
63 micInfo8096 = new DataLine.Info(TargetDataLine.class, micFormat8096);
64
65 // Try to find a microphone line that we can use
66 if (AudioSystem.isLineSupported(micInfo22050)) {
67 micInfo_ = micInfo22050;
68 micFormat_ = micFormat22050;
69 } else if (AudioSystem.isLineSupported(micInfo11025)) {
70 micInfo_ = micInfo11025;
71 micFormat_ = micFormat11025;
72 } else if (AudioSystem.isLineSupported(micInfo8000)) {
73 micInfo_ = micInfo8000;
74 micFormat_ = micFormat8000;
75 } else if (AudioSystem.isLineSupported(micInfo8096)) {
76 micInfo_ = micInfo8096;
77 micFormat_ = micFormat8096;
78 } else {
79 micInfo_ = null;
80 micFormat_ = null;
81 }
82 }
83
84 protected boolean initMic() {
85 establishMicInfo();
86
87 // Get the microphone line
88 try {
89 micLine_ = (TargetDataLine) AudioSystem.getLine(micInfo_);
90 } catch (Exception ex) {
91 System.err
92 .println("Exception occurred getting the microphone line.\n\n"
93 + ex);
94 return false;
95 }
96
97 // Calculate the size of the microphone buffer required
98 int frameSize = (micFormat_.getChannels() * (micFormat_
99 .getSampleSizeInBits() / 8));
100 int bytesPerSecond = (int) (micFormat_.getSampleRate() * frameSize);
101 int micBufferSize = (int) (bytesPerSecond / MIC_FREQUENCY);
102
103 // Open the microphone data line for recording
104 try {
105 micLine_.open(micFormat_, micBufferSize);
106 } catch (Exception ex) {
107 System.err
108 .println("Exception occurred opening the microphone line.\n\n"
109 + ex);
110 return false;
111 }
112
113 return true;
114 }
115
116 protected void record_prompt(int p, int fixed) {
117 System.out.print("Recording: [");
118 for (int i = 0; i < p; i++) {
119 System.out.print(".");
120 }
121 for (int i = p; i < fixed; i++) {
122 System.out.print(" ");
123 }
124
125 System.out.print("]\r");
126 System.out.flush();
127 }
128
129 public AudioInputStream record() {
130 // Make sure that we found a supported microphone line
131 if (micInfo_ == null) {
132 System.err
133 .println("Sorry, a suitable microphone line could not be found.");
134 return null;
135 }
136
137 // Create a buffer for the recorded data
138 byte[] micBuffer = new byte[micLine_.getBufferSize()];
139
140 // Create an output stream to save the recorded data
141 ByteArrayOutputStream micOut = new ByteArrayOutputStream();
142
143 // Start the microphone actually recording
144 micLine_.start();
145
146 // Continue recording until the Stop button is pressed
147 int fixed = 30;
148 int i = 0;
149 while (i <= fixed) {
150 record_prompt(i, fixed);
151
152 // Read some data from the microphone line...
153 int numBytesRead = micLine_.read(micBuffer, 0, micLine_
154 .getBufferSize());
155
156 // ...save it to the output stream
157 micOut.write(micBuffer, 0, numBytesRead);
158
159 i++;
160 }
161 System.out.println("");
162
163 // We have finished recording, so stop and close the microphone line
164 micLine_.stop();
165 micLine_.close();
166
167 // Flush and close the output stream
168 try {
169 micOut.flush();
170 micOut.close();
171 } catch (Exception ex) {
172 System.err
173 .println("Exception occurred flushing/closing output stream.\n\n"
174 + ex);
175 return null;
176 }
177
178 // Load the data recorded into the audio input stream ready for playback/processing
179 byte audioBytes[] = micOut.toByteArray();
180 ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
181 AudioInputStream audioData = new AudioInputStream(bais, micFormat_,
182 audioBytes.length / micFormat_.getFrameSize());
183
184 return audioData;
185 }
186
187 public void doMatch(WavSample sample_query, WavSample sample_track) throws IOException {
188
189 RogTrack transcribed_query = transcriber_
190 .transcribeSample(sample_query);
191
192 RogTrack transcribed_track = transcriber_
193 .transcribeSample(sample_track);
194
195 System.out.println("Query");
196 System.out.println(transcribed_query);
197 System.out.println("Track");
198 System.out.println(transcribed_track);
199
200 Melody melody_query = transcribed_query.toMelody();
201 Melody melody_track = transcribed_track.toMelody();
202
203 DynamicProgrammingAlgorithm dpa = new McNabMongeauSankoffAlgorithm();
204 // int match_mode = DynamicProgrammingAlgorithm.MATCH_AT_START;
205 int match_mode = DynamicProgrammingAlgorithm.MATCH_ANYWHERE;
206
207 float score = dpa
208 .matchToPattern(melody_query, melody_track, match_mode);
209
210 System.out.println("Edit distance = " + score);
211
212 }
213
214 public void liveQuery(String audiotrack) {
215 File input_file = new File(audiotrack);
216
217 WavSample sample_track = new WavSample();
218
219 if (sample_track.loadFromFile(input_file) != true) {
220 System.err.println("Error: Unable to load wav file: " + audiotrack);
221 } else {
222 initMic();
223 AudioInputStream audioData = record();
224
225 WavSample sample_query = new WavSample(audioData);
226
227 try {
228 doMatch(sample_query, sample_track);
229 } catch (IOException e) {
230 // TODO Auto-generated catch block
231 e.printStackTrace();
232 }
233 }
234
235 }
236
237 public void cannedQuery(String audioquery, String audiotrack) {
238 File file_query = new File(audioquery);
239 File file_track = new File(audiotrack);
240
241 WavSample sample_query = new WavSample();
242 WavSample sample_track = new WavSample();
243
244 if (sample_query.loadFromFile(file_query) != true) {
245 System.err.println("Error: Unable to load wav file: " + audioquery);
246 } else if (sample_track.loadFromFile(file_track) != true) {
247 System.err.println("Error: Unable to load wav file: " + audiotrack);
248 } else {
249 try {
250 doMatch(sample_query, sample_track);
251 } catch (IOException e) {
252 // TODO Auto-generated catch block
253 e.printStackTrace();
254 }
255 }
256 }
257
258 public static void main(String args[]) {
259 MeldexMatch meldex = new MeldexMatch();
260
261 int argc = args.length;
262 if (argc == 1) {
263 meldex.liveQuery(args[0]);
264 } else if (argc == 2) {
265 meldex.cannedQuery(args[0], args[1]);
266 } else {
267 System.err.println("Usage: MeldexMatch wav-file1 [wav-file2]");
268 System.exit(-1);
269 }
270 }
271}
Note: See TracBrowser for help on using the repository browser.