2

プログラムが音量で認識できるように、特定の音の平均的な音量を見つけようとしているため、マイク入力の最大音量を見つけようとしています。RMS の計算方法は、この Web サイト ( https://forums.oracle.com/forums/thread.jspa?threadID=1270831 ) からのものです。すべてがどのように機能するかを理解しようとしています...

問題は、どんなにノイズを出しても、RMS レベルが毎回 0 として出力されることです。そのため、targetDataLine の設定が完全​​に間違っていて、音声がキャプチャされていないか、どこかで何か間違ったことをしたかのどちらかです。

これが私がこれまでに持っているものです:

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));
    }
}
}

タイマーコード:

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++;
    }
}
}
4

1 に答える 1

0

line.start()after を追加するとうまくいきましたline.open()

于 2013-04-08T06:29:56.303 に答える