I'm trying to find the max volume of the microphone input because I'm trying to find how loud a certain sound is on average so my program can recognize it by volume. The RMS calculating method is from this website(https://forums.oracle.com/forums/thread.jspa?threadID=1270831), I'm just trying to figure out how everything works...
The problem is that no matter how much noise I make the RMS level is output as 0 every time! So I've either set my targetDataLine up completely wrong and it's not capturing audio...or I've done something wrong somewhere else.
Here is what I have so far:
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
public class MicrophoneTesting {
public MicrophoneTesting() {
// TODO Auto-generated constructor stub
}
protected static int calculateRMSLevel(byte[] audioData)
{ // audioData might be buffered data read from a data line
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);
}
public static void main(String[] args){
// Open a TargetDataLine for getting microphone input & sound level
TargetDataLine line = null;
AudioFormat format = new AudioFormat(8000, 0, 1, true, true);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info)) {
System.out.println("The line is not supported.");
}
// Obtain and open the line.
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException ex) {
System.out.println("The TargetDataLine is Unavailable.");
}
Timer t = new Timer(); // I used a timer here, code is below
while(t.seconds < 2){
byte[] bytes = new byte[line.getBufferSize() / 5];
line.read(bytes, 0, bytes.length);
System.out.println("RMS Level: " + calculateRMSLevel(bytes));
}
}
}
Timer Code:
public class Timer implements Runnable{
int seconds;
Thread t;
public Timer() {
this.seconds = 0;
t = new Thread(this, "Clap Timer");
t.start(); // Start the thread
}
@Override
public void run() {
// TODO Auto-generated method stub
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {
System.out.println("Waiting interupted.");
}
seconds++;
}
}
}
It worked when i added in line.start()
after line.open()
.