一、聲波波束求和

1. 聲波傳播和求和

下圖,一個簡化的麥克風陣列波束形成設置。 從揚聲器傳播來的聲波,將在不同的時刻到達麥克風,此屬性是陣列空間濾波功能的本質。 模擬陣列的空間濾波性能時,有必要計算麥克風信號如何針對不同的信號源位置或角度求和。

根據揚聲器和麥克風的位置,可以首先計算波束傳播的距離,然後對於給定的聲速,波束離開揚聲器併到達每個麥克風所花費的時間。

上圖顯示了一個100Hz的“源波”,代表信號離開揚聲器。 該圖還顯示了“麥克風1處的信號”和“麥克風2處的信號”。 可以清楚地看到源信號傳播到麥克風所引起的延遲。 最後顯示了陣列的“輸出”(兩個麥克風信號的總和)。 由於傳播時間的差異,輸出的幅度爲1.825,而不是幅度爲源波的兩倍(有兩個麥克風)。

注意:未考慮信號從揚聲器傳播到麥克風時的衰減。

2.用相量計算組合麥克風信號幅度

相量(Phasors )是一種簡單的計算組合的麥克風信號(陣列的輸出)幅度方法。 下圖顯示瞭如何計算兩個信號之間的相位差。 波的一個週期對應於360°,給定的週期爲10ms,2.305ms的延遲對應於82.975°的相移。

兩種麥克風信號的相位計算如下所示:

相量圖提供了一種表示正弦波的幅度和相位方法,還提供相加波形的圖形方法。 三個相量圖表示兩個麥克風信號和陣列的輸出。 相量長度對應于波的幅度,角度對應於相位,被繪製爲復軸上的向量。 通過將向量相加,可以很容易地實現相量求和,所得向量代表相加波。

對向量求和的最簡單方法是將其從極座標(振幅和相位)轉換爲笛卡爾座標(實數和虛數)。 然後,可以根據兩個麥克風矢量的總和輕鬆計算出輸出矢量。

最後,計算波幅總和,使用畢達哥拉斯定理計算總和向量的長度,如下所示

3.簡化形式

綜合上述階段,可以得出以下公式:

根據波的頻率,行間距離和聲速來計算波的複數表示。 要輸出一組波,只需計算併疊加每個波的實部和虛部,然後使用畢達哥拉斯定理計算最終振幅。

以下c代碼執行上述兩個麥克風設置的波加和計算:

File: waves.c
#include <stdio.h>
#include <math.h>

int main(void)
{
   double phase, distance, delay;

   double freq = 100.0;            // Hz   
   double speedSound = 343.0;      // m/s

   // Microphone 1
   distance = sqrt(0.25*0.25 + 0.75*0.75);
   delay = distance / speedSound;
   double re1 = cos(2.0 * M_PI * freq * delay);
   double im1 = sin(2.0 * M_PI * freq * delay);
   phase = 180 * atan2(im1, re1) / M_PI;
   printf("Mic1 - Distance:%.4f, Delay:%.4f, Phase:%.3f, [%.3f %.3f]\n", distance, delay*1000, phase, re1, im1);

   // Microphone 2
   distance = sqrt(1.00*1.00 + 0.75*0.75);
   delay = distance / speedSound;
   double re2 = cos(2.0 * M_PI * freq * delay);
   double im2 = sin(2.0 * M_PI * freq * delay);
   phase = 180 * atan2(im2, re2) / M_PI;
   printf("Mic2 - Distance:%.4f, Delay:%.4f, Phase:%.3f, [%.3f %.3f]\n", distance, delay*1000, phase, re2, im2);

   // Output
   double re = re1 + re2;
   double im = im1 + im2;
   double amp = sqrt(re*re + im*im);
   phase = 180 * atan2(im, re) / M_PI;
   printf("Output - Amplitude:%.3f, Phase:%.3f, [%.3f %.3f]\n", amp, phase, re, im);

   return 0;
}

可以使用以下命令來編譯和執行代碼:

gcc -Wall -lm -o waves waves.c
./waves

輸出顯示麥克風的極性和笛卡爾形式以及輸出信號。

Mic1 - Distance:0.7906, Delay:2.3049, Phase:82.975, [0.122 0.992]
Mic2 - Distance:1.2500, Delay:3.6443, Phase:131.195, [-0.659 0.752]
Output - Amplitude:1.826, Phase:107.085, [-0.536 1.745]

4. 歐拉公式表示

可以使用歐拉公式表示波的複數。 下面的等式顯示了歐拉公式,以及如何調整它來表示頻率爲f的波動。 

對於延遲爲d的波,方程式:

5. 線性陣列示例

以線性陣列爲例, 每個陣列麥克風之間的距離爲1米, 對於從角度θ以聲速c到達的頻率爲f的平面波,使用以下公式計算陣列的輸出。

下面代碼用相量和指數方法計算線性陣列的輸出幅度。

相量方法:

File: array1.c
#include <stdio.h>
#include <math.h>

int main(void)
{
   int numElements = 4;            // Number of array elements
   double spacing = 0.75;          // Element separation in metre
   double angle = 30.0;            // Degrees from broadside
   double freq = 100.0;            // Signal frequency in Hz 
   double speedSound = 343.0;      // m/s

   int i;
   double realSum = 0;
   double imagSum = 0;

   // Iterate through array elements
   for (i=0 ; i<numElements ; i++)
   {
      // Calculate element position and wavefront delay
      double position = i * spacing;
      double delay = position * sin(M_PI * angle / 180) / speedSound;

      printf("%3d) Position: %f, Delay: %e\n", i, position,  delay);

      // Add Wave
      realSum += cos(2.0 * M_PI * freq * delay);
      imagSum += sin(2.0 * M_PI * freq * delay);
   }

   double output = sqrt(realSum * realSum + imagSum * imagSum);
   printf("Output Amplitude: %.3f [%f, %f]\n", output, realSum, imagSum);

   return 0;
}

指數方法 

File: array2.c
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>

int main(void)
{
   int numElements = 4;            // Number of array elements
   double spacing = 0.75;          // Element separation in metre
   double angle = 30.0;            // Degrees from broadside
   double freq = 100.0;            // Signal frequency in Hz 
   double speedSound = 343.0;      // m/s

   int i;
   gsl_complex total;
   GSL_SET_COMPLEX(&total, 0 ,0);
   gsl_complex comp;

   // Iterate through array elements
   for (i=0 ; i<numElements ; i++)
   {
      // Calculate element position and wavefront delay
      double position = i * spacing;
      double delay = position * sin(M_PI * angle / 180) / speedSound;

      printf("%3d) Position: %f, Delay: %e\n", i, position,  delay);

      // Calculate exponential form
      comp.dat[0] = 0;                              // Real
      comp.dat[1] = 2.0 * M_PI * freq * delay;      // Imaginary
      gsl_complex w = gsl_complex_exp(comp);        // Exponential

      // Add Wave
      total = gsl_complex_add(total, w);           // Accumulate
   }

   double output = gsl_complex_abs(total);
   printf("Output Amplitude: %.3f [%f, %f]\n", output, total.dat[0], total.dat[1]);

   return 0;
}

可以使用以下命令來編譯和執行代碼

> gcc -Wall -lm -o array1 array1.c
> ./array1
> gcc -Wall -lm -lgsl -o array2 array2.c
> ./array2

這兩個程序的輸出是相同的,因爲它們都計算相同的內容,儘管方式略有不同。 輸出以米爲單位顯示每個陣列元素的物理位置,以及相對於第一個麥克風的波前延遲。 求和信號的幅度也以其複雜的形式顯示。

0) Position: 0.000000, Delay: 0.000000e+00
1) Position: 0.750000, Delay: 1.093294e-03
2) Position: 1.500000, Delay: 2.186589e-03
3) Position: 2.250000, Delay: 3.279883e-03
Output Amplitude: 2.912 [1.498204, 2.497171]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章