20

.WAV または .AIFF ファイルを読み取るプログラムがあり、ファイルのオーディオが浮動小数点のサンプル値としてエンコードされているとします。適切な形式の (浮動小数点ベースの) .WAV または .AIFF ファイルには [-1.0f,+1.0f] の範囲のサンプル値のみが含まれるとプログラムが想定するのは正しいですか? WAV や AIFF の仕様には、この点に対処するものは何も見つかりませんでした。

それが有効な仮定でない場合、ファイル内のオーディオの完全なダイナミック レンジが意図されていたものをどのように知ることができますか? (ファイル全体を読み取って、ファイルの実際の最小サンプル値と最大サンプル値が何であるかを調べることができますが、これには 2 つの問題があります。(1) ファイルが非常に大きい場合は、処理が遅くて費用がかかります。(2 ) 情報が失われます。ファイルの作成者がファイルにある程度の「ヘッドルーム」を持たせて、最大音量で dbFS で再生しないようにした場合、私のプログラムはそれを検出できません)

4

3 に答える 3

12

あなたが述べているように、公開されているドキュメントでは、浮動小数点に使用される範囲についての詳細は説明されていません。ただし、過去数年間の業界での実践と、浮動小数点ファイルとして存在する実際のデータから、これは有効な仮定であると言えます。

これには実用的な理由と、カラー、オーディオ、3D などの高精度データの正規化の非常に一般的な範囲があります。

範囲が [-1, 1] の範囲内にある主な理由は、ターゲット ビット範囲へのスケーリング/変換が高速かつ簡単であるためです。ターゲット範囲を指定して乗算するだけです。

例えば:

16ビットで再生したい場合は、次のようにします(疑似、整数の結果に丸められた符号付きを想定):

sample = in < 0 ? in * 0x8000 : in * 0x7fff;

または 24 ビット:

sample = in < 0 ? in * 0x800000 : in * 0x7fffff;

または 8 ビット:

sample = in < 0 ? in * 0x80 : in * 0x7f;

元の入力値を調整する必要はありません。-1 と 1 は、ターゲット (1x = x) に変換されるときの最小/最大値を表します。

[-0.5, 0.5] の範囲を使用した場合、最初に (またはある時点で) 入力値を調整する必要があるため、たとえば 16 ビットへの変換には追加の手順が必要になります。余分なステップだけでなく、計算が重い浮動小数点ドメインで作業する場合もあります (最近の浮動小数点処理は非常に高速であるため、後者はおそらく少し古い理由ですが、いずれにせよ)。

in = in * 2;
sample = in < 0 ? in * 0x8000 : in * 0x7fff;

事前にスケーリングされた範囲 ([-32768, 32767] など) ではなく [-1, 1] の範囲に保つことで、精度のためにより多くのビットを使用することもできます (IEEE 754 表現を使用)。

2017/07更新

テスト

コメントの質問に基づいて、1 秒の正弦波で 3 つのファイルを使用してテストを行い、トリプルチェックすることにしました。

A) クリップされた浮動小数点
B) 最大 0dB の浮動小数点、および
C) クリップされた整数 (A から変換)

次に、チャンクおよびサイズ フィールドの後に始まる正の値 <= -1.0 および >= 1.0 をスキャンしてdata、最小/最大値がオーディオ データで見つかった実際の値を反映するようにします。

結果は、範囲が実際に [-1, 1] を含む範囲内にあることを確認します(クリッピングしていない場合(非真 <= 0 dB))。

しかし、それは別の側面も明らかにしました -

浮動小数点として保存された WAV ファイルでは、0 dB の範囲を超える値を使用できますこれは、通常はクリップする値の範囲が実際には [-1, 1] を超えていることを意味します。

これについての説明は、浮動小数点形式は、将来の処理 (ゲイン ステージング、圧縮、制限など) で (損失なしで) 値を戻すことができるダイナミック レンジの損失がほとんどないため、プロダクション セットアップでの中間使用を目的としている可能性があります。最終的かつ正常な -0.2 ~ 0 dB の範囲内に十分に収まる。したがって、値はそのまま保持されます。

結論は

浮動小数点を使用する WAV ファイルは、クリッピングされていない場合 (<= 0dB)、[-1, 1] の値を保存しますが、クリッピングされたと見なされる値は許可します

ただし、整数形式に変換すると、これらの値、整数形式のビット範囲でスケーリングされた同等の [-1, 1] 範囲にクリップされます。これは、各幅が保持できる範囲が限られているため、当然のことです。

そのため、プレーヤー/DAW/編集ソフトウェアは、データを正規化するか、単に [-1, 1] にクリップして戻すことにより、クリップされた浮動小数点値を処理します。

ファイル1
注: すべてのファイルの最大値は、サンプル データから直接測定されます。

ファイル2
注: クリップされた浮動小数点 (+6 dB) として生成され、符号付き 16 ビットに変換されて浮動小数点に戻されます

ファイル3
注: +6 dB にクリッピング

ファイル4
注: +12 dB にクリップ

簡単なテスト スクリプトとファイルは、ここにあります。

于 2015-04-30T01:00:40.927 に答える
3

質問が特定のプログラミング言語またはフレームワークに固有のものではないことは知っていますが、どの仕様にも答えが見つかりませんでした。確かに言えることは、.NET フレームワーク用に作成されたアプリケーションで .WAV ファイルを処理するために広く使用されている NAudio ライブラリは、float サンプルが [-1.0,+1.0] の範囲にあると想定しているということです。

ソースコードからの該当するコードは次のとおりです。

namespace NAudio.Wave
{
    public class WaveFileReader : WaveStream
    {
        ...
        /// <summary>
        /// Attempts to read the next sample or group of samples as floating point normalised into the range -1.0f to 1.0f
        /// </summary>
        /// <returns>An array of samples, 1 for mono, 2 for stereo etc. Null indicates end of file reached
        /// </returns>
        public float[] ReadNextSampleFrame()
        {
            ...
            var sampleFrame = new float[waveFormat.Channels];
            int bytesToRead = waveFormat.Channels*(waveFormat.BitsPerSample/8);
            ...
            for (int channel = 0; channel < waveFormat.Channels; channel++)
            {
                if (waveFormat.BitsPerSample == 16)
                ...
                else if (waveFormat.BitsPerSample == 32 && waveFormat.Encoding == WaveFormatEncoding.IeeeFloat)
                {
                    sampleFrame[channel] = BitConverter.ToSingle(raw, offset);
                    offset += 4;
                }
                ...
            }
            return sampleFrame;
        }
        ...
    }
}

したがって、浮動小数点数を変換せずに配列にコピーし、指定された範囲内にあることを約束します。

于 2015-04-28T19:31:55.030 に答える
1

はい。

オーディオ ファイル形式は、オーディオ データの 1 つ以上のチャネルのキャリアとして機能します。そのオーディオ データは、特定のオーディオ コーディング フォーマットを使用してエンコードされています。各コーディング形式は、エンコーダ アルゴリズムを使用します。アルゴリズムは重要な部分です。ファイルとコーディング形式の価値を手放すことができます。

AIFF と WAV はどちらもPulse-Code Modulation (PCM)またはその子孫を使用します。(このOracle docを確認すると、PCM ベースのアルゴリズムの「Encoding/CompressionType」リストの下にあることがわかります。) PCM は、一定の時間間隔でオーディオ正弦波をサンプリングし、最も近いデジタル表現を選択することによって機能します。ここで重要なのが「正弦波」です。

正弦波は -1 と 1 の間で変調するため、すべての PCM 派生エンコーディングはこの原則に基づいて動作します。mu-law の実装を考えてみましょう。その定義式では、範囲が -1 から 1 である必要があることに注意してください。

私は手短にこれに答えるために手を振っています。時には私たちは子供たちに嘘をつく必要があります。浮動小数点と固定小数点、エラーに対するビット深度の重要性などについて詳しく知りたい場合は、DSP に関する優れた本を参照してください。開始するには:

于 2015-04-30T02:51:18.913 に答える