1

javax.sound.sampled.SourceDataLine を使用して、バイト配列に保存された信号を再生しようとしています。単純な正弦波の再生を開始しようとしています。一部の周波数 (1000Hz、400Hz など) ではうまく機能しますが、他の周波数 (1001、440) ではほとんどピッチレスのバズしか聞こえません。サンプリング レートは、エイリアシングを防止するのに十分な高さです (16Khz)。何か案は ?乾杯。

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.SourceDataLine;

public class Player
{

    private static float SAMPLE_RATE = 16000;

    public static void main(String[] args)
    {
        playSound();
    }


    private static void playSound()
    {
        try
        {
            final AudioFormat audioFormat = new AudioFormat( SAMPLE_RATE, 8, 1, true,  true );
            SourceDataLine line = AudioSystem.getSourceDataLine( audioFormat );
            line.open( audioFormat );
            line.start();
        /* the last argument here is the frequency in Hz. works well with 1000, but with 1001 I get week and pitchless clicking sound sound*/
            byte[] signal = smpSin( 1, 1, 1000 );
            play( line, signal );
            line.drain();
            line.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }


    private static byte[] smpSin(double lenInSec, double amp, double signalFreq)
    {
        int len = (int)(SAMPLE_RATE * lenInSec);
        byte[] out = new byte[len];
        for (int i = 0; i < out.length; i++)
        {
            out[i] = (byte)(amp * Math.sin( ((2.0 * Math.PI * signalFreq) *  ((double)i)) / SAMPLE_RATE ));
        }
        return out;
    }

    private static void play(SourceDataLine line, byte[] array)
    {
        line.write( array, 0, array.length );
    }

}

4

1 に答える 1

0

バッファ呼び出し間の正弦波の位相を保存していません。したがって、フェーズの不連続は、 play() が呼び出されるレートでバズを引き起こします。バズがない周波数は、たまたまデフォルトの開始フェーズで終了します。

于 2013-02-16T01:34:33.163 に答える