ノイズシェーピングのない基本的なディザリング
ノイズシェーピングのない基本的なディザ量子化は次のように機能します。
図1.基本的なディザー量子化システムの図。ノイズは、最大絶対値が1のゼロ平均三角ディザです。丸めは最も近い整数になります。残差は出力と入力の差であり、分析のためにのみ計算されます。
三角形のディザは、結果として生じる残差誤差の分散を3倍に増やします(から11214
独立した追加の残差誤差があると、システムのより単純なモデルになります。
図2.基本的なディザ量子化の近似。残留誤差はホワイトノイズです。
近似モデルでは、出力は単純に入力に加えて、独立したホワイトノイズ残差です。
ノイズシェーピングによるディザリング
Mathematicaを上手に読むことができないので、あなたのシステムの代わりに、Lipshitz らのシステムを分析します。「最小限の可聴ノイズシェーピング」J. Audio Eng。Soc。、Vol.39、No.11、1991年11月:
図3. Lipshitz et al。1991年のシステム図(彼らの図1から適応)。フィルター(テキストで斜体)には1サンプルの遅延が含まれているため、エラーフィードバックフィルターとして使用できます。ノイズは三角ディザです。
残留誤差が信号Aの現在および過去の値から独立している場合、システムはより単純になります。
図4. Lipshitzらの近似モデル。1991年システム。フィルターは図3と同じで、1サンプルの遅延が含まれています。フィードバックフィルターとしては使用されなくなりました。残留誤差はホワイトノイズです。
この回答では、より簡単に分析できる近似モデルを使用します(図4)。オリジナルのLipshitz ら。1991年のシステムであるFilterには、IIRフィルターと有限インパルス応答(FIR)フィルターの両方をカバーする一般的な無限インパルス応答(IIR)フィルター形式があります。以下では、FilterがFIRフィルターであると想定します。これは、システムで使用している係数での係数の実験に基づいていると私は考えています。フィルターの伝達関数は次のとおりです。
HFilter(z)=−b1z−1−b2z−2−b3z−3−…
z−1
H(z)=1−HFilter(z)=1+b1z−1+b2z−2+b3z−3+….
…,−b3,−b2,−b11,b1,b2,b3,…b0=1horzcat
以下のオクターブスクリプトで)、最後にリストが逆になります(flip
)。
pkg load signal
b = [-0.16, 0.51, -0.74, 0.52, -0.04, -0.25, 0.22, -0.11, -0.02, 0.31, -0.56, 0.45, -0.13, 0.04, -0.14, 0.12, -0.06, 0.19, -0.22, -0.15, 0.4, 0.01, -0.41, -0.1, 0.84, -0.42, -0.81, 0.91, 0.75, -2.37, 2.29];
c = flip(horzcat(-b, 1));
freqz(c)
zplane(c)
スクリプトは、フルノイズシェーピングフィルターの振幅周波数応答とゼロ位置をプロットします。
図5.完全なノイズシェーピングフィルターの振幅周波数応答。
×∘
フィルター係数を見つける問題は、先行係数1の最小位相フィルターを設計する問題として再定式化できると思います。そのようなフィルターの周波数応答に固有の制限がある場合、これらの制限は同等の制限に移されますそのようなフィルターを使用するノイズシェーピングで。
全極設計から最小位相FIRへの変換
異なるが多くの点で同等のフィルターの設計手順は、Stojanović らに記載されています。、「超球多項式に基づく全極再帰的デジタルフィルター設計」、Radioengineering、vol 23、no 3、2014年9月。IIR全極ローパスフィルターの伝達関数の分母係数を計算します。それらは、常に1の分母係数を持ち、すべての極が安定したIIRフィルターの要件である単位円の内側にあります。これらの係数を最小位相FIRノイズシェーピングフィルターの係数として使用すると、ローパスIIRフィルターと比較して反転したハイパス周波数応答が得られます(伝達関数の分母係数が分子係数になります)。あなたの記法では{-0.0076120, 0.0960380, -0.5454670, 1.8298040, -3.9884220, 5.8308660, -5.6495140, 3.3816780}
、その記事からの係数の1つのセットはです。これは、仕様に厳密ではありませんが、ノイズシェーピングアプリケーションでテストできます。
図7.Stojanovićらの係数を使用したFIRフィルターの振幅周波数応答。2014。
図8.Stojanovićらの係数を使用したFIRフィルターの極-零点プロット。2014。
全極伝達関数は次のとおりです。
H(z)=11+a1z−1+a2z−2+a3z−3+…
ab
全極フィルターを設計し、それを最小位相FIRフィルターに変換するには、アナログプロトタイプフィルターから開始して、双一次変換を使用して極と零点をデジタル領域にマッピングするIIRフィルター設計法を使用できません。 。それは、cheby1
、cheby2
、およびellip
オクターブとPythonのscipyのダウンロードに。これらの方法は、z平面の原点から離れたところにゼロを与えるため、フィルターは必要な全極型ではありません。
理論的な質問への回答
サンプリング周波数の4分の1を超える周波数でノイズがどれほどあるかを気にしない場合は、Lipshitz ら。1991年はあなたの質問に直接対処します:
帯域の一部でゼロになるこのような重み関数の場合、図1の回路から得られる重み付きノイズ電力削減に理論上の制限はありません。これは、たとえば、耳は、たとえば20 kHzとナイキスト周波数の間の感度がゼロであり、この事実を反映するように重み関数を選択します。
彼らの図1は、現在のFIR構造とは非常に異なる、極と零点の両方を備えた一般的なIIRフィルター構造を持つノイズシェーパーを示していますが、FIRフィルターのインパルス応答は任意の安定したIIRフィルターのインパルス応答に任意に近づけます。
フィルター設計のためのオクターブスクリプト
ν=0dip
pkg load signal
N = 14; #number of taps including leading tap with coefficient 1
att = 97.5; #dB attenuation of Dolph-Chebyshev window, must be positive
dip = 2; #spectrum lift-up multiplier, must be above 1
c = chebwin(N, att);
c = conv(c, c);
c /= sum(c);
c(N) += dip*10^(-att/10);
r = roots(c);
j = (abs(r(:)) <= 1);
r = r(j);
c = real(poly(r));
c .*= (-1).^(0:(N-1)); #if this complains, then root finding has probably failed
freqz(c)
zplane(c)
printf('%f, ', flip(-c(2:end))), printf('\n'); #tobalt's format
係数はドルフチェビシェフウィンドウで始まり、それを畳み込んで伝達関数のゼロを2倍にし、周波数応答を「持ち上げる」数値を追加します(中央のタップがゼロ時間であると見なします)。それはどこでも正であり、ゼロを見つけ、単位円の外側にあるゼロを削除し、ゼロを係数に変換し(からの先頭の係数poly
は常に1です)、2番目の係数の符号を反転してフィルターをハイパスにします。スクリプトの結果(古いがほぼ同等のバージョン)は有望に見えます。
図9.上記のスクリプト(以前のバージョンとほぼ同等のバージョン)からのフィルターの振幅周波数応答。
図10.上記のスクリプト(古いがほぼ同等のバージョン)のフィルターの極-零点プロット。
上記のスクリプトの(古いがほぼ同等のバージョン)からの係数:表記{0.357662, -2.588396, 9.931419, -26.205448, 52.450624, -83.531276, 108.508775, -116.272581, 102.875781, -74.473956, 43.140431, -19.131434, 5.923468}
。数値が大きいため、数値の問題が発生する可能性があります。
ノイズシェーピングのオクターブ実装
最後に、Octaveでノイズシェーピングを独自に実装しましたが、あなたのように問題が発生することはありません。コメントでの議論に基づいて、あなたの実装における制限は、ノイズスペクトルが、高周波数スペクトルを低周波数に波及させる「ウィンドウなし」として知られる長方形のウィンドウを使用して評価されたことであったと思います。
pkg load signal
N = length(c);
M = 16384; #signal length
input = zeros(M, 1);#sin(0.01*(1:M))*127;
er = zeros(M, 1);
output = zeros(M, 1);
for i = 1:M
A = input(i) + er(i);
output(i) = round(A + rand() - rand());
for j = 2:N
if (i + j - 1 <= M)
er(i + j - 1) += (output(i) - A)*c(j);
endif
endfor
endfor
pwelch(output, max(nuttallwin(1024), 0), 'semilogy');
図11.一定のゼロ入力信号に対するノイズシェーピングの上記のOctave実装からの量子化ノイズスペクトル分析。横軸:正規化された周波数。黒:ノイズシェーピングなし(c = [1];
)、赤:元のフィルター、青:セクション「フィルター設計のオクターブスクリプト」のフィルター。
図12.一定のゼロ入力信号に対するノイズシェーピングの上記のOctave実装からの時間領域出力。横軸:サンプル番号、縦軸:サンプル値。赤:元のフィルター、青:セクション「フィルター設計のオクターブスクリプト」のフィルター。
より極端なノイズシェーピングフィルター(青)は、ゼロ入力でも非常に大きな量子化出力サンプル値をもたらします。