Skip to content

Commit 2fcd62c

Browse files
committed
Re-implemented volume detection. Added fundamental frequency detection.
Continued re-branding to J.A.R.V.I.S. Built framework for Voice Activity Detection algorithm. Created Microphone Analyzer class. Updated microphone class.
1 parent c7c2591 commit 2fcd62c

File tree

8 files changed

+535
-83
lines changed

8 files changed

+535
-83
lines changed

CHANGELOG.markdown

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ Changelog corresponds with a tagged and signed Git commit. This marks the chang
55
A tagged commit may or may not have a corresponding binary version available.
66
Format: Tag: `<Corresponding Tag>`
77

8+
* Version 1.10 (Tag v1.100)
9+
* Added new Microphone Analyzer class.
10+
* Added volume and frequency detection and frame work for (Voice Activity Detection)
11+
* Microphone API updated to make it more usable.
12+
* API re-branded as J.A.R.V.I.S. (Just A Reliable Vocal Interpreter & Synthesiser)
13+
814
* Version 1.06 (Tag v1.016)
915
* Added support for synthesiser for strings longer than 100 characters (Credits to @Skylion007)
1016
* Added support for synthesiser for multiple languages, accents, and voices. (Credits to @Skylion007)

CREDITS.markdown

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#Java-Speech API Credits
1+
#J.A.R.V.I.S. Speech API (Java-Speech API) Credits
22

33
##Credits
44
The following people/organizations have helped provide functionality for the API,
@@ -15,6 +15,8 @@ The following people/organizations have helped provide functionality for the API
1515
* Synthesiser
1616
* Allows for text to speech translation
1717
* Homepage: http://google.com
18-
19-
I would like to thank the above so much for your work, this wrapper/API could not have been
18+
* Princeton University
19+
* The implemented FFT algorithm is derived from one on the university's website.
20+
* Homepage: http://www.princeton.edu
21+
We would like to thank the above so much for your work, this wrapper/API could not have been
2022
created without it.

README.markdown

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#J.A.R.V.I.S. (Java-Speech-API)
22

3-
J.A.R.V.I.S. Speech API: Just A Real Vocal Interpreter & Synthesizer.
4-
This is a project for the Java Speech API. Interprets vocal inputs into text and synthesises MP3Data from text input.
5-
(Think Steven Hawkings) Even includes language auto-detection!
3+
J.A.R.V.I.S. Speech API: Just A Reliable Vocal Interpreter & Synthesizer.
4+
This is a project for the Java Speech API. The program interprets vocal inputs into text and synthesizes voices from text input.
5+
The program supports dozens of languages and even has the ability to auto-detect languages!
66

77
## Description
88
The J.A.R.V.I.S. Speech API is designed to be simple and efficient, using the speech engines created by Google

src/com/darkprograms/speech/microphone/Microphone.java

Lines changed: 43 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.darkprograms.speech.microphone;
22

33
import javax.sound.sampled.*;
4+
45
import java.io.File;
56

67
/**
@@ -91,6 +92,22 @@ public void setTargetDataLine(TargetDataLine targetDataLine) {
9192
public Microphone(AudioFileFormat.Type fileType) {
9293
setState(CaptureState.CLOSED);
9394
setFileType(fileType);
95+
initTargetDataLine();
96+
}
97+
98+
/**
99+
* Initializes the target data line.
100+
*/
101+
private void initTargetDataLine(){
102+
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, getAudioFormat());
103+
try {
104+
setTargetDataLine((TargetDataLine) AudioSystem.getLine(dataLineInfo));
105+
} catch (LineUnavailableException e) {
106+
// TODO Auto-generated catch block
107+
e.printStackTrace();
108+
return;
109+
}
110+
94111
}
95112

96113

@@ -135,84 +152,13 @@ public void captureAudioToFile(String audioFile) throws Exception {
135152

136153
}
137154

138-
/**
139-
* Gets the volume of the microphone input
140-
* Interval is 100ms so allow 100ms for this method to run in your code or specify smaller interval.
141-
* @return The volume of the microphone input or -1 if data-line is not available
142-
*/
143-
public int getAudioVolume(){
144-
return getAudioVolume(100);
145-
}
146-
147-
/**
148-
* Gets the volume of the microphone input
149-
* @param interval: The length of time you would like to calculate the volume over in milliseconds.
150-
* @return The volume of the microphone input or -1 if data-line is not available.
151-
*/
152-
public int getAudioVolume(int interval){
153-
return calculateAudioVolume(this.getNumOfBytes(interval/1000d));
154-
}
155-
156-
/**
157-
* Gets the volume of microphone input
158-
* @param numOfBytes The number of bytes you want for volume interpretation
159-
* @return The volume over the specified number of bytes or -1 if data-line is unavailable.
160-
*/
161-
private int calculateAudioVolume(int numOfBytes){
162-
if(getTargetDataLine()!=null){
163-
byte[] data = new byte[numOfBytes];
164-
this.getTargetDataLine().read(data, 0, numOfBytes);
165-
return calculateRMSLevel(data);
166-
}
167-
else{
168-
return -1;
169-
}
170-
}
171-
172-
/**
173-
* Calculates the volume of AudioData which may be buffered data from a data-line
174-
* @param audioData The byte[] you want to determine the volume of
175-
* @return the calculated volume of audioData
176-
*/
177-
private int calculateRMSLevel(byte[] audioData){
178-
long lSum = 0;
179-
for(int i=0; i<audioData.length; i++)
180-
lSum = lSum + audioData[i];
181-
182-
double dAvg = lSum / audioData.length;
183-
184-
double sumMeanSquare = 0d;
185-
for(int j=0; j<audioData.length; j++)
186-
sumMeanSquare = sumMeanSquare + Math.pow(audioData[j] - dAvg, 2d);
187-
188-
double averageMeanSquare = sumMeanSquare / audioData.length;
189-
return (int)(Math.pow(averageMeanSquare,0.5d) + 0.5);
190-
}
191-
192-
/**
193-
* Returns the number of bytes over interval for useful when figuring out how long to record.
194-
* @param seconds The length in seconds
195-
* @return the number of bytes the microphone will save.
196-
*/
197-
public int getNumOfBytes(int seconds){
198-
return getNumOfBytes((double)seconds);
199-
}
200-
201-
/**
202-
* Returns the number of bytes over interval for useful when figuring out how long to record.
203-
* @param seconds The length in seconds
204-
* @return the number of bytes the microphone will output over the specified time.
205-
*/
206-
public int getNumOfBytes(double seconds){
207-
return (int)(seconds*getAudioFormat().getSampleRate()*getAudioFormat().getFrameSize()+.5);
208-
}
209155

210156
/**
211157
* The audio format to save in
212158
*
213159
* @return Returns AudioFormat to be used later when capturing audio from microphone
214160
*/
215-
private AudioFormat getAudioFormat() {
161+
public AudioFormat getAudioFormat() {
216162
float sampleRate = 8000.0F;
217163
//8000,11025,16000,22050,44100
218164
int sampleSizeInBits = 16;
@@ -226,6 +172,28 @@ private AudioFormat getAudioFormat() {
226172
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
227173
}
228174

175+
/**
176+
* Opens the microphone, starting the targetDataLine.
177+
* If it's already open, it does nothing.
178+
*/
179+
public void open(){
180+
if(getTargetDataLine()==null){
181+
initTargetDataLine();
182+
}
183+
if(!getTargetDataLine().isOpen() && getState()==CaptureState.CLOSED){
184+
try {
185+
setState(CaptureState.PROCESSING_AUDIO);
186+
getTargetDataLine().open(getAudioFormat());
187+
getTargetDataLine().start();
188+
} catch (LineUnavailableException e) {
189+
// TODO Auto-generated catch block
190+
e.printStackTrace();
191+
return;
192+
}
193+
}
194+
195+
}
196+
229197
/**
230198
* Close the microphone capture, saving all processed audio to the specified file.<br>
231199
* If already closed, this does nothing
@@ -235,6 +203,7 @@ public void close() {
235203
} else {
236204
getTargetDataLine().stop();
237205
getTargetDataLine().close();
206+
setState(CaptureState.CLOSED);
238207
}
239208
}
240209

@@ -248,13 +217,11 @@ private class CaptureThread implements Runnable {
248217
*/
249218
public void run() {
250219
try {
251-
setState(CaptureState.PROCESSING_AUDIO);
252220
AudioFileFormat.Type fileType = getFileType();
253221
File audioFile = getAudioFile();
254-
getTargetDataLine().open(getAudioFormat());
255-
getTargetDataLine().start();
222+
open();
256223
AudioSystem.write(new AudioInputStream(getTargetDataLine()), fileType, audioFile);
257-
setState(CaptureState.CLOSED);
224+
//Will write to File until it's closed.
258225
} catch (Exception ex) {
259226
ex.printStackTrace();
260227
}

0 commit comments

Comments
 (0)