1

ある周波数から別の周波数に直線的に遷移する Java サウンド アプリケーションを作成しています。

一定の周波数 (最初と最後の周波数が同じ) を入力すると、正しい周波数が再生されます。

ただし、2 つの周波数の差が 0 より大きい場合は常に、再生される周波数は正しい値で開始されますが、2 倍のレートで増加し、2 倍の差で終了します。(たとえば、500 と 1000 を入力します。周波数は 500 で始まり、1500 で終わります)。

最初は単に周波数を誤ってインクリメントしているだけだと思っていましたが、周波数値を印刷すると、意図した値が印刷されます (たとえば、500 と 1000 を入力すると、印刷出力は 500 で始まり 1000 で終わります)。

出力音を録音し、周波数スペクトログラムでその周波数を見て、可聴周波数の値を確認しました。これが私のコードの関連する簡略化された部分です:

import java.lang.Math;
import javax.sound.sampled.*;

public class MainSpeech {

    public static void main(String[] args) throws LineUnavailableException {

        double freq; //  frequency in Hz
        int volume = 30;
        int time = 1; // in seconds
        float sampleRate = 8000.0f; // in Hz
        int numSamples = (int)(sampleRate * time); // # of samples within given time
        byte stream[] = new byte[(int)(sampleRate*1)]; // waveform values

        freq = 700;
        for (int i = 0; i < numSamples; i++) {
            freq += 0.1;
            stream[i] = (byte) (Math.sin(2*Math.PI*i*freq/sampleRate)*volume);
        }

        AudioFormat af = new AudioFormat(sampleRate, 8, 1, true, false);
        SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
        sdl.open(af);
        sdl.start();
        sdl.write(stream, 0, stream.length); // play sound
        sdl.drain();
        sdl.close();
    }
}

この単純化されたスニペットでは、周波数は 700 から始まり、0.1 ずつ 8,000 倍に増加し、1500 の周波数で終了します。これは印刷出力に正しく表示されます。ただし、可聴周波数は実際には 2300 で終了します。

4

1 に答える 1

3

ここにエラーがあります:

2*Math.PI*i*freq/sampleRate

ここでは i または freq を使用しますが、両方を使用することはできません。あなたが持っているのは、周波数の線形変化ではなく、二次変化です。以下で説明するように動作させたい場合は、使用します

2*Math.PI*freq/sampleRate
于 2013-01-09T10:42:31.457 に答える