【问题标题】:Java: Mixing two WAV files without introducing noiseJava:混合两个 WAV 文件而不引入噪音
【发布时间】:2015-12-27 16:37:51
【问题描述】:

我正在尝试将 2 个 WAV 文件混合成一个 WAV 文件。这些文件将始终具有完全相同的持续时间并具有相同的格式(16 位、44.1 kHz、有符号、小端序、单声道)。使用 AudioSystem.getAudioInputSream 使用 ByteArrayOutputStream 将两个 WAV 放入字节数组,以确保我只是获取 PCM 数据而没有标题。

在其他几个线程的帮助下,我已经能够成功地组合阵列,但并非没有给信号引入大量噪声。这听起来绝对不像削波或失真,但为了安全起见,我已经尝试平均每对字节的总和,这只会让一切变得更安静、噪音和其他一切。

任何见解将不胜感激!我尝试了两种应该做同样事情的方法,并且似乎产生了相同的声音结果。

第一种更简单的方法:

private byte[] mixBuffers(byte[] bufferA, byte[] bufferB) {
    byte[] array = new byte[bufferA.length];
    for (int i=0; i<bufferA.length; i++) {
        array[i] = (byte) ((bufferA[i] + bufferB[i]));
    }
    return array;
}

还有第二种更具体的方法:

private byte[] mixBuffers(byte[] bufferA, byte[] bufferB) {
    byte[] array = new byte[bufferA.length];

    for (int i=0; i<bufferA.length; i+=2) {
        short buf1A = bufferA[i+1];
        short buf2A = bufferA[i];
        buf1A = (short) ((buf1A & 0xff) << 8);
        buf2A = (short) (buf2A & 0xff);

        short buf1B = bufferB[i+1];
        short buf2B = bufferB[i];
        buf1B = (short) ((buf1B & 0xff) << 8);
        buf2B = (short) (buf2B & 0xff);

        short buf1C = (short) (buf1A + buf1B);
        short buf2C = (short) (buf2A + buf2B);

        short res = (short) (buf1C | buf2C);

        array[i] = (byte) res;
        array[i+1] = (byte) (res >> 8);
    }

    return array;
}

如果有帮助,以下是我将文件放入字节数组的方法:

{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    AudioInputStream ais;
    ais = AudioSystem.getAudioInputStream(audioFile);
    int read;
    byte[] buffer = new byte[1024];
    while ((read = ais.read(buffer)) != -1) {
        baos.write(buffer, 0, read);
    }
    baos.flush();
    byte[] byteBufferA = baos.toByteArray();

    baos = new ByteArrayOutputStream();
    ais = AudioSystem.getAudioInputStream(audioFile2);
    buffer = new byte[1024];
    while ((read = ais.read(buffer)) != -1) {
        baos.write(buffer, 0, read);
    }
    baos.flush();
    byte[] byteBufferB = baos.toByteArray();

    byte[] byteBufferC = mixBuffers(byteBufferA, byteBufferB);
}

【问题讨论】:

  • 这些是 16 位/示例文件,对吧?所以每个样本占用两个字节,你试图分别混合每个字节。
  • 如果您使用第二种方法,但将| 更改为+,会发生什么情况?

标签: java audio merge wav


【解决方案1】:

这些文件包含 16 位样本 - 每个样本有两个字节长。但是,您的第一种方法尝试独立混合每个字节。结果就像通过添加每个数字(不带进位)来添加一个数字:165 + 248 -> 103。

您的第二种方法是使用按位或而不是加法。这就像通过取每个数字的最大值来添加两个数字:165 + 248 -> 268。

尝试使用第二种方法,但将 | 替换为 +

【讨论】:

  • 是的,成功了。我知道我的数学一定有错误。这就是我为《科学怪人》编写代码所得到的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
  • 2011-11-11
相关资源
最近更新 更多