在Java中将double []写为WAV文件

时间:2015-12-18 20:29:20

标签: java audio bytearray wav audio-processing

我尝试使用此方法将double []数组保存为.WAV文件:

public static void saveWav(String filename, double[] samples) {

    // assumes 44,100 samples per second
    // use 16-bit audio, 2 channels, signed PCM, little Endian
    AudioFormat format = new AudioFormat(SAMPLE_RATE * 2, 16, 1, true, false);
    byte[] data = new byte[2 * samples.length];
    for (int i = 0; i < samples.length; i++) {
        int temp = (short) (samples[i] * MAX_16_BIT);
        data[2*i + 0] = (byte) temp;
        data[2*i + 1] = (byte) (temp >> 8);
    }

    // now save the file
    try {
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        AudioInputStream ais = new AudioInputStream(bais, format, samples.length);
        if (filename.endsWith(".wav") || filename.endsWith(".WAV")) {
            AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File(filename));
        }
        else if (filename.endsWith(".au") || filename.endsWith(".AU")) {
            AudioSystem.write(ais, AudioFileFormat.Type.AU, new File(filename));
        }
        else {
            throw new RuntimeException("File format not supported: " + filename);
        }
    }
    catch (IOException e) {
        System.out.println(e);
        System.exit(1);
    }
}

但是当我重新加载我保存的文件时,对于每首歌[i],双倍值与原始值不同。我使用这种方法来读取WAV文件:

public static double[] read(String filename) {
    byte[] data = readByte(filename);
    int N = data.length;
    double[] d = new double[N/2];
    for (int i = 0; i < N/2; i++) {
        d[i] = ((short) (((data[2*i+1] & 0xFF) << 8) + (data[2*i] & 0xFF))) / ((double) MAX_16_BIT);
    }
    return d;
}
private static byte[] readByte(String filename) {
    byte[] data = null;
    AudioInputStream ais = null;
    try {

        // try to read from file
        File file = new File(filename);
        if (file.exists()) {
            ais = AudioSystem.getAudioInputStream(file);
            data = new byte[ais.available()];
            ais.read(data);
        }

        // try to read from URL
        else {
            URL url = StdAudio.class.getResource(filename);
            ais = AudioSystem.getAudioInputStream(url);
            data = new byte[ais.available()];
            ais.read(data);
        }
    }
    catch (IOException e) {
        System.out.println(e.getMessage());
        throw new RuntimeException("Could not read " + filename);
    }

    catch (UnsupportedAudioFileException e) {
        System.out.println(e.getMessage());
        throw new RuntimeException(filename + " in unsupported audio format");
    }

    return data;
}

我需要double []数组才能拥有完全相同的值,而事实并非如此。 当我听到这首歌时,我无法区分,但我仍然需要那些原始值。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:0)

双精度版需要64位存储空间并且具有很高的精度。您不能在往返中丢弃48位数据,并期望得到完全相同的值。它类似于从高分辨率图像开始,将其转换为缩略图,然后期望您可以神奇地恢复原始高分辨率图像。在现实世界中,人耳无法区分这两者。在计算和信号处理程序期间,较高分辨率 是有用的,以减少计算错误的累积。话虽这么说,如果你想存储64位,你需要使用.WAV以外的东西。你最接近的是32位。