ĐỀ TÀI 9:
.
PGS.TS. Trịnh Văn Loan
Nguyễn Khánh Hưng 20081279 TTM-K53
Nguyễn Lê Hoài Nam 20081819 TTM-K53
4/2012
2
LI GII THIU 3
I. LÝ THUYT 4
1. Cấu trúc file wave 4
1.1. RIFF file 4
1.2. WAVE file 5
1.3. Subchunk “fmt” 5
1.4. Subchunk “data” 6
1.5. Sơ đồ cấu trúc file WAVE 7
2. Biên độ của tín hiệu tiếng nói 7
3. Năng lượng của tín hiệu tiếng nói 7
4. Tỷ lệ biến thiên qua giá trị không của tín hiệu tiếng nói 9
II. THIT K 10
1. Các chức năng của chương trình 10
2. Các lớp và hàm chính của chương trình 10
2.1. Đọc và biểu diễn file *.wav 10
2.2. Biên độ của tín hiệu tiếng nói 12
2.3. Năng lượng của tín hiệu tiếng nói 12
2.4. Tỷ lệ biến thiên qua giá trị không của tín hiệu tiếng nói 13
III. KT LUN 14
TÀI LIU THAM KHO 15
3
Trong năm học trước, chúng em đã được trang bị các kiến thức cơ bản về xử
lý tín hiệu số. Năm học này, chúng em tiếp tục được học môn Xử lý tiếng nói. Môn
học này giúp chúng em cụ thể hoá một số vấn đề trong lý thuyết xử lý tín hiệu số.
Xử lý tiếng nói thực sự đối với chúng em là một môn học khó, nhưng qua việc
hoàn thành đề tài bài tập lớn này, chúng em cũng phần nào hiểu rõ hơn về môn học.
Qua đây, chúng em cũng xin gửi lời cảm ơn chân thành tới thầy Trịnh Văn
Loan, giảng viên trực tiếp giảng dạy môn học Xử lý tiếng nói, đã rất tận tình truyền
đạt cho chúng em các vấn đề trong xử lý tín hiệu số nói chung và xử lý tiếng nói nói
riêng
4
I.
1.
Tiếng nói là tín hiệu tương tự, để lưu trữ được trong máy tính đặt trưng bởi
chuỗi số 01…ta phải “lấy mẫu” và “lượng tử hoá” tín hiệu tương tự thành tín hiệu
số mới lưu trữ được trong máy tính. Phương pháp “lấy mẫu” và “lượng tử hoá” âm
thanh hiện nay thường là phương pháp PCM. Phương pháp này sẽ lấy mẫu âm
thanh với tần số khoảng từ 11.025 kHz cho đến 44.1 kHz. Mỗi giá trị mẫu được
lượng tử hoá bằng 8 bits tương ứng giá trị mẫu từ –128 đến 127 hoặc lượng tử hoá
bằng 16 bits tương ứng giá trị mẫu từ –32768 đến 32767. So với lượng tử hoá bằng
8 bits thì lượng tử hoá bằng 16 bits sẽ lưu trữ âm thanh trung thực hơn nhưng bù lại
số byte lưu tăng gấp đôi.
1.1. RIFF file
Cấu trúc của Wave File thuộc vào lớp file được sử dụng bỡi các hàm
Multimedia của Windows : đó là RIFF file. RIFF là chữ viết tắt của Resource
Interchange File Format (format file trao đổi tài nguyên). Một RIFF file gồm một
hoặc nhiều loại chunks, trong mỗi chunk lại chứa con trỏ để chỉ đến chunk kế tiếp.
Mỗi chunk bao gồm loại chunk và dữ liệu theo sau loại chunk đó. Một ứng
dụng muốn đọc RIFF file có thể đi qua lần lượt từng chunk, đọc dữ liệu ở những
chunk nó quan tâm và có thể bỏ qua các chunk mà nó không quan tâm. Một chunk
của RIFF file luôn bắt đầu bởi một header có cấu trúc như sau:
typedef struct
{
FOURCC ckID;
DWORD ckSize;
} CK;
FOURCC gồm 4 bytes chỉ ra loại chunk. Đối với Wave File, field này có giá
trị là "WAVE". Nếu loại chunk ít hơn 4 ký tự thì các ký tự còn lại bên phải sẽ được
đệm thêm vào các khoảng trắng.
ckSize gồm 4 byte chứa kích thước vùng dữ liệu của chunk, vùng dữ liệu này
nằm ngay sau header và có kích thước là ckSize bytes.
5
Chunk có thể chứa các subchunks. Subchunk cũng là một chunk. Một RIFF
file luôn bắt đầu bằng một chunk loại "RIFF".
1.2. WAVE file
Wave file bắt đầu là chunk loại "RIFF. Hai subchunk trong Wave chunk đặc tả
thông tin về âm thanh của wave file và tiếp đó là dữ liệu của từng subchunk. Đó là
subchunk "fmt" và subchunk "data".
1.3.
Dữ liệu của “fmt” chunk là cấu trúc WAVEFORMAT có cấu trúc như sau:
typedef struct waveformat_tag
{
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
} WAVEFORMAT;
+ wFormatTag: Thường có giá trị là WAVE_FORMAT_PCM được định
nghĩa trong tập tin MMSYSTEM như sau:
#define WAVE_FORMAT_PCM 1
Giá trị này báo cho phần mềm đang đọc Wave file biết kiểu mã hoá dữ liệu âm
thanh sang dữ liệu số là kiểu mã hoá PCM. Hiện nay đây là kiểu mã hoá duy nhất
của Wave file.
• nChannels: có hai giá trị : bằng 1 cho âm thanh mono và bằng 2 cho âm
thanh stereo.
• nSamplesPerSec: cho biết tốc độ lấy mẫu, có các giá trị:
11025 11.025 kHz
22050 22.050 kHz
44100 44.100 kHz
• nAvgBytesPerSec: cho biết số byte yêu cầu trung bình trong một giây để
phát lại mẫu dữ liệu của sóng âm.
6
• nBlockAlign: cho biết số byte dùng để chứa một mẫu âm thanh. Như vậy
mẫu 8 bit hay ít hơn sẽ yêu cầu 1 byte, mẫu 9 đến 16 bit sẽ yêu cầu 2 byte. Nếu âm
thanh là stereo thì yêu cầu số byte gấp 2 lần âm thanh mono.
Ta thấy trong WAVEFORMAT chưa có thông tin về số bit dùng để lượng tử
hoá một mẫu dữ liệu của sóng âm. Thực tế Wave file sẽ xác lập số bit dùng cho một
mẫu dữ liệu bằng một trường gắn vào cuối cấu trúc của WAVEFORMAT. Cấu trúc
đó như sau:
Typedef struct pcmwaveformat_tag
{
WAVEFORMAT wf;
WORD wBitsPerSample;
} PCMWAVEFORMAT
Trong đó:
• wBitsPerSample: cho biết số bit trong một mẫu dữ liệu.
Chú ý:
Các mẫu dữ liệu vẫn phải lưu trữ ở dạng byte hoặc word. Do đó, nếu một
wave file dùng 12 bit để lượng tử hoá một mẫu sóng âm thì sẽ phải lưu trữ 4 bit
thừa không dùng đến.
1.4.
Dữ liệu của data subchunk của wave file chứa các số liệu của âm thanh đã
được số hoá. Đối với mẫu âm thanh 8 bit, dữ liệu của data subchunk bao gồm các
giá trị 1 byte (có giá trị trong khoảng 0-255) của các mẫu âm thanh. Đối với mẫu
âm thanh 16 bit, mỗi mẫu dữ liệu gồm 2 byte (có giá trị trong khoảng từ -32768 đến
32767). Điều này không có nghĩa là file wave 16 bit sẽ nghe to hơn 256 lần file
wave 8 bit, mà nó có nghĩa là âm thanh được lượng tử hoá chính xác hơn, nghe
trung thực hơn.
Trong mẫu mono 8 bit, dữ liệu của data subchunk gồm chuỗi các giá trị 1 byte.
Với stereo 8 bit, mỗi mẫu gồm 2 byte, dữ liệu sẽ được sắp xếp xen kẽ (interleave),
7
với byte đầu (byte chẵn) là mẫu âm thanh của kênh bên trái, byte sau (byte lẻ) là của
kênh bên phải
1.5.
Kích thước
Giá trị
4 bytes
"RIFF"
4 bytes
Kích thước file RIFF
4 bytes
"WAVE"
4 bytes
"fmt "
4 bytes
Kích thước subchunk "fmt "
2 bytes
Kiểu mã hóa dữ liệu của file wave
(thường là PCM)
2 bytes
Số kênh: 1 – mono
2 – stereo
4 bytes
Số mẫu/1giây
4 bytes
Số bytes/1 giây
2 bytes
Số bytes/1mẫu
2 bytes
Số bits/1mẫu
4 bytes
"data"
4 bytes
Kích thước dữ liệu
Dữ liệu sóng âm
2.
Biên độ tín hiệu tiếng nói theo thời gian cho biết đường bao biên độ của tín
hiệu. Vì vậy chỉ cần lấy giá trị tuyệt đối của biên độ và biểu diễn giá trị này theo
thời gian.
3.
Tiếng nói được tạo từ sự rung động đường thanh âm theo thời gian. Vì vậy tín
hiệu tiếng nói trong tự nhiên là không ổn định. Hầu hết các công thức trong xử lý
tín hiệu đã học, các hệ thống hay quá trình xử lý tín hiệu đều giả sử hệ thống bất
8
biến theo thời gian, thời gian bất biến và tín hiệu không thay đổi. Do đó những công
thức này không áp dụng trực tiếp cho quá trình xử lý tiếng nói.
Công thức tính tổng năng lượng của tín hiệu tiếng nói:
Công thức này được sử dụng trong trường hợp tín hiệu không thay đổi và năng
lượng giới hạn. Giả sử, nếu chúng ta sử dụng công thức trên để tính tổng năng
lượng của tín hiệu tiếng nói. Nhưng tổng năng lượng này không được sử dụng. Bởi
vì, thực tế tiếng nói của năng lượng thay đổi theo thời gian. Vì vậy chúng ta phải
đưa ra công thức tính năng lượng thay đổi theo thời gian. Để rõ ràng chúng ta giả sử
tín hiệu trong quá trình xử lý không thay đổi, tín hiệu tiếng nói không thay đổi khi
chúng ta biểu diễn trong những khối từ 10 tới 30 ms. Vì vậy để xử lý tiếng nói, ta
xử lý tín hiệu tiếng nói trong khối 10-30ms. Đây gọi là quá trình xử lý ngắn hạn.
Năng lượng của tín hiệu tiếng nói biến thiên theo thời gian. Do đó mục đích
của quá trình xử lý tiếng nói là làm sao để nhận biết được sự thay đổi của năng
lượng theo thời gian. Tín hiệu tiếng nói bao gồm âm vô thanh, hữu thanh và khoảng
lặng. Hơn nữa, phải so sánh năng lượng của vùng âm hữu thanh với vùng âm vô
thanh và vùng khoảng lặng không có năng lượng. Vì vậy năng lượng ngắn hạn có
thể sử dụng để phân loại âm hữu thanh, âm vô thanh và khoảng lặng.
Công thức tính năng lượng ngắn hạn có thể dựa trên công thức tính tổng năng
lượng.
Để tính năng lượng ngắn hạn chúng ta xét tín hiệu trong khoảng 10-30ms. Đặt
những mẫu trong khung là n = 0 tới n = N-1, trong đó N là tổng số mẫu trong
khung.
Công thức tính năng lượng ngắn hạn:
Trong đó w(n) là hàm cửa sổ như cửa sổ chữ nhật, hanning, hamming.
Hàm cửa sổ Hamming
9
4.
Tỷ lệ biến thiên qua giá trị không đưa ra thông tin về tỷ lệ tín hiệu thay đổi
dấu trong suốt chiều dài tín hiệu, tỷ lệ mà tại đó tín hiệu thay đổi từ dương sang âm
hoặc ngược lại. Đặc điểm này được sử dụng nhiều trong cả việc nhận biết tín hiệu
tiếng nói và khôi phục lại thông tin tiếng nhạc, để phân loại âm thanh va đập.
Nếu tỷ lệ biến thiên qua giá trị không lớn thì tín hiệu có thay đổi lớn, đoạn tín
hiệu đó có tần số cao với các đường giống nhau. Nếu tín hiệu có tỷ lệ biến thiên qua
giá trị không nhỏ, tín hiệu thay đổi chậm, do đó tín hiệu chứa thông tin về tần số
thấp. Tỷ lệ biến thiên qua giá trị không đưa ra thông tin về tần số của tín hiệu tiếng
nói.
Công thức tính tỷ lệ biến thiên qua giá trị không của tín hiệu tiếng nói:
Trong đó
w(m) là cửa sổ chữ nhật
0.5|sgn{x[m]} – sgn{x[m – 1]}| = 1 nếu x[m] và x[m – 1] khác dấu và bằng 0
nếu hai mẫu cùng dấu.
10
II.
1.
- Đọc và hiển thị tín hiệu tiếng nói từ file *.WAV
- Biểu năng lượng, biên độ và tỷ lệ biến thiên qua giá trị không của tín hiệu
tiếng nói.
Các menu:
Open menu: chọn file *.wav
Wave file information menu: xem thông tin header file *.wav
Next, Back menu: chuyển hình biểu diễn.
2.
2.1. Đọc và biểu diễn file *.wav
Đọc file *.wav
class WaveFile
{
#region RIFF HEAD
private byte[] m_RiffID; //Chuỗi "RIFF": 4 byte
private int m_RiffSize; //Tổng kích thước của trường sau nó
private byte[] m_RiffFormat; //Chuỗi "WAVE": 4 byte
#endregion
#region FMT HEAD
private byte[] m_FmtID; //String "fmt":4 byte
private int m_FmtSize; //Tổng kích thước các trường sau
private int m_FmtTag; //Dạng nén dữ liệu(VD: 1-PCM): 2 byte
private int m_Channels; //Số kênh(Mono=1; Stereo=2): 2 byte
private int m_SamplesPerSec; //Tần số lấy mẫu:số mẫu trên1giây:4 byte
private int m_AverageBytesPerSec; //Số bytes trên giây: 4 byte
private int m_BlockAlign; //Số byte trong một mẫu: 2byte
private int m_BitsPerSample; //Số bit trên mẫu: 2 byte
#endregion
#region DATA WAVE
private byte[] m_DataID; //Chuỗi data
private int m_DataSize; //Kích thước dữ liệu âm thanh
private int m_NumSamples; //Tổng số mẫu
private int[] m_Data1; //Chứa byte của dứ liệu âm thanh
private int[] m_Data2;
#endregion
}
11
Biểu diễn file *.wav: class ViewWave
public void DrawSpeechSignal()
{
using( Graphics g = Graphics.FromImage(bitmap))
{
Pen pen = new Pen(Color.Blue);
g.DrawLine(pen, new Point(50, height / 2), new Point(width, height /
2));
PointF[] point = new PointF[NumSample];
int dtMax = getValueMax(Data);
int fheight = height / 2 - 15;
g.TranslateTransform(0, height / 2);
for (int i = 0; i < Data.Length; i++)
{
int val = Data[i];
point[i].X = (i * (width - 50)) / NumSample + 50;
point[i].Y = (-1) * ((fheight * val) / dtMax);
}
g.DrawLines(pen, point);
g.Dispose();
}
picGraph.Image = bitmap;
}
- Trong hàm biểu diễn trên, mẫu có giá trị lớn nhất được biểu diễn bằng
đoạn có độ dài fheight.
12
2.2. Biên độ của tín hiệu tiếng nói: class ViewAmplitude
public void DrawAmplitude()
{
using (Graphics g = Graphics.FromImage(bitmap))
{
Pen pen = new Pen(Color.Blue);
PointF[] point = new PointF[NumSample];
int dtMax = getValueMax(Data);
g.DrawString(dtMax + "", new Font("Courier", 8, FontStyle.Regular),
Brushes.Black, new Point(15, 13));
int fheight = height - 30;
g.TranslateTransform(0, height - 15);
for (int i = 0; i < Data.Length; i++)
{
int val = Math.Abs(Data[i]);
point[i].X = (i * (width - 50)) / NumSample + 50;
point[i].Y = (-1) * ((fheight * val) / dtMax);
}
g.DrawLines(pen, point);
g.Dispose();
}
picGraph.Image = bitmap;
}
2.3. Năng lượng của tín hiệu tiếng nói: class ViewEnergy
Tính năng lượng của tín hiệu tiếng nói
Hamming = WindowHamming(lenWindow); //Cửa sổ Hamming
int numPoint = NumSample / lenShift; //Tổng số điểm tren Ox
Energy = new int[numPoint];
newData = new int[NumSample];
int dtMax = getValueMax(data);
int fheight = height / 2 - 15;
for (int i = 0; i < NumSample; i++)
{
newData[i] = (fheight * data[i]) / dtMax;
}
for (int i = 0; i < numPoint; i++)
{
double temp = 0;
for (int m = 0; m < lenWindow; m++)
{
if (i * lenShift + m >= NumSample) continue;
temp += Math.Pow(newData[m + i * lenShift], 2) *
Math.Pow(Hamming[m], 2);
}
Energy[i] = (int)temp;
}
13
2.4. Tỷ lệ biến thiên qua giá trị không của tín hiệu tiếng nói
Class ViewZeroCrossingRate
int numPoint = NumSample / lenShift;
ZCR = new int[numPoint];
for (int i = 0; i < numPoint; i++)
{
double temp = 0;
for (int m = 0; m < lenWindow; m++)
{
if (i * lenShift + m + 1 >= NumSample) continue;
temp += 0.5 * Math.Abs(Math.Sign(data[m + i *
lenShift]) - Math.Sign(data[m + 1 + i * lenShift]));
}
ZCR[i] = (int)(temp);
}
14
III. K
Thông qua quá trình nghiên cứu bài tập lớn đã đem lại cho chúng em những
hiểu biết toàn diện hơn về tín hiệu tiếng nói, cũng như những ứng dụng thực tế của
việc xác định và biểu diễn tín hiệu tiếng nói, năng lượng và tỷ lệ biến thiên qua giá
trị không của tín hiệu tiếng nói. Do thời gian có hạn nên không thể tránh khỏi những
sai sót, chúng em mong nhận được sự góp ý bổ sung của thầy.
15
- Trịnh Văn Loan, Bài giảng xử lý tiếng nói
-
- http://125.20.82.167:8091/virtual/experiment7.php?link=T00107
- />001§ion=x1-56r1