2

高解像度の .wav ファイルを操作する Java アプリケーションを作成しようとしています。オーディオ データのインポート、つまり .wav ファイルを double の配列に変換するのに問題があります。

標準的なアプローチを使用すると、例外がスローされます。

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 AudioSystem を (Mac と Windows の両方で) 試しました。Andrew Greensted のWavFile クラスも使用してみましたが、これも失敗します (WavFileException: Compression Code 3 はサポートされていません)。1 つの回避策は、(-b 16 フラグを使用して) sox を使用してオーディオを 16 ビットに変換することですが、ノイズ フロアが増加するため、これは最適ではありません。

ちなみに、このファイルは libsndfile で読み取ることができることに気付きました。libsndfile の周りに jni ラッパーを作成するのが私の最善の策ですか、それとももっと早い方法を提案できますか?

オーディオを再生する必要はないことに注意してください。オーディオを分析して操作し、新しい .wav ファイルに書き出すだけで済みます。

* アップデート *

Andrew Greensted のWavFile クラスを変更することで、この問題を解決しました。彼の元のバージョンは、整数値 (「フォーマット コード 1」) としてエンコードされたファイルのみを読み取りました。私のファイルはフロート (「フォーマット コード 3」) としてエンコードされており、それが問題の原因でした。

機会があれば、Greensted のコードの修正版を投稿します。とりあえず欲しい人いたらメッセください。

4

2 に答える 2

2

非常に遅い返信ですが、他の人はこれから恩恵を受けるかもしれません.

libsndfile Java ラッパーが存在するようになりました。これは、このようなオーディオの読み取り/書き込み/変換の問題に役立つはずです。ラッパー (swig によって生成される) は libsndfile API に忠実であるため、構造は典型的な 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);
}

Windows7 上の JDK1.7 用にコンパイルされた「使用可能な」バージョンを含む Google コード プロジェクトは、次の場所にあります。

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

于 2012-09-19T21:23:42.353 に答える
1

自分でwavデータを読み取ることができますが、実際にはそれほど難しくありません。WAV ファイル形式の情報を検索するだけです。

于 2011-06-23T17:52:06.740 に答える