HƯỚNG PHÁT TRIỂN

Một phần của tài liệu Nghiên cứu công nghệ nhận dạng tiếng nói tiếng việt và ứng dụng (Trang 90 - 119)

Trên nền tảng các kết quả đã đạt được, một số vấn đề có thể được xem xét nghiên cứu và phát triển xa hơn nhằm nâng cao hiệu quả của đề tài:

- Mở rộng cho nhiều dịch vụ khác của VTTP đang cung cấp cho khách hàng. Một số dịch vụ cung cấp cho khách hàng:

o Ứng dụng xây dựng tổng đài tiếp nhận thông tin tư vấn: Khách hàng muốn tư vấn thông tin tư vấn về lĩnh vực gì thì chỉ cần gọi vào tổng đài nói tên lĩnh vực cần tư vấn cuộc gọi sẽ chuyển thẳng đến bộ phận tương ứng, tập dữ liệu tiếng nói cho bộ phận này bao gồm tư vấn tâm lý giáo dục, Luật Dân sự - Hình sự - Lao động, Luật Kinh tế - Doanh nghiệp, Luật Đầu tư – Xuất nhập khẩu, Luật Nhà đất, Luật Hành chánh – Xuất nhập cảnh, Luật Sở hữu trí tuệ, Thị trường chứng khoán, Kế toán – thuế , Tin học, Hỗ trợ giải bài tập phổ thông, Tuyển sinh – Hướng nghiệp, Dịch thuật , Du học, Tâm lý, Nữ công gia Du lịch, Tâm lý giáo dục trẻ chánh, Sức khỏe sinh sản - Nhi khoa, Tiêm phòng - Miễn dịch, Y học cổ truyền, Da liễu – Thẩm mỹ, Nha khoa – Răng hàm mặt, An toàn vệ sinh thực phẩm – mỹ phẩm, Dinh dưỡng.

o Cung cấp cho khách hàng tổng đài IP PBX có chức năng tương tác thoại IVR(Interactive voice response) nhận dạng tiếng nói: Khách hàng gọi vào tổng đài PBX của công ty và đọc tên phòng ban chức năng của công ty cần gặp. Tổng đài sẽ chuyển cuộc gọi đến phòng ban chức năng theo yêu cầu. Tập dữ liệu tiếng nói là tên các phòng ban và bộ phận cần chuyển cuộc gọi đến.

có thể triển khai dễ dàng khi thu thập dữ liệu thu âm phù hợp với từng bài toán.

- Tổng đài có khả năng mở rộng xây dựng tập từ vựng để có thể ứng dụng vào nhiều dịch vụ khác nhau trong toàn Tập Đoàn Bưu Chính Viễn Thông Việt Nam.

- Tìm hiểu thêm phần khắc phục nhiễu tín hiệu âm thanh được truyền tải trên môi trường mạng viễn thông.

- Dữ liệu huấn luyện phải được thu âm, lấy mẫu trên mạng viễn thông đúng với thiết bị dùng để nhận dạng.

- Thu thập thêm dữ liệu huấn luyện và cải thiện sao cho hệ thống có thể nhận dạng tốt trong môi trường có tiếng ồn xung quanh với mức ngưỡng cho phép và nhận dạng cùng lúc nhiều chữ số liên tục.

- Sử dụng mô hình ngữ âm subspace Gaussian mixture models để cải thiện chất lượng nhận dạng.

Tài liệu Tiếng Việt

[12] Phạm Minh Nhựt; Định danh người nói độc lập văn bản bằng mô hình thống kê; luận văn thạc sỹ khoa học máy tính 2006, Đại học Khoa học tự nhiên Tp HCM

Tài liệu Tiếng Anh

[1] Frederico Rodrigues, Ricardo Rodrigues, Ciro Martins: An Isolated Letter

Recognizer for Proper Name Identification Over the Telephone; INESC - Instituto de Engenharia de Sistemas e Computadores

[2] Goel, S. Garg, V. Ranjan, P. Rao, S. Bhattacharya, M. : ASR System

Integration with Asterisk for SIP or IAX Softphone Clients

Dept. of Inf. Technol., Indian Inst. of Inf. Technol. & Manage., Gwalior, India.

[3] Alexandre Maciel, Weber Campos, Clêunio França, Edson Carvalho,

SPEAKER VERIFICATION SYSTEM THROUGH TELEPHONE CHANNEL An integrated system for telephony plataform Asterisk; Informatics Center, Federal University of Pernambuco, Recife, Brazil.

[4] Theodore Wallingford, VoIP Hacks, O'Reilly Media, CA 95472, 2006

[5] Jim Van Meggelen, Jared Smith, Leif Madsen, “Asterisk: The Future of

vol. 4274, pp. 464-474, 2006

[7] L. Rabiner, B. Juang. Fundamentals of Speech Recognition. PTR Prentice

Hall (Signal Pro-cessing Series), Englewood Clies NJ, 1993, ISBN 0-13- 015157-2.

[8] Vu Thang Tat, Dung Tien Nguyen, Mai Luong Chi, John-Paul Hosom, “Vietnamese Large Vocabulary Recognition”, Proc. Eurospeech05, pp. 1689-1692.

[9] L. Rabiner, B. Juang. Fundamentals of Speech Recognition. PTR Prentice

Hall (Signal Pro-cessing Series), Englewood Clies NJ, 1993, ISBN 0-13- 015157-2.

[10] Peinado, A., and Segura, J.C. (2006) Speech Recognition Over Digital

Channels. Wiley.

[11]. J Matousek, Z. H., And Tihelka, D. Hybrid syllable/triphone speech

synthesis. In Proceedings of Eurospeech 2005 (2005).

[12] B.H. Juang, Lawrence R. Rabiner, "Automatic Speech Recognition – A Brief History of the Technology".

Huấn luyện nhận dạng tiếng nói tiếng việt với tập từ vựng là các chữ số tiếng nói tiếng việt, đây là giai đoạn thực hiện các bước chuyển tiếng nói từ dạng âm thanh thành mô hình ngữ âm trên mô hình markov ẩn hợp gauss. mô hình ngữ âm này là dữ liệu huấn luyện để phục vụ cho công đoạn nhận dạng tiếng nói.

Công việc huấn luyện gồm 4 giai đoạn: + Chuẩn bị dữ liệu âm thanh giọng nói. + Huấn luyện dữ liệu âm thanh giọng nói. + Kiểm tra kết quả nhận dạng.

+ Đánh giá kết quả nhận dạng, xem độ chính xác thu được bao nhiêu nhiêu phần trăm so với tiếng nói đưa vào.

Các bước huấn luyện HTK sẽ được trình bày từng bước như dưới đây:

Chuẩn bị dữ liệu huấn luyện HTK Xây dựng tập tin cú pháp

Soạn tập tin gram.txt với nội dung như sau:

$speaker = MOOJT | HAI | BA | BOOSN | NAWM | SASU | BARY | TASM | CHISN | KHOONG|DDUSNG|TROWR LAJI; ($speaker)

Tập tin trên thể hiện chúng ta muốn huấn luyện tập dữ liệu tiếng nói tiếng việt với tập từ vựng gồm các chữ số.

Tạo sơ đồ word network

Đây là công đoạn tạo ra đồ thị mô tả cách thức chuyển tiếp giữa các từ, muốn tạo sơ đồ word network ta thực hiện lệnh như sau:

N=18 L=40 I=0 W=SENT-END I=1 W=LAJI I=2 W=!NULL I=3 W=TROWR I=4 W=DDUSNG I=5 W=KHOONG I=6 W=CHISN I=7 W=TASM I=8 W=BARY I=9 W=SASU I=10 W=NAWM I=11 W=BOOSN I=12 W=BA I=13 W=HAI I=14 W=MOOJT I=15 W=SENT-START I=16 W=!NULL I=17 W=!NULL J=0 S=2 E=0 J=1 S=3 E=1 J=2 S=1 E=2 J=3 S=4 E=2

Thu âm giọng nói

Huấn luyện HTK từ các tập tin âm thanh, việc thu âm tiếng nói làm dữ luyện mẫu là công đoạn khá mất thời gian và tiền bạc, đối với hệ thống triển khai thực tế đòi hỏi chúng ta phải thuê người đi thu âm, dự án xây dựng tổng đài nhận dạng chữ số tiếng nói tiếng việt trong đề tài nghiên cứu này chúng tôi đã thực hiện thu âm lên đến 2796 người.

Để thu âm chúng ta có hai cách một là chúng ta thu âm trước các từ mong muốn ở đây là tập dữ liệu chữ số tiếng nói tiếng việt, sau đó thực hiện tạo file text chứa nội dung tập tin âm thanh đã thu âm, hai là chúng ta dùng công cụ HSGen dựa vào sơ đồ word network để tạo ra các câu text tương ứng sau đó chúng ta tiến hành thu âm.

Tạo nội dung thu âm bằng lệnh:

Nội dung file dict như sau:

BA B A sp BARY B AR Y sp BOOSN B OOS N sp CHISN CH IS N sp DDUSNG DD US NG sp HAI H A I sp KHOONG KH OO NG sp LAJI L AJ I MOOJT M OOJ T sp NAWM N AW M sp SASU S AS U sp SENT-END [] sil SENT-START [] sil TASM T AS M sp TROWR TR OWR sp

Nội dung file prompst như sau:

KHOONG MOOJT SASU CHISN NAWM BARY MOOJT BA CHISN KHOONG BARY BARY BA SASU TASM KHOONG CHISN MOOJT KHOONG MOOJT SASU TASM SASU HAI TASM SASU MOOJT BOOSN KHOONG CHISN BOOSN CHISN BOOSN KHOONG BARY HAI MOOJT KHOONG MOOJT SASU TASM SASU HAI SASU MOOJT BOOSN BA KHOONG CHISN BARY BARY HAI TASM BARY KHOONG BOOSN HAI KHOONG SASU BARY TASM SASU BA MOOJT TASM CHISN

………..

Huấn luyện dữ liệu

Trích đặc trưng mfcc dùng lệnh HCopy

Rút trích đặc trưng tiếng nói là giai đoạn quan trọng để thực hiện huấn luyện HTK trên mô hình markov ẩn, có nhiều phương pháp rút trích đặt trưng như LPC-Linear prediction coefficients, MFCC-Mel-frequency cepstral coefficients, đến thoefi điểm hiện tại MFCC là phương pháp được

Ghi chú:

+ File Hcopy.cfg có nội dung:

SOURCEKIND = WAVEFORM SOURCEFORMAT = WAV TARGETKIND = MFCC_0_D_A TARGETRATE = 100000.0 SAVECOMPRESSED = T SAVEWITHCRC = T WINDOWSIZE = 250000.0 USEHAMMING = T PREEMCOEF = 0.97 NUMCHANS = 26 CEPLIFTER = 22 NUMCEPS = 12 ENORMALISE = F

+ File listwavmfccTrain.scp có được bằng cách thực hiện lệnh:

F:\labsimple\wav\train\01.wav F:\labsimple\wav\train\01.mfc F:\labsimple\wav\train\02.wav F:\labsimple\wav\train\02.mfc ………

Khởi tạo giá trị huấn luyện

Trước khi huấn luyện chúng ta phải thực hiện công đoạn khởi tạo giá trị, đây là công đoạn phải làm trong mô hình huấn luyện HTK trên mô hình markov ẩn.

Ghi chú:

+ File train.scp có nội dung:

F:\labsimple\mfcc\train\01.mfc

HCopy -T 1 -C cfg\HCopy.cfg -S listwavmfccTrain.scp

listwavmfc.pl wav\train listwavmfccTrain.scp

HCompV -C cfg\HCompV.cfg -f 0.01 -m -S train.scp -M hmm\hmm0 hmm\hmm0\proto

+ Tạo file proto trong thư mục hmm\hmm0 có nội dung: ~o <VecSize> 39 <MFCC_0_D_A> ~h “proto” <BeginHMM> <NumStates> 5 <State> 2 <Mean> 39 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 <Variance> 39 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 <State> 3 <Mean> 39 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 <Variance> 39 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ~o <VecSize> 39 <MFCC_0_D_A> ~h “proto” <BeginHMM> <NumStates> 5 <State> 2 <Mean> 39 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 <Variance> 39 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0

0.0 0.0 0.0 <Variance> 39

1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0

1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0

+ tạo file hmmdefs trong thư mục hmm\hmm0, sao cho mỗi phone được thay bằng “proto”

+ file mkphones.led có nội dung

EX IS sil sil DE sp

 Lệnh trên sẽ tạo ra file phones0.mlf

 Lệnh trên sẽ tạo ra file monophones0

 Lệnh trên tạo file hmmdefs

Nội dung của File macros có được từ cách chép phần đầu ~o của file proto và nội dung của file vFloors

~o

<STREAMINFO> 1 39

<VECSIZE> 39<NULLD><MFCC_D_A_0><DIAGC> ~v varFloor1

<Variance> 39

2.909618e-001 1.896888e-001 3.646610e-001 2.376805e-001 2.649882e-001 2.794672e-001 2.323876e-001 2.089114e-001 1.858883e-001 2.667808e-001 2.119271e-001 1.591346e-001 2.950959e-001 7.393611e-003 6.921536e-003 7.833419e-003 9.061966e-003 1.120140e-002 1.136315e-002 1.120127e-002 1.078344e-002 1.207254e-002 1.367865e-002 1.039116e-002 8.883036e-003

prompts2mlf.pl lable.mlf train

HLed -l ‘*’ -d dict -i phones0.mlf mkphones.led lable.mlf

HDMan -A -D -T 1 -m -w wlist -n monophones0 -i -l dlog dict lexicon

 mkHmmdefsFile.pl hmm\hmm0\proto monophones0

2.347129e-003 1.784228e-003 1.629085e-003 5.131669e-004

Tiến hành huấn luyện ước lượng thông số:

Kết quả huấn luyện

 Kết quả nhận dạng được sẽ chứa trong tập tin recout.mlf

Đánh giá kết quả

Kết quả được phân tích như dưới đây

--- Overall Results --- SENT: %Correct=67.50 [H=108, S=52, N=160]

WORD: %Corr=96.99, Acc=95.46 [H=1644, D=8, S=43, I=26, N=1695]

Các định nghĩa ký hiệu:

N = total number(tổng số từ(số))

HVite -H hmm\hmm3\macros -H hmm\hmm3\hmmdefs -S test.scp -i kq\recout.mlf -w wdnet -p 0.0 -s 5.0 dict HmmList

HERest -C cfg\HERest.cfg -I phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm\hmm0\macros -H hmm\hmm0\hmmdefs -M hmm\hmm1 monophones0

HERest -C cfg\HERest.cfg -I phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm\hmm1\macros -H hmm\hmm1\hmmdefs -M hmm\hmm2 monophones0

HERest -C cfg\HERest.cfg -I phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H hmm\hmm2\macros -H hmm\hmm2\hmmdefs -M hmm\hmm3 monophones0

HResults -I phones0test.mlf hmmlist kq\recout.mlf

Correct: H = N - S - D %Correct: %Corr = H/N %Accuracy: Acc = (H-I)/N

Kết quả huấn luyện được đưa vào hệ thống nhận dạng off-line với 160 câu test cho độ chính xác từ (word) là 95.46% như kết quả phân tích trên.

Với kết quả này được ứng dụng vào xây dựng tổng đài nhận dạng tiếng nói tiếng việt trên mạng viễn thông.

THỐNG NHẬN DẠNG

1. Cấu hình hệ thống trên tổng đài Asterisk

[from-pstn] exten => s,1,Answer() exten => s,n(restart),SpeechCreate(julius) exten => s,n,SpeechStart() exten => s,n,Wait(1) exten => s,n,SpeechBackground(/nhandang/gioithieu/04aluachon_baihatbiendao) exten => s,n,Verbose(1,The recognized input is ${SPEECH_TEXT(0)})

exten => s,n,Set(RECOG=$

{FILTER(MOOJTHAIBABOOSNNAWMSASUBARYTASMCHISNKHOON GDDUSNGTROWRLAJI,${SPEECH_TEXT(0)})})

exten => s,n,SpeechDestroy()

exten => s,n,GotoIf($["${RECOG}" = ""]?restart)

exten => s,n,GotoIf($["${RECOG}" = "DDUSNG"]?restart) exten => s,n,GotoIf($["${RECOG}" = "TROWRLAJI"]?restart) exten => s,n(dachonso),Set(tendata=${RECOG}); exten => s,n,Playback(/nhandang/gioithieu/bandachonso) exten => s,n,Playback(/nhandang/so/${RECOG}) exten => s,n,Playback(/nhandang/gioithieu/dungkhong) exten => s,n,SpeechCreate(julius);///////////////////////////////////////////////////////// exten => s,n,SpeechStart() exten => s,n,SpeechBackground(/nhandang/gioithieu/imlang) exten => s,n,Set(RECOG=$ {FILTER(MOOJTHAIBABOOSNNAWMSASUBARYTASMCHISNKHOON GDDUSNGTROWRLAJI,${SPEECH_TEXT(0)})}) exten => s,n,SpeechDestroy()

exten => s,n,GotoIf($["${RECOG}" = "DDUSNG"]?baihat) exten => s,n,GotoIf($["${RECOG}" = "KHOONG"]?restart)

exten => s,n(baihat),Background(/nhandang/baihatbiendao/${tendata}) exten => s,n,Goto(restart) exten => s,n,Hangup() exten => 1,1,Goto(s,restart) exten => 2,1,Goto(s,restart) exten => 3,1,Goto(s,restart) exten => 4,1,Goto(s,restart)

exten => 9,1,Goto(s,restart) exten => 0,1,Goto(s,restart) exten => *,1,Goto(s,restart) exten => #,1,Goto(s,restart) exten => s,n,Hangup()

exten => s,n,GotoIf($["${RECOG}" = "TROWRLAJI"]?restart) exten => s,n,SpeechCreate(julius) exten => s,n,SpeechStart() exten => s,n,Goto(dachonso) exten => s,n,Hangup() 2. Cấu hình hệ thống với hệ thống nhận dạng -dfa sohoidap.dfa -v sohoidap.dict -h hmmdefs_sohoidap -hlist tiedlist_sohoidap -input adinnet -smpFreq 8000 -headmargin 500 -tailmargin 1000 -cmnmapweight 10.0 -b 1500 -b2 100 -m 3000 -n 10 -output 1 -record /nhandang/luutaptinnhandang

TIẾNG NÓI

#include "asterisk.h"

ASTERISK_FILE_VERSION(__FILE__, "$Revision: $") /* Asterisk-Julius Generic Speech API Module

* (c) 2013, Le Quoc Toan *

* Distributed under whatever is the freest license I'm allowed * under Asterisk, I'd assume that's the GPL.

*/ #include <sys/poll.h> #include <sys/select.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include "asterisk/module.h" #include "asterisk/logger.h" #include "asterisk/strings.h" #include "asterisk/config.h" #include "asterisk/frame.h" #include "asterisk/dsp.h" #include "asterisk/speech.h"

#define JULIUS_ENGINE_NAME "julius" #define JULIUS_ERROR 0

#define JULIUS_SUCCESS 1

int JULIUS_SILENCE_TIME = 500; int JULIUS_NOISE_FRAMES = 0;

int heardspeech = 0; int noiseframes = 0; int final = 0; int s; #ifndef __ASTERISK_SPEECH_JULIUS_H #define __ASTERISK_SPEECH_JULIUS_H 1 /* Create/Destroy the Speech Engine itself */

static int julius_create(struct ast_speech *speech, int format); int julius_destroy(struct ast_speech *speech);

/* Load/Unload a particular grammar

* - neither of these has any implementation; they do nothing. */

int julius_load_grammar(struct ast_speech *speech, char *grammar_name, char *grammar);

int julius_unload_grammar(struct ast_speech *speech, char *grammar_name); /* Activate/Deactivate a particular grammar

* - valid grammars are determined by your settings on the Sphinx server. */ int julius_activate_grammar(struct ast_speech *speech, char *grammar_name); /* Note: Deactivating a grammar has the side-effect of telling the engine * this is its last chance to provide results (and doesn't actually deactive a grammar) */

int julius_deactivate_grammar(struct ast_speech *speech, char *grammar_name); /* julius_write: send some data to engine for processing - data is required to be SLINEAR,

* 8khz, which is OK since that's what Asterisk sends */

int julius_write(struct ast_speech *speech, void *data, int len); /* julius_dtmf - unimplemented */

int julius_dtmf(struct ast_speech *speech, const char *dtmf); /* julius_start: prepare to proces incoming speech data */ int julius_start(struct ast_speech *speech);

/* julius_change: unimplemented */

int julius_change(struct ast_speech *speech, char *name, const char *value); /* julius_change_results_type: unimplemented */

int julius_change_results_type(struct ast_speech *speech, enum ast_speech_results_type results_type);

/* julius_get: retrieve results */

struct ast_speech_result* julius_get(struct ast_speech *speech); #endif

int julius_connect(struct ast_speech *speech, char const *host, const int port); int julius_disconnect(struct ast_speech *speech);

/** \brief Speech engine declaration */

static struct ast_speech_engine ast_engine = { JULIUS_ENGINE_NAME, julius_create, julius_destroy, julius_load_grammar, julius_unload_grammar, julius_activate_grammar, julius_deactivate_grammar, julius_write, julius_dtmf, julius_start, julius_change, julius_change_results_type, julius_get, AST_FORMAT_SLINEAR };

static int julius_create(struct ast_speech *speech, int format) {

ast_log(LOG_NOTICE,"julius_create called\n"); if(speech->data == NULL)

{

speech->data = ast_calloc(sizeof(struct ast_speech),1); if(speech->data == NULL) return JULIUS_ERROR; } if(dsp != NULL) { ast_dsp_free(dsp); dsp = NULL; } heardspeech = 0; noiseframes = 0; final = 0; dsp = ast_dsp_new(); ast_dsp_set_threshold(dsp, JULIUS_SILENCE_THRESHOLD);

ast_log(LOG_ERROR, "Can't create Julius server\n"); return -1;

}

int julius_destroy(struct ast_speech *speech) {

ast_log(LOG_NOTICE,"julius_destroy called\n"); //if(speech == NULL) return JULIUS_ERROR;

//if(speech->data == NULL) return JULIUS_SUCCESS; speech->data = NULL; if(dsp != NULL) { ast_dsp_free(dsp); dsp = NULL;

Một phần của tài liệu Nghiên cứu công nghệ nhận dạng tiếng nói tiếng việt và ứng dụng (Trang 90 - 119)