Cài đặt thuật toán FFT Cooley-Tookey

Một phần của tài liệu Nhận dạng bản nhạc dựa trên việc phân tích ký âm (Trang 63 - 66)

4. Phạm vi luận án Error! Bookmark not defined.

8.3.Cài đặt thuật toán FFT Cooley-Tookey

Trình tự thuật toán FFT được thực hiện qua các bước sau:

- Kiểm tra độ dài mẫu tín hiệu đầu vào có là bội của 2 ( ) , nếu không là bội của 2 thì ta thêm các mẫu vào sau sao cho thỏa mãn yêu cầu, tính toán lưu lại giá trị i, chiều dài mẫu tín hiệu đầu vào:

//---

if (IsPowerOfTwo(end-begin+1)) {

length = end - begin + 1;

bitsInLength = Log2(length) - 1; }

else

{

bitsInLength = Log2(end - begin + 1); length = 1 << bitsInLength;

// the items will be pad with zeros }

//---

- Sắp xếp mảng đầu vào theo một trật tự mới, bằng phương pháp đảo bit, phương pháp đảo bit có thể hình dung như sau: xét mảng đầu vào x(N), phần tử tại vị trí 3=0x011 sẽ lưu giá trị của phần tử tại vị trí 0x110=6, nghĩa là x[3]=x[6], và ngược lại. Như vậy dựa vào vị trí ta tiến hành đảo ngược các bit này cho ra vị trí mới, gán giá trị lại theo trật tự mới.

//---

// bit reversa

//- Sắp xếp lưu vào mảng mới data, mỗi phần tử được xem như số phức, gồm 2 phần: phần thực, và phần ảo, khởi gán cho các giá trị đầu tiên phần ảo=0

ComplexNumber[] data = newComplexNumber[length]; for (int i = begin; i <= end; i++)

{

int j = ReverseBits(i, bitsInLength); data[j] = new ComplexNumber(x[i]); }

//-Phương thức Dịch chuyển bit

privatestaticint ReverseBits(int n, int bitsCount) {

int reversed = 0;

for (int i = 0; i < bitsCount; i++) {

int nextBit = n & 1; n >>= 1; reversed <<= 1; reversed |= nextBit; } return reversed; } //---

- Dữ liệu đầu vào đã được sắp xếp, áp dụng công thức (1.5), cài đặt thuật toán FFT Cooley-Tookey:

//---

// Cooley-Tukey

for (int i = 0; i < bitsInLength; i++) {

int m = 1 << i; int n = m * 2;

double alpha = -(2 * Math.PI / n);

for (int k = 0; k < m; k++) {

// e^(-2*pi/N*k) (adsbygoogle = window.adsbygoogle || []).push({});

ComplexNumber oddPartMultiplier = newComplexNumber(0, alpha * k).PoweredE();

for (int j = k; j < length; j += n) {

ComplexNumber evenPart = data[j];

ComplexNumber oddPart = oddPartMultiplier * data[j + m]; data[j] = evenPart + oddPart;

data[j + m] = evenPart - oddPart; }

} }

//---

Giải thích: Cooley-Tookey dựa trên ý tưởng chia để trị, với mẫu có độ dài 2^i thì số lần đệ quy chia sẽ là i lần, tương ứng với vòng for đầu tiên. Tại mỗi lần chia ta tính toán các giá trị đầu ra của DFT theo công thức (1.5).

//---

// calculate spectrogram

PublicVar.spectrogram = newdouble[length];

for (int i = 0; i < PublicVar.spectrogram.Length; i++) {

PublicVar.spectrogram[i] = data[i].AbsPower2(); }

// Phương thức AbsPower2

publicdouble AbsPower2() {

return Re * Re + Im * Im; }

//---

Như vậy ta đã thu được mảng giá trị là phổ tần số của tín hiệu đầu vào.

Một phần của tài liệu Nhận dạng bản nhạc dựa trên việc phân tích ký âm (Trang 63 - 66)