最近、phased.TimeDelayBeamformer からそのコードを取得し、それを最も基本的なマイク配列アルゴリズムに変換して学習しました。
https://www.mathworks.com/help/phased/ref/phased.timedelaybeamformer-system-object.htmlを参照してください。
1. 遅延蓄積とビームフォーマー
間違いなく最も基本的なマイク配列アルゴリズムです。
この方法は非常に単純で、各チャネルのデータを適切な位置にシフトし、調整係数を累積するだけです。
しかし、問題は何ですか?
一般に、収集されたマイク データはデジタル化され、サンプリング ポイントの間隔は 1/fs になります.シフトする時間がちょうど N サンプル ポイントである場合、対応するサンプリング2 つのオプションを考慮する必要があります。
1.時間領域で補間を行い、周囲のサンプリングポイントに従って、必要な翻訳のデータを補間および補間します
2. 周波数ドメイン操作に変換
周波数領域の遅延については、信号の位相を調整するだけで、
特定の操作: fft を介して周波数領域に移動し、位相変換を実行してから、時間領域に戻ります。
次に、特定の matlab コード
すべてをクリアし、
すべての
clc を閉じます。
% phased.TimeDelayBeamformer
fs = 8000;
% 入射角、またはアレイが指したい場所、回転角および位相角。ここで、位相角は xy 平面から z 軸への角度である
incidentAngle = [-50;30];
%Array 取得データ
ロード rx
%マイクユニット数
M=11;
%Array トポロジ、その他の任意の配列形状も利用可能
ArrayPos = [0 0 0 0 0 0 0 0 0 0;
-0.2 -0.16 -0.12 -0.08 -0.04 0 0.04 0.08 0.12 0.16 0.2;
0 0 0 0 0 0 0 0 0 0];
% 回転角とピッチ角、
アザン=インシデントアングル(1,:);
イーグル=インシデントアングル(2,:);
% ガイド ベクトル
incidentdir = [-cosd(elang).*cosd(azang);...
-cosd(elang).*sind(azang);...
-sind(elang)];
% 遅延時間
遅延 = ArrayPos.'*incidentdir/c;
pSampleRate = fs;
% x_steered = delayseq(rx,-delay,pSampleRate);
% 初期化
x=rx;
inputLength = size(x,1);
たまたま「アンチ」の動き、アレイ自体のキャリブレーションであるため、遅延は一貫しています
dt = -delay;
dt = dt *fs;
% 整数遅延部分 (サンプル ポイント)
delayInt = round(dt); % サンプル内の整数遅延
% 非整数遅延部分 (サンプル ポイント、単位は 1)
delayFrac = dt - delayInt;
% 最大遅延ポイントを見つけます。遅延によりデータ長が拡張されます
maxLength = inputLength+max(0, max(delayInt)); % 最大シーケンス長
% 上限
maxLengthLimit = maxLength を定義します。
%適切な fft サイズを見つける
nfftLimit = 2^nextpow2(2*inputLength);
出力 = ゼロ (maxLengthLimit、長さ (dt));
% colI=1:length(dt) の遅延チャネルごとに、遅延操作を実行します。
endIdx = inputLength+delayInt(colI); % if (endIdx <= 0) ||
遅延または範囲外の場合は操作なし
(endIdx > 2*inputLength)
続行します。
終了
tmpx = x(:,colI);
%If there is a requirements for fractional delay points, convert to frequency domain
if delayFrac(colI)
nfft = 2^nextpow2(inputLength + max(0, delayInt(colI)));
assert(nfft <= nfftLimit);
binStart = floor (nfft/2);
% FFT ビンは [-pi, pi] に属していることに注意してください.
fftBin = 2*pi*ifftshift(((0:nfft-1)-binStart).')/nfft;
if isscalar(tmpx ) && nfft==1
tmpxd = tmpx;
else % コア コード
tmpxd = fft(tmpx,nfft);
tmpxd = ifft(tmpxd(:).*exp(-1i*dt(colI)*fftBin));
end
%below転送遅延の最初の数点は不要であると考え、ゼロに設定します
% 負の時間軸 (t<0) からデータを持ってくる (移動する) ことはできず、すべて 0 であると考えることができます
if delayInt(colI) >= 0
orgStart = delayInt(colI) + 1;
newStart = delayInt(colI) + 1;
そうでなければ
orgStart = 1;
newStart = 1;
orgEnd
= endIdx を終了します。
if isreal(x)
output(newStart:endIdx,colI) = real(tmpxd(orgStart:orgEnd));
他の
出力 (newStart:endIdx、colI) = tmpxd (orgStart:orgEnd);
end
else
% 整数サンプリングのシフト
if delayInt(colI) >= 0
orgStart = 1;
newStart = delayInt(colI) + 1;
それ以外
orgStart = 1-delayInt(colI);
newStart = 1; orgEnd = inputLength を
終了します。 output(newStart:endIdx,colI) = tmpx(orgStart:orgEnd); 終了終了
% 出力は入力と同じ長さになります
x_steered = output(1:inputLength, :);
w = ones(M,1)/M; % 正規化された重み
y = x_steered*conj(w); % 合計のために乗算されます
plot(t,rx(:,6),'r:',t,y)
xlabel('時間 (秒)')
ylabel('振幅')
legend('オリジナル','ビーム形成')