FFT (Fast Fourier Transform)

Một phần của tài liệu Xây dựng chương trình xử lý âm thanh số (Trang 51)

1.1. Nguyờn lý

Biến đổi Fourier được thực hiện dựa trờn nguyờn lý rằng ta cú thể dựng bất cứ hàm tuần hoàn theo thời gian x(t) nào và chuyển nú sang dạng một phộp tổng xỏc định của cỏc súng hỡnh sin hay hỡnh cosin tương ứng với cỏc tần số bắt đầu tại 0 và tăng dần theo cấp số nhõn một số nguyờn lần của tần số cơ bản f0=1/T, với T là chu kỳ của x(t).

Dĩ nhiờn, ta khụng thể thực hiện một tổng khụng xỏc định của bất cứ loại nào trong sự tớnh toỏn thực, nờn chỳng ta phải thiết lập một tập xỏc định cỏc hỡnh sin và cosin. Điều này tạo thuận lợi cho đầu vào được lấy mẫu một cỏch số hoỏ, khi chỳng ta quy định rằng số cỏc mẫu tần số ra và cỏc mẫu thời gian vào là như nhau. Hơn nữa, thật may mắn khi mọi quỏ trỡnh thu thanh õm số hoỏ đều cú độ dài xỏc định. Chỳng ta cú thể giả thiết rằng, hàm x(t) là tuần hoàn, và chu kỳ cú cựng độ dài như quỏ trỡnh thu thanh. Mặt khỏc, hóy coi qỳa trỡnh thu thanh được lặp mói mói, và gọi hàm lặp x(t). Quóng của phõn đoạn lặp xỏc định tần số cơ bản f0, mà f0=samplingRate/N, với N là số cỏc mẫu trong quỏ trỡnh thu thanh.

Vớ dụ như vậy, nếu ta đang sử dụng một tần số lấy mẫu 44100 mẫu /giõy, và độ dài quỏ trỡnh thu thanh là 1024 mẫu, thỡ tổng thời gian được thể hiện bởi quỏ trỡnh thu thanh là 1024/44100=0.02322 giõy, nờn tần số cơ bản f0

sẽ là 1/0.02322=43.07 Hz. Nếu ta xử lý 1024 mẫu này với FFT, đầu ra sẽ là cỏc hệ số sin và cosin (giả sử là ak và bk) và cho cỏc tần số 43.07Hz, 2*43.07Hz, 3*43.07Hz, vv... Để kiểm tra lại rằng sự tớnh toỏn hoàn toàn chớnh xỏc, ta cú thể phỏt sinh mọi súng hỡnh sin và cosin tại cỏc tần số này, nhõn chỳng với cỏc hệ số ak và bk tương ứng, cộng chỳng lại với nhau, và ta sẽ nhận được lại quỏ trỡnh thu thanh gốc.

1.2. FFT trong õm thanh số

Đặt vấn đề

trỡnh thu thanh số phải được làm vỡ thành cỏc khỳc (chunks) với độ dài mỗi khỳc là n mẫu, trong đú n luụn phải là một số nguyờn bội của 2. Đầu tiờn, sẽ lấy FFT của một khối, xử lý mảng ra FFT (vớ dụ như điền 0 vào mọi mẫu tần số bờn ngoài một dẫy xỏc định cỏc tần số), sau đú thực hiện biến đổi ngược FFT để nhận lại tớn hiệu trong miền thời gian đó được lọc. Khi õm được làm vỡ thành từng khỳc giống như vậy, và được sử lý với FFT, kết quả nhận được sau khi lọc sẽ cú những sự giỏn đoạn mà chỳng dẫn đến việc cú tiếng lỏch cỏch trong õm nhận được tại mỗi đường bao của khỳc. Vớ dụ như, nếu quỏ trỡnh thu thanh cú tần số lấy mẫu là 44,100Hz, và cỏc khối cú kớch thước là n=1024, thỡ sẽ cú một tiếng lỏch cỏch cú thể nhận rừ tại mỗi khoảng 1024/(44,100Hz)=0.0232 giõy.

Giải phỏp

Để giải quyết điều này, ta cú thể xử lý theo cỏch sau: Giả sử rằng kớch

thước bộ nhớ đệm là n = 2N. Trong bước lặp đầu tiờn, đọc n mẫu từ õm vào,

thực hiện FFT, xử lý, và IFFT, sau giữ lại dữ liệu theo thời gian nhận được trong bộ nhớ đệm thứ 2. Sau đú dịch nửa thứ 2 của bộ nhớ đệm gốc sang nửa đầu (chỳ ý rằng n là luỹ thừa của 2 nờn nú chia hết cho 2), và đọc n/2 mẫu vào nửa thứ 2 của bộ nhớ đệm. Sau đú thực hiện biến đổi FFT, xử lý, và IFFT. Bõy giờ thực hiện một phộp suy giảm tuyến tớnh trờn nửa thứ 2 của bộ nhớ đệm cũ mà nú đó được ghi từ bộ ba (FFT, xử lý, và IFFT) đầu tiờn bằng cỏch nhõn mỗi mẫu với một giỏ trị thay đổi từ 1 (cho mẫu số n/2) tới 0 (cho mẫu số n-1). Thực hiện phộp tăng tuyến tớnh trờn nửa đầu của bộ nhớ đệm ra mới (đi một cỏch tuyến tớnh từ 0 tới 1), sau đú cộng 2 nửa lại với nhau để nhận được một đầu ra với sự chuyển tiếp mịn. Chỳ ý rằng, cỏc vựng xung quanh mỗi điểm giỏn đoạn được xoỏ bỏ thực sự từ đầu ra, qua một mức õm lượng thớch hợp được giữ nguyờn. Kỹ thuật này làm việc rất tốt khi quỏ trỡnh xử lý khụng làm nhiễu loạn thụng tin về phase của phổ tần số. Vớ dụ như, một bộ lọc thụng dải (bandpass) sẽ hoạt động rất tốt, nhưng ta cú thể bắt gặp sự mộo õm với sự dịch chuyển về cường độ.

2. Cepstrum

Đặc điểm của homomorphic là sự biến đổi đại số tuyến tớnh mà nhờ đú cú thể tỏch hai tớn hiệu khụng cộng nhờ thuật toỏn phi tuyến trờn cơ sở lọc tuyến tớnh. Tuỳ theo kiểu tổ hợp, ta tỏch thành hai khỏi niệm:

• Homomorphic nhõn: tỏch tớch của hai dóy tớn hiệu.

• Tỏch tớch chập homomorphic: tỏch tớch chập của hai tớn hiệu.

Tớn hiệu vào x(n) là tớch của hai dóy phức x1(n) và x2(n). Để cú thể tỏch hai dóy tớn hiệu này bằng toỏn tử tuyến tớnh, ta cần phải lấy log phức.

Và: xˆ(n)=ln[x(n)]=lnx(n) +jarg[x(n)] (2.11) sẽ cho hai thành phần thực và ảo:

[ˆ( )] ln ( ) ln ( )

[ˆ( )] arg ( ) ( )

Im x n = argx(n) = x1 n +argx2 n (2.13)

Nếu phổ của cỏc dóy x1(n)=ln[x1(n)] và x2(n)=ln[x2(n)] khụng trựm hoặc trựm ớt thỡ ta cú thể dựng bộ lọc tuyến tớnh để lọc một tớn hiệu và chặn tớn hiệu cũn lại. Khi đú đầu ra của hệ thống tuyến tớnh là dóy phức

[x(n)]

R ˆ

) ( ˆ n =

y chỉ chứa log phức của một tớn hiệu. Như vậy, khi dựng toỏn tử

ngược của log tự nhiờn y(n)=exp[yˆ(n)] ta sẽ nhận được một thành phần tớn hiệu.

Do đú, ta cú sơ đồ tớnh Cepstrum như sau:

1 - a.z W(n) FFT Log| | IFFT

s(n) -1 Cepstrum

Homomorphic Tiền xử lý (adsbygoogle = window.adsbygoogle || []).push({});

Chương 6

PHƯƠNG PHÁP THIẾT KẾ

1. Khỏi quỏt chức năng

Sau khi đó nghiờn cứu, tỡm hiểu về cỏc khuụn dạng lưu trữ õm thanh cũng như cỏc kỹ thuật xử lý tớn hiệu số, ta tiến hành thiết kế và xõy dựng chương trỡnh.

Và, với chủ đề "Xõy dựng chương trỡnh xử lý õm thanh số", ta cú thể tỏch cỏc chức năng của chương trỡnh thành 2 phần khỏ riờng biệt: õm thanh và tớn hiệu của õm thanh.

• Với õm thanh, ta xột tới cỏc đặc trưng của cỏc khuụn dạng lưu trữ dữ

liệu, cỏch tạo một tệp õm thanh và một số thao tỏc chuyển đổi dưới dạng trực quan.

• Và để cú thể phõn tớch, nhận dạng cỏc õm thanh với cỏc tham số đặc

trưng như tần số, cường độ..., thỡ ta phải xột tới dạng của tớn hiệu cũng như phổ tương ứng của dữ liệu õm thanh đú.

Do đú, ta cú mụ phỏng cỏc chức năng của chương trỡnh như sau:

Âm thanh số

Thao tác với tệp âm thanh Phân tích tín hiệu

Khuôn dạng lưu trữ

Thao tác

dữ liệu Tiền xử lý Phân tích phổ Lọc tín

hiệu cửa sổHàm FFT Cepstrum Tạo file Soạn thảo Phát âm

Hỡnh 4.1: Mụ hỡnh xử lý

2. Cơ chế thực hiện

Do dữ liệu đầu vào của chương trỡnh là cỏc tệp õm thanh nờn chức năng đầu tiờn của chương trỡnh là mở tệp và đọc dữ liệu.

Tuy nhiờn, do cú rất nhiều khuụn dạng tệp lưu trữ õm thanh khỏc nhau nờn khi mở một tệp õm thanh ta phải kiểm tra để xỏc định khuụn dạng của tệp để từ đú cú phương thức đọc tệp tương ứng. Trong chương trỡnh, ta xột tới 2 khuụn dạng: tệp *.Wav và tệp *.Voc.

Núi chung, ta nờn kiểm tra dạng tệp Voc trước bởi tệp Voc cú 20 bits ký hiệu định vị ngay đầu tệp nờn khả năng cú sự giả mạo dạng tệp là rất thấp, do đú nhanh chúng xỏc định được lệnh rẽ nhỏnh tiếp theo.

Sau khi xỏc định được dạng tệp, ta sẽ cú phương thức đọc dữ liệu tương ứng. Sau cỏc chức năng xử lý và biểu diễn kết quả, chương trỡnh cú thể kết thỳc hay tiếp tục mở một tệp mới để phõn tớch.

Yes Mở file mới IsVocFile ? No IsWaveFile ? Read VocFile Read WaveFile Yes Xử lý Hiển thị No Kết thúc . . . Khởi đầu

Chương 7

THAO TÁC VỚI TỆP ÂM THANH

1. Truy nhập tệp Wave Mụ phỏng cấu trỳc WaveHeader: WaveHeader=record case boolean of false:( rID:longint; { 'RIFF' } rLen:longint; { dLen+36 } wID:longint; { 'WAVE' } fID:longint; { 'fmt ' } fLen:longint; { 16 wFT:word; { FormatTag : 1:PCM } nC:word; { Chanel: 1-mono; 2-stereo } nSp:word; { NumSamplesPerSecond } nAB:word; { 0: AvegBytesPerSecond } nBA:word; { BlockAligne = nSp*un1 } Fs:word; { 0: FormatSpecific }

un1:word; { BitsPerSample:1-PCM8bit;2-PCM16bit } un2:word; { cbSize: 8-PCM8bits; 16-PCM16bits } dID:longint; { 'data' }

dLen:longint; {NumBytes of TotalSamples } );

true:(hb:array[0..43]of byte); end;

Định dạng dữ liệu (adsbygoogle = window.adsbygoogle || []).push({});

Sau khi đọc khỳc header định dạng (khỳc "fmt "), ta sẽ biết được dữ liệu õm thanh PCM biểu diễn dưới dạng nào (dữ liệu trong khỳc "data"). Điều đầu tiờn mà ta cần biết là kớch thước của mỗi mẫu dữ liệu. Giỏ trị này được xỏc định qua tham số un2 (nBitsPerSample) từ header định dạng. Nếu un2 nhỏ hơn hay bằng 8 bits, thỡ mỗi mẫu PCM sẽ là một byte, và sẽ xắp xếp theo cỏc giỏ trị từ 0 tới 255. Tuy nhiờn, nếu un2 là giỏ trị trong khoảng từ 9 tới 16 thỡ mỗi mẫu PCM sẽ chiếm 2 bytes, và giỏ trị nằm trong khoảng -32768 tới +32767 (và đõy thực sự là một mõu thuẫn khi ta sử dụng dữ liệu dạng biểu diễn "unsigned" trong một khuụn dạng, và trong khuụn dạng khỏc lại là "signed").

Số kờnh truyền

Sau đú, ta cần biết số kờnh truyền (numChannels - nC). Nếu chỉ là một kờnh, thỡ dữ liệu PCM sẽ được xắp xếp theo thứ tự thời gian: mẫu đầu tiờn sẽ ở đầu tệp, và mẫu cuối cựng định vị ở cuối tệp. Nếu cú nhiều hơn một kờnh, thỡ mọi mẫu cho chỉ số đầu tiờn được đưa trước, quỏ trỡnh lặp lại qua cỏc kờnh. Sau đú đưa ra mẫu tiếp theo, và tiếp tục lặp lại qua cỏc kờnh.

Một cỏch mụ phỏng, với số kờnh tuỳ ý: i:= 0; While i < numSamples do Begin For c:= 0 to numChannels - 1 do {...xử lý Sample[i+c]...}; i:= i + numChanels; End;

Cần chỳ ý rằng, nếu cú 2 kờnh thỡ giỏ trị đầu tiờn trong mỗi cặp là của kờnh trỏi, và giỏ trị thứ hai là của kờnh phải. Do đú, ta cú thể coi kờnh trỏi như Channel 0, và kờnh phải như Channel 1.

Tần số lấy mẫu

Và một định lượng quan trọng khỏc là tần số lấy mẫu (số mẫu/giõy hay Hz - nSp: NumSamplesPerSecond). Tham số này thực sự quan trọng khi ta cần xử lý õm dựa trờn cỏc giỏ trị thời gian thực biểu diễn theo giõy, hay cần thể hiện thụng tin về tần số theo Hz (như khi sử dụng FFT). Do đú, cần lưu giỏ trị tần số lấy mẫu này vào một biến (Fs) để cú thể ỏp dụng cho quỏ trỡnh phõn tớch tớn hiệu sau đú.

2. Truy nhập tệp Voc

Do đặc tớnh của tệp Voc là gồm cỏc khối nờn cần phải đọc lần lượt cho tới khi hết tệp hay gặp khối dữ liệu. Ngoại trừ khối dạng 0 chỉ chứa một byte đơn giỏ trị 0 đỏnh dấu cuối tệp, khuụn dạng cỏc khối khỏc đều gồm một header kớch thước 4 bytes và tiếp theo là dữ liệu. Do đú, ta cú cấu trỳc chung:

Khuụn dạng khối

VocBlockFormat = record header: VocBlockHeader; data: VocData;

End;

Trong đú, dạng VocBlockHeader là cấu trỳc chung cho mọi khối. VocBlockHeader = record

blockType:byte; {1 byte định danh dạng khối } dataLen: longint; {3 byte xỏc định độ dài dữ liệu } End;

dạng 1, dạng 8 và dạng 9. Bởi vỡ đõy là cỏc khối chứa thụng tin về khuụn dạng lưu trữ dữ liệu.

Khối dạng 1:

VocData1 = record

SamRateCode :byte; {1 byte mó tần số lấy mẫu}

DataCompresCode :byte; {1 byte mó phương thức nộn dữ liệu} End;

Trong đú, tần số lấy mẫu được tớnh theo cụng thức: Fs = 1000000/(256 - SamRateCode);

Và mó phương thức nộn trong bảng thuộc phần khuụn dạng tệp Voc. Tuy nhiờn, 2 dạng thường dựng là: 0 - PCM 8bits; 4 - PCM 16bits.

Khối dạng 8:

VocData8 = record

SamRateCode :word; {2 byte mó tần số lấy mẫu}

DataCompresCode :byte; {1 byte mó phương thức nộn dữ liệu} Mode :byte; {0: mono; 1: stereo}

End;

Trong đú, tần số lấy mẫu được tớnh theo cụng thức:

Fs = 256*1000000/(65536 - SamRateCode);

Fs = Fs *2;

Khối dạng 9: (adsbygoogle = window.adsbygoogle || []).push({});

VocData9 = record

SamRate :longint; {4 byte tần số lấy mẫu} NumBitsPerSam :byte; {Số bits cho mỗi mẫu} NumChannel :byte; {Số kờnh truyền: 1-mono; 2-stereo}

DataCompresCode :word; {2 byte mó phương thức nộn dữ liệu} Exten :longint; {Phần mở rộng}

End;

3. Cấu hỡnh dữ liệu

Do đụi khi khụng cần thiết phải đọc toàn bộ cỏc mẫu dữ liệu trong tệp để phõn tớch (vớ dụ như khi tớn hiệu là tuần hoàn, trong mỗi chu kỳ tớn hiệu là như nhau), hay do số mẫu quỏ lớn (làm chậm thời gian đọc và xử lý), nờn ta chỉ cần đọc một số mẫu nhất định (NPTS mẫu). Tuy nhiờn, để tạo sự bao quỏt toàn bộ tệp, ta cú thể tuỳ chọn vị trớ mẫu bắt đầu được đọc.

Hỡnh 4.3: Cấu hỡnh dữ liệu

Dữ liệu được đọc từ tệp và gỏn vào một mảng kiểu nguyờn (integer) (do cỏc tệp cú lưu dữ liệu theo byte), và sau đú biểu diễn tớn hiệu theo dạng thời gian.

Hỡnh 4.4: Biểu diễn dữ liệu gốc theo thời gian

4. Soạn thảo

4.1. Nguyờn lý

Trong phần này, ta thực hiện một số thao tỏc trực quan trờn màn hỡnh. Tức là thao tỏc qua sự hiển thị của dữ liệu gốc được biểu diễn theo thời gian. Ta chỉ ỏp dụng với dữ liệu gốc, tức là dữ liệu õm thanh chưa được xử lý (chưa qua cỏc quỏ trỡnh lọc hay được giới hạn qua hàm cưả sổ). Và cỏc phộp xử lý này chỉ tỏc động lờn một tệp õm thanh trong mỗi phiờn làm việc, cú nghĩa là mọi thao

tỏc xử lý trờn phần súng õm của một tệp được hiển thị trờn màn hỡnh, sau đú nếu muốn lưu cỏc thay đổi thỡ cỏc tệp õm mới sẽ cú định dạng như tệp gốc. Chỳng sẽ cú cựng header với tần số lấy mẫu, số kờnh truyền, ... chỉ khỏc cỏc mẫu dữ liệu.

Nờn, nếu F là tham số tệp gốc, và Fsave là tham số của tệp õm mới được lưu sau một số thao tỏc soạn thảo, và header cú dạng WaveHeaderFile (trong chương trỡnh mới chỉ ỏp dụng soạn thảo trờn tệp Wave, tuy nhiờn muốn soạn thảo trờn khuụn dạng khỏc ta cú thể chuyển đổi khuụn dạng về dạng Wave, hay núi chung cơ sở của thuật toỏn trờn cỏc khuụn dạng khỏc cũng tương tự như vậy). Assigned(F, MainFilename); Assigned(Fsave, CurentFilename); Reset(F); Rewrite(Fsave); BlockRead(F, Header, 44);

{... Thay đổi tham số về độ dài dữ liệu ...} BlockWrite(Fsave, Header);

Close(F); Close(Fsave);

4.2. Thao tỏc dưới dạng trực quan

Thực chất của cỏc thao tỏc là tỏc động một cỏch trực quan lờn hai màn hỡnh: màn hỡnh biểu diễn súng õm gốc và màn hỡnh soạn thảo. Nếu cỏc thao tỏc chỉ đơn giản là cắt hay xoỏ bớt cỏc mẫu của dữ liệu gốc thỡ chỉ cần một màn hỡnh biểu diễn dữ liệu gốc là đủ. Bởi ta sẽ cắt, xoỏ ngay trờn phần súng õm gốc, và sau đú ghi phần súng õm cũn lại dưới dạng một tệp mới cú cựng định dạng kiểu.

Để cú thể chọn phần dữ liệu tỏc động, ta sử dụng phương phỏp nhấn và kộo chuột để khoanh vựng dữ liệu, hay chọn toàn bộ phần súng õm hiển thị.

Hỡnh 4.5: Chọn một phần dữ liệu

súng õm gốc, thỡ thay đổi do cỏc phộp cắt, xoỏ tạo ra là như nhau: phần dữ liệu lựa chọn bị xoỏ mất, và khi lưu tạo tệp mới thỡ cỏc mẫu dữ liệu phớa sau sẽ dồn lờn chiếm chỗ cỏc mẫu dữ liệu đó mất.

Hỡnh 4.6: Xoỏ phần dữ liệu đó chọn

Tuy nhiờn, những thay đổi đú chỉ cú thể làm thay đổi vị trớ chứ khụng phải trỡnh tự lưu trữ dữ liệu. Muốn cú một trỡnh tự mới, ta phải cắt, ghộp cỏc phần súng õm tương ứng tuỳ theo mong muốn. Chớnh vỡ vậy, ta cần một màn hỡnh thứ 2 (chớnh là màn hỡnh soạn thảo) để cú thể biểu diễn cỏc phõn đoạn súng õm theo một trỡnh tự nào đú.

Hỡnh 4.7: Màn hỡnh soạn thảo

Do đú, cú sự khỏc nhau giữa lệnh cắt và xoỏ. Lệnh cắt khỏc ở chỗ xoỏ

Một phần của tài liệu Xây dựng chương trình xử lý âm thanh số (Trang 51)