Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.

Commit a15aed6

Browse files
author
TheDutchMC
committed
Housekeeping
- Split out README.md into standalone.md, for all the bits that are standalone-specific - Removed all automatically generated java files (generated by SWIG) - Updated .gitignore to reflect the change above - Updated DeepSpeechModel.java to be API-compatible with how it was, whilst also allowing the standalone to function (allowing you to load the libraries yourself, if wanted)
1 parent 86a3c52 commit a15aed6

15 files changed

+237
-733
lines changed

native_client/java/.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,9 @@ jni/*.cpp
1818
jni/*.o
1919

2020
#Setup.sh output
21-
build/
21+
build/
22+
23+
#Autogenerated java files by SWIG
24+
libdeepspeech/src/main/java/org/deepspeech/libdeepspeech/*.java
25+
!libdeepspeech/src/main/java/org/deepspeech/libdeepspeech/DeepSpeechModel.java
26+
!libdeepspeech/src/main/java/org/deepspeech/libdeepspeech/DeepSpeechStreamingState.java=

native_client/java/README.md

Lines changed: 1 addition & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -17,199 +17,4 @@ For use with Android
1717
## Standalone Java Bindings for DeepSpeech
1818
For use with standalone Java
1919

20-
### Setup
21-
1. Get `libdeepspeech.so` by compiling or (from here)[], and copy it into `./libdeepspeech/libs/`
22-
2. Run `setup.sh` as root or with `sudo`
23-
3. You can now find the files needed for your project at `./build/`
24-
25-
### Adding DeepSpeech to your Java project
26-
>Note: You can do this on your own way too, but this works with the example usage code provided below.
27-
1. Copy `libdeepspeech.jar` from `./build/` into `{YOUR PROJECT ROOT}/libs/`
28-
2. Copy '*.so' from `./build/` into `{YOUR PROJECT ROOT}/src/main/resources/jni/x86_64/`
29-
3. Modify your `build.gradle` file to include:
30-
```groovy
31-
plugins {
32-
id 'com.github.johnrengelman.shadow' version '5.0.0'
33-
}
34-
35-
repositories {
36-
flatDir {
37-
dirs 'libs'
38-
}
39-
}
40-
41-
dependencies {
42-
compile ':libdeepspeech'
43-
}
44-
```
45-
4. You can now compile your project with `./gradlew shadowJar`.
46-
47-
### Notes
48-
- At this moment, this will only run on x86-64 Linux.
49-
50-
### Example usage
51-
`LibDeepSpeech.java` example
52-
```java
53-
import java.io.File;
54-
import java.io.IOException;
55-
import java.io.InputStream;
56-
import java.net.URL;
57-
import java.nio.file.Files;
58-
59-
import org.deepspeech.libdeepspeech.DeepSpeechModel;
60-
61-
//This class facilitates the loading of the native libraries.
62-
//The implementation in here works with the Gradle guide provided in the README.md document.
63-
//However you can modify this to whatever you wish.
64-
public class LibDeepSpeech extends DeepSpeechModel {
65-
66-
public LibDeepSpeech(String modelPath) {
67-
loadNativeLibs();
68-
super.loadModel(modelPath);
69-
}
70-
71-
@Override
72-
public void loadNativeLibs() {
73-
String jniName = "libdeepspeech-jni.so";
74-
String libName = "libdeepspeech.so";
75-
76-
System.out.println("Setting up DeepSpeech...");
77-
78-
URL jniUrl = DeepSpeechModel.class.getResource("/jni/x86_64/" + jniName);
79-
URL libUrl = DeepSpeechModel.class.getResource("/jni/x86_64/" + libName);
80-
File tmpDir = null;
81-
try {
82-
tmpDir = Files.createTempDirectory("libdeepspeech").toFile();
83-
} catch (IOException e) {
84-
e.printStackTrace();
85-
}
86-
tmpDir.deleteOnExit();
87-
88-
File jniTmpFile = new File(tmpDir, jniName);
89-
jniTmpFile.deleteOnExit();
90-
File libTmpFile = new File(tmpDir, libName);
91-
libTmpFile.deleteOnExit();
92-
93-
try (
94-
InputStream jniIn = jniUrl.openStream();
95-
InputStream libIn = libUrl.openStream();
96-
) {
97-
Files.copy(jniIn, jniTmpFile.toPath());
98-
Files.copy(libIn, libTmpFile.toPath());
99-
} catch (IOException e) {
100-
e.printStackTrace();
101-
}
102-
103-
System.load(jniTmpFile.getAbsolutePath());
104-
System.load(libTmpFile.getAbsolutePath());
105-
}
106-
}
107-
```
108-
109-
`DeepSpeechExample.java`
110-
```java
111-
import java.io.FileNotFoundException;
112-
import java.io.IOException;
113-
import java.io.RandomAccessFile;
114-
import java.nio.ByteBuffer;
115-
import java.nio.ByteOrder;
116-
117-
public class DeepSpeechExample {
118-
private LibDeepSpeech deepSpeechModel = null
119-
120-
private final String TF_MODEL = "PATH_TO_YOUR_TENSORFLOW_MODEL";
121-
private final int BEAM_WIDTH = 50;
122-
123-
public void createModel(String tensorFlowModel) {
124-
if(this.deepSpeechModel == null) {
125-
this.deepSpeechModel = new LibDeepSpeech(tensorFlowModel);
126-
this.deepSpeechModel.setBeamWidth(BEAM_WIDTH);
127-
}
128-
}
129-
130-
//The format we want is a 16Khz 16 bit mono .WAV file!
131-
public void doInfer(String audioFile) {
132-
long inferenceExecTime = 0L;
133-
134-
//Create a new model to use during the inference
135-
this.newModel(this.TF_MODEL);
136-
137-
System.out.println("Extracting audio features...");
138-
139-
try {
140-
RandomAccessFile wave = new RandomAccessFile(audioFile, "r");
141-
142-
//Assert that the audio format is PCM
143-
wave.seek(20);
144-
char audioFormat = this.readLEChar(wave);
145-
assert (audioFormat == 1); // 1 is PCM
146-
147-
//Assert that the amount of channels is 1, meaning mono audio
148-
wave.seek(22);
149-
char numChannels = this.readLEChar(wave);
150-
assert (numChannels == 1); // MONO
151-
152-
//Assert that the sample rate is the sample rate expected by the model
153-
//This can vary per model!
154-
wave.seek(24);
155-
int sampleRate = this.readLEInt(wave);
156-
assert (sampleRate == this.deepSpeechModel.sampleRate()); // desired sample rate
157-
158-
//Assert that the bits per sample is 16
159-
wave.seek(34);
160-
char bitsPerSample = this.readLEChar(wave);
161-
assert (bitsPerSample == 16); // 16 bits per sample
162-
163-
//Assert that the buffer size is more than 0
164-
wave.seek(40);
165-
int bufferSize = this.readLEInt(wave);
166-
assert (bufferSize > 0);
167-
168-
//Read the actual contents of the audio
169-
wave.seek(44);
170-
byte[] bytes = new byte[bufferSize];
171-
wave.readFully(bytes);
172-
173-
//Turn the byte[] into a short[] and set the correct byte order
174-
short[] shorts = new short[bytes.length/2];
175-
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
176-
177-
System.out.println("Running inference...");
178-
179-
//current time. Used later on to calculate the time the inference took
180-
long inferenceStartTime = System.currentTimeMillis();
181-
182-
//This is where we actually do the inference
183-
String decoded = this.deepSpeechModel.stt(shorts, shorts.length);
184-
185-
//Calculate how long it took to run the inference
186-
inferenceExecTime = System.currentTimeMillis() - inferenceStartTime;
187-
188-
System.out.println(decoded);
189-
190-
} catch (FileNotFoundException e) {
191-
e.printStackTrace();
192-
} catch (IOException e) {
193-
e.printStackTrace();
194-
}
195-
196-
System.out.println("Finished! Took " + inferenceExecTime);
197-
}
198-
199-
//Helper function to read a char from a RandomAccessFile in little endian
200-
private char readLEChar(RandomAccessFile f) throws IOException {
201-
byte b1 = f.readByte();
202-
byte b2 = f.readByte();
203-
return (char)((b2 << 8) | b1);
204-
}
205-
206-
//Helper function to read an integer from a RandomAccessFile in little endian
207-
private int readLEInt(RandomAccessFile f) throws IOException {
208-
byte b1 = f.readByte();
209-
byte b2 = f.readByte();
210-
byte b3 = f.readByte();
211-
byte b4 = f.readByte();
212-
return (int)((b1 & 0xFF) | (b2 & 0xFF) << 8 | (b3 & 0xFF) << 16 | (b4 & 0xFF) << 24);
213-
}
214-
}
215-
```
20+
See [standalone.md](standalone.md)

native_client/java/libdeepspeech/src/main/java/org/deepspeech/libdeepspeech/CandidateTranscript.java

Lines changed: 0 additions & 46 deletions
This file was deleted.

native_client/java/libdeepspeech/src/main/java/org/deepspeech/libdeepspeech/DeepSpeechModel.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,28 @@
99
/**
1010
* @brief Exposes a DeepSpeech model in Java
1111
**/
12-
public abstract class DeepSpeechModel {
12+
public class DeepSpeechModel {
1313

14-
public abstract void loadNativeLibs();
14+
/**
15+
* Create a new DeepSpeechModel object and load the native libraries.<br>
16+
* Use on: Android
17+
*/
18+
public DeepSpeechModel() {
19+
System.loadLibrary("deepspeech-jni");
20+
System.loadLibrary("deepspeech");
21+
}
22+
23+
/**
24+
* Create a new DeepSpeechModel object.<br>
25+
* Use on: Android, Standalone
26+
* @param loadNativeLibrariesManually if true, the native libraries will not be loaded. The developer must do this manually then.
27+
*/
28+
public DeepSpeechModel(boolean loadNativeLibrariesManually) {
29+
if(!loadNativeLibrariesManually) {
30+
System.loadLibrary("deepspeech-jni");
31+
System.loadLibrary("deepspeech");
32+
}
33+
}
1534

1635
// FIXME: We should have something better than those SWIGTYPE_*
1736
private SWIGTYPE_p_p_ModelState _mspp;

native_client/java/libdeepspeech/src/main/java/org/deepspeech/libdeepspeech/DeepSpeech_Error_Codes.java

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)