Я хочу построить график формы волны из аудиофайла .wav. Я нашел на этом сайте функцию, которая извлекает байт из .wav:

ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = null;
try {
    in = new BufferedInputStream(new FileInputStream(args[0]));
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

int read;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0)
{
    out.write(buff, 0, read);
}
out.flush();

byte[] audioBytes = out.toByteArray();
for (int i=0; i<audioBytes.length; i++) {
    System.out.println(audioBytes[i]);
}

Затем я использую точки, которые я нашел в консоли (System.out ...), чтобы построить мою звуковую волну в «Microsoft Excel», и результат:

форма волны в Excel НО эта форма волны моего .wav файла сильно отличается от формы волны, которая отображает (т.е.) открытый исходный код "Praat":

форма волны на Praat Где я не прав? Не те байты файла, которые я должен взять?

0
Re De Pasquale 25 Ноя 2016 в 21:31

2 ответа

Лучший ответ

В массиве «результат» есть точка, которую вы бы нашли.

public double[] extract(File inputFile) {
        AudioInputStream in = null;
        try {
            in = AudioSystem.getAudioInputStream(inputFile);
        } catch (Exception e) {
            System.out.println("Cannot read audio file");
            return new double[0];
        }
        AudioFormat format = in.getFormat();
        byte[] audioBytes = readBytes(in);

        int[] result = null;
        if (format.getSampleSizeInBits() == 16) {
            int samplesLength = audioBytes.length / 2;
            result = new int[samplesLength];
            if (format.isBigEndian()) {
                for (int i = 0; i < samplesLength; ++i) {
                    byte MSB = audioBytes[i * 2];
                    byte LSB = audioBytes[i * 2 + 1];
                    result[i] = MSB << 8 | (255 & LSB);
                }
            } else {
                for (int i = 0; i < samplesLength; i += 2) {
                    byte LSB = audioBytes[i * 2];
                    byte MSB = audioBytes[i * 2 + 1];
                    result[i / 2] = MSB << 8 | (255 & LSB);
                }
            }
        } else {
            int samplesLength = audioBytes.length;
            result = new int[samplesLength];
            if (format.getEncoding().toString().startsWith("PCM_SIGN")) {
                for (int i = 0; i < samplesLength; ++i) {
                    result[i] = audioBytes[i];
                }
            } else {
                for (int i = 0; i < samplesLength; ++i) {
                    result[i] = audioBytes[i] - 128;
                }
            }
        }

        return result;
    }
2
Margherita 28 Ноя 2016 в 12:03

Кажется, вы предполагаете, что каждый байт в файле представляет амплитуду волны в следующий момент времени. Это (вообще говоря) не случай. Помимо того факта, что файл начинается с заголовка, каждая выборка состоит из нескольких каналов, и внутри каждого канала выборка может занимать меньше (например, 4 бита или более (например, 16 бит)), чем только один байт. См., Например, это объяснение: http://www.topherlee.com/software/ pcm-tut-wavformat.html.

0
Peter 25 Ноя 2016 в 19:10