如何在Java中逐字节更改WAV文件的容量?

时间:2018-12-20 23:23:14

标签: java audio wav

我可以在以下功能中读取WAV文件(每个样本8位)并将其复制到另一个文件中。我想使用给定的scale参数来处理源文件的整体容量,该参数的范围为[0,1]。我的幼稚方法是使用scale将多个字节转换为字节。我所有的文件都很吵。如何逐字节调整音量?

public static final int BUFFER_SIZE = 10000;
public static final int WAV_HEADER_SIZE = 44;

public void changeVolume(File source, File destination, float scale) {
    RandomAccessFile fileIn = null;
    RandomAccessFile fileOut = null;

    byte[] header = new byte[WAV_HEADER_SIZE];
    byte[] buffer = new byte[BUFFER_SIZE];

    try {
        fileIn = new RandomAccessFile(source, "r");
        fileOut = new RandomAccessFile(destination, "rw");

        // copy the header of source to destination file
        int numBytes = fileIn.read(header); 
        fileOut.write(header, 0, numBytes);

        // read & write audio samples in blocks of size BUFFER_SIZE
        int seekDistance = 0;
        int bytesToRead = BUFFER_SIZE;
        long totalBytesRead = 0;

        while(totalBytesRead < fileIn.length()) {
            if (seekDistance + BUFFER_SIZE <= fileIn.length()) {
                bytesToRead = BUFFER_SIZE;
            } else {
                // read remaining bytes                   
                bytesToRead = (int) (fileIn.length() - totalBytesRead);
            }

            fileIn.seek(seekDistance);
            int numBytesRead = fileIn.read(buffer, 0, bytesToRead);
            totalBytesRead += numBytesRead;

            for (int i = 0; i < numBytesRead - 1; i++) {
                // WHAT TO DO HERE?
                buffer[i] = (byte) (scale * ((int) buffer[i]));
            }

            fileOut.write(buffer, 0, numBytesRead);
            seekDistance += numBytesRead;
        }

        fileOut.setLength(fileIn.length());         
    } catch (FileNotFoundException e) {
        System.err.println("File could not be found" + e.getMessage());
    } catch (IOException e) {
        System.err.println("IOException: " + e.getMessage());
    } finally {
        try {
            fileIn.close();
            fileOut.close();
        } catch (IOException e) {
            System.err.println("IOException: " + e.getMessage());
        }       
    }
}

1 个答案:

答案 0 :(得分:0)

java字节的范围是-128到127,而wav pcm格式中使用的字节的范围是0到255。这很可能就是您将pcm数据更改为随机/嘈杂值的原因。

buffer [i] =(字节)(比例*(buffer [i] <0?256+(int)buffer [i]:buffer [i]));