Как изменить объем файла WAV побайтно в Java?

Я могу прочитать файл 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());
        }       
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
457
1

Ответы 1

Байт java находится в диапазоне от -128 до 127, в то время как байт, используемый в формате wav pcm, находится в диапазоне от 0 до 255. Это, скорее всего, причина, по которой вы меняете свои данные pcm на случайные / шумные значения.

буфер [я] = (байт) (масштаб * (буфер [я] <0? 256+ (целое) буфер [я]: буфер [я]));

Другие вопросы по теме