Tổng hợp tiếng nói bằng phương pháp tổng hợp trực tiếp

Ngày nay thế giới chúng ta đã và đang bước vào một kỷ nguyên về sự bùng nổ thông tin. Cùng với sự phát triển như vũ bão của các phương tiện truyền thông        đại chúng thì lĩnh vực thu thập, lưu trữ và xử lý thông tin là một trong những vấn đề có ý nghĩa then chốt đối với mọi lĩnh vực nói chung và đặc biệt có ý nghĩa với ngành Công nghệ thông tin nói riêng. Trong đó, các vấn đề liên quan đế xử lý tiếng nói ngày càng được đề cập nhiều hơn, áp dụng vào thực tế nhiều hơn.

Trong phạm vi bài tập lớn này, chúng em xin đề cập đến vấn đề tổng hợp tiếng nói trực tiếp gồm có các bước : ghi âm trực tiếp các từ, tổng hợp các từ thành câu hoàn chỉnh và hiển thị tiếng nói.

Nội dung gồm các phần sau :

  1. Cấu trúc file Wave
  2. Một số thuật toán sử dụng trong chương trình
  • Chức năng chính của chương trình

  1. Cấu trúc file Wave

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.

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. Cấu trúc file Wave

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. Subchunk “fmt”

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.H 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ã hóa dữ liệu âm thanh sang dữ liệu số là kiểu mã hóa PCM.

nChannels có hai giá trị: bằng 1 cho âm thanh mono và bằng 2 cho âm thanh steréo.

nSamplesPerSec cho biết tốc độ lấy mẫu. Giá trị thông thường của trường này là:

11025 — 11.025 kHz •

22050 — 22.05 kHz •

44100 — 44.1 kHz

nAvgBytesPerSec cho biết số byte trung bình yêu cầu trong 1 giây để phát lại mẫu dữ liệu của sóng âm.

nBlockAlign cho biết số byte dùng để chứa một mẫu âm thanh.

Ta thấy trong WAVEFORMAT chưa có thông tin về số bit dùng để lượng tử hóa 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 đó được định nghĩa như sau:

typedef struc pcmwaveformat_tag

{

WAVEFORMAT wf;

WORD wBitsPerSample;

} PCMWAVEFORMAT;

wBitsPerSample cho biết số bit trong một mẫu dữ liệu. Chú ý rằng 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ử hóa một mẫu sóng âm thì sẽ phải lưu trữ cả 4 bit thừa không dùng đến.

  1. Subchunk “data”

Dữ liệu của “data” subchunk của Wave File chứa các số liệu của âm thanh đã được số hóa. Đố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ị từ 0 – 255) của các mẫu âm thanh. Đối với mẫu âm thanh 16 bits, mỗi mẫu dữ liệu gồm 2 bytes (có giá trị từ -32768 tới 32767). Điều này không có nghĩa là file wave 16 bits sẽ nghe to hơn 256 lần file wave 8 bits mà nó có nghĩa là âm thanh được lượng tử hóa chính xác hơn, nghe trung thực hơn.

Trong mẫu Mono 8 bits, dữ liệu của subchunk “data” gồm chuỗi các giá trị 1 bytes. Với Stereo 8 bits, mỗi mẫu gồm 2 bytes, dữ liệu sẽ được sắp xếp xen kẻ (interleave), 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.

CẤU TRÚC FILE WAVE

 

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

  1. Một số thuật toán sử dụng trong chương trình

 

  1. Giải thuật kiểm tra có phải khoảng lặng không :

 

  1. Lấy một frame âm thanh.
  2. Tính trung bình bình phương năng lượng của các mẫu âm thanh.
  3. Nếu

Năng lượng trung bình của Frame đó nhỏ hơn so với ngưỡng đã chọn

thì

     {

     _Tăng số frame lặng liên tiếp trong khoảng này lên một.

     _Kiểm tra số frame trong khoảng này đã vượt quá số frame cần thiết để khẳng định đó là khoảng lặng chưa.

      _Nếu thoả mãn thì khẳng định đây là khoảng lặng.

      _Nếu không thì trở về hàm gọi nó.

}

  1. Nếu

Năng lượng trung bình của Frame này lớn hơn ngưỡng đã chọn

thì

Khẳng định đây là tín hiệu thuộc một từ nào đó.

 

 

  1. Giải thuật tách các từ từ một câu dài :

  1. Tách một frame âm thanh từ buffer ra.

  1. 2. Nếu

Đó không là một frame của khoảng lặng

    Thì

{

    Nếu

chưa đánh dấu bắt đầu từ mới

    thì

Đánh dấu đây là điểm bắt đầu của một từ mới

    Copy tiếp Frame âm thanh đang xét vào Buffer của từ đang chuẩn bị ghi.

              Đặt con trỏ sang frame tiếp theo.

}

  1. 3. Không Thì // Đây là chỗ kết thúc một từ

{

    Đánh dấu vừa kết thúc một từ mới.

    Ghi dữ liệu trong Buffer đang chứa từ cần ghi ra một file tạm.

    Đặt con trỏ sang frame kế tiếp.

}

 

3.Giải thuật tổng hợp các từ :

 

  1. Lấy các từ đã được ghi âm trong một thư mục định trước theo một thứ tự định tổng hợp.
  2. Đọc file wave chứa từ đó, bỏ qua phần header, đưa vào bộ đệm đã chuẩn bị trước đó, cập nhật con trỏ trong bộ đệm.
  3. Tạo một Header cho file wave mới.
  4. Ghi vào file wave: Header + Dữ liệu trong Buffer.

 

 

 

  • Chức năng chính của chương trình :

Chương trình được thiết kế và cài đặt trên môi trường Visual C++.

Các chức năng chính của chương trình :

          + Ghi trực tiếp các từ từ mic vào file wave (Record)

          + Tổng hợp các từ từ file wave thành câu (Synthesis)

          + Hiển thị câu tổng hợp được ra thiết bị âm thanh (Play)

Leave a Reply