【问题标题】:Microphone level in JavaJava中的麦克风级别
【发布时间】:2010-10-10 08:27:18
【问题描述】:

我正在尝试通过 Java 访问麦克风的级别。 我不需要录制任何东西,我只是想知道声级的相对比例。

这可能是实时的吗?

如果不可能,也许这可行: 当电平超过一定值时开始记录,当电平下降到一定电平以下一定时间时停止 录制四分之一秒的比特并读取它的音量,如果低于阈值则停止录制。

提前致谢

【问题讨论】:

    标签: java audio microphone


    【解决方案1】:

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

    这方面的文章很不错。帮了我很多忙。

    据我所知,这使用了@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);
    }
    

    【讨论】:

    • 已更新。虽然我不确定你的要求是否值得反对。
    • 已删除反对票。如果你解释了这段代码是如何工作的以及它为什么这样做,我可能会赞成。
    • @durron597 我希望我能告诉你。很确定它使用了另一个答案中谈到的均方根
    【解决方案2】:

    您可以通过 Sound API 访问麦克风,但它不会为您提供简单的响度级别。您只需要捕获数据并自行决定它的响度。

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

    录制意味着保存数据,但在这里您可以在确定其响度后丢弃数据。

    root mean squared方法是计算一段波数据幅度的好方法。

    在回答您的评论时,是的,您将捕获一小段数据(可能只有几毫秒)并计算其幅度。根据您需要更新的频率定期重复此操作。如果您想跟踪以前的响度并比较它们,这取决于您——此时它只是比较数字。您可以使用最近响度的平均值来计算房间的环境响度,这样您就可以检测到噪音的突然增加。

    我不知道打开和关闭音频捕获有多少开销,但您最好让TargetDataLine 一直打开,并在需要时计算响度。当线路打开时,您确实需要继续对其调用 read() ,否则应用程序将挂起等待您读取数据。

    【讨论】:

    • 那么你会建议记录微小的比特并计算它们与之前的比特相比的响度吗?
    • javax.sound 如果您调用 line.read 太快/太频繁,则性能不佳。为了实现“最小的 CPU 影响”(1% ~ 4%),我建议使用大小为 read byte[] 的缓冲区,以便每 250 毫秒调用一次 read 的频率不超过一次。对于 16 位 16kHz 单声道音频,这意味着使用大小为 8000 的 byte[]。您可以更快地阅读,但您将开始为 CPU 周期显着增加而付费。
    猜你喜欢
    • 2015-04-23
    • 1970-01-01
    • 2014-11-23
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多