Как читать / записывать WAV-файлы высокого разрешения (24-битные, 8-канальные) в Java? - PullRequest
2 голосов
/ 23 июня 2011

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

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

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

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

<code>
dB$ soxi orig.wav
soxi WARN wav: wave header missing FmtExt chunk</p>

<p>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 AudioSystem (как на Mac, так и на Windows).Я также пытался использовать класс WavFile Эндрю Гринстеда , но это также не удается (WavFileException: код сжатия 3 не поддерживается).Одним из обходных путей является преобразование звука в 16 бит с использованием sox (с флагом -b 16), но это неоптимально, так как увеличивает минимальный уровень шума.

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

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

* ОБНОВЛЕНИЕ *

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

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

Ответы [ 2 ]

2 голосов
/ 20 сентября 2012

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

A libsndfile java wrapper теперь существует, что должно помочь с такими проблемами чтения / записи / преобразования аудио, как эта. Оболочка (сгенерированная 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, включая скомпилированную «пригодную для использования» версию для JDK1.7 для Windows7, существует здесь:

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

1 голос
/ 23 июня 2011

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

...