1919import javax .sound .sampled .LineUnavailableException ;
2020import javax .sound .sampled .TargetDataLine ;
2121
22- import com .darkprograms .speech .util .ChunkedOutputStream ;
2322import com .darkprograms .speech .util .StringUtil ;
2423
2524//TODO Add a better logging system to GSpeechDuplex
@@ -109,6 +108,8 @@ public void recognize(File flacFile, int sampleRate) throws IOException{
109108 recognize (mapFileIn (flacFile ), sampleRate );
110109 }
111110
111+
112+
112113 /**
113114 * Send a byte[] to the URL with a specified sampleRate.
114115 * 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{
119120 public void recognize (byte [] data , int sampleRate ){
120121
121122 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..." );
123123 byte [][] dataArray = chunkAudio (data );
124124 for (byte []array : dataArray ){
125125 recognize (array , sampleRate );
@@ -162,9 +162,10 @@ public void recognize(TargetDataLine tl, AudioFormat af) throws IOException, Lin
162162 final String API_UP_URL = GOOGLE_DUPLEX_SPEECH_BASE +
163163 "up?lang=" + language + "&lm=dictation&client=chromium&pair=" + PAIR +
164164 "&key=" + API_KEY + "&continuous=true&interim=true" ; //Tells Google to constantly monitor the stream;
165-
165+
166166 //Opens downChannel
167167 this .downChannel (API_DOWN_URL );
168+
168169 //Opens upChannel
169170 this .upChannel (API_UP_URL , tl , af );
170171 }
@@ -191,15 +192,16 @@ public void run() {
191192 Scanner inStream = openHttpsConnection (url );
192193 if (inStream == null ){
193194 //ERROR HAS OCCURED
195+ System .out .println ("Error has occured" );
196+ return ;
194197 }
195- while ( inStream . hasNextLine ()){
196- String response = inStream .nextLine ();
198+ String response ;
199+ while ( inStream . hasNext () && ( response = inStream .nextLine ()) != null ){
197200 if (response .length ()>17 ){//Prevents blank responses from Firing
198201 GoogleResponse gr = new GoogleResponse ();
199202 parseResponse (response , gr );
200203 fireResponseEvent (gr );
201204 }
202-
203205 }
204206 inStream .close ();
205207 System .out .println ("Finished write on down stream..." );
@@ -233,7 +235,7 @@ public void run() {
233235 * @param af The AudioFormat to stream with.
234236 * @throws LineUnavailableException If cannot open or stream the TargetDataLine.
235237 */
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 {
237239 final String murl = urlStr ;
238240 final TargetDataLine mtl = tl ;
239241 final AudioFormat maf = af ;
@@ -243,9 +245,8 @@ private void upChannel(String urlStr, TargetDataLine tl, AudioFormat af) throws
243245 }
244246 new Thread ("Upstream Thread" ) {
245247 public void run () {
246- openHttpsPostConnection (murl , mtl , maf );
248+ openHttpsPostConnection (murl , mtl , ( int ) maf . getSampleRate () );
247249 }
248-
249250 }.start ();
250251
251252 }
@@ -258,8 +259,6 @@ public void run() {
258259 private Scanner openHttpsConnection (String urlStr ) {
259260 int resCode = -1 ;
260261 try {
261-
262-
263262 URL url = new URL (urlStr );
264263 URLConnection urlConn = url .openConnection ();
265264 if (!(urlConn instanceof HttpsURLConnection )) {
@@ -270,7 +269,6 @@ private Scanner openHttpsConnection(String urlStr) {
270269 // TIMEOUT is required
271270 httpConn .setInstanceFollowRedirects (true );
272271 httpConn .setRequestMethod ("GET" );
273-
274272 httpConn .connect ();
275273 resCode = httpConn .getResponseCode ();
276274 if (resCode == HttpsURLConnection .HTTP_OK ) {
@@ -293,49 +291,53 @@ private Scanner openHttpsConnection(String urlStr) {
293291 * @param mtl The TargetDataLine you want to post data from. <b>Note should be open</b>
294292 * @param maf The AudioFormat of the data you want to post
295293 */
296- private void openHttpsPostConnection (final String murl ,
297- final TargetDataLine mtl , final AudioFormat maf ) {
294+ private void openHttpsPostConnection (String murl , TargetDataLine mtl , int sampleRate ) {
298295 URL url ;
299296 try {
300297 url = new URL (murl );
301298 URLConnection urlConn = url .openConnection ();
302299 if (!(urlConn instanceof HttpsURLConnection )) {
303300 throw new IOException ("URL is not an Https URL" );
304301 }
302+
305303 HttpsURLConnection httpConn = (HttpsURLConnection )urlConn ;
306304 httpConn .setAllowUserInteraction (false );
307305 httpConn .setInstanceFollowRedirects (true );
308306 httpConn .setRequestMethod ("POST" );
309307 httpConn .setDoOutput (true );
310308 httpConn .setChunkedStreamingMode (0 );
311309 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 );
313311 // also worked with ("Content-Type", "audio/amr; rate=8000");
314312 httpConn .connect ();
315-
313+
316314 // this opens a connection, then sends POST & headers.
317- OutputStream out = httpConn .getOutputStream ();
315+ final OutputStream out = httpConn .getOutputStream ();
318316 //Note : if the audio is more than 15 seconds
319317 // dont write it to UrlConnInputStream all in one block as this sample does.
320318 // Rather, segment the byteArray and on intermittently, sleeping thread
321319 // supply bytes to the urlConn Stream at a rate that approaches
322320 // the bitrate ( =30K per sec. in this instance ).
323321 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
330325 // do you need the trailer?
331326 // NOW you can look at the status.
332- int resCode = httpConn .getResponseCode ();
327+
328+ //Diagonostic Code.
329+ /*int resCode = httpConn.getResponseCode();
333330 if (resCode / 100 != 2) {
334331 System.out.println("ERROR");
335332 }
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 ){
337340 ex .printStackTrace ();
338-
339341 }
340342 }
341343
@@ -369,34 +371,32 @@ private Scanner openHttpsPostConnection(String urlStr, byte[][] data, int sample
369371 httpConn .setRequestProperty ("Content-Type" , "audio/x-flac; rate=" + sampleRate );
370372 // also worked with ("Content-Type", "audio/amr; rate=8000");
371373 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 ();
396388 }
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+ }
398398 if (resCode == HttpsURLConnection .HTTP_OK ) {
399- return new Scanner (httpConn .getInputStream ());
399+ return new Scanner (httpConn .getInputStream (), "UTF-8" );
400400 }
401401 else {
402402 System .out .println ("HELP: " + resCode );
0 commit comments