0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AudioTrackで正弦波の単音を再生させるためのデータ型選択

Posted at

はじめに

AudioTrackを使って生成した正弦波をリアルタイムで再生するアプリを作成。再生できるようになったが再生したい周波数と違う周波数の音(雑音)も再生されていたため、修正。

正弦波生成

周波数を引数として正弦波を生成し、byte型の値の範囲-128~127で正規化。

getSound
/**
 * 正弦波生成
 * @param frequency 音の周波数
 * @return 音声データ
 */
public byte[] getSound(double frequency) {
    frequency = frequency / 2;
    // byteバッファを作成
    byte[] buffer = new byte[bufferSize];
    double max = 0;
    double[] t = new double[buffer.length];
    double hz = frequency / this.sampleRate;
    for(int i = 0; i < buffer.length; i++) {
        t[i] = Math.sin(i * 2 * Math.PI * hz);
        if(t[i] > max) {
            max = t[i];
        }
    }
    double trans = 127 / max;
    for(int i = 0; i < buffer.length; i++) {
        buffer[i] = (byte)Math.round(t[i]*trans);
    }
    return buffer;
}

結果

20kHzの音を再生した。これ自体は非可聴音だが、可聴音も再生されてしまっている。この可聴音は雑音なので除去したい。

修正したこと

音声データをbyte型ではなくshort型にしただけ。short型の値の範囲-32768~32767で正規化することで正弦波の分解能が高くなった。

getSoundShort
/**
 * 正弦波生成
 * @param frequency 音の周波数
 * @return 音声データ
 */
public short[] getSoundShort(double frequency) {
    double[] value = new double[sampleRate];
    double max = 0.0;
    for(int i = 0; i < sampleRate; i++) {
        value[i] = Math.sin(2.0 * Math.PI * frequency * i / sampleRate);
        if(value[i] > max) {
            max = value[i];
        }
    }
    short[] buffer = toShort(value, max);

    return buffer;
}

/**
 * double型をshort型に変換(-32768~32767で正規化)
 * @param val double型音声データ
 * @param max 最大値
 * @return short型音声データ
 */
public short[] toShort(double[] val, double max) {
    double trans = 32767 / max;
    short[] buf = new short[sampleRate];
    for(int i = 0; i < sampleRate; i++) {
        buf[i] = (short)Math.round(val[i] * trans);
    }
    return buf;
}

修正結果

同様に20kHzを再生したところ、可聴域の雑音がなくなり、20kHzの単音になった。

おそらく

詳しいことはわからないが、byte型の-128~127の範囲だと分解能が低く、誤差が生じて雑音が発生したと思われる。

AudioTrackの書込処理(writeメソッド)にはbyte型、short型、float型を用いることができるが、float型は値の範囲等が複雑なため試していない。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?