AudioSystem.write (входной файл, AudioFileFormat.Type.WAVE, файл) создает поврежденный файл WAVE. Неверная длина RIFF - PullRequest
0 голосов
/ 05 марта 2020

Этот код создает файлы WAV, которые не работают во многих приложениях.

Когда я проверяю приложение RIFFVIEWER, оно жалуется на неверную длину RIFF. BWFMetaEdit утверждает, что файл урезан. Некоторые толерантные приложения, такие как Audacity, будут воспроизводить их.

Я что-то здесь не так делаю или java глючит звук?

// The essence data is PCM formatted, so convert it to a WAVE file
File extractPCM(WAVEPCMDescriptor descriptor, EssenceData data, String name) {
    try {
        Stream stream = data.getEssenceStream();
        URI uri = stream.getStreamURI();
        int hashCode = uri.hashCode();

        File file = new File(mediaDir, 
                name + "_" +
                String.format("%08X", hashCode)
                + ".wav"
                );

        if (file.exists()) {
            return file;
        }

        mediaDir.mkdir(); // Ensure exists

        log("Copying essence data stream"); 

        stream.setPosition(0);
        ByteBuffer buff = stream.read((int)stream.getLength());
        stream.close();
        buff.flip();

        AudioFormat format = new AudioFormat(
                Encoding.PCM_SIGNED,
                (float)descriptor.getSampleRate().doubleValue(),
                (int)descriptor.getQuantizationBits(),
                (int)descriptor.getChannelCount(),
                (int)descriptor.getBlockAlign(),
                (float)descriptor.getAverageBytesPerSecond(),
                false
                );
        AudioInputStream input = new AudioInputStream(
                new ByteArrayInputStream(buff.array()), format, buff.capacity());           
        AudioSystem.write(input,
                   AudioFileFormat.Type.WAVE, file);        
        log("Extracted file " + file);
        return file;
    } catch (EndOfDataException | IllegalArgumentException | IOException e1) {
        log(e1);
        return null;
    }
}

1 Ответ

0 голосов
/ 05 марта 2020

Похоже, что я указывал длину в байтах, а не в примерах кадров.

Когда я делю размер буфера на размер кадра, приложения, не допускающие переноса, перестают жаловаться.

        AudioInputStream input = new AudioInputStream(
                new ByteArrayInputStream(buff.array()), format, buff.capacity() / format.getFrameSize());           
...