Java:从 8 位 wav 文件中检索字节数组并将其规范化为 -1.0 到 1.0

标签 java audio arrays wav waveform

请耐心等待,因为我是处理音频的新手,我已经谷歌搜索了好几天的解决方案,但没有找到任何解决方案。

所以我用这个检索 .wav 文件的字节数组(来源:Wav file convert to byte array in java)

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。 (来源:Convert wav audio format byte array to floating point)

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 个字节作为标题

最佳答案

您需要修改这部分代码:

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;
}

您根本不需要ByteBuffer——您已经有了字节数组。所以只需将其转换为 float :

float[] audioFloats = new float[audioBytes.length];
for (int i = 0; i < audioBytes.length; i++) {
    audioFloats[i] = ((float)audioBytes[i])/0x80;
}

关于Java:从 8 位 wav 文件中检索字节数组并将其规范化为 -1.0 到 1.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12827489/

相关文章:

java - 如何连接到在 Docker 中运行的远程 Cassandra 实例以使用 Java 检索数据?

java - 为什么 .jar 文件中的 .classes 文件的名称看起来很奇怪?

c# - Asio,c#,同时从麦克风和线路输入录制声音

ios - 在 iPhone 上播放歌曲时通过麦克风检测噪音

java - 我如何映射 Java 中的数组?

java - 编写 JUnit 测试以检查 SharedPreferences 数据

java - 如何将一定数量的字节读入缓冲区?

audio - 调试NAudio MP3的阅读区别?

Javascript 根据定义的值对对象属性进行排序

arrays - 从数组平均值计算数组元素平均差的有效方法