我正在尝试通过 Java 访问麦克风的级别。我不需要记录任何东西,我只想知道声级的相对比例。
这可能是实时的吗?
如果不可能,也许这可以工作:当电平超过某个值时开始录制,当电平下降到某个电平以下一定时间时停止录制四分之一秒的位并读取它的音量,如果它低于阈值停止录制。
提前致谢
我正在尝试通过 Java 访问麦克风的级别。我不需要记录任何东西,我只想知道声级的相对比例。
这可能是实时的吗?
如果不可能,也许这可以工作:当电平超过某个值时开始录制,当电平下降到某个电平以下一定时间时停止录制四分之一秒的位并读取它的音量,如果它低于阈值停止录制。
提前致谢
这方面的文章很不错。帮了我很多。
据我所知,这使用了@Nick 的回答中谈到的均方根
基本上:
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);
}
和用法:
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);
}
您可以通过 Sound API 访问麦克风,但它不会为您提供简单的响度级别。您只需要捕获数据并自行决定它的响度。
http://download.oracle.com/javase/tutorial/sound/capturing.html
录音意味着保存数据,但在这里您可以在确定其响度后丢弃数据。
均方根法是计算一段波数据幅度的好方法。
在回答您的评论时,是的,您将捕获一小段数据(可能只有几毫秒)并计算其幅度。根据您需要更新的频率定期重复此操作。如果您想跟踪以前的响度并比较它们,这取决于您——此时它只是比较数字。您可以使用最近响度的平均值来计算房间的环境响度,这样您就可以检测到噪音的突然增加。
我不知道打开和关闭音频捕获有多少开销,但最好始终保持TargetDataLine
打开状态,并在需要时计算响度。当线路打开时,您确实需要继续调用 read() ,否则应用程序将挂起等待您读取数据。