Как читать / писать с высоким разрешением (24-бит, 8 каналов).wav файлы на Java?


Я пытаюсь написать Java-приложение, которое управляет высоким разрешением .файлы wav. У меня возникли проблемы с импортом аудиоданных, то есть преобразованием .wav-файл в массив двойников.

Когда я использую стандартный подход, возникает исключение.

AudioFileFormat as = AudioSystem.getAudioFileFormat(new File("orig.wav"));
-->
javax.sound.sampled.UnsupportedAudioFileException: file is not a supported file type

Вот информация о формате файла в соответствии с soxi:


dB$ soxi orig.wav
soxi WARN wav: wave header missing FmtExt chunk

Input File : 'orig.wav' Channels : 8 Sample Rate : 96000 Precision : 24-bit Duration : 00:00:03.16 = 303526 samples ~ 237.13 CDDA sectors File Size : 9.71M Bit Rate : 24.6M Sample Encoding: 32-bit Floating Point PCM

Может ли кто-нибудь предложить самый простой способ для получения этого аудио в Java?

Я попробовал использовать несколько техник. Как было сказано выше, я экспериментировал с аудиосистемой Java (как на Mac, так и на Windows). Я также пытался использовать класс WavFile Эндрю Гринстеда , но это также не удается (исключение WavFileException: код сжатия 3 не поддерживается). Одним из обходных путей является преобразование звука в 16 бит с помощью sox (с флагом-b 16), но это неоптимально, так как увеличивает уровень шума.

Кстати, я заметил, что файл может быть прочитан libsndfile. Является ли мой лучший выбор, чтобы написать оболочку jni вокруг libsndfile, или может вы предлагаете что-нибудь более быстрое?

Обратите внимание, что мне не нужно воспроизводить звук, мне просто нужно проанализировать его, манипулировать им, а затем записать его на новый .WAV-файл.

* обновление *

Я решил эту проблему, модифицировав класс WavFile Эндрю Гринстеда . Его исходная версия считывала только файлы, закодированные как целочисленные значения ("код формата 1"); Мои файлы были закодированы как поплавки ("код формата 3"), и это было причиной проблемы.

Я отправлю сообщение модифицированная версия кода Гринстеда, когда у меня будет возможность. А пока, если кто-нибудь захочет, пришлите мне сообщение.

2 2

2 ответа:

Вы можете прочитать данные wav в себе, это на самом деле не так сложно сделать. Просто найдите информацию о формате файла WAV.

Очень поздний ответ, но другие могут извлечь из этого пользу.

В libsndfile выступает обертку Java существует сейчас, которые должны помочь с аудио чтение/запись/проблемы преобразования такой. Оболочка (генерируемая swig) соответствует API libsndfile, поэтому структура немного отличается от типичного стиля Java, но полностью применима.

В вашем конкретном случае использование будет выглядеть примерно так:

String filePath = "path/to/some/audio_8_channels.wav";

// open the sound file
SF_INFO sndInfo = new SF_INFO();
SWIGTYPE_p_SNDFILE_tag sndFile = libsndfile.sf_open(filePath, libsndfile.SFM_READ, sndInfo);

// create a buffer array large enough to hold all channels (double per channel) of all frames
int arraySize = sndInfo.getFrames() * sndInfo.getChannels();
CArrayDouble darray = new CArrayDouble(arraySize);

// read every frame (includes all channels) into the buffer array
long count = libsndfile.sf_readf_double(sndFile, darray.cast(), sndInfo.getFrames());

// iterate over the doubles that make up the audio
for (int i=0; i < arraySize; i++) {
    // every 8 doubles is a frame..
    double d = darray.getitem(i);
}

Проект google code, включающий скомпилированную "полезную" версию для JDK1. 7 на Windows7 существует здесь:

Http://code.google.com/p/libsndfile-java/