Microphone level in Java

主宰稳场 提交于 2019-12-01 19:39:22

You can access microphones through the Sound API, but it won't give you a simple loudness level. You'll just have to capture the data and make your own decision about how loud it is.

http://download.oracle.com/javase/tutorial/sound/capturing.html

Recording implies saving the data, but here you can discard the data once you've finished determining its loudness.

The root mean squared method is a good way of calculating the amplitude of a section of wave data.

In answer to your comment, yes, you'd capture a short length of data (maybe just a few milliseconds worth) and calculate the amplitude of that. Repeat this periodically depending on how often you need updates. If you want to keep track of previous loudnesses and compare them, that's up to you - at this point it's just comparing numbers. You might use the average of recent loudnesses to calculate the ambient loudness of the room, so you can detect sudden increases in noise.

I don't know how much overhead there is in turning audio capture on and off, but you may be better off keeping the TargetDataLine open all the time, and just calculating the loudness when you need it. While the line is open you do need to keep calling read() on it though, otherwise the application will hang waiting for you to read data.

http://www.technogumbo.com/tutorials/Java-Microphone-Selection-And-Level-Monitoring/Java-Microphone-Selection-And-Level-Monitoring.php

Pretty good article on this. Helped me out a lot.

From what i can tell, this uses the root mean squared stuff talked about in @Nick's answer

Basically:

public 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 += Math.pow(audioData[j] - dAvg, 2d);

    double averageMeanSquare = sumMeanSquare / audioData.length;

    return (int)(Math.pow(averageMeanSquare,0.5d) + 0.5);
}

and the usage:

int level = 0;
byte tempBuffer[] = new byte[6000];
stopCapture = false;
try {
    while (!stopCapture) {
        if (targetRecordLine.read(tempBuffer, 0, tempBuffer.length) > 0) {
            level = calculateRMSLevel(tempBuffer);
        }
    }
    targetRecordLine.close();
} catch (Exception e) {
    System.out.println(e);
    System.exit(0);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!