私がやったことについて少し混乱しています..私の知る限り、Java、特にDataOutputStreamはビッグエンディアンで値を書き込みます。
小さな信号発生器を作成していて、ファイルをリトル エンディアンで保存する必要があります。これまでのところ問題ありません。バイトを交換するだけです。
writeShort()
「上位バイトを最初に書き込む」とも言います。
たとえば、10 進数の '2' は通常、次のように格納されます。
00 02 (big endian)
02 00 (little endian) is what I need.
だから私はバイトを交換します:
public static short swap (short value)
{
int b1 = value & 0xff;
int b2 = (value >> 8) & 0xff;
return (short) (b1 << 8 | b2 << 0);
}
短く書いてください:
dos.writeShort(swap(x[t]));
16 進エディターは、次の形式でファイルを表示します。02 00
生成されたオーディオ ファイルを開こうとすると、何も聞こえません。(大胆な生データのインポートとサンプルレートなどの設定はすべて正しい)。
00 02
ビッグエンディアンのファイルを取得して、バイトスワッピングを削除しました。
audacity を再度開いたところ、同じ構成でトーンが聞こえました。間違いなくリトルエンディアンを設定しました!
ファイルを Windows にコピーし (Mac で作業しています)、Cool Edit 2000 でファイルを開き、16khz、16 ビット符号なし pcm、リトル エンディアン (16 ビット LSB、MSB) を選択しました。ビッグエンディアンを何も選択せずに、再びトーンが聞こえました。
私の失敗はどこですか?これは私が説明したように機能しないはずなので、何かが私を混乱させます..
トーンの生成:
// x(t) = A*cos (2*pi * f * t + phi)
//
if(null != dos)
{
double sampPeriod = 1.0/16000;
short x[] = new short[16000]; // 16k samples for 1 second
for(int t=0; t < x.length; t++)
{
double time = t * sampPeriod;
x[t] = (short) (amplitude * Math.sin(2.0*Math.PI*frequenz*time+phase));
}
for(int t=0; t < x.length; t++)
{
try {
dos.writeShort(x[t]);
} catch (IOException e) {
e.printStackTrace();
}
}
}
編集済み 2:16pm 02/04/13: 私の理解では何かが失敗であると想定して読んでいたところ、ウィキペディアで次の写真を見つけました。
次の投稿の問題の答えを参照してください。