Skip to content

Commit 16407a9

Browse files
puneithlesv
authored andcommitted
Fix the sleep logic for streaming as per sample rate (#279)
* sleep 100ms instead of sleeping as function of rate * added sleep as inverse of sampling rate * added LINEAR16 bytes per sample constant * added few variables * added truth and log4j * added 32khz audio * added Streaming Test * added unit tests for 16 and 32 khz audio * checkstyle fixes * renamed to KHz * added comment
1 parent ebdad96 commit 16407a9

File tree

4 files changed

+121
-8
lines changed

4 files changed

+121
-8
lines changed

speech/grpc/pom.xml

+11
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,17 @@ limitations under the License.
152152
<version>1.1.33.Fork14</version>
153153
<classifier>${tcnative.classifier}</classifier>
154154
</dependency>
155+
<dependency>
156+
<groupId>com.google.truth</groupId>
157+
<artifactId>truth</artifactId>
158+
<version>0.28</version>
159+
<scope>test</scope>
160+
</dependency>
161+
<dependency>
162+
<groupId>log4j</groupId>
163+
<artifactId>log4j</artifactId>
164+
<version>1.2.17</version>
165+
</dependency>
155166
</dependencies>
156167
<!-- // [END dependency] -->
157168

speech/grpc/resources/audio32KHz.raw

162 KB
Binary file not shown.

speech/grpc/src/main/java/com/examples/cloud/speech/StreamingRecognizeClient.java

+23-8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.examples.cloud.speech;
1818

19+
import static org.apache.log4j.ConsoleAppender.SYSTEM_OUT;
20+
1921
import com.google.cloud.speech.v1beta1.RecognitionConfig;
2022
import com.google.cloud.speech.v1beta1.RecognitionConfig.AudioEncoding;
2123
import com.google.cloud.speech.v1beta1.SpeechGrpc;
@@ -26,7 +28,6 @@
2628
import com.google.protobuf.TextFormat;
2729

2830
import io.grpc.ManagedChannel;
29-
import io.grpc.Status;
3031
import io.grpc.stub.StreamObserver;
3132

3233
import org.apache.commons.cli.CommandLine;
@@ -35,6 +36,10 @@
3536
import org.apache.commons.cli.OptionBuilder;
3637
import org.apache.commons.cli.Options;
3738
import org.apache.commons.cli.ParseException;
39+
import org.apache.log4j.ConsoleAppender;
40+
import org.apache.log4j.Level;
41+
import org.apache.log4j.Logger;
42+
import org.apache.log4j.SimpleLayout;
3843

3944
import java.io.File;
4045
import java.io.FileInputStream;
@@ -43,8 +48,7 @@
4348
import java.util.List;
4449
import java.util.concurrent.CountDownLatch;
4550
import java.util.concurrent.TimeUnit;
46-
import java.util.logging.Level;
47-
import java.util.logging.Logger;
51+
4852

4953
/**
5054
* Client that sends streaming audio to Speech.Recognize and returns streaming transcript.
@@ -60,6 +64,9 @@ public class StreamingRecognizeClient {
6064

6165
private final SpeechGrpc.SpeechStub speechClient;
6266

67+
private static final int BYTES_PER_BUFFER = 3200; //buffer size in bytes
68+
private static final int BYTES_PER_SAMPLE = 2; //bytes per sample for LINEAR16
69+
6370
private static final List<String> OAUTH2_SCOPES =
6471
Arrays.asList("https://www.googleapis.com/auth/cloud-platform");
6572

@@ -73,6 +80,13 @@ public StreamingRecognizeClient(ManagedChannel channel, String file, int samplin
7380
this.channel = channel;
7481

7582
speechClient = SpeechGrpc.newStub(channel);
83+
84+
//Send log4j logs to Console
85+
//If you are going to run this on GCE, you might wish to integrate with gcloud-java logging.
86+
//See https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/README.md#stackdriver-logging-alpha
87+
88+
ConsoleAppender appender = new ConsoleAppender(new SimpleLayout(), SYSTEM_OUT);
89+
logger.addAppender(appender);
7690
}
7791

7892
public void shutdown() throws InterruptedException {
@@ -91,8 +105,7 @@ public void onNext(StreamingRecognizeResponse response) {
91105

92106
@Override
93107
public void onError(Throwable error) {
94-
Status status = Status.fromThrowable(error);
95-
logger.log(Level.WARNING, "recognize failed: {0}", status);
108+
logger.log(Level.WARN, "recognize failed: {0}", error);
96109
finishLatch.countDown();
97110
}
98111

@@ -127,9 +140,12 @@ public void onCompleted() {
127140
// Open audio file. Read and send sequential buffers of audio as additional RecognizeRequests.
128141
FileInputStream in = new FileInputStream(new File(file));
129142
// For LINEAR16 at 16000 Hz sample rate, 3200 bytes corresponds to 100 milliseconds of audio.
130-
byte[] buffer = new byte[3200];
143+
byte[] buffer = new byte[BYTES_PER_BUFFER];
131144
int bytesRead;
132145
int totalBytes = 0;
146+
int samplesPerBuffer = BYTES_PER_BUFFER / BYTES_PER_SAMPLE;
147+
int samplesPerMillis = samplingRate / 1000;
148+
133149
while ((bytesRead = in.read(buffer)) != -1) {
134150
totalBytes += bytesRead;
135151
StreamingRecognizeRequest request =
@@ -138,8 +154,7 @@ public void onCompleted() {
138154
.build();
139155
requestObserver.onNext(request);
140156
// To simulate real-time audio, sleep after sending each audio buffer.
141-
// For 16000 Hz sample rate, sleep 100 milliseconds.
142-
Thread.sleep(samplingRate / 160);
157+
Thread.sleep(samplesPerBuffer / samplesPerMillis);
143158
}
144159
logger.info("Sent " + totalBytes + " bytes from audio file: " + file);
145160
} catch (RuntimeException e) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.examples.cloud.speech;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import io.grpc.ManagedChannel;
22+
import org.apache.log4j.Logger;
23+
import org.apache.log4j.SimpleLayout;
24+
import org.apache.log4j.WriterAppender;
25+
import org.junit.After;
26+
import org.junit.Before;
27+
import org.junit.Test;
28+
import org.junit.runner.RunWith;
29+
import org.junit.runners.JUnit4;
30+
31+
import java.io.File;
32+
import java.io.IOException;
33+
import java.io.StringWriter;
34+
import java.io.Writer;
35+
import java.net.URI;
36+
import java.nio.file.Path;
37+
import java.nio.file.Paths;
38+
39+
40+
/**
41+
* Unit tests for {@link StreamingRecognizeClient }.
42+
*/
43+
@RunWith(JUnit4.class)
44+
public class StreamingRecognizeClientTest {
45+
private Writer writer;
46+
private WriterAppender appender;
47+
48+
@Before
49+
public void setUp() {
50+
writer = new StringWriter();
51+
appender = new WriterAppender(new SimpleLayout(), writer);
52+
Logger.getRootLogger().addAppender(appender);
53+
}
54+
55+
@After
56+
public void tearDown() {
57+
Logger.getRootLogger().removeAppender(appender);
58+
}
59+
60+
@Test
61+
public void test16KHzAudio() throws InterruptedException, IOException {
62+
URI uri = new File("resources/audio.raw").toURI();
63+
Path path = Paths.get(uri);
64+
65+
String host = "speech.googleapis.com";
66+
int port = 443;
67+
ManagedChannel channel = AsyncRecognizeClient.createChannel(host, port);
68+
StreamingRecognizeClient client = new StreamingRecognizeClient(channel, path.toString(), 16000);
69+
70+
client.recognize();
71+
assertThat(writer.toString()).contains("transcript: \"how old is the Brooklyn Bridge\"");
72+
}
73+
74+
@Test
75+
public void test32KHzAudio() throws InterruptedException, IOException {
76+
URI uri = new File("resources/audio32KHz.raw").toURI();
77+
Path path = Paths.get(uri);
78+
79+
String host = "speech.googleapis.com";
80+
int port = 443;
81+
ManagedChannel channel = AsyncRecognizeClient.createChannel(host, port);
82+
StreamingRecognizeClient client = new StreamingRecognizeClient(channel, path.toString(), 32000);
83+
84+
client.recognize();
85+
assertThat(writer.toString()).contains("transcript: \"how old is the Brooklyn Bridge\"");
86+
}
87+
}

0 commit comments

Comments
 (0)