Skip to content

Commit

Permalink
Re-implemented volume detection. Added fundamental frequency detection.
Browse files Browse the repository at this point in the history
Continued re-branding to J.A.R.V.I.S. Built framework for Voice Activity
Detection algorithm. Created Microphone Analyzer class. Updated
microphone class.
  • Loading branch information
Skylion007 committed Sep 14, 2013
1 parent c7c2591 commit 2fcd62c
Show file tree
Hide file tree
Showing 8 changed files with 535 additions and 83 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Changelog corresponds with a tagged and signed Git commit. This marks the chang
A tagged commit may or may not have a corresponding binary version available.
Format: Tag: `<Corresponding Tag>`

* Version 1.10 (Tag v1.100)
* Added new Microphone Analyzer class.
* Added volume and frequency detection and frame work for (Voice Activity Detection)
* Microphone API updated to make it more usable.
* API re-branded as J.A.R.V.I.S. (Just A Reliable Vocal Interpreter & Synthesiser)

* Version 1.06 (Tag v1.016)
* Added support for synthesiser for strings longer than 100 characters (Credits to @Skylion007)
* Added support for synthesiser for multiple languages, accents, and voices. (Credits to @Skylion007)
Expand Down
8 changes: 5 additions & 3 deletions CREDITS.markdown
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Java-Speech API Credits
#J.A.R.V.I.S. Speech API (Java-Speech API) Credits

##Credits
The following people/organizations have helped provide functionality for the API,
Expand All @@ -15,6 +15,8 @@ The following people/organizations have helped provide functionality for the API
* Synthesiser
* Allows for text to speech translation
* Homepage: http://google.com

I would like to thank the above so much for your work, this wrapper/API could not have been
* Princeton University
* The implemented FFT algorithm is derived from one on the university's website.
* Homepage: http://www.princeton.edu
We would like to thank the above so much for your work, this wrapper/API could not have been
created without it.
6 changes: 3 additions & 3 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#J.A.R.V.I.S. (Java-Speech-API)

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

## Description
The J.A.R.V.I.S. Speech API is designed to be simple and efficient, using the speech engines created by Google
Expand Down
119 changes: 43 additions & 76 deletions src/com/darkprograms/speech/microphone/Microphone.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.darkprograms.speech.microphone;

import javax.sound.sampled.*;

import java.io.File;

/**
Expand Down Expand Up @@ -91,6 +92,22 @@ public void setTargetDataLine(TargetDataLine targetDataLine) {
public Microphone(AudioFileFormat.Type fileType) {
setState(CaptureState.CLOSED);
setFileType(fileType);
initTargetDataLine();
}

/**
* Initializes the target data line.
*/
private void initTargetDataLine(){
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, getAudioFormat());
try {
setTargetDataLine((TargetDataLine) AudioSystem.getLine(dataLineInfo));
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}

}


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

}

/**
* Gets the volume of the microphone input
* Interval is 100ms so allow 100ms for this method to run in your code or specify smaller interval.
* @return The volume of the microphone input or -1 if data-line is not available
*/
public int getAudioVolume(){
return getAudioVolume(100);
}

/**
* Gets the volume of the microphone input
* @param interval: The length of time you would like to calculate the volume over in milliseconds.
* @return The volume of the microphone input or -1 if data-line is not available.
*/
public int getAudioVolume(int interval){
return calculateAudioVolume(this.getNumOfBytes(interval/1000d));
}

/**
* Gets the volume of microphone input
* @param numOfBytes The number of bytes you want for volume interpretation
* @return The volume over the specified number of bytes or -1 if data-line is unavailable.
*/
private int calculateAudioVolume(int numOfBytes){
if(getTargetDataLine()!=null){
byte[] data = new byte[numOfBytes];
this.getTargetDataLine().read(data, 0, numOfBytes);
return calculateRMSLevel(data);
}
else{
return -1;
}
}

/**
* Calculates the volume of AudioData which may be buffered data from a data-line
* @param audioData The byte[] you want to determine the volume of
* @return the calculated volume of audioData
*/
private int calculateRMSLevel(byte[] audioData){
long lSum = 0;
for(int i=0; i<audioData.length; i++)
lSum = lSum + audioData[i];

double dAvg = lSum / audioData.length;

double sumMeanSquare = 0d;
for(int j=0; j<audioData.length; j++)
sumMeanSquare = sumMeanSquare + Math.pow(audioData[j] - dAvg, 2d);

double averageMeanSquare = sumMeanSquare / audioData.length;
return (int)(Math.pow(averageMeanSquare,0.5d) + 0.5);
}

/**
* Returns the number of bytes over interval for useful when figuring out how long to record.
* @param seconds The length in seconds
* @return the number of bytes the microphone will save.
*/
public int getNumOfBytes(int seconds){
return getNumOfBytes((double)seconds);
}

/**
* Returns the number of bytes over interval for useful when figuring out how long to record.
* @param seconds The length in seconds
* @return the number of bytes the microphone will output over the specified time.
*/
public int getNumOfBytes(double seconds){
return (int)(seconds*getAudioFormat().getSampleRate()*getAudioFormat().getFrameSize()+.5);
}

/**
* The audio format to save in
*
* @return Returns AudioFormat to be used later when capturing audio from microphone
*/
private AudioFormat getAudioFormat() {
public AudioFormat getAudioFormat() {
float sampleRate = 8000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
Expand All @@ -226,6 +172,28 @@ private AudioFormat getAudioFormat() {
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}

/**
* Opens the microphone, starting the targetDataLine.
* If it's already open, it does nothing.
*/
public void open(){
if(getTargetDataLine()==null){
initTargetDataLine();
}
if(!getTargetDataLine().isOpen() && getState()==CaptureState.CLOSED){
try {
setState(CaptureState.PROCESSING_AUDIO);
getTargetDataLine().open(getAudioFormat());
getTargetDataLine().start();
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
}

}

/**
* Close the microphone capture, saving all processed audio to the specified file.<br>
* If already closed, this does nothing
Expand All @@ -235,6 +203,7 @@ public void close() {
} else {
getTargetDataLine().stop();
getTargetDataLine().close();
setState(CaptureState.CLOSED);
}
}

Expand All @@ -248,13 +217,11 @@ private class CaptureThread implements Runnable {
*/
public void run() {
try {
setState(CaptureState.PROCESSING_AUDIO);
AudioFileFormat.Type fileType = getFileType();
File audioFile = getAudioFile();
getTargetDataLine().open(getAudioFormat());
getTargetDataLine().start();
open();
AudioSystem.write(new AudioInputStream(getTargetDataLine()), fileType, audioFile);
setState(CaptureState.CLOSED);
//Will write to File until it's closed.
} catch (Exception ex) {
ex.printStackTrace();
}
Expand Down
Loading

0 comments on commit 2fcd62c

Please sign in to comment.