19
19
import javax .sound .sampled .LineUnavailableException ;
20
20
import javax .sound .sampled .TargetDataLine ;
21
21
22
- import com .darkprograms .speech .util .ChunkedOutputStream ;
23
22
import com .darkprograms .speech .util .StringUtil ;
24
23
25
24
//TODO Add a better logging system to GSpeechDuplex
@@ -109,6 +108,8 @@ public void recognize(File flacFile, int sampleRate) throws IOException{
109
108
recognize (mapFileIn (flacFile ), sampleRate );
110
109
}
111
110
111
+
112
+
112
113
/**
113
114
* Send a byte[] to the URL with a specified sampleRate.
114
115
* NOTE: The byte[] should contain no more than 15 seconds of audio.
@@ -119,7 +120,6 @@ public void recognize(File flacFile, int sampleRate) throws IOException{
119
120
public void recognize (byte [] data , int sampleRate ){
120
121
121
122
if (data .length >= MAX_SIZE ){//Temporary Chunking. Does not allow for Google to gather context.
122
- System .out .println ("Chunking the audio into smaller parts..." );
123
123
byte [][] dataArray = chunkAudio (data );
124
124
for (byte []array : dataArray ){
125
125
recognize (array , sampleRate );
@@ -162,9 +162,10 @@ public void recognize(TargetDataLine tl, AudioFormat af) throws IOException, Lin
162
162
final String API_UP_URL = GOOGLE_DUPLEX_SPEECH_BASE +
163
163
"up?lang=" + language + "&lm=dictation&client=chromium&pair=" + PAIR +
164
164
"&key=" + API_KEY + "&continuous=true&interim=true" ; //Tells Google to constantly monitor the stream;
165
-
165
+
166
166
//Opens downChannel
167
167
this .downChannel (API_DOWN_URL );
168
+
168
169
//Opens upChannel
169
170
this .upChannel (API_UP_URL , tl , af );
170
171
}
@@ -191,15 +192,16 @@ public void run() {
191
192
Scanner inStream = openHttpsConnection (url );
192
193
if (inStream == null ){
193
194
//ERROR HAS OCCURED
195
+ System .out .println ("Error has occured" );
196
+ return ;
194
197
}
195
- while ( inStream . hasNextLine ()){
196
- String response = inStream .nextLine ();
198
+ String response ;
199
+ while ( inStream . hasNext () && ( response = inStream .nextLine ()) != null ){
197
200
if (response .length ()>17 ){//Prevents blank responses from Firing
198
201
GoogleResponse gr = new GoogleResponse ();
199
202
parseResponse (response , gr );
200
203
fireResponseEvent (gr );
201
204
}
202
-
203
205
}
204
206
inStream .close ();
205
207
System .out .println ("Finished write on down stream..." );
@@ -233,7 +235,7 @@ public void run() {
233
235
* @param af The AudioFormat to stream with.
234
236
* @throws LineUnavailableException If cannot open or stream the TargetDataLine.
235
237
*/
236
- private void upChannel (String urlStr , TargetDataLine tl , AudioFormat af ) throws LineUnavailableException {
238
+ private void upChannel (String urlStr , TargetDataLine tl , AudioFormat af ) throws IOException , LineUnavailableException {
237
239
final String murl = urlStr ;
238
240
final TargetDataLine mtl = tl ;
239
241
final AudioFormat maf = af ;
@@ -243,9 +245,8 @@ private void upChannel(String urlStr, TargetDataLine tl, AudioFormat af) throws
243
245
}
244
246
new Thread ("Upstream Thread" ) {
245
247
public void run () {
246
- openHttpsPostConnection (murl , mtl , maf );
248
+ openHttpsPostConnection (murl , mtl , ( int ) maf . getSampleRate () );
247
249
}
248
-
249
250
}.start ();
250
251
251
252
}
@@ -258,8 +259,6 @@ public void run() {
258
259
private Scanner openHttpsConnection (String urlStr ) {
259
260
int resCode = -1 ;
260
261
try {
261
-
262
-
263
262
URL url = new URL (urlStr );
264
263
URLConnection urlConn = url .openConnection ();
265
264
if (!(urlConn instanceof HttpsURLConnection )) {
@@ -270,7 +269,6 @@ private Scanner openHttpsConnection(String urlStr) {
270
269
// TIMEOUT is required
271
270
httpConn .setInstanceFollowRedirects (true );
272
271
httpConn .setRequestMethod ("GET" );
273
-
274
272
httpConn .connect ();
275
273
resCode = httpConn .getResponseCode ();
276
274
if (resCode == HttpsURLConnection .HTTP_OK ) {
@@ -293,49 +291,53 @@ private Scanner openHttpsConnection(String urlStr) {
293
291
* @param mtl The TargetDataLine you want to post data from. <b>Note should be open</b>
294
292
* @param maf The AudioFormat of the data you want to post
295
293
*/
296
- private void openHttpsPostConnection (final String murl ,
297
- final TargetDataLine mtl , final AudioFormat maf ) {
294
+ private void openHttpsPostConnection (String murl , TargetDataLine mtl , int sampleRate ) {
298
295
URL url ;
299
296
try {
300
297
url = new URL (murl );
301
298
URLConnection urlConn = url .openConnection ();
302
299
if (!(urlConn instanceof HttpsURLConnection )) {
303
300
throw new IOException ("URL is not an Https URL" );
304
301
}
302
+
305
303
HttpsURLConnection httpConn = (HttpsURLConnection )urlConn ;
306
304
httpConn .setAllowUserInteraction (false );
307
305
httpConn .setInstanceFollowRedirects (true );
308
306
httpConn .setRequestMethod ("POST" );
309
307
httpConn .setDoOutput (true );
310
308
httpConn .setChunkedStreamingMode (0 );
311
309
httpConn .setRequestProperty ("Transfer-Encoding" , "chunked" );
312
- httpConn .setRequestProperty ("Content-Type" , "audio/x-flac; rate=" + ( int ) maf . getSampleRate () );
310
+ httpConn .setRequestProperty ("Content-Type" , "audio/x-flac; rate=" + sampleRate );
313
311
// also worked with ("Content-Type", "audio/amr; rate=8000");
314
312
httpConn .connect ();
315
-
313
+
316
314
// this opens a connection, then sends POST & headers.
317
- OutputStream out = httpConn .getOutputStream ();
315
+ final OutputStream out = httpConn .getOutputStream ();
318
316
//Note : if the audio is more than 15 seconds
319
317
// dont write it to UrlConnInputStream all in one block as this sample does.
320
318
// Rather, segment the byteArray and on intermittently, sleeping thread
321
319
// supply bytes to the urlConn Stream at a rate that approaches
322
320
// the bitrate ( =30K per sec. in this instance ).
323
321
System .out .println ("Starting to write data to output..." );
324
- AudioInputStream ais = new AudioInputStream (mtl );
325
- ChunkedOutputStream os = new ChunkedOutputStream (out );
326
- AudioSystem .write (ais , FLACFileWriter .FLAC , os );
327
- out .write (FINAL_CHUNK );
328
- System .out .println ("IO WRITE DONE" );
329
- out .close ();
322
+ final AudioInputStream ais = new AudioInputStream (mtl );;
323
+ AudioSystem .write (ais , FLACFileWriter .FLAC , out );
324
+ //Output Stream is automatically closed
330
325
// do you need the trailer?
331
326
// NOW you can look at the status.
332
- int resCode = httpConn .getResponseCode ();
327
+
328
+ //Diagonostic Code.
329
+ /*int resCode = httpConn.getResponseCode();
333
330
if (resCode / 100 != 2) {
334
331
System.out.println("ERROR");
335
332
}
336
- }catch (Exception ex ){
333
+ Scanner scanner = new Scanner(httpConn.getInputStream());
334
+ while(scanner.hasNextLine()){
335
+ System.out.println("UPSTREAM READS:" + scanner.nextLine());
336
+ }
337
+ scanner.close();*/
338
+ System .out .println ("Upstream Closed..." );
339
+ }catch (IOException ex ){
337
340
ex .printStackTrace ();
338
-
339
341
}
340
342
}
341
343
@@ -369,34 +371,32 @@ private Scanner openHttpsPostConnection(String urlStr, byte[][] data, int sample
369
371
httpConn .setRequestProperty ("Content-Type" , "audio/x-flac; rate=" + sampleRate );
370
372
// also worked with ("Content-Type", "audio/amr; rate=8000");
371
373
httpConn .connect ();
372
-
373
- // this opens a connection, then sends POST & headers.
374
- out = httpConn .getOutputStream ();
375
- //Note : if the audio is more than 15 seconds
376
- // dont write it to UrlConnInputStream all in one block as this sample does.
377
- // Rather, segment the byteArray and on intermittently, sleeping thread
378
- // supply bytes to the urlConn Stream at a rate that approaches
379
- // the bitrate ( =30K per sec. in this instance ).
380
- System .out .println ("Starting to write" );
381
- for (byte [] dataArray : mextrad ){
382
- out .write (dataArray ); // one big block supplied instantly to the underlying chunker wont work for duration > 15 s.
383
- try {
384
- Thread .sleep (1000 );//Delays the Audio so Google thinks its a mic.
385
- } catch (InterruptedException e ) {
386
- e .printStackTrace ();
387
- }
388
- }
389
- out .write (FINAL_CHUNK );
390
- System .out .println ("IO WRITE DONE" );
391
- // do you need the trailer?
392
- // NOW you can look at the status.
393
- resCode = httpConn .getResponseCode ();
394
- if (resCode / 100 != 2 ) {
395
- System .out .println ("ERROR" );
374
+ // this opens a connection, then sends POST & headers.
375
+ out = httpConn .getOutputStream ();
376
+ //Note : if the audio is more than 15 seconds
377
+ // dont write it to UrlConnInputStream all in one block as this sample does.
378
+ // Rather, segment the byteArray and on intermittently, sleeping thread
379
+ // supply bytes to the urlConn Stream at a rate that approaches
380
+ // the bitrate ( =30K per sec. in this instance ).
381
+ System .out .println ("Starting to write" );
382
+ for (byte [] dataArray : mextrad ){
383
+ out .write (dataArray ); // one big block supplied instantly to the underlying chunker wont work for duration > 15 s.
384
+ try {
385
+ Thread .sleep (1000 );//Delays the Audio so Google thinks its a mic.
386
+ } catch (InterruptedException e ) {
387
+ e .printStackTrace ();
396
388
}
397
-
389
+ }
390
+ out .write (FINAL_CHUNK );
391
+ System .out .println ("IO WRITE DONE" );
392
+ // do you need the trailer?
393
+ // NOW you can look at the status.
394
+ resCode = httpConn .getResponseCode ();
395
+ if (resCode / 100 != 2 ) {
396
+ System .out .println ("ERROR" );
397
+ }
398
398
if (resCode == HttpsURLConnection .HTTP_OK ) {
399
- return new Scanner (httpConn .getInputStream ());
399
+ return new Scanner (httpConn .getInputStream (), "UTF-8" );
400
400
}
401
401
else {
402
402
System .out .println ("HELP: " + resCode );
0 commit comments