2

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++;
    }
}
}
leppie
  • 115,091
  • 17
  • 196
  • 297
Riptyde4
  • 5,134
  • 8
  • 30
  • 57

1 Answers1

0

It worked when i added in line.start() after line.open().

hyde
  • 60,639
  • 21
  • 115
  • 176
Riptyde4
  • 5,134
  • 8
  • 30
  • 57
  • @user2247192 It's ok to answer your own question, but you should write it in proper answer format, like you'd answer question of somebody else. Leave out stuff like "silly mistake!" and tell where that line should be added (after `line.open()`?), and preferably also why it is needed (well, in this case it may be obvious). Then this is a good answer, and you can come back and accept it later. – hyde Apr 08 '13 at 07:05
  • Will keep in mind... I added "line.start()" just below line.open() – Riptyde4 Apr 08 '13 at 21:34