私はオーディオの操作に非常に慣れていないため、何日も解決策を探していましたが、何も見つかりませんでした。
だから私はこれで .wav ファイルのバイト配列を取得します (出典: Java で Wav ファイルをバイト配列に変換)
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(WAV_FILE));
int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
out.flush();
byte[] audioBytes = out.toByteArray();
次に、バイト配列を float 配列に変換し、-1.0 から 1.0 に正規化します。(ソース: wav オーディオ形式のバイト配列を浮動小数点に変換)
ShortBuffer sbuf =
ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
short[] audioShorts = new short[sbuf.capacity()];
sbuf.get(audioShorts);
float[] audioFloats = new float[audioShorts.length];
for (int i = 0; i < audioShorts.length; i++) {
audioFloats[i] = ((float)audioShorts[i])/0x8000;
}
return audioFloats;
後でこれを線画に変換し、java.swing を使用して波形を出力します。
class Panel2 extends JPanel {
float[] audioFloats;
Dimension d;
public Panel2(Dimension d, float[] audioFloats) {
// set a preferred size for the custom panel.
this.d = d;
setPreferredSize(d);
this.audioFloats = audioFloats;
}
@Override
public void paint(Graphics g) {
//super.paintComponent(g);
super.paint(g);
//shift by 45 because first 44 bytes used for header
for (int i = 45; i<audioFloats.length; i++){
Graphics2D g2 = (Graphics2D) g;
float inc = (i-45)*((float)d.width)/((float)(audioFloats.length-45-1));
Line2D lin = new Line2D.Float(inc, d.height/2, inc, (audioFloats[i]*d.height+d.height/2));
g2.draw(lin);
}
}
}
波形は 16 ビットの wav ファイルでのみ正しく表示されます (goldwave でクロス チェックしたところ、私の波形とその波形の両方が 16 ビットで同様に見えます)。
8 ビットの .wav ファイルでこれを行うにはどうすればよいですか?
これは宿題なので、私の唯一の制限は、wav ファイルをバイトごとに読み取ることです。
また、wav ファイルは PCM でコーディングされており、最初の 44 バイトがヘッダーとして予約されていることも知っています。