Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

java soundについて

double Fs = 44100;
double F0 = 1000;
byte[] sin_wave = new byte[(int)Fs*2];
AudioFormat format = new 
AudioFormat((float)Fs,16,1,true,false);
for(int i = 0; i < sin_wave.length;i++){
            sin_wave[i] = (byte)(110*Math.sin(2 * Math.PI * F0 * i / 
Fs));
        }
InputStream bytefile = new ByteArrayInputStream(sin_wave);
            File file = new File("sin.wav");
            AudioInputStream inputstreem = new 
AudioInputStream(bytefile,format,wave.length);
            
AudioSystem.write(inputstreem,AudioFileFormat.Type.WAVE,file);

このようなプログラムを作ったのですが、これを実行して出力された
wavファイルをSonicVisualiserを用いてスペクトルを見ると基本周波
数が出てこず、2倍の周波数が出てくるのですがどうしてでしょう
か?

3

回答

94196

閲覧

3件の回答

評価

0

AudioFormatのサンプルビット数が16で符号付き、Littele 
endianを指定されてますので、サンプルあたり2バイトで
出力しないといけませんがコードでは1サンプル1バイト
で生成しているのが原因と思います。
AudioFormatのサンプルビット数を8にしてやれば期待どお
りの結果になると思います。

評価

0

すいません、少し私の頭では理解できませんでした。
このコードで1サンプルあたり2バイトで出力しようとするならばどうす
ればよろしいでしょうか?

評価

0

new AudioFormat((float)Fs,16,1,true,false);

ここの最後のfalseがリトルエンディアンを意味してま
す。2バイトのサンプルデータを下位バイト、上位バイ
トの順番で並べてくださいということです。
forループだけ書き換えるとすると(再生時間が2秒から1
秒に縮まりますが)以下の感じです。

for (int i = 0; i < sin_wave.length; i += 2) {
  // iはバイト位置。siに何番目のサンプルかを計算
  int si = i / 2;
  double phase = 2 * Math.PI * F0 * si / Fs;
  // 最大レベルを110*256とする。
  short s = (short)(110*256*Math.sin(phase);
  // 下位バイト、上位バイトの順に格納
  sin_wave[i] = (byte)s;
  sin_wave[i + 1] = (byte)(s >> 8);
}

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。