Đề tài Tìm hiểu thông báo kết quả học tập của học sinh qua điện thoại

Tài liệu Đề tài Tìm hiểu thông báo kết quả học tập của học sinh qua điện thoại: LỜI NÓI ĐẦU Trong mỗi gia đình, các bậc cha mẹ có con cắp sách tới trường lúc nào cũng quan tâm đến việc học của con mình. Chẳng hạn bữa nay con mình có lên trả bài hay không ? Các bài kiểm tra trong tháng được bao nhiêu điểm ? Kết quả thi ở cuối mỗi học kỳ ra sao ? Và kể cả việc muốn biết con mình có nghỉ học bữa nào không hoặc có vi phạm nội quy gì ở trường hay không và lý do tại sao ? Thông thường, gia đình chỉ biết những chuyện này sau khi nhà trường phát sổ liên lạc về nhà. Ngày nay, với sự phát triển liên tục của ngành máy tính, ta có thể tự động hóa công việc này bằng cách kết nối máy tính với điện thoại như là một hệ thống trả lời tự động. Khi một phụ huynh gọi điện thoại tới số máy này, hệ thống sẽ thông báo các kết quả học tập của học sinh. Điều này thật là thuận lợi, nhanh chóng và dễ dàng , có thể thực hiện ở mọi lúc mọi nơi. Tuy đề tài này đã được hoàn thành nhưng chắc chắn không tránh khỏi thiếu sót. Em rất mong được sự quan tâm, giúp đỡ và góp ý của các thầy, cô và cá...

doc116 trang | Chia sẻ: hunglv | Lượt xem: 1214 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Đề tài Tìm hiểu thông báo kết quả học tập của học sinh qua điện thoại, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
LỜI NĨI ĐẦU Trong mỗi gia đình, các bậc cha mẹ cĩ con cắp sách tới trường lúc nào cũng quan tâm đến việc học của con mình. Chẳng hạn bữa nay con mình cĩ lên trả bài hay khơng ? Các bài kiểm tra trong tháng được bao nhiêu điểm ? Kết quả thi ở cuối mỗi học kỳ ra sao ? Và kể cả việc muốn biết con mình cĩ nghỉ học bữa nào khơng hoặc cĩ vi phạm nội quy gì ở trường hay khơng và lý do tại sao ? Thơng thường, gia đình chỉ biết những chuyện này sau khi nhà trường phát sổ liên lạc về nhà. Ngày nay, với sự phát triển liên tục của ngành máy tính, ta cĩ thể tự động hĩa cơng việc này bằng cách kết nối máy tính với điện thoại như là một hệ thống trả lời tự động. Khi một phụ huynh gọi điện thoại tới số máy này, hệ thống sẽ thơng báo các kết quả học tập của học sinh. Điều này thật là thuận lợi, nhanh chĩng và dễ dàng , cĩ thể thực hiện ở mọi lúc mọi nơi. Tuy đề tài này đã được hồn thành nhưng chắc chắn khơng tránh khỏi thiếu sĩt. Em rất mong được sự quan tâm, giúp đỡ và gĩp ý của các thầy, cơ và các bạn. Cuối cùng, em xin cảm ơn các thầy cơ ở bộ mơn Cơng nghệ thơng tin đã dành cho em đề tài này và đặc biệt là thầy Nguyễn Đức Thuần, người đã trực tiếp gợi ý và hướng dẫn, giúp em hồn thành đề tài này. Sinh viên thực hiện Bùi Danh Đạt PHẦN 1 GIỚI THIỆU ĐỀ TÀI Đặt vấn đề : Hiện nay, thơng thường mỗi học sinh cắp sách tới trường sẽ được phát cho một cuốn sổ liên lạc. Nhà trường sẽ sử dụng sổ này để thơng báo cho phụ huynh của học sinh biết kết quả học tập của học sinh ở sau mỗi tháng hoặc sau mỗi học kỳ. Trong sổ liên lạc, nhà trường thường chỉ ghi kết quả cuối cùng của mỗi tháng hoặc mỗi học kỳ. Do vậy phụ huynh khơng thể biết được chi tiết các cột điểm của các mơn học trong mỗi tháng. Ngồi ra, những lần nghỉ học cũng như những lần vi phạm nội quy của học sinh sẽ khơng được ghi vào trong ấy. Vì thế các bậc phụ huynh khĩ cĩ thể theo dõi chặt chẽ những diễn biến học tập của con mình ở trường như thế nào. Cơng việc giáo dục học sinh cần phải cĩ sự phối hợp giữa gia đình và nhà trường. Nhằm tạo sự thuận lợi cho các bậc phụ huynh cĩ thể nắm bắt được những thơng tin về học sinh một cách nhanh chĩng, đầy đủ, ở đề tài tốt nghiệp này, em đã tìm hiểu và viết một chương trình tự động thơng báo kết quả học tập của học sinh qua điện thoại. Em nhận thấy cĩ 3 vấn đề chính sau đây được đặt ra cần giải quyết là : Nhận được tín hiệu gọi tới từ điện thoại , tạo một kết nối giữa máy tính và cuộc gọi đĩ và nhận biết phím nào đã được bấm từ máy điện thoại của người gọi để thực hiện yêu cầu của người đĩ Tìm kết quả trong cơ sở dữ liệu Thơng báo bằng giọng nĩi cho người gọi nghe Vấn đề đầu tiên là phải tạo được một giao tiếp giữa điện thoại và máy tính thơng qua một modem. Và để truyền được tín hiệu tiếng nĩi từ máy tính đến điện thoại, modem này phải cĩ hỗ trợ chức năng “voice“. Máy tính lúc này sẽ đồng thời đĩng vai trị của máy điện thoại và nhân viên trường học. Người gọi cĩ thể sử dụng bất kỳ điện thoại nào để gọi tới. Lúc này máy tính sẽ tự động “nhấc máy” và đối thoại với người gọi. Vấn đề thứ hai được giải quyết bằng cách sử dụng các câu lệnh truy vấn (SQL) mà bất kỳ thao tác nào với cơ sở dữ liệu cũng cần phải cĩ. Vấn đề cuối cùng là áp dụng cơng nghệ “text-to-speech” để chuyển từ chữ trong máy tính sang tiếng nĩi, sau đĩ sẽ truyền đi qua điện thoại tới người gọi. Tất cả những vấn đề này sẽ được trình bày chi tiết trong các phần sau. Mơi trường lập trình : Chương trình “Thơng báo kết quả học tập qua điện thoại” được viết bằng ngơn ngữ lập trình Visual Basic 6.0 trên hệ điều hành Microsoft Windows 98. Hệ quản trị cơ sở dữ liệu được dùng để cài đặt cơ sở dữ liệu là Microsoft Access 97 Giới thiệu về hoạt động của chương trình : Chương trình được thiết kế để thơng báo mọi vấn đề liên quan đến đến học tập và đạo đức thường gặp nhất ở học sinh. Khi một người gọi điện tới, hệ thống sẽ yêu cầu nhập vào mã số của học sinh. Sau đĩ, hệ thống sẽ đưa ra menu để chọn lựa vấn đề đang quan tâm. Người gọi muốn nghe thơng tin chỉ cần nhấn các phím tương ứng với các mục sau đây : Phím Ý nghĩa # Thay đổi mã số học sinh 1 Nghe thơng tin về các lần nghỉ học trong tháng (ngày nghỉ học, số ngày nghỉ, cĩ phép/khơng phép, lý do) 2 Nghe thơng tin về các lần vi phạm nội quy trong tháng (ngày vi phạm, lý do) 3 Nghe điểm kiểm tra của các mơn học trong tháng 4 Nghe điểm thi của các mơn học ở cuối học kỳ 5 Nghe kết quả cuối tháng (điểm trung bình, hạng, học lực, hạnh kiểm) 6 Nghe kết quả cuối học kỳ (điểm trung bình, hạng, học lực, hạnh kiểm) 7 Nghe kết quả cuối năm học (điểm trung bình, hạng, học lực, hạnh kiểm) 8 Nghe thơng tin chi tiết về học sinh mang mã số hiện tại (họ, tên, ngày sinh, giới tính, nơi sinh, tên lớp đang học ở năm học hiện tại được chọn) 9 Chọn năm học khác (năm học mặc định là năm học hiện tại) * Kết thúc cuộc gọi Nếu người gọi nhấn một trong các phím 1, 2, 3, 5 thì sẽ được yêu cầu nhập vào tháng muốn biết. Nếu nhấn phím 4 hay 6 thì sẽ được yêu cầu nhập vào học kỳ muốn biết. Bất cứ lúc nào, người gọi cĩ thể nhấn phím * để trở về menu. Muốn kết thúc cuộc gọi, ngồi cách nhấn phím * tại menu chọn lựa, người gọi cĩ thể gác máy như bình thường, lúc này hệ thống sẽ tự phát hiện ra , ngắt kết nối với cuộc gọi hiện tại và tiếp tục chờ cuộc gọi khác đến. Nếu hệ thống phát hiện sau một khoảng thời gian định trước (thời gian rỗi) mà khơng cĩ một tác động nào từ phía người gọi thì hệ thống cũng sẽ tự động ngắt kết nối. PHẦN 2 CƠ SỞ LÝ THUYẾT Chương 1 GIAO TIẾP GIỮA ĐIỆN THOẠI VÀ MÁY TÍNH Sự cần thiết của modem : Như chúng ta đã biết kỹ thuật điện thoại ra đời và phát triển rất sớm trước kỹ thuật máy tính. Ngày đĩ, đường dây điện thoại được thiết kế chỉ để truyền tín hiệu của tiếng nĩi cĩ tần số của âm thanh. Dạng tín hiệu này thuộc loại tín hiệu tương tự (analog) và thường gọi là sĩng âm tần hình sin. Trong khi đĩ, máy tính chỉ cĩ thể xử lý các tín hiệu số (digital) cĩ tần số cao. Nếu tín hiệu số này được truyền trực tiếp trên đường dây điện thoại thì chúng sẽ bị suy giảm và biến dạng. Vì thế, một thiết bị chuyển đổi qua lại giữa hai tín hiệu này đã ra đời, gọi là modem. Cơng việc chuyển tín hiệu số của máy tính thành tín hiệu tương tự của đường dây điện thoại được thực hiện bằng một số phương pháp mà người ta gọi là điều chế (Modulation). Ngược lại, cơng việc chuyển tín hiệu tương tự của đường dây điện thoại thành tín hiệu số của máy tính cũng được thực hiện bằng một số phương pháp mà người ta gọi là giải điều chế (Demodulation). Modem chính là viết tắt của 2 chữ Modulation và Demodulation. Ứng dụng của modem mà chúng ta thường thấy nhất là kết hợp với máy tính để truy cập internet. Trong trường hợp này, mỗi đầu của đường dây điện thoại sẽ nối vào một modem gắn vào máy tính. Nhờ đĩ chúng ta cĩ thể truy xuất được dữ liệu của máy kia (máy chủ). Cịn ở đây, đối với cơng việc thơng báo qua điện thoại từ máy tính, ta chỉ cần nối một đầu dây điện thoại vào modem gắn với máy tính tại trường học. Người gọi cĩ thể sử dụng bất kỳ điện thoại nào để gọi tới. Lúc này tín hiệu từ đường dây điện thoại sẽ được modem chuyển đổi thành tín hiệu số và đưa vào máy tính để xử lý. Sau đĩ máy tính sẽ phát trở lại các tín hiệu số (ví dụ như tiếng nĩi ở dạng số) cho modem để modem chuyển đổi thành các tín hiệu tương tự (tiếng nĩi ở dạng tương tự) và truyền ngược trở lại người gọi. Nhờ đĩ , người gọi cĩ thể nghe được. Giao tiếp lập trình ứng dụng cho hệ thống điện thoại - TAPI (Telephony Application Programming Interface) : Một số khái niệm trong mơ hình TAPI : TAPI là gì ? TAPI được phát triển bởi sự kết hợp của hai hãng Intel và Microsoft . TAPI được thiết kế để truy xuất các dịch vụ điện thoại trên tất cả các hệ điều hành Windows. Nĩi cách khác, TAPI là tập hợp các hàm đơn lẻ được Windows cung cấp để hỗ trợ cho việc lập trình giao tiếp giữa điện thoại và máy tính thơng qua modem hoặc các thiết bị truyền thơng . Với TAPI , người lập trình khơng phải lo lắng về các tập lệnh của modem để khởi tạo nĩ hoặc phải chọn cổng hoạt động cho modem. Mục đích của TAPI là cho phép các nhà lập trình viết những ứng dụng mà khơng cần quan tâm chi tiết đến thiết bị phần cứng. Ví dụ với modem, người lập trình khơng cần biết modem loại nào, của hãng nào, tập lệnh của của modem là gì, sử dụng cổng nối tiếp hay song song hay cổng USB, chỉ cần thiết bị phần cứng đĩ cĩ một TAPI driver gọi là TSP(Telephone Service Provider) do nhà sản xuất cung cấp, mà thường khi cài thiết bị phần cứng này vào máy thì tất cả các driver của nĩ đều được cài vào. Do đĩ chỉ cần thiết bị này hoạt động tốt thì ứng dụng TAPI sẽ khơng gặp vấn đề gì. TAPI hỗ trợ cả việc truyền số liệu lẫn tiếng nĩi ở nhiều loại thiết bị đầu cuối khác nhau, hỗ trợ các kiểu kết nối phức tạp và các kỹ thuật quản lý cuộc gọi như: tạo cuộc gọi, chờ cuộc gọi , hộp thư thoại, vv... Các ứng dụng được viết bởi TAPI cĩ thể truy cập trực tiếp vào các dịch vụ trên đường dây điện thoại. Các ứng dụng này cĩ thể phát ra và nhận vào mọi tín hiệu của điện thoại. Dù đường dây điện thoại truyền tín hiệu dạng tương tự hay dạng số thì ta cũng cần một thiết bị giao tiếp giữa máy tính và đường dây điện thoại . Dĩ nhiên, thiết bị giao tiếp đĩ phải cĩ hỗ trợ TAPI TSP. Thiết bị này cĩ thể là một trạm ISDN , một bảng mạch hệ thống điện thoại hoặc đơn giản là một modem Chương trình ứng dụng TAPI : Ứng dụng TAPI là ứng dụng mà cĩ sử dụng giao tiếp lập trình hệ thống điện thoại nhằm thực hiện một cơng việc gì đĩ. Ví dụ : phần mềm giả lập điện thoại trong mạng điện thoại chuyển mạch cơng cộng (PSTN), phần mềm gửi/nhận fax, hộp thư thoại, hệ thống trả lời tự động, điện thoại qua internet (VoIP) vv ... TAPI DLL (Dynamic link library - Thư viện liên kết động) : Các thư viện này cùng với TAPI Server (Tapisvr.exe) là sự trừu tượng hĩa trong việc phân cách giữa người dùng và các nhà cung cấp dịch vụ điện thoại. Một thư viện TAPI liên kết với TAPI Server để cung cấp một giao tiếp giữa 2 lớp (xem mơ hình lập trình cho hệ thống điện thoại ở phần sau). Cĩ 3 thư viện liên quan tới TAPI : Tapi.dll, Tapi32.dll, Tapi3.dll . Mỗi thư viện này đều cĩ vài trị như nhau : Ứng dụng TAPI 16-bit Tapi.dll Tapi32.dll Ứng dụng TAPI 32-bit Tapi32.dll Ứng dụng TAPI3 32-bit Tapi3.dll MSP TAPISVR.EXE TSP Registry Telephony Control Panel, Dialing Properties, vv ... Mỗi thư viện này tương ứng với một thời điểm phiên bản của TAPI. Các ứng dụng 16-bit liên kết với Tapi.dll . Trong Windows 98/NT/2000, Tapi.dll sẽ hoạt động bằng cách ánh xạ các địa chỉ 16-bit tới các địa chỉ 32-bit , đồng thời chuyển các yêu cầu tới Tapi32.dll. Với các ứng dụng 32-bit thì chúng sẽ liên kết với Tapi32.dll (TAPI phiên bản 1.4 - 2.2). Với TAPI 3.0 và 3.1 thì ứng dụng sẽ liên kết với Tapi3.dll MSP (Media Service Provider ) : Trước hết MSP chỉ đến với TAPI 3, nĩ cho phép việc điều khiển một ứng dụng qua phương tiện với cơ chế vận chuyển đặc biệt. Một MSP luơn luơn tồn tại song song với một TSP (Tapi Service Provider). Một MSP cho phép việc điều khiển phương tiện thơng qua việc sử dụng thiết bị cuối và các giao tiếp luồng được định nghĩa bởi TAPI MSPI (Media Service Provider Interface) : MSPI là tập hợp các giao tiếp và các phương thức được thực hiện bởi MSP nhằm cho phép việc điều khiển một ứng dụng TAPI 3 trên phương tiện trong suốt phiên liên lạc truyền thơng. TAPI Server : TAPI Server được xem như kho trung tâm lưu trữ các thơng tin về hệ thống điện thoại trên máy người dùng. Tiến trình của dịch vụ này giám sát các tài nguyên cục bộ và ở xa của hệ thống điện thoại, giám sát các ứng dụng TAPI, và thực hiện một giao tiếp phù hợp với các TSP. (xem mơ hình lập trình hệ thống điện thoại ở phần sau để thấy mối liên hệ giữa TAPI Server và các thành phần khác) . Trong Windows 95, 98, NT, TAPI Server (Tapisrv.exe) sẽ chạy như một tiến trình riêng biệt. Trong Windows 2000, nĩ chạy trong ngữ cảnh của Svchost.exe . Khi ứng dụng nạp TAPI DLL và thực hiện cơng việc khởi tạo xong, DLL sẽ xây dựng một kết nối tới TAPI Server. Sau đĩ TAPI Server sẽ nạp các TSP. TSP (Telephony Service Provider ) : TSP thực chất là một thư viện liên kết động hỗ trợ việc điều khiển các thiết bị truyền thơng thơng qua một tập các hàm dịch vụ. Ứng dụng TAPI sử dụng các lệnh được chuẩn hĩa , và TSP điều khiển các lệnh đặc trưng mà cần phải được trao đổi với thiết bị. TSPI (Telephony Service Provider Interface) : TSP phải tạo ra một giao tiếp TSP phù hợp để thực hiện chức năng như một nhà cung cấp dịch vụ trong mơi trường hệ thống điện thoại. TSPI định nghĩa ra các hàm ngoại mà được hỗ trợ bởi TSP. Service Providers : Đây được xem như bộ phận cung cấp các dịch vụ cần thiết để thực hiện việc điều khiển thiết bị điện thoại một cách chi tiết. TSP cung cấp các điều khiển cuộc gọi và MSP nếu cĩ sẽ cung cấp điều khiển luồng qua phương tiện. Tất cả các TSP thực thi bên trong tiến trình TAPISRV. Các bộ phận cung cấp dịch vụ cĩ thể tạo ra các thread ngay trong ngữ cảnh của TAPISRV khi cần và được chắc chắn rằng khơng cĩ tài nguyên nào mà chúng tạo ra bị hủy do thốt khỏi một ứng dụng cá nhân nào đĩ. Khi cần TAPI Server cĩ thể dịch các câu lệnh của ứng dụng sang tập các lệnh phù hợp như là TSPI. Các MSP thực thi ngay trong tiến trình của ứng dụng, cho phép phản hồi nhanh một số yêu cầu trong việc điều khiển phương tiện. TAPI DLL cung cấp một kết nối chặt chẽ tới MSPI. Mơ hình lập trình cho hệ thống điện thoại : Ứng dụng TAPI TAPI DLL (Dynamic Link Library) MSP (Media Service Provider) TAPISVR (TAPI Server) TSP (TAPI Service Provider) Device MSPI Service Providers TSPI Ứng dụng TAPI sẽ nạp thư viện TAPI (TAPI DLL) vào và sử dụng TAPI cho các nhu cầu truyền thơng TAPI sẽ tạo ra một kết nối với TAPI Server. Ngồi ra, với TAPI phiên bản 3 sẽ tạo thêm một đối tượng MSP và kết nối với nĩ bằng cách sử dụng tập các câu lệnh được định nghĩa trước, hình thành nên MSPI Khi ứng dụng thực hiện một thao tác TAPI, thư viện TAPI sẽ làm một số kiểm tra cần thiết , sau đĩ sẽ chuyển thơng tin cho TAPISVR TAPISVR liên lạc với các tài nguyên khả dụng trên máy tính và giao tiếp với các TSP bằng cách sử dụng TSPI Những kết nối giữa TSP và MSP được diễn ra bằng cách sử dụng một kết nối ảo thơng qua TAPI DLL và TAPISVR TSP và MSP sẽ làm nhiệm vụ cung cấp những thơng tin về các trạng thái, chức năng của thiết bị khi cĩ yêu cầu. Kết quả của việc lập trình theo mơ hình này là ứng dụng vẫn cĩ thể hoạt động khi thay thế thiết bị mới mà khơng cần thực hiện những thay đổi mã nguồn. Mơ hình ứng dụng TAPI : Khởi tạo TAPI Điều khiển phiên làm việc Điều khiển thiết bị Điều khiển phương tiện Kết thúc TAPI Khởi tạo TAPI (TAPI Initialization) : Khởi tạo mơi trường truyền thơng trên máy tính Việc khởi tạo là đồng bộ và khơng quay trở về cho tới khi thao tác hồn tất hoặc bị lỗi Nếu TAPISRV khơng đang chạy thì TAPI sẽ gọi nĩ TAPI thiết lập một kết nối cho tiến trình TAPISRV TAPISRV nạp vào các bộ phận cung cấp dịch vụ được chỉ định trong registry và buộc chúng khởi tạo những thiết bị mà chúng hỗ trợ. Lấy số phiên bản thích hợp cho ứng dụng TAPI, TAPI và bộ cung cấp dịch vụ điện thoại . Cơng việc này bắt buộc phải làm ở TAPI 2. Kiểm tra và thu nhận thơng tin liên quan đến các thiết bị khả dụng cho ứng dụng TAPI Đăng ký thơng điệp để nhận được các sự kiện liên quan tới những thay đổi trạng thái của đường truyền. Điều khiển phiên làm việc (Session Control) : Một phiên làm việc nĩi chung hay một cuộc gọi nĩi riêng là một kết nối giữa hai hay nhiều địa chỉ. Kết nối này là động và các đối tượng liên quan phải được tạo , quản lý và hủy khi khơng cịn dùng. Trong trường hợp đơn giản nhất thì đây là quá trình từ lúc tạo cho đến lúc ngắt kết nối một cuộc gọi. Gồm 2 cơng việc chính : Điều khiển hoạt động của phiên làm việc : khởi tạo, duy trì và kết thúc phiên làm việc Lấy thơng tin của phiên làm việc : lấy những thơng tin chi tiết trong phiên làm việc. Điều khiển thiết bị (Device Control) : Thiết lập và lấy thơng tin của các thiết bị Network : là lớp giao vận cho việc truyền thơng. Line : là một kết nối tới một network. Đĩ là một thiết bị vật lý như bảng mạch fax, modem, hay cạc ISDN. Thiết bị cĩ thể khơng cần kết nối thẳng vào máy tính mà cĩ ứng dụng TAPI đang chạy Channel : là sự chia nhỏ của một line Address : một address đại diện cho một sự định vị trên network. Mỗi line hay channel đều cĩ một hay nhiều địa chỉ liên kết với nhau Terminal : một nguồn hồn trả lại cho một địa chỉ đặc trưng và một kiểu phương tiện. Điều khiển phương tiện (Media Control) : Phương tiện của phiên làm việc truyền thơng được thiết kế cho dữ liệu truyền qua. Nĩ cho phép một ứng dụng nhận biết những thay đổi của các kiểu phương tiện và điều chỉnh các luồng trên phương tiện như âm lượng của tiếng nĩi được truyền. Đĩ cũng cĩ thể là việc gửi và nhận các tín hiệu DTMF từ điện thoại. Kết thúc TAPI (TAPI Shutdown) : Kết thúc các phiên làm việc Giải phĩng các tài nguyên hệ thống đang chiếm giữ Các phiên bản TAPI : Bất kỳ một vấn đề nào liên quan đến TAPI cũng gồm cĩ 3 thành phần : chương trình ứng dụng, TSP, và chính bản thân của TAPI. Mỗi một trong ba thành phần này đều cĩ thể hỗ trợ đến một phiên bản TAPI tối đa nào đĩ . Đây là cơng việc của ứng dụng phải kiểm tra và chọn lựa phiên bản cao nhất của TAPI mà cả ba thành phần này đều hỗ trợ. Các con số phiên bản này được duy trì sự tương thích khi Microsoft mở rộng các khả năng của TAPI. Các phiên bản của hệ điều hành Windows khác nhau sẽ hỗ trợ các phiên bản Windows khác nhau : Hệ điều hành Windows Phiên bản TAPI ban đầu Phiên bản TAPI tối đa cĩ thể nâng cấp Windows 95 1.4 2.2 Windows 98 2.0 2.2 Windows ME 2.2 2.2 Windows NT 4 2.2 *SP5 2.2 Windows 2000 3.0 3.3 Windows XP 3.3 3.3 Cĩ một sự thuận lợi là các ứng dụng TAPI 1.4 vẫn cĩ thể hoạt động mà khơng gặp vấn đề gì khi chạy trên các hệ điều hành Windows khác. Cịn một ứng dụng TAPI 2.0 sẽ tự động loại bỏ một số chức năng của nĩ khi chạy cùng với một TSP 1.4. Dưới đây là các chức năng được hỗ trợ thêm đối với mỗi phiên bản TAPI : Phiên bản TAPI Các chức năng chính được hỗ trợ thêm 1.4 Các chức năng cơ bản cho Windows 32 bit 2.0 Đầy đủ các chức năng cho Windows 32 bit; Hỗ trợ Unicode 2.1 Hỗ trợ Client/Server 2.2 Quản lý cuộc gọi chuyên dụng 3.0 Giao tiếp kiểu COM (Component Object Model); Hỗ trợ Media Stream Providers ; TSP 2.1 vẫn được dùng 3.1 Một số điều khiển thiết bị điện thoại và một số giao tiếp trạm chuyên dụng Cĩ 2 thay đổi lớn trong các phiên bản này. Thứ nhất là ở phiên bản TAPI 2.1 khi chức năng hỗ trợ Client/Server được thêm vào. Điều này tạo khả năng cho thiết bị hệ thống điện thoại cĩ thể được cài đặt trên một máy Server mà các máy Client trong mạng cĩ thể truy cập được. Thay đổi lớn thứ hai đến với TAPI 3.0 khi nĩ được tổ chức như một bộ các đối tượng kiểu COM , sẽ tốt hơn kiểu kiến trúc ngơn ngữ C++ cho Windows. Nĩ tạo điều kiện dễ dàng cho việc viết các ứng dụng bằng bất cứ ngơn ngữ nào : C++ , Visual Basic hay Java. Ngồi ra , chức năng khác biệt chính là khả năng hỗ trợ MSP (Media Service Providers) nhằm cung cấp cách thức truy cập các luồng phương tiện trong một cuộc gọi và cĩ thể hỗ trợ hệ thống điện thoại theo giao thức internet (IP) DTMF trong hệ thống điện thoại : DTMF là viết tắt của cụm từ “Dual Tone Multi Frequency” (Cặp tín hiệu đa tần). Mỗi khi ta nhấn phím để gọi điện thoại, các âm thanh phát ra mà ta nghe được chính là các tín hiệu DTMF được gửi đến tổng đài. Theo chuẩn thì cĩ tổng cộng 16 cặp tín hiệu DTMF tương ứng với 16 phím bấm trên điện thoại. Tuy nhiên, với các máy điện thoại thơng thường hiện nay, chỉ cĩ 12 phím trên điện thoại cĩ thể gửi tín hiệu này, đĩ là : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, # . Bốn cặp tín hiệu cịn lại thì thường khơng dùng đến, đĩ là các phím : A, B, C, D . 16 cặp tín hiệu này được tổ chức dưới dạng ma trận 4x4. Khi ta nhấn 1 phím bình thường trên điện thoại, sẽ cĩ 2 tín hiệu được phát đi : 1 tín hiệu thuộc nhĩm tần số cao và 1 tín hiệu thuộc nhĩm tần số thấp. Sự kết hợp của 2 tín hiệu này sẽ tạo ra một tín hiệu DTMF. Ví dụ : Khi ta nhấn phím số 1 trên điện thoại thì sẽ tạo ra cặp tín hiệu (1209Hz , 697Hz), nhấn phím # thì sẽ tạo ra cặp tín hiệu (1477Hz , 941Hz ) 1209 Hz 1336 Hz 1477 Hz 1633 Hz 697 Hz [1] [2] [3] A 770 Hz [4] [5] [6] B 852 Hz [7] [8] [9] C 941 Hz [*] [0] [#] D Các tín hiệu DTMF này thường được sử dụng trong dịch vụ hộp thư thoại hoặc trong hệ thống máy điện thoại trả lời tự động. Khi một người gọi điện tới, máy sẽ nhận các yêu cầu của người đĩ thơng qua các tín hiệu này. Chương 2 TỔNG QUAN VỀ CƠ SỞ DỮ LIỆU Cơ sở dữ liệu trong thế giới hiện đại : Mơ hình cơ sở dữ liệu quan hệ do tiến sĩ E.F.Codd sáng chế đầu tiên vào năm 1970 để lưu trữ thơng tin. Mơ hình này là nền tảng của tất cả các hệ quản trị cơ sở dữ liệu thương mại như Access, SQL Server, Oracle, vv... Trong cơ sở dữ liệu quan hệ, các mục dữ liệu được lưu trữ trong các bảng (table), được cấu tạo bởi các dịng gọi là các mẫu tin (record) và các cột gọi là các trường (field). Cơ sở dữ liệu quan hệ cho phép nối các bảng với nhau với mục đích truy cập các mẫu tin liên quan với nhau chứa trong các bảng khác nhau. Ví dụ, ta cĩ một cơ sở dữ liệu để lưu trữ thơng tin học sinh. Trong cơ sở dữ liệu này, mỗi mẩu tin tương ứng với một học sinh. Mỗi mẩu tin cĩ 6 trường : mã số , họ , tên , ngày sinh, giới tính, mã nơi sinh. Đối với mọi học sinh, ta muốn biết cùng loại thơng tin nhưng những chi tiết cụ thể về từng học sinh dĩ nhiên là khác nhau. Từng học sinh phải được xác định một cách riêng rẽ, do đĩ mỗi mẫu tin sẽ cĩ một mã nhận dạng duy nhất được gọi là khĩa (key). Khĩa cĩ thể được dùng để tham chiếu chéo (cross reference) thơng tin lưu trong các bảng khác nhau trong cùng cơ sở dữ liệu. Các mẩu tin trong cơ sở dữ liệu cĩ dạng như sau: Mã số Họ Tên Ngày sinh Giới tính Mã nơi sinh 0058613 Bùi Danh Đạt 26/01/1980 Nam 31 0058614 Nguyễn Thị Trinh 8/10/1985 Nữ 31 Sơ lược về ODBC (Open DataBase Connectivity) : Chuẩn ODBC ra đời năm 1982 và được hỗ trợ bởi Microsoft. ODBC là một định nghĩa chuẩn của ứng dụng lập trình giao tiếp (API) được sử dụng để truy cập dữ liệu quan hệ hoặc truy xuất tuần tự theo chỉ mục (indexed sequential access method (SAM)) . Mọi hệ quản trị cơ sở dữ liệu đều hỗ trợ giao tiếp ODBC bằng cách cung cấp cho nĩ một driver tương ứng. Các ứng dụng được viết bằng C, C++, Visual Basic đều cĩ thể truy xuất được mọi cơ sở dữ liệu được cài đặt trong các hệ quản trị cơ sở dữ liệu . ODBC nhắm tới một thiên đường cho việc truy cập dữ liệu . Đĩ là một cơng nghệ cho phép ứng dụng client nối với cơ sở dữ liệu từ xa. Lưu trú trên máy Client, ODBC tìm cách làm cho nguồn dữ liệu quan hệ trở thành tổng quát đối với ứng dụng Client. Điều này cĩ nghĩa là ứng dụng Client khơng cần quan tâm kiểu cơ sở dữ liệu nĩ đang nối là gì. ODBC khơng phù hợp với cơ sở dữ liệu khơng phải là cơ sở dữ liệu quan hệ như dữ liệu dạng ISAM bởi vì nĩ khơng cĩ các giao tiếp cho phép tìm kiếm truy cập ngẫu nhiên các mẫu tin, việc thiết lập các phạm vi hoặc duyệt qua các chỉ mục . ODBC đơn giản là khơng được thiết kế để truy cập dữ liệu ISAM. Các cách truy xuất cơ sở dữ liệu : DAO (Data Access Objects): Như tên gọi của nĩ, các đối tượng truy cập dữ liệu, DAO được sử dụng để thao tác với cơ sở dữ liệu thơng qua lập trình. . Với DAO ta cĩ thể thi hành các câu truy vấn, cập nhật dữ liệu trong các bảng và cấu trúc cho cơ sở dữ liệu. DAO cũng được các nhà lập trình sử dụng để truy cập các cơ sở dữ liệu trên máy cá nhân hay Client/Server và DAO hoạt động khá hiệu quả với cơ sở dữ liệu Access RDO (Remote Data Object) : RDO tương tự như DAO nhưng mục đích chính là để truy cập dữ liệu từ xa thơng qua ODBC. ADO (ActiveX Data Objects) : ADO là nền tảng của kỹ thuật truy cập cơ sở dữ liệu Internet. Tuy nhiên, ta cĩ thể sử dụng ADO khơng chỉ để truy cập dữ liệu thơng qua trang Web mà cịn cĩ thể dùng nĩ để lấy dữ liệu từ ứng dụng. ADO là giao diện dựa trên đối tượng cho cơng nghệ dữ liệu mới nổi gọi là OLE DB. OLE DB được thiết kế để thay thế ODBC như một phương thức truy cập dữ liệu. ODBC hiện thời là tiêu chuẩn phía Client để truy cập các cơ sở dữ liệu quan hệ . OLE DB đi sâu hơn một bước bằng cách làm cho tất cả các nguồn dữ liệu trở thành tổng quát đối với ứng dụng Client. Sơ lược về SQL (Structured Query Language) : SQL là viết tắt của cụm từ “Structured Query Language” , tạm dịch là ngơn ngữ truy vấn cĩ cấu trúc. SQL thuộc loại ngơn ngữ thế hệ thứ tư. Việc sử dụng nĩ cĩ thể giải quyết nhanh chĩng vấn đề cung cấp thơng tin mà với ngơn ngữ thế hệ thứ ba phải tốn khá nhiều thời gian mã hĩa. Cùng với sự phát triển mạnh mẽ của các hệ quản trị cơ sở dữ liệu, SQL ngày càng được mở rộng. Ngơn ngữ : SQL khơng phải là ngơn ngữ thảo chương theo nghĩa cổ điển mà là một tập hợp các động từ cho phép thao tác các bảng (table). Các động từ này cĩ thể cĩ ở trong các ngơn ngữ khác ( C, COBOL, FORTRAN, ... ) Truy vấn : Đây khơng phải là chức năng duy nhất. SQL cịn cho phép xác định cấu trúc dữ liệu , đặc trưng hĩa ràng buộc tồn vẹn để đảm bảo sự tương thích giữa chúng, thiết lập các luật truy cập để đảm bảo bí mật thơng tin. Những chức năng này đều thực hiện một cách đơn giản thơng qua khả năng hỏi và truy xuất . Hiện tại mọi cố gắng để làm phong phú SQL đều nhằm vào hướng này. Cĩ cấu trúc : SQL khơng phải là một mơ hình hợp thức khi đối chiếu với lý thuyết ngơn ngữ hình thức. Trong nĩ cịn các tồn tại , ví dụ khi dùng kỹ thuật lồng nhau , tổ hợp các chức năng, vv.. Ngày nay SQL đã được chuẩn hĩa và trở thành chuẩn mực của việc truy xuất các cơ sở dữ liệu quan hệ. Những giao diện khác thực hiện qua thực đơn , cửa sổ, lưới, vv.... thường được cung cấp bởi SQL. SQL trở thành các điểm vào bắt buộc đối với các hệ quản trị cơ sở dữ liệu quan hệ . Ngồi SQL, trên thế giới cịn cĩ các ngơn ngữ khác như QUEL, QBE cũng cho phép thao tác cơ sở dữ liệu quan hệ. QUEL là ngơn ngữ do đại học Berkeley đề nghị cho hệ quản trị cơ sở dữ liệu quan hệ INGRES của họ. Hiện tại QUEL ngày càng ít được dùng. QBE (Query By Example) là ngơn ngữ “mắt lưới” xuất phát từ logic, thơng thường nĩ được xây dựng trên SQL. QBE ngày nay vẫn cịn được sử dụng bởi Access Một cách tổng quát, SQL dùng mọi tiêu chuẩn tìm kiếm được xây dựng từ logic mệnh đề bậc nhất, nĩ gồm 4 từ khĩa cơ bản : SELECT (Tìm), INSERT (Chèn), DELETE (Xĩa), UPDATE (Sửa) Các đối tượng truy cập dữ liệu DAO, RDO, ADO đều hỗ trợ rất mạnh việc thực thi các câu lệnh SQL nhằm tạo sự uyển chuyển, linh động và tối ưu trong các thao tác dữ liệu. Chương 3 SƠ LƯỢC VỀ TIẾNG NĨI VÀ CÁC PHƯƠNG PHÁP TỔNG HỢP TIẾNG NĨI Sơ lược về tiếng nĩi : Đặc tính chung của tiếng nĩi : Tiếng nĩi là cơng cụ diễn đạt thơng tin rất uyển chuyển và đặc biệt. Khi chúng ta phát ra một tiếng thì cĩ rất nhiều bộ phận như lưỡi, thanh mơn, mơi, họng, thanh quản…kết hợp với nhau để tạo thành âm thanh. Âm thanh này lan truyền trong khơng khí để đến tai người nhận; chính vì sự kết hợp của rất nhiều bộ phận để tạo ra âm thanh này nên âm thanh được phát ra ở mỗi lần hầu như là khác nhau. Vì vậy việc phân chia tiếng nĩi thành những loại cĩ đặc tính riêng là rất khĩ. Ở đây người ta tạm chia thành ba loại: Voiced sound : Khi chúng ta nĩi chữ "a" hay chữ "o" thanh mơn của ta rung và giãn ra, áp suất khơng khí ban đầu lớn và từ từ giảm xuống, lúc này âm phát ra cĩ dạng sĩng wave đặc trưng như hình vẽ. Unvoiced sound : Là âm khi ta phát ra một tiếng mà thanh mơn khơng rung. Cĩ hai loại cơ bản: phụ âm sát (fricative) và âm bật hơi (aspirate). Đối với phụ âm sát (khi phát âm vần "s"), điểm co thắt được tạo ra tại vài điểm trên bộ máy phát âm, và khơng khí được đẩy qua nĩ. Vì điểm co thắt cĩ khuynh hướng xảy ra gần miệng, tiếng dội của bộ máy phát âm cĩ ảnh hưởng nhỏ trong việc tạo nên phụ âm sát. Đối với âm bật hơi (khi phát âm vần "h") sự dao động khơng khí xảy ra tại thanh mơn bởi vì dây thanh âm được giữ lại một phần. Trong trường hợp này, tiếng dội của bộ máy phát âm điều chỉnh phổ của tiếng ồn. Điều này được thấy rõ nhất khi chúng ta nghe những âm thanh nhỏ, xì xào. Plosive sound : Trong trường hợp này, bộ máy phát âm được đĩng kín, áp suất khơng khí bị nén và được giải thốt thình lình. Sự giải thốt nhanh chĩng áp suất này tạo nên một sự kích thích ngắn cho bộ máy phát âm. Sự kích thích ngắn này cĩ thể xảy ra với sự cĩ rung / khơng rung của dây thanh mơn để tạo nên âm thanh voice/unvoice plosive Cơng nghệ Text–to–speech dùng để tổng hợp tiếng nĩi : Text-to-speech là một kỹ thuật dùng để chuyển dạng văn bản (text) sang tiếng nĩi (speech) . Text–to–speech được phân loại dựa vào phương pháp chuyển văn bản sang tiếng nĩi : Concatenated word : Với phương pháp này, những từ và ngữ phải được thu âm trước. Khi nhận được một chuỗi cần đọc, máy sẽ tách ra thành từng từ một. Sau đĩ, máy sẽ tìm các từ đã được thu âm tương ứng và ghép lại với nhau , tạo ra một chuỗi tiếng nĩi liên tục Tổng hợp : Phương pháp này phức tạp hơn nhiều vì sẽ tổng hợp tạo âm giống như những gì được tạo bởi giọng nĩi của con người phát ra. Phương pháp này cần cung cấp nhiều bộ lọc mơ phỏng chiều dài, cổ họng, khoang miệng, hình dạng mơi và vị trí lưỡi. Tuy nhiên tiếng nĩi được tạo bởi kỹ thuật tổng hợp này thường ít giống giọng con người , nhưng cĩ thể đạt được những chất lượng khác nhau của giọng bằng cách thay đổi một vài thơng số. Hai âm tố (Diphone Concatenation) : Phương pháp này nối những đoạn ngắn âm thanh được số hĩa lại với nhau và tạo ra âm thanh liên tục. Mỗi diphone bao gồm hai âm vị (phonemes), một âm vị bắt đầu âm ,âm vị cịn lại kết thúc âm. Ví dụ từ "hello" bao gồm những âm vị sau: " h eh l oe" .Những diphone tương ứng là "silence - h h -eh eh -l l-oe oe-silence” . Diphone được tạo bằng cách thu giọng người và xác định một cách cẩn thận tỉ mỉ vị trí bắt đầu và kết thúc của những âm vị. Mặc dù kỹ thuật này cĩ thể tạo âm giống thật, phải tốn cơng sức để làm việc này và giọng khơng cố định bởi những âm vị chỉ đặc trưng bởi ngơn ngữ của người phát âm. Sự cần thiết của cơng nghệ Text–to–speech (TTS) : Một ứng dụng sử dụng TTS khi nĩ cần chuyển dạng văn bản mang tính chất động sang dạng tiếng nĩi. Đĩ là những văn bản cĩ thể thay đổi thường xuyên, khơng cố định. Nếu chúng ta sử dụng phương pháp ghi âm cho tồn văn bản thì trước hết là khơng gian lưu trữ sẽ cần rất lớn nếu như văn bản đĩ dài hoặc cĩ nhiều văn bản khác nhau. Và sau đĩ nếu ta thay đổi văn bản khác thì sẽ phải tiến hành ghi âm lại. Nĩi tĩm lại TTS cĩ một số lợi ích và ứng dụng như sau : Đọc văn bản động : TTS hữu dụng cho những văn bản thay đổi thường xuyên. Ví dụ : sau khi nhận được e-mail, ta cĩ thể yêu cầu máy tự đọc cho mình nghe. Kiểm tra văn bản : Với một văn bản chi chít chữ, ta cĩ thể yêu cầu máy đọc để phát hiện những từ gõ sai Tiết kiệm khơng gian lưu trữ Thơng báo bằng giọng nĩi thay cho chuỗi thơng báo trên màn hình Ứng dụng truyền thơng : TTS được ứng dụng trong hộp thư thoại, hệ thống trả lời tự động Các phương pháp tổng hợp tiếng nĩi trong hệ thống tiếng Việt : Sự cần thiết của việc tổng hợp tiếng nĩi : Khi cần thơng báo cho người sử dụng bằng tiếng nĩi thì những chuỗi tiếng nĩi này phải được thu âm trước. Cách đơn giản nhất là mỗi câu nĩi ta thu âm lại thành một file. Khi cần đọc câu nào thì ta mở file âm thanh tương ứng với câu đĩ. Cách làm này cĩ ưu điểm là trung thực và đạt độ tự nhiên cao nhưng cĩ hai nhược điểm rất lớn là khơng linh hoạt và tốn nhiều dung lượng nhớ để lưu trữ các file âm thanh. Nhằm tăng tính linh hoạt cho hệ thống tự động và giảm dung lượng lưu trữ , ta phải dùng kỹ thuật tổng hợp tiếng nĩi. Các tiêu chuẩn cần thỏa mãn khi tổng hợp tiếng nĩi : Tiếng nĩi tổng hợp dù sao cũng khơng phải là tiếng nĩi thực cho nên khơng thể giống hồn tồn tiếng nĩi tự nhiên. Tuy nhiên khi sử dụng kỹ thuật này, cần thỏa 2 tiêu chuẩn tối thiểu: Đạt độ trung thực tương đối để mọi người cĩ thể hiểu được mà khơng cần học hỏi hoặc tập trung nghe cao độ. Nếu khơng đạt được điều này thì tiếng nĩi tổng hợp sẽ khơng thể sử dụng được trong thực tế vì sẽ làm người nghe khĩ chịu. Khối lượng lưu trữ khơng quá lớn để tiện sử dụng và cĩ thể phổ biến nhiều nơi Các phương pháp tổng hợp tiếng nĩi cho tiếng Việt : Cĩ 2 hướng tổng hợp tiếng nĩi chính là tổng hợp dựa vào việc phân tích tần số và tổng hợp dựa vào việc ghép âm. Đối với hướng phân tích tần số, ta phân tích các đặc trưng tiếng nĩi để tìm ra tần số, pha. Khi tổng hợp sẽ tái tạo tiếng nĩi từ các đặc tính này. Theo nghiên cứu của các chuyên gia thì hướng này rất phức tạp và chất lượng âm cịn kém. Trong khi đĩ, hướng tổng hợp dựa vào việc ghép âm dễ dàng được hiện thực trên máy tính hơn. Ghép từng từ đơn : Tính chất tiếng Việt là âm của từ đầu khơng ảnh hưởng âm các từ sau. Do đĩ ta cĩ thể ghép các từ thành một câu. Tiếng Việt phổ thơng cĩ khoảng hơn 6000 từ. Nếu ta thu với tần số lấy mẫu 8KHz, 8 bit/mẫu, mono, nén PCM. Mỗi từ thu trong 0.8 giây thì khối lượng âm thanh cần lưu trữ là: 6000 * 8000 * 1 * 1 * 0.8 = 38,400,000 byte ü Nhận xét : Phương pháp này đạt độ tự nhiên cao nhất và cách hiện thực đơn giản nhất. Mức độ ảnh hưởng của từ đi trước với từ đi sau là khơng đáng kể và cĩ thể chấp nhận được. Khơng thể thu âm đầy đủ các từ trong tiếng Việt vì tiếng Việt cĩ rất nhiều từ vay mượn từ các thứ tiếng khác, và cĩ từ khơng cĩ trong từ điển tiếng Việt nhưng vẫn cĩ thể phát âm ra được. Khối lượng dữ liệu của phương pháp này là khá lớn so với các phương pháp khác. Tuy nhiên, với dung lượng đĩa cứng ngày nay thì vấn đề dung lượng như thế khơng phải là vấn đề đáng lo ngại. Ghép âm theo các âm tiết cơ bản nhất: Ví dụ: "bằng" được ghép từ [b]+[ằ]+[ng] Phương pháp này cĩ khối lượng lưu trữ nhỏ nhất vì chỉ cĩ 28 phụ âm và 68 nguyên âm cùng các biến thể thanh. Khối lượng lưu trữ: (28+68) * 8000 * 1 * 1 * 0.8 = 614,400 byte ü Nhận xét : Khối lượng lưu trữ rất nhỏ Rất khĩ hiện thực vì khi phụ âm cĩ vai trị làm phụ âm cuối, chúng được phát âm khác với khi chúng làm phụ âm đầu. Phụ âm đầu mở ra để kết hợp với nguyên âm, phụ âm cuối khép lại khơng kết hợp với nguyên âm nữa. Cần chú ý khi phát âm nguyên âm trong trường hợp âm cuối là loại tắc (vơ thanh), ví dụ như p, t, c. Khi này thanh điệu khơng thể hiện trên phụ âm cuối mà thể hiện ở giai đoạn chuyển tiếp từ nguyên âm sang âm cuối. Chất lượng âm của phương pháp này rất thấp. Ghép âm từ hai âm (loại 1): Ví dụ : "bằng" được ghép từ [b] + [ ằng] . Một từ được tách ra làm hai phần là phụ âm đầu và vần. điều này căn cứ trên đặc điểm tiếng Việt là phụ âm đầu ít phụ thuộc vào phần vần và thanh điệu. Trong đĩ, phụ âm đầu được cắt rất ngắn chỉ cịn lại âm bật. Phần vần cũng được cắt bỏ ở phần đầu một lượng tưng ứng. Phương pháp này cho chất lượng âm thanh tương đương so với phương pháp ghép từ đơn. Theo phương pháp này ta tách được 28 phụ âm đầu và 650 phần vần. Với cách thu âm như trước thì khối lượng lưu trữ sẽ là: 650 * 8000 * 1 * 1 * (0.8 - 0.15) + 28 * 8000 * 1 * 1 * 0.15 = 3,143,600 byte Âm của phụ âm “tr” Âm của vần “inh” Vần “inh” sau khi được xén bớt phần thừa Âm “tr” sau khi được xén bớt phần thừa Âm của từ “trinh” HÌNH MƠ TẢ CÁCH GHÉP HAI ÂM THÀNH TỪ ü Nhận xét : Một từ tiếng việt bao gồm 2 phần: phần âm đầu và phần vần. Âm đầu chủ yếu là các phụ âm trong tiếng việt. Ứng với một loại âm đầu ( ở đây chủ yếu là phụ âm ) phần vần ở phía sau sẽ thay đổi theo một quy luật nào đĩ so với phần vần chuẩn khi chưa cĩ âm đầu tuỳ theo cách phát âm của phụ âm. Chẳng hạn : /t/ /am/ t /ch/ /am/ ch nếu đem /ch/ ráp với /am/ t thì tiếng phát ra sẽ khơng trung thực, tức là khi xây dựng mơ hình âm thanh phần vần độc lập với so với âm đầu sẽ khơng tận dụng được hết tính phân biệt giữa các từ do sự biến đổi phổ tín hiệu phần vần so với tác động của các âm đầu khác nhau. Để tìm ra quy luật biến đổi phổ tín hiệu này địi hỏi ta phải cĩ máy phân tích phổ và đi vào lĩnh vực xử lý tiếng nĩi, ta mới cĩ thể quan sát và phân tích mẫu sĩng âm tại từng thời điểm nhằm tìm ra quy luật. Ghép âm từ hai âm (loại 2): Ví dụ "bằng" được ghép từ [bà]+[ằng] Phương pháp này gần giống phương pháp trên nhưng phần phụ âm đầu được cắt lấn sang phần vần. Theo đĩ, ta sẽ cĩ 28*650 = 18,200 phần phụ âm đầu tương ứng với 650 phần vần. Trong thực tế, chỉ cần khoảng 1400 phần đầu. Như vậy khối lượng lưu trữ tổng cộng sẽ là: (1400+650)* 8000 * 1 * 1 * 0.8 = 13,120,000 byte ü Nhận xét : Vị trí cắt lấn sang phần vần nên khĩ xác định vì đây là vùng trộn lẫn giữa hai âm. Tuy khối lượng lưu trữ là nhỏ so với ghép từ (2.5 lần) nhưng lớn hơn nhiều so với ghép âm loại 1 (4 lần). Khi dùng phương pháp ghép âm thì việc chuẩn bị các âm mất thời gian rất lớn. Việc chuẩn bị âm được thực hiện thủ cơng do khơng thể xác định chính xác vị trí cần cắt. Do đĩ nếu phương pháp này cĩ số lượng âm lớn gấp 4 lần thì thời gian và chi phí bỏ ra cũng lớn gấp 4 lần so với phương pháp ghép âm loại một. Ngồi ra chất lượng âm của phương pháp này cũng chưa được kiểm nghiệm để cĩ thể đánh giá ưu điểm về chất lượng so với phương pháp loại 1. Giới thiệu về file Wave (*.wav) : Khái niệm về file Wave và file RIFF : File Wave là một dạng file theo chuẩn của Microsoft cho phép lưu trữ dữ liệu sĩng âm được số hĩa. Nĩ hỗ trợ rất đa dạng các thơng số của âm thanh như số bit lượng tử hĩa, tốc độ lấy mẫu, số kênh. Dạng file này rất phổ biến trên các thế hệ máy tính IBM và được sử dụng rộng rãi trong các chương trình chuyên nghiệp để xử lý các sĩng âm được số hĩa. File Wave là một trong số các file thuộc chuẩn của file RIFF (Resource Interchange File Format - Dạng file trao đổi tài nguyên). File RIFF sử dụng phương pháp lưu trữ dữ liệu trong các chunk. Mỗi chunk sẽ gồm 3 trường : Tên nhận dạng của chunk (ID) : gồm 4 byte kiểu Char Kích thước của chunk (Size) : Kiểu DoubleWord. Giá trị này khơng bao gồm 4 byte của ID và 4 byte của Size Dữ liệu của chunk đĩ (Data) Đặc biệt, chunk RIFF cĩ thể chứa các chunk khác trong trường dữ liệu. Các chunk này được gọi là subchunk và chunk RIFF lúc này được gọi là parent chunk. Một file RIFF luơn bắt đầu bằng một chunk RIFF. Kích thước của chunk RIFF là kích tổng số byte mà trường dữ liệu của nĩ chiếm, nĩi cách khác chính là kích thước của file RIFF - 8 . Tất cả các chunk khác trong file RIFF đều là subchunk của chunk RIFF. Chunk RIFF cĩ thêm một trường bổ sung nằm ở 4 byte đầu tiên trong trường dữ liệu của nĩ. Trường bổ sung này được gọi là kiểu định dạng (form type) , gồm 4 byte kiểu Char. Nĩ cho biết dạng dữ liệu được lưu trữ bên trong file RIFF là gì. Ví dụ, đối với các file Wave trường này sẽ cĩ tên là “WAVE” , đối với các file Avi trường này sẽ cĩ tên là “AVI ” Trường dữ liệu (Data) của chunk RIFF Hình sau minh họa 2 subchunk trong chunk RIFF của file RIFF : Cấu trúc file Wave : Một file wave là một tập hợp các loại chunk khác nhau. Vì file Wave chính là file RIFF nên chunk đầu tiên sẽ là chunk RIFF. Ngồi ra, cĩ 2 chunk rất quan trọng khơng thể thiếu là chunk Format mơ tả các thơng số của sĩng âm như tốc độ lấy mẫu, số bit lượng tử hĩa, vv... Chunk thứ hai là chunk Data để chứa dữ liệu âm thanh đã được số hĩa. Các chunk khác tùy trường hợp cĩ thể cĩ, cĩ thể khơng. Chunk Format : typedef struct { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; WORD wBitsPerSample; WORD cbSize; } WAVEFORMATEX; Cấu trúc của chunk Format được định nghĩa như sau : Trước hết chunk Format luơn cĩ tên nhận dạng là “fmt ”. Kích thước của chunk Format cĩ thể thay đổi tùy theo giá trị của wFormatTag. Giá trị này cho biết chuẩn nén âm thanh. Cĩ hơn 50 chuẩn của Microsoft và các hãng khác được định nghĩa trong file mmreg.h . Thơng thường chuẩn PCM (Pulse Code Modulation) của Microsoft là chuẩn phổ biến nhất. Với chuẩn này, các mẫu âm thanh được lưu trữ sẽ khơng được nén và cĩ giá trị được định nghĩa là 1. wChannels là số kênh âm thanh. Giá trị 1 cho âm thanh mono, 2 cho âm thanh stereo, 4 cho âm thanh 4 kênh, vv ... dwSamplesPerSec là tốc độ lấy mẫu, nghĩa là số mẫu được phát trong một giây, đơn vị là Hertz . Cĩ 3 giá trị thơng dụng là : 11025, 22050 và 44100 Hz mặc dù các tốc độ khác vẫn được dùng. dwAvgBytesPerSec sẽ chỉ ra cĩ bao nhiêu byte được phát mỗi giây. Nếu là chuẩn PCM thì giá trị này chính là dwSamplesPerSec * wBlockAlign . Ngược lại, giá trị này phải được tính tốn phù hợp với chuẩn tương ứng. wBlockAlign là kích thước của một khung mẫu âm thanh, tính theo byte. Ví dụ một khung mẫu âm thanh 16-bit mono là 2 byte, 16-bit stereo là 4 byte. Nếu chuẩn là PCM thì giá trị này bằng wChannels * (wBitsPerSample / 8) wBitsPerSample cho biết số bit dùng để lượng tử hĩa mỗi điểm lấy mẫu. Nếu chuẩn là PCM thì giá trị này là 8 hoặc 16. Vì các mẫu phải được lưu dạng BYTE hoặc WORD nên khi lưu trữ vẫn phải lưu hẳn 1 BYTE hoặc 1 WORD. Ví dụ số bit lượng tử hĩa là 12 thì sẽ cĩ 4 bit thừa khơng dùng tới. cbSize là kích thước của những thơng tin mở rộng thêm được thêm vào cuối cấu trúc WAVEFORMATEX. Thơng tin này được dùng khi chuẩn khác PCM. Với chuẩn PCM thì giá trị này bẳng 0 Chunk Data : Sau chunk Format là chunk Data. Chunk này chỉ đơn giản chứa các mẫu âm thanh đã được số hĩa. Tùy theo số kênh được chọn và số bit dùng để lượng tử hĩa mà các mẫu âm thanh này được sắp xếp khác nhau trong chunk Data. Cĩ 2 khái niệm về điểm mẫu và khung mẫu Một điểm mẫu chính là một giá trị đại diện cho một mẫu âm thanh được lấy tại một thời điểm nào đĩ. Nếu số bit dùng để lượng tử hĩa là 8 thì giá trị của một điểm mẫu dao động từ 0 đến 255. Nếu số bit dùng để lượng tử hĩa là 16 thì giá trị của một điểm mẫu dao động từ đến -32768 đến 32767. Đối với âm thanh cĩ nhiều kênh, các điểm mẫu từ mỗi kênh sẽ được xếp xen kẽ. Ví dụ với âm thanh stereo, các điểm mẫu sẽ được lưu trữ như sau : mẫu đầu tiên của kênh trái rồi tới mẫu đầu tiên của kênh phải, tiếp đĩ là mẫu thứ hai của kênh trái rồi tới mẫu thứ hai của kênh phải, ... và cứ như thế. Một khung mẫu bao gồm nhiều điểm mẫu được phát đồng thời. Ví dụ, với âm thanh stereo, 2 điểm mẫu thuộc 2 kênh sẽ tạo thành một khung mẫu Khung mẫu 1 Khung mẫu 2 Khung mẫu N Kênh 1 Kênh 2 Kênh 1 Kênh 2 ... Kênh 1 Kênh 2 = 1 điểm mẫu Với âm thanh mono thì mỗi khung mẫu chỉ cĩ 1 điểm mẫu. Đối với âm thanh cĩ nhiều kênh thì tùy theo số lượng kênh mà các thứ tự của các điểm mẫu trong một khung mẫu sẽ khác nhau : 1 2 Stereo Trái Phải 1 2 3 3 kênh Trái Phải Giữa 1 2 3 4 Quad Trái - Trước Phải - Trước Trái - Sau Phải - Sau 1 2 3 4 4 kênh Trái Giữa Phải Surround 1 2 3 4 5 6 6 kênh Giữa - Trái Trái Giữa Giữa - Phải Phải Surround ?Tĩm lại cấu trúc file Wave được mơ tả như bảng sau : Mơ tả Kích thước Giá trị thơng thường Tên của chunk RIFF (RIFF chunk ID) 4 byte “RIFF” Kích thước chunk RIFF (RIFF chunk size) 4 byte Kích thước file RIFF - 8 Định dạng của file RIFF (Form type) 4 byte "WAVE" Tên của chunk Format (Format chunk ID) 4 byte “fmt “ Kích thước chunk Format (Format chunk size) 4 byte 16 Chuẩn của file Wave (wFormatTag) 2 byte PCM = 1 Số kênh (wChannels) 2 byte mono = 1 stereo = 2 Tốc độ lấy mẫu (dwSamplesPerSec) 4 byte 11025 Hz, 22050 Hz, 44100 Hz Số byte/1 giây (dwAvgBytesPerSec) 4 byte dwSamplesPerSec * wBlockAlign Kích thước khung mẫu (wBlockAlign) 2 byte wChannels * (wBitsPerSample / 8) Số bit lượng tử hĩa (wBitsPerSample) 2 byte 8 16 Tên của chunk Data (Data chunk ID) 4 byte "data" Kích thước chunk Data (Data chunk size) 4 byte wBlockAlign * Tổng số khung mẫu Dữ liệu mẫu âm thanh ? ? Các phương pháp phát một file Wave : Dùng hàm sndPlaySound hoặc PlaySound : Windows cung cấp 2 hàm sau để phát một file wave : sndPlaySound và PlaySound . Hai hàm này tuy gọn, nhẹ, đơn giản nhưng sẽ nạp tồn bộ dữ liệu âm thanh vào bộ nhớ, và cũng vì vậy mà kích thước của file sẽ bị giới hạn đến 100 KB. Ngồi ra, hai hàm này cũng địi hỏi định dạng của dữ liệu âm thanh phải được nhận biết bởi trình điều khiển âm thanh và chỉ phát ra soundcard. Dùng MCI (Media Control Interface) : Các hàm của MCI được chứa trong thư viện Winmm.lib của Windows. Các khai báo đặc tả liên quan được cung cấp trong 2 file Mmsystem.h và Windows.h Để phát một file Wave cĩ kích thước lớn hơn, Windows cung cấp một giao tiếp MCI (Media Control Interface). Đây là một giao tiếp rất mạnh thực hiện cơng việc giao tiếp giữa ứng dụng và thiết bị âm thanh để thu hoặc phát rất nhiều loại file âm thanh như : phát các bản nhạc từ CD Audio, các file Wave, Midi, Video, vv... MCI là tập hợp các hàm, mỗi hàm cĩ một chức năng riêng biệt. Điều đặc biệt là MCI sử dụng các chuỗi lệnh để nhận biết cơng việc cần làm. Ví dụ, hàm mciSendString() sẽ gửi các chuỗi lệnh sau để phát 10000 mẫu âm thanh : mciSendString( "open c:\Sound\MyWave.wav type waveaudio alias finch", lpszReturnString, lstrlen(lpszReturnString), NULL); mciSendString("set finch time format samples", lpszReturnString, lstrlen(lpszReturnString), NULL); mciSendString("play finch from 1 to 10000", lpszReturnString, lstrlen(lpszReturnString), NULL); mciSendString("close finch", lpszReturnString, lstrlen(lpszReturnString), NULL); Dùng các hàm cấp thấp của Windows : Các hàm này được chứa trong thư viện Winmm.lib của Windows. Các khai báo đặc tả liên quan được cung cấp trong 2 file Mmsystem.h và Windows.h 4 hàm chính sau đây sẽ luơn được dùng để điều khiển việc phát một file Wave : waveOutOpen() waveOutPrepareHeader() waveOutWrite() waveOutClose() Trong đĩ, hàm waveOutOpen() sẽ yêu cầu cung cấp địa chỉ của một hàm gọi là CallBack. Hàm CallBack này sẽ cho biết một trong 3 sự kiện liên quan sẽ xảy ra , và 3 sự kiện này tương ứng với 3 thơng điệp sau được gửi đến hàm CallBack : MM_WOM_OPEN Được gửi khi thiết bị được mở bằng hàm waveOutOpen() MM_WOM_DONE Được gửi khi thiết bị đã phát xong khối dữ liệu âm thanh mà được gửi đi bằng hàm waveOutWrite() MM_WOM_CLOSE Được gửi khi thiết bị được đĩng bằng hàm waveOutClose() Ngồi ra, hàm waveOutOpen() cịn địi hỏi một số tham số quan trọng như : mã nhận dạng thiết bị âm thanh, handle của thiết bị sau khi mở, con trỏ tới một cấu trúc mơ tả file Wave. Để chọn thiết bị âm thanh mặc định, ta dùng hằng WAVE_MAPPER thay cho mã nhận dạng thiết bị âm thanh. Hàm waveOutPrepareHeader() sẽ tạo ra một header cho khối dữ liệu âm thanh sẽ phát bao gồm cả các mẫu âm thanh đã được nạp vào bộ nhớ. Cuối cùng, hàm waveOutWrite() sẽ bắt đầu gửi khối dữ liệu âm thanh này ra thiết bị để phát với header đĩ. Sau khi phát xong, ta phải gọi hàm waveOutClose() để đĩng thiết bị đã mở nhằm giải phĩng tài nguyên hệ thống. Tất cả các hàm liên quan đến cơng việc phát âm thanh này đều hoạt động thơng qua handle của thiết bị mà được lấy từ hàm waveOutOpen(). ? Nhận xét chung về 3 cách phát file Wave : Theo thứ tự của 3 cách nêu trên thì tính đơn giản tỷ lệ nghịch với tính linh động, uyển chuyển trong việc phát một file Wave, nghĩa là ta muốn nắm quyền kiểm sốt, điều khiển càng nhiều thì phải thực hiện càng nhiều thao tác. Trong 3 cách phát file Wave trên thì 2 cách đầu (dùng hàm sndPlaySound, PlaySound hoặc MCI) ta khơng cần quan tâm đến việc đọc file Wave và nạp các mẫu âm thanh vào bộ nhớ. Riêng cách thứ ba thì điều này là bắt buộc. Phần dưới đây sẽ nĩi sơ về cách đọc dữ liệu âm thanh vào bộ nhớ trước khi gọi các hàm đĩ. Cách đọc file Wave vào bộ nhớ : Để thao tác với file Wave, Windows cung cấp hàng loạt các hàm được chứa trong thư viện Winmm.lib. Sau đây là một số hàm chính thực hiện cơng việc đọc file Wave : Để làm việc với file Wave, ta phải mở file đĩ bằng hàm : mmioOpen() Sau đĩ định vị vào chunk ta cần bằng hàm : mmioDescend() Lúc này con trỏ file sẽ trỏ vào đầu phần dữ liệu của chunk đĩ và ta sẽ đọc dữ liệu vào bộ nhớ bằng hàm : mmioRead() Khi làm việc xong với 1 chunk, trước khi muốn định vị vào một chunk khác, ta phải ra khỏi chunk cũ bằng hàm : mmioAscend() Sau khi hồn tất cơng việc, ta sẽ đĩng file Wave đã mở bằng hàm : mmioClose() Trước khi đọc dữ liệu âm thanh vào bộ nhớ, ta nên đọc header của file Wave trong chunk Format. Từ header này ta sẽ xác định tổng số byte mà bộ nhớ cần để lưu trữ dữ liệu âm thanh và tiến hành cấp phát bộ nhớ bằng hàm : GlobalAlloc() Sau đĩ ta chỉ việc đọc dữ liệu vào vùng nhớ đĩ. Bất cứ lúc nào cần ta cũng cĩ thể giải phĩng vùng nhớ đĩ bằng hàm : GlobalFree() Ngồi ra, nếu ta muốn thay đổi vị trí hiện tại của con trỏ file sau khi đã mở file, ta cĩ thể dùng hàm : mmioSeek() Phương pháp thu âm : Với MCI đã giới thiệu ở phần trên để phát một file Wave, ta cũng cĩ thể dùng MCI để thu âm. Cách thứ hai là dùng các hàm cấp thấp của Windows. Như đã giới thiệu, các hàm này sẽ cho ta sự linh hoạt trong mọi thao tác. Trước hết ta phải mở thiết bị âm thanh bằng hàm : waveInOpen() Tương tự như khi phát, ta phải cung cấp địa chỉ của một hàm gọi là hàm CallBack mà sẽ phát ra các sự kiện liên quan đến quá trình thu âm. Các thơng điệp tương ứng với các sự kiện này là : MM_WIM_OPEN Được gửi khi thiết bị được mở bằng hàm waveInOpen() MM_WIM_DATA Được gửi khi thiết bị hồn tất việc thu âm sau khi gọi hàm waveInStart() MM_WIM_CLOSE Được gửi khi thiết bị được đĩng bằng hàm waveInClose() Ngồi ra, ta cũng cần cung cấp mã nhận dạng thiết bị âm thanh và một cấu trúc mơ tả các thơng số định dạng của file Wave. Để chọn thiết bị âm thanh mặc định, ta dùng hằng WAVE_MAPPER thay cho mã nhận dạng thiết bị âm thanh. Một việc khác khơng thể thiếu là cấp phát bộ nhớ để lưu các mẫu âm thanh thu được. Dựa vào các thơng số được mơ tả trong cấu trúc file Wave, ta phải tính tốn dung lượng bộ nhớ tối thiểu cần được cấp phát trong một khoảng thời gian nào đĩ. Cụ thể là : dwAvgBytesPerSec * thời gian thu âm Kế đĩ, ta sẽ tạo ra header file sẽ thu âm bao gồm cả vùng nhớ vừa cấp phát bằng hàm : waveInPrepareHeader() Sau đĩ ta sẽ gửi những thơng tin này đến thiết bị thu âm bằng hàm : waveInAddBuffer() Cuối cùng, quá trình thu âm sẽ được bắt đầu bằng hàm : waveInStart() PHẦN 3 THIẾT KẾ HỆ THỐNG Chương 1 SƠ ĐỒ HOẠT ĐỘNG CỦA HỆ THỐNG Lưu đồ giải thuật : Nếu nhìn một cách tổng quát thì chương trình sẽ gồm 4 giai đoạn chính : Kết nối cuộc gọi tới Tiếp nhận yêu cầu của người gọi Tìm dữ liệu trong máy tính Thơng báo kết quả tìm được Dưới đây là lưu đồ hoạt động tổng quát của chương trình : Bắt đầu Chuơng reo Kết nối Cĩ phím bấm Tìm dữ liệu Thơng báo kết quả F T T F Sơ đồ luồng hoạt động của hệ thống : Sau khi cuộc gọi đã được kết nối với máy tính, hệ thống sẽ ở một trong 11 trạng thái sau đây : Trạng thái Ý nghĩa MENU Đang thơng báo các mục trong menu MASO Đang nhận vào mã số học sinh NGHIHOC Đang lấy ra thơng tin về các lần nghỉ học của học sinh VIPHAM Đang lấy ra thơng tin về các lần vi phạm nội quy của học sinh KQKIEMTRA Đang lấy ra kết quả của các lần kiểm tra trong tháng KQTHI Đang lấy ra kết quả thi học kỳ KQTHANG Đang lấy ra kết quả cuối tháng KQHOCKY Đang lấy ra kết quả cuối học kỳ KQNAMHOC Đang lấy ra kết quả cuối năm học HOCSINH Đang lấy ra thơng tin chi tiết về học sinh NAMHOC Đang chọn năm học Dựa vào các trạng thái này mà hệ thống biết được cơng việc hiện tại cần thực hiện là gì. Hoạt động của hệ thống được mơ tả qua sơ đồ dưới đây : Mỗi hình elip tượng trưng cho một thủ tục để thực hiện cơng việc tương ứng. Các đường mũi tên chỉ hướng thực hiện giữa các thủ tục. Các con số, dấu *, # và tên trạng thái nằm trên đường mũi tên cĩ ý nghĩa hoặc là trạng thái hiện tại hoặc là chúng được gửi đi theo luồng hoạt động của hệ thống. Nếu chúng được bao giữa hai dấu thì đĩ là trạng thái hiện tại, nếu khơng thì chúng sẽ được gửi từ thủ tục này tới thủ tục kia. Thủ tục “nhận mã DTMF” sẽ nhận mã DTMF từ người gọi, sau đĩ sẽ truyền tới các thủ tục khác. Trong sơ đồ này chỉ tập trung chủ yếu ở phần nhận yêu cầu của người gọi. Sau khi nhận yêu cầu, hệ thống chỉ việc tìm dữ liệu và thơng báo kết quả cho người gọi theo một luồng hoạt động duy nhất. Chi tiết về hoạt động sẽ được đề cập trong các phần sau. MENU Nhận mã DTMF Thơng báo kết quả Menu KQTHANG KQHOCKY KQTHI KQKIEMTRA VIPHAM NGHIHOC MASO *,#, 0..9 MENU 0..9 1..2 0..9 Nhận năm học Nhận học kỳ Nhận tháng Tìm dữ liệu Chờ Bắt đầu Kết nối Ngắt kết nối Nhận mã số MASO NAMHOC MASO MENU #,*, 0..9 HOCSINH KQNAMHOC Chương 2 HOẠT ĐỘNG GIAO TIẾP GIỮA ĐIỆN THOẠI VÀ MÁY TÍNH Yêu cầu của ứng dụng là chỉ cần tạo một phiên làm việc giữa máy tính và điện thoại để cĩ thể nhận được các mã DTMF và truyền tiếng nĩi tới người gọi. Với yêu cầu này, mọi phiên bản TAPI cho ứng dụng 32-bit đều hỗ trợ nên em chọn phiên bản đầu tiên là TAPI 1.4 . Phiên bản này được thiết kế theo kiến trúc ngơn ngữ C++ nên khi lập trình trong Visual Basic sẽ khĩ khăn hơn. Tuy nhiên, ứng dụng TAPI 1.4 sẽ cĩ thể chạy trên mọi phiên bản Windows 32-bit và khơng địi hỏi cấu hình cao, trong khi ứng dụng TAPI 3 chỉ chạy trên Windows 2000/XP. Để sử dụng các hàm của TAPI, các hàm này phải được khai báo trước trong một module giống như các hàm API khác của Windows. Sau đây là các bước để tạo một kết nối với cuộc gọi tới : Khởi tạo đường truyền (line) : Mọi hoạt động giao tiếp giữa điện thoại và máy tính muốn diễn ra thì trước hết cần phải khởi tạo đường truyền giữa máy tính và điện thoại. Ở đây, modem sẽ là thiết bị trung gian giữa máy tính và điện thoại. Vì thế, đường truyền mà ta cần quan tâm chính là modem. Một máy tính cĩ thể cĩ gắn nhiều hơn một modem. Vì vậy, trước hết ta cần phải sử dụng hàm lineInitialize() để lấy về tổng số đường truyền (line) mà nĩ phát hiện cĩ trong máy. Cũng từ đây, ta sẽ chỉ định hàm nào sẽ tiếp nhận các sự kiện được sinh ra bởi các hoạt động của TAPI (ví dụ như khi chuơng reo, khi cĩ mã DTMF được gửi tới, vv...). Hàm này được gọi là lineCallBack() , do ta tự định nghĩa. Sau đĩ, ta sẽ lấy địa chỉ của hàm này và đưa vào hàm lineInitialize() như là một tham số của hàm lineInitialize() Sau khi đã khởi tạo thành cơng, lineInitialize() sẽ trả về một handle của TAPI đã nạp vào bộ nhớ. Handle này sẽ được sử dụng trong suốt quá trình hoạt động của hệ thống. Kiểm tra đường truyền (line) hợp lệ : Vì mục đích của ta là lấy được các modem hiện cĩ nên ta cần phải kiểm tra những line nào thích hợp. Sau khi cĩ được tổng số các line, ta duyệt qua từng line để tìm line thích hợp bằng cách kết hợp gọi 2 hàm lineNegotiateAPIVersion() và lineGetDevCaps(). Ứng với mỗi line, hàm lineNegotiateAPIVersion() sẽ trả về con số phiên bản (version) API mà tương thích với phiên bản của TAPI hiện đang sử dụng. Với con số phiên bản lấy được, hàm lineGetDevCaps() sẽ kiểm tra và trả về những chức năng được hỗ trợ trên line này. Từ đây, ta sẽ chọn được các line thích hợp chính là các modem hiện cĩ. Mở line : Để bắt đầu cho sự bắt tay làm việc giữa máy tính và điện thoại, sau khi đã chọn được line thích hợp, ta mở line đĩ bằng hàm lineOpen(). Nếu mở thành cơng. nĩ sẽ trả về một handle của line được mở. Với handle này, ta sẽ điều khiển mọi hoạt động diễn ra trên line này. Đăng ký các sự kiện cho TAPI : Mọi sự kiện liên quan đến TAPI (ví dụ chuơng reo, phát/nhận các mã DTMF, ... ) được gửi đến hàm lineCallBack() đều phải được đăng ký sau khi mở line. Để đăng ký, ta gọi hàm lineSetStatusMessages() và đưa vào giá trị mơ tả các sự kiện mà ta cần. Giá trị này thực chất là một dãy các 32 bit liên tiếp, mỗi bit tương ứng với một sự kiện của TAPI. Kết nối với cuộc gọi đến : Khi cĩ tín hiệu gọi tới (chuơng reo), thơng điệp LINEDEVSTATE_RINGING sẽ được gửi tới trong hàm lineCallBack() cùng với một handle của cuộc gọi đĩ. Nếu số tiếng chuơng reo bằng với một con số mà ta quy định trước đĩ thì ta sẽ gọi hàm lineAnswer() với handle vừa nhận được để kết nối với cuộc gọi đến. Cơng việc này tương đương với việc nhấc máy điện thoại lên để trả lời người gọi tới. Vì vậy, kể từ lúc này, ta cĩ thể gửi và nhận các mã DTMF hoặc gửi đi một chuỗi âm thanh nào đĩ và người gọi cĩ thể nghe được. Thu nhận các mã DTMF : Một khi đã kết nối thành cơng với cuộc gọi đến, ta gọi hàm lineMonitorDigits() để giám sát và thu nhận các mã DTMF được gửi tới. Cĩ thể nĩi đây là phần trung tâm của hệ thống, vì hệ thống sẽ tiếp nhận yêu cầu của người gọi thơng qua các mã DTMF này. Khi người gọi nhấn các phím trên điện thoại thì thơng điệp LINE_MONITORDIGITS sẽ được gửi tới hàm lineCallBack() cùng với các mã DTMF tương ứng như sau : Phím Mã DTMF (Hex) 0 30 1 31 2 32 3 33 4 34 5 35 6 36 7 37 8 38 9 39 * 2A # 23 Kết thúc cuộc gọi : Khi người gọi chọn yêu cầu “kết cầu thúc cuộc gọi” từ menu hoặc người gọi gác máy bất kỳ lúc nào, ta phải gọi hàm lineDrop() để hủy cuộc gọi hiện tại đang kết nối và hàm lineDeallocateCall() để giải phĩng cuộc gọi khỏi bộ nhớ. Bây giờ hệ thống sẽ trở về trạng thái chờ đợi cuộc gọi khác đến. Đĩng line hiện tại : Nếu muốn chọn modem khác để hoạt động, hoặc kết thúc hoạt động của hệ thống, ta cần gọi hàm lineClose() để đĩng line hiện tại đang được mở. Đây là điều nên làm vì nĩ sẽ hồn trả tài nguyên về cho máy. Kết thúc TAPI : Sau khi khởi tạo các line bằng hàm lineInitialize(), một số tài nguyên hệ thống sẽ bị chiếm dụng suốt phiên làm việc của TAPI. Khi thốt chương trình, ta gọi hàm lineShutdown() để kết thúc phiên làm việc đĩ, đồng thời giải phĩng các tài nguyên hệ thống. Chương 3 THIẾT KẾ VÀ TRUY XUẤT CƠ SỞ DỮ LIỆU Sơ lược về cơ sở dữ liệu : Một số đặc điểm của cơ sở dữ liệu dùng trong chương trình này : Mơ hình cơ sở dữ liệu được chọn là mơ hình cơ sở dữ liệu quan hệ Được cài đặt trong hệ quản trị cơ sở dữ liệu Microsoft Access 97. Phơng chữ được sử dụng trong cơ sở dữ liệu này thuộc bảng mã VNI Windows (2 byte). Mặc dù bảng mã này sử dụng 2 byte để mã hĩa một ký tự tiếng Việt , nhưng tồn bộ các ký tự hoa và ký tự thường đều cùng nằm trong một phơng chữ. Cịn bảng mã TCVN3 (ABC) chỉ sử dụng 1 byte cho mỗi ký tự tiếng Việt nhưng lại phân ra thành 2 phơng khác nhau : một phơng cho chữ hoa và một phơng cho chữ thường. Điều này sẽ gây khĩ khăn cho cả việc thiết kế và việc nhập dữ liệu từ người dùng. Bảng mã Unicode cũng sử dụng 2 byte cho mỗi ký tự tiếng Việt nhưng giá trị chênh lệch mã ASCII giữa ký tự hoa và ký tự thường khơng đồng đều. Cịn bảng mã VNI thì giá trị chênh lệch này luơn là 20h. Ví dụ : chữ “A” cĩ mã ASCII là 41h, chữ “a” cĩ mã ASCII là 61h ; chữ “B” cĩ mã ASCII là 42h, chữ “b” cĩ mã ASCII là 62h . Sự chênh lệch đồng đều này sẽ thuận lợi cho việc chuyển đổi giữa chữ hoa và chữ thường. Mơ hình quan niệm dữ liệu : Hoạt động truy xuất cơ sở dữ liệu : Đối tượng truy xuất dữ liệu được sử dụng trong chương trình này là Microsoft DAO 3.6. Khi hệ thống bắt đầu hoạt động, cơ sở dữ liệu sẽ được mở bằng phương thức OpenDatabase() để sẵn sàng phục vụ cho các hoạt động truy xuất dữ liệu. Và khi hệ thống ngừng hoạt động, cơ sở dữ liệu cũng sẽ được đĩng lại bằng phương thức Close. Mỗi khi cĩ người gọi tới muốn nghe một kết quả nào đĩ thì hệ thống sẽ yêu cầu người gọi cung cấp một số thơng số cần thiết như : mã số học sinh, tên tháng hoặc tên học kỳ muốn biết, vv.... Từ những thơng số này, hệ thống sẽ tạo ra một câu truy vấn SQL để tìm kết quả trong cơ sở dữ liệu và lấy về thơng qua phương thức OpenRecordset(). Nếu khơng tìm thấy kết quả nào, thuộc tính EOF của biến đối tượng Recordset sẽ mang giá trị TRUE và ngược lại sẽ mang giá trị FALSE. Vì mỗi lần truy vấn, hệ thống chỉ truy vấn trên một học sinh và được giới hạn bởi một tháng hoặc một học kỳ nào đĩ nên tốc độ truy vấn khá nhanh, người gọi cĩ thể nhận được kết quả ngay mà khơng phải chờ lâu. Ngồi ra, vì cơ sở dữ liệu được cài đặt bằng Access nên được hỗ trợ cơ chế cập nhật dữ liệu động, hệ thống cĩ thể hoạt động liên tục kể cả lúc dữ liệu đang được cập nhật vào. Chương trình cập nhật dữ liệu : Nhằm tạo điều kiện thuận lợi cho người quản trị hệ thống, ngồi chương trình chính là thơng báo kết quả cịn cĩ thêm một chương trình phụ kèm theo để cập nhật dữ liệu vào cơ sở dữ liệu. Người dùng cĩ thể mở chương trình này thơng qua menu của chương trình chính, kể cả lúc hệ thống đang hoạt động. Các phần cập nhật dữ liệu trong chương trình này đều sử dụng đối tượng truy cập dữ liệu Microsoft DAO 3.6 . Mọi thao tác với cơ sở dữ liệu đều thơng qua các phương thức cĩ sẵn của DAO , đồng thời kết hợp với các câu lệnh SQL. Trước khi thực hiện cập nhật dữ liệu, người sử dụng cần phải chọn năm học và lớp ở năm học đĩ. Mọi thao tác cập nhật sẽ ảnh hưởng tới một trong các học sinh thuộc lớp đĩ. Chương trình cập nhật dữ liệu tổ chức dạng menu gồm 8 phần : Học sinh : Dùng để cập nhật các thơng tin chi tiết về học sinh Khi thêm một học sinh mới vào lớp được chọn, chương trình sẽ tự sinh ra một mã số cho học sinh đĩ. Mã số này được đánh theo số thứ tự tăng dần. Vì vậy, chương trình sẽ lấy mã số của học sinh cuối cùng trong bảng HOCSINH rồi tăng lên một đơn vị để làm mã số cho học sinh mới sắp sửa thêm vào. Mã số này sẽ luơn được chương trình quản lý, người dùng khơng thể tự ý thay đổi. Ở phần ngày sinh, để người sử dụng khơng phải lúng túng trong việc gõ ngày tháng theo kiểu của Mỹ (tháng/ngày/năm) , em đã viết thêm một hàm chuyển từ kiểu ngày/tháng/năm sang kiểu tháng/ngày/năm để lưu vào cơ sở dữ liệu. Nhờ đĩ, người dùng cĩ thể gõ vào ngày sinh bình thường theo kiểu Việt Nam. Song song đĩ, em cũng phải viết thêm hàm chuyển ngược lại từ tháng/ngày/năm sang ngày/tháng/năm nhằm hiển thị ra màn hình ngày sinh được lấy từ cơ sở dữ liệu. Trong phần nơi sinh, tên của tất cả 61 tỉnh/thành phố đã được nạp sẵn vì một học sinh cĩ thể học tại trường thuộc tỉnh/thành phố này nhưng lại được sinh ra ở một tỉnh/thành phố khác. Ứng với mỗi học sinh được thêm vào bảng HOCSINH thì mã số của học sinh đĩ cùng với mã lớp và mã năm học sẽ được cập nhật vào trong bảng HS_LOP để biết học sinh đĩ thuộc lớp nào ở năm học nào. Vì mỗi học sinh sẽ được gán cho một mã số duy nhất nên mỗi học sinh chỉ được thêm vào trong bảng HOCSINH một lần. Do đĩ, nút “Chuyển lớp” được dùng để chuyển một học sinh từ lớp này sang lớp khác ở cùng năm học. Nhờ đĩ mà các kết quả trước đĩ của học sinh sẽ vẫn được bào tồn. Cơng việc này đơn giản chỉ là cập nhật lại mã lớp mới thay cho mã lớp cũ. Tương tự , nút “Học sinh cũ” sẽ cho phép thêm tất cả các học sinh thuộc một lớp nào đĩ ở năm học trước vào lớp hiện tại ở năm học hiện tại. Lúc này chương trình chỉ cập nhật các học sinh vào bảng HS_LOP. Nghỉ học : Dùng để thêm các lần nghỉ học của học sinh Phần nhập ngày nghi học được thiết kế tương tự như phần ngày sinh ở trên Dữ liệu sẽ được ghi vào bảng NGHIHOC Lỗi vi phạm : Dùng để thêm các lần vi phạm nội quy của học sinh Phần nhập ngày vi phạm được thiết kế tương tự như phần ngày sinh ở trên Dữ liệu sẽ được ghi vào bảng VIPHAM Điểm kiểm tra : Dùng để thêm điểm kiểm tra của học sinh Dữ liệu sẽ được ghi vào bảng KQKIEMTRA Điểm thi : Dùng để thêm điểm thi của học sinh Dữ liệu sẽ được ghi vào bảng KQTHI Kết quả cuối tháng : Dùng để thêm kết quả ở cuối tháng của học sinh Dữ liệu sẽ được ghi vào bảng KQTHANG Kết quả cuối học kỳ : Dùng để thêm kết quả ở cuối học kỳ của học sinh Dữ liệu sẽ được ghi vào bảng KQHOCKY Kết quả cuối năm học : Dùng để thêm kết quả ở cuối năm học của học sinh Dữ liệu sẽ được ghi vào bảng KQNAMHOC Ngồi ra, nhằm tạo sự linh động cho người dùng, chương trình cịn cho phép thêm mới một số loại dữ liệu sau : năm học, lớp, lý do nghỉ học, lý do vi phạm nội quy, mơn học, loại kiểm tra. Chương 4 TỔ CHỨC, TRUY XUẤT VÀ PHÁT FILE TIẾNG NĨI Sau khi đã tìm kiếm dữ liệu trong cơ sở dữ liệu , cơng việc cuối cùng là thơng báo kết quả bằng giọng nĩi qua điện thoại cho người gọi nghe, tức là chuyển dữ liệu từ dạng chữ, số sang tiếng nĩi. Cơng việc này chủ yếu gồm 2 giai đoạn chính : tìm dữ liệu tiếng nĩi tương ứng và phát qua điện thoại . Trước hết, em sẽ giới thiệu về cách tổ chức và lưu trữ tiếng nĩi. Chọn phương pháp tổng hợp tiếng nĩi : Ở phần cơ sở lý thuyết tổng hợp tiếng nĩi, em đã nêu bốn phương pháp ghép âm, trong đĩ đáng chú ý là phương pháp ghép âm loại một và phương pháp ghép từng từ đơn. Để đảm bảo chất lương âm cho ứng dụng, em dùng phương pháp ghép từ đơn. Chọn định dạng (format) cho file tiếng nĩi : Cĩ rất nhiều chuẩn khác nhau cho file âm thanh. Tuy nhiên nếu chọn chuẩn cho ra tiếng nĩi chất lượng càng cao thì kích thước dữ liệu thu âm cũng sẽ càng lớn. Ở đây, tiếng nĩi sẽ được truyền qua điện thoại nên khơng cần chất lượng cao như các bài nhạc, nhưng cũng khơng quá thấp khiến người gọi khĩ nghe. Sau khi thử nghiệm, em chọn chuẩn với các thơng số như sau : Kiểu mã hĩa PCM Số kênh 1 (mono) Tần số lấy mẫu 11025 Hz Số byte trên 1 giây 11025 Số byte trên 1 mẫu 1 Số bit trên một mẫu 8 Cách tổ chức file tiếng nĩi : Tiếng Việt cĩ khoảng hơn 6000 từ đơn thơng dụng. Dù tổ chức như thế nào thì ta cũng phải thu âm cho từng từ. Ngồi ra cịn cĩ một số câu nĩi sẽ được thu nguyên văn như : lời chào, lời tạm biệt, lời yêu cầu, thơng báo lỗi , vv... Cĩ hai cách tổ chức file tiếng nĩi : Tổ chức thành từng file .wav : Ta sẽ tiến hành thu âm mỗi từ thành một file .wav . Khi cần từ nào thì phát file .wav tương ứng. Đây là cách bình thường nhất, đơn giản nhất và dễ thực hiện nhất. Với một file .wav đúng chuẩn thì ta cĩ thể dùng bất kỳ chương trình thu nhạc nào để thu, và lúc phát thì cũng cĩ rất nhiều điều khiển hoặc hàm để phát file .wav này. Vì thế ta sẽ đỡ mất thời gian và cơng sức để lập trình lại. Tuy nhiên, với số lượng hơn 6000 từ thì đây khơng phải là cách giải quyết tốt. Lý do là vì sau khi thu âm xong tất cả, ta sẽ cĩ tổng cộng 6000 file .wav được lưu trên đĩa cứng, chưa kể một số file .wav để thu các câu nĩi nguyên văn. Với số lượng lớn các file .wav như vậy, cơng việc sao chép hoặc di chuyển sẽ gặp nhiều khĩ khăn và mất thời gian, Ngồi ra dung lượng đĩa để lưu trữ sẽ bị lãng phí rất nhiều vì cơ chế cấp phát dung lượng đĩa theo cluster. Hơn hết, đối với chương trình này thì cách tổ chức này cĩ một nhược điểm rất lớn, đĩ là để đọc ra một câu nĩi, chương trình sẽ phải mở và đĩng liên tục rất nhiều file .wav. Điều này làm cho tiếng nĩi giữa các từ bị gián đoạn, khơng liên tục một cách tự nhiên, đồng thời tốc độ thực hiện cũng chậm đi rất nhiều. Tổ chức thành các file dữ liệu tiếng nĩi (chỉ lưu trữ các mẫu âm thanh) : Như đã giới thiệu trong phần cơ sở lý thuyết, mỗi file âm thanh sẽ gồm 2 phần : phần header và phần dữ liệu (data) . Mặc dù ta phải thu âm từng từ nhưng các lần thu này đều phải theo một chuẩn nhất định, hay nĩi cách khác là các thơng số trong phần header phải hồn tồn giống nhau. Dựa vào đặc điểm này, ta cĩ thể cắt bỏ các header ra, chỉ lưu trữ các mẫu âm thanh. Như vậy ta cĩ thể chỉ cần 1 file duy nhất để lưu trữ các mẫu âm thanh này. Tuy nhiên, kích thước file này sẽ lên tới hàng chục MB. Điều này sẽ làm chậm quá trình đọc file để phát cũng như sẽ làm chậm quá trình cập nhật hoặc xĩa dữ liệu trong file này (tức là khi thu hoặc xĩa 1 từ). Để giải quyết vấn đề này, em chia thành 24 file (*.sam) tương ứng với 24 chữ cái tiếng Anh. Mỗi file này sẽ chứa dữ liệu của các từ thuộc cùng 1 chữ cái đầu tiên (ví dụ : “trinh”, “thành” thuộc file T.sam). Với tiếng Việt thì cĩ thêm 1 số chữ cái riêng như : Đ , Ă , Â , Ê, Ơ , Ổ, Ở , Ú, vv.... Đây thực ra chỉ là các chữ cái cơ bản cĩ ghép thêm dấu vào. Vì vậy, em sắp chúng theo chữ cái cơ bản, tức là “Đ” sẽ thuộc file D.sam , “Ă” sẽ thuộc file A.sam, “Ú” sẽ thuộc file U.sam Song song đĩ, ta phải tổ chức một bảng chỉ mục (index) cho các từ đã được thu âm. Bảng chỉ mục này sẽ gồm cĩ 4 mục : từ được thu âm, vị trí bắt đầu (FileOffset) , kích thước của phần dữ liệu tiếng nĩi (DataSize) và tên nhĩm (chữ cái cơ bản đầu tiên) ứng với từ này trong file *.sam . Thơng thường, bảng chỉ mục này sẽ được tổ chức thành một file riêng lẻ. Khi cần sẽ mở file này, dùng một thuật tốn để tìm kiếm từ đã được thu âm, sau đĩ đọc ra giá trị FileOffset , DataSize và tên nhĩm tương ứng. Dựa vào 3 giá trị này, ta sẽ mở file *.sam tương ứng để đọc phần dữ liệu tiếng nĩi vào bộ nhớ , sau đĩ phát đi cùng với một header được quy định trước. Tuy nhiên, ở chương trình này, em sẽ ghép bảng chỉ mục này vào trong file cơ sở dữ liệu KQHT.mdb . Khi cần ta chỉ việc dùng phương thức Seek của đối tượng Recordset để tìm từ được thu âm và tiếp tục tương tự như trên. Với cách tổ chức dữ liệu tiếng nĩi như thế này, ta đã khắc phục được các nhược điểm mà cách trên đã mắc phải. Tuy nhiên, mọi cơng việc từ thu âm, ghi vào file cho đến đọc file và phát ra âm thanh thì ta phải tự làm lấy, cĩ nghĩa là ta phải viết rất nhiều mã lệnh để thực hiện. Do đĩ sẽ mất khá nhiều thời gian và nếu khơng nghiên cứu kỹ , chương trình sẽ chiếm nhiều tài nguyên của hệ thống và cĩ thể xảy ra xung đột, tranh chấp tài nguyên hệ thống với các ứng dụng khác. Mặc dù vậy, sau khi chạy thử, chương trình hoạt động khá tốt và nhanh hơn. Đây là cách tổ chức dữ liệu tiếng nĩi được sử dụng trong chương trình này. Ngồi ra, cịn cĩ thêm một file @.sam chứa dữ liệu của các câu thơng báo, lời chảo . Sở dĩ em chọn tên “@” mà khơng phải một tên nào khác là vì trong bảng mã ASCII , ký tự “@” đứng trước ký tự “A”. Nhờ đĩ ta cĩ thể đưa vào vịng lặp từ ký tự “@” tới ký tự “Z” cho một số việc nào đĩ (ví dụ mở tất cả các file *.sam). Khi người dùng đang thu lại một số từ nào đĩ, các file *.sam sẽ bị thay đổi. Vì vậy, những lúc này, khi cĩ người gọi tới, hệ thống phải thơng báo cho người gọi biết hệ thống đang bận cập nhật dữ liệu. Dữ liệu của câu thơng báo này phải để ra một file riêng (wait.sam). FileOffset và DataSize của khối dữ liệu này cũng được lưu trong bảng chỉ mục như những khối dữ liệu khác trong các file *.sam . Chọn phương pháp phát và thu tiếng nĩi : Vì các dữ liệu tiếng nĩi được ta tự tổ chức và lưu trữ trong các file *.sam nên để phát và thu thì ta chỉ cĩ thể sử dụng các hàm multimedia cấp thấp của Windows. Ta sẽ điều khiển tồn bộ quá trình này, từ việc cấp phát bộ nhớ , định vị khối dữ liệu tiếng nĩi trong file *.sam cho đến việc chọn thiết bị âm thanh và phát tiếng nĩi đi, hoặc thu tiếng nĩi vào vùng đệm và lưu vào file *.sam. Đọc dữ liệu tiếng nĩi vào bộ nhớ : Để phát một câu nĩi, ta phải tách câu đĩ thành các từ đơn lẻ, sau đĩ tìm dữ liệu tiếng nĩi tương ứng của các từ đĩ rồi phát đi. Tuy nhiên, mỗi lần như thế hệ thống sẽ phải thực hiện hàng loạt các cơng việc như khởi tạo và dọn dẹp vùng đệm , mở và đĩng thiết bị vào ra âm thanh. Vì vậy, ở đây em sẽ khơng phát lần lượt từng từ mà sẽ đọc hết vào bộ nhớ rồi phát đi một lần. Nhờ đĩ tốc độ và chất lượng âm thanh được cải thiện đáng kể. Các bước thực hiện như sau : Mở các file *.sam bằng hàm mmioOpen() Tách một chuỗi thành các từ đơn Kiểm tra nếu từ nào là số thì chuyển thành chữ Tìm lần lượt các từ đĩ trong bảng chỉ mục đồng thời lấy ra 3 giá trị FileOffset , DataSize và tên nhĩm , nếu từ nào khơng cĩ thì sẽ bỏ qua. Lần lượt đọc vào vùng đệm dữ liệu tiếng nĩi của từng từ . Vùng đệm này được tạo ra cĩ kích thước bằng tổng kích thước của các dữ liệu tiếng nĩi. Để tìm đến đúng offset trong file *.sam và đọc dữ liệu ra, ta sử dụng 2 hàm thuộc bộ hàm multimedia : mmioSeek() và mmioRead() Phát dữ liệu tiếng nĩi từ vùng đệm : Muốn phát âm thanh đi, ta phải chỉ ra thiết bị mà âm thanh sẽ xuất ra. Ở đây, thiết bị xuất âm thanh chính là modem. Vậy trước hết, ta phải lấy giá trị ID tương ứng cho cuộc gọi được kết nối thơng qua modem. Cuộc gọi này cĩ handle được lưu giữ ngay khi cĩ tín hiệu gọi đến, kết hợp với handle của line hiện tại để truyền cho hàm lineGetID(). Giá trị ID này sẽ thay đổi tương ứng với mỗi cuộc gọi đến. Vì vậy, ta chỉ cần thực hiện việc này một lần cho mỗi cuộc gọi đến. Sau khi cĩ ID của thiết bị xuất âm thanh và vùng đệm dữ liệu tiếng nĩi đã sẵn sàng, ta lần lượt gọi các hàm waveOutOpen(), waveOutPrepareHeader(), waveOutWrite() để bắt đầu phát đi cùng với một vài thơng số của header đã nêu ở phần 2. Tất cả các hàm này đều đã được giới thiệu trong phần cơ sở lý thuyết. Chương trình thu âm : Mặc dù các từ tiếng Việt cũng như các lời chào và tạm biệt đã được thu âm sẵn trước khi tới tay người sử dụng, chương trình thơng báo kết quả học tập vẫn kèm thêm một chương trình thu âm nhằm cho phép người dùng thu âm lại nếu cần. Ngồi chức năng thu, chương trình cịn cho phép phát lại hoặc xĩa bất cứ từ nào đã thu âm. Nếu một từ đã cĩ mà ta thu lại thì từ cũ đã thu âm sẽ bị thay bằng từ mới vừa thu âm. Để thu âm thì người dùng cần trang bị một micro loa nối vào soundcard. Các chức năng của chương trình thu âm : Thu : Các thơng số cần cung cấp cho header hồn tồn giống như đã nêu ở phần 2 Để điều khiển soundcard dùng để thu âm, ta gọi hàm waveInOpen() với ID của thiết bị thu âm thanh sẽ được gán bằng hằng WAVE_MAPPER và chương trình sẽ tự động chọn thiết bị thu âm thanh phù hợp. Tiếp đĩ ta phải tạo ra vùng đệm để lưu trữ các mẫu âm thanh thu được. Vùng đệm này cĩ kích thước tối đa được tính như sau : BufferSize = MaxTime * Số mẫu trên 1giây * Số byte trên 1 mẫu Với MaxTime được quy định là 90 giây. Khi thời gian thu đến 90 giây thì chương trình sẽ ngừng thu và ghi dữ liệu vừa thu vào file. Sau đĩ, dùng 2 hàm waveInPrepareHeader() và waveInAddBuffer() để nạp header chuẩn bị cho việc thu. Khi đã sẵn sàng, hàm waveInStart() sẽ bắt đầu cơng việc thu âm. Từ lúc này mọi âm thanh thu vào sẽ được lưu vào vùng đệm. Khi ngừng thu, chương trình sẽ kiểm tra từ được nhập vào đã cĩ chưa, nếu cĩ thì sẽ xĩa phần dữ liệu tiếng nĩi cũ và ghi lại dữ liệu mới vào cuối file *.sam tương ứng, đồng thời cập nhật lại 2 giá trị FileOffset và DataSize trong bảng chỉ mục. Song song đĩ, chương trình cũng sẽ cập nhật lại FileOffset và DataSize của các từ trong nhĩm mà cĩ FileOffset > FileOffset của từ vừa cập nhật. Đĩ là vì khối dữ liệu tương ứng trong file *.sam đã bị xĩa (khối dữ liệu mới được để ở cuối file) nên tồn bộ các khối dữ liệu phía dưới sẽ được đơn lên, dẫn đến FileOffset của các từ phía dưới thay đổi theo. Cịn FileOffset của các từ phía trên khơng thay đổi Như thế các FileOffset của các từ phía dưới sẽ được cập nhật lại như sau: FileOffset = FileOffset - DataSize của từ vừa xĩa Nếu từ này chưa cĩ thì dữ liệu tiếng nĩi sẽ được ghi vào cuối file *.sam tương ứng , đồng thời thêm từ này và 3 giá trị FileOffset , DataSize và tên nhĩm vào bảng chỉ mục. Tên nhĩm sẽ là chữ cái cơ bản dựa vào ký tự đầu tiên của từ vừa thu. Tuy nhiên thường trước và sau khi khi thu âm sẽ cĩ một khoảng im lặng. Khi phát ra một câu gồm nhiều từ ghép lại, nếu khoảng im lặng này quá lâu sẽ làm ngắt quãng câu nĩi. Do đĩ, trước khi ghi dữ liệu tiếng nĩi vào file *.sam , chương trình sẽ cắt bỏ những mẫu âm thanh nào cĩ giá trị nằm trong khoảng 7Ah đến 86h. Phát : Quá trình phát ở đây tương tự như quá trình phát qua điện thoại, chỉ khác ở chỗ thiết bị xuất âm thanh là soundcard. Lúc này ID của thiết bị phát âm thanh sẽ được gán bằng hằng WAVE_MAPPER và chương trình sẽ tự động chọn thiết bị phát âm thanh phù hợp. Xĩa : Trước tiên chương trình sẽ đọc 2 giá trị FileOffset và DataSize tương ứng với từ cần xĩa. Dựa vào đĩ chương trình sẽ định vị được khối dữ liệu tiếng nĩi cần loại bỏ trong file *.sam tương ứng. Chương trình sẽ đọc lại 2 khối dữ liệu trước và sau khối dữ liệu cần cắt bỏ , sau đĩ ghi ra một file tạm, xĩa file *.sam , sau đĩ đổi tên file tạm trở thành *.sam đĩ Lúc này trong bảng chỉ mục, FileOffset của các từ được thu trước đĩ khơng cịn đúng so với file *.sam mới nữa. Vì vậy, ta phải tiến hành cập nhật lại những từ nào thuộc cùng nhĩm với từ vừa xĩa và FileOffset cĩ lớn hơn FileOffset của từ vừa xĩa, tương tự như trong phần thu một từ đã cĩ. Chèn khoảng im lặng : Cĩ một số từ cần thêm một khoảng thời gian im lặng ở đầu hoặc cuối từ vừa thu . Vì vậy chương trình cung cấp thêm chức năng này Dựa vào thời gian im lặng đầu và cuối (theo mili giây) do người dùng nhập vào, chương trình sẽ tính tốn kích thước dữ liệu mới như sau : DataSize= DataSize + (TgDau+TgCuoi)/1000*11500 Số mẫu âm thanh cần thêm vào đầu và cuối được tính : SoMauDau = TgDau/1000*11500 SoMauCuoi = TgCuoi/1000*11500 Tất cả các mẫu âm thanh được thêm vào sẽ được gán giá trị 80h. Bây giờ ta chỉ việc đọc khối dữ liệu tiếng nĩi cũ vào bộ nhớ, sau đĩ xĩa khối dữ liệu này trong file *.sam, cuối cùng ghi lại vào cuối file này các mẫu im lặng đầu, khối dữ liệu tiếng nĩi cũ trong bộ nhớ và các mẫu im lặng cuối. đồng thời cập nhật lại 2 giá trị FileOffset và DataSize của từ đĩ vào bảng chỉ mục và FileOffset của các từ phía trước bị thay đổi. PHẦN 4 VẬN HÀNH VÀ ĐÁNH GIÁ HỆ THỐNG Vận hành : Chưong trình chính : Lần đầu tiên chạy chương trình, hộp thoại cấu hình sẽ hiện ra cho người dùng chọn modem, số tiếng chuơng reo và thời gian rỗi tối đa. Khi bắt đầu chạy, chương trình cĩ giao diện như sau : Đây là trạng thái của hệ thống đang tắt, nghĩa là mọi cuộc gọi tới sẽ khơng được trả lời. Sau khi nhấn nút “Chờ cuộc gọi” thì hệ thống sẽ bắt đầu hoạt động, chờ tín hiệu của cuộc gọi tới : Nếu cĩ người gọi tới, hình ảnh minh họa tiếng chuơng đang reo của chiếc điện thoại như sau : Sau một số tiếng chuơng reo được đặt trước thì hệ thống sẽ “nhấc máy” để trả lời người gọi : Sau khi người gọi kết thúc cuộc gọi, hệ thống sẽ trở lại trạng thái 2, tức là chờ đợi cuộc gọi khác. Khi hệ thống đang hoạt động, bất kỳ lúc nào người sử dụng nhấn nút “Dừng” thì hệ thống sẽ ngắt kết nối (nếu cĩ) và ngừng hoạt động ngay. Tĩm lại, hệ thống sẽ ở một trong 4 trạng thái trên. Ngồi ra, người dùng cĩ thể mở chương trình cập nhật dữ liệu và thu tiếng nĩi thơng qua menu “Cập nhật dữ liệu” : Chưong trình cập nhật dữ liệu : Chương trình chia làm 8 phần cập nhật sẽ được chọn thơng qua menu : Phần “Học sinh” sẽ cho phép thêm, sửa, xĩa các học sinh thuộc lớp và năm học hiện tại được chọn : Trong phần này, nút “Chuyển lớp” cho phép chuyển một học sinh từ lớp hiện tại sang lớp khác. Nút “Học sinh cũ” cho phép lấy lại tất cả các học sinh thuộc một lớp ở năm học trước. Đây chính là thời điểm bắt đầu năm học mới nên cần cho các học sinh lên lớp sang năm học mới. Bảy phần cập nhật cịn lại sẽ cĩ giao diện tương tự như nhau : Ở bất kỳ phần nào, người dùng cĩ thể tìm tới một học sinh nào đĩ thơng qua mã số của học sinh. Ngồi ra, ở các mục như : năm học, lớp, lý do nghỉ học, lý do vi phạm nội quy, mơn học, loại kiểm tra, người dùng cĩ thể nhấn vào nút bên cạnh để thêm, sửa hoặc xĩa tùy thích Chưong trình thu tiếng nĩi : Bên trái là bảng liệt kê các từ đã được thu sẵn. Người dùng cĩ thể chọn một từ trong bảng này hoặc gõ vào ơ trắng bên phải để nghe hoặc thu âm lại hoặc xĩa bỏ. Để tìm nhanh một từ, người dùng gõ vào ơ trắng từ cần tìm rồi nhấn nút “Tìm” .Nếu tìm thấy, từ đĩ sẽ xuất hiện trong bảng liệt kê từ bên trái. Nếu khơng tìm thấy, một thơng báo sẽ xuất hiện. Người dùng cĩ thể chọn lời chào hoặc lời tạm biệt bên dưới bảng liệt kê từ để thu âm lại nếu muốn , nhưng khơng cho phép xĩa. Để thu một từ (hoặc lời chào) , người dùng chỉ cần gõ từ đĩ vào ơ trắng (theo bảng mã tiếng Việt là VNI for Windows) hoặc chọn từ đĩ ở bảng liệt kê , sau đĩ nhấn nút “Thu”. Quá trình thu âm sẽ bắt đầu cho tới khi người dùng nhấn nút “Dừng” hoặc quá 90 giây. Để nghe lại, người dùng cĩ thể nhấn nút “Phát”. Nếu khơng hài lịng thì nhấn lại nút “Thu” và thực hiện việc thu âm lại. Nếu nhấn nút “Xĩa” thì chương trình sẽ xĩa từ hiện tại trong ơ trắng Để chèn thêm một khoảng thời gian im lặng vào trước hoặc sau từ đã thu, gõ thời gian vào 2 ơ trắng (đơn vị là mili giây), sau đĩ nhấn nút “Thêm” Phía dưới cùng là thanh trạng thái cho biết tiến trình thực hiện đang diễn ra của một thao tác nào đĩ. Đánh giá hệ thống : Sau khi hồn tất và chạy thử chương trình , em cĩ một số nhận xét như sau : Ưu điểm : Chạy được trên các phiên bản Windows khác nhau Khơng địi hỏi cấu hình máy tính cao. Chẳng hạn với cấu hình như sau, chương trình vẫn hoạt động tốt : CPU : AMD- K5 - 100 MHz ; RAM : 48 MB ; MODEM : Motorola 56K - Internal Chương trình sử dụng giao tiếp là modem để hoạt động nên người dùng chỉ cần trang bị một modem (internal/external) với giá khơng quá cao. Cĩ khả năng đọc được hầu hết những từ tiếng Việt thơng dụng Cho phép cập nhật dữ liệu của học sinh ngay khi hệ thống đang hoạt động Cho phép thu lại tiếng nĩi của người dùng Hạn chế : Vì chương trình sử dụng giao tiếp là modem nên tại một thời điểm, hệ thống chỉ tiếp nhận được một cuộc gọi. Tuy nhiên, hệ thống chỉ hoạt động trong một trường học nên điều này cĩ thể chấp nhận được. Cơ sở dữ liệu được cài đặt bằng Access nên chưa được mã hĩa để bảo mật Vì thời gian cĩ hạn nên tiếng nĩi thu vào chưa được lọc để đạt chất lượng cao hơn Bảng chỉ mục chưa được tối ưu Hướng phát triển : Hỗ trợ telephony card nhằm kết nối với nhiều cuộc gọi tới ở cùng thời điểm. Mã hĩa cơ sở dữ liệu Access hoặc thay thế bằng hệ quản trị cơ sở dữ liệu khác như Oracle, SQL Server, ... để tăng cường khả năng bào mật Mở rộng chương trình cập nhật dữ liệu ở dạng bảng (lưới) nhằm cho phép thấy nhiều mẫu tin cùng lúc Thêm một số chức năng cho chương trình thu âm để người dùng linh động hơn trong việc thu tiếng nĩi như : giảm độ ồn, chỉnh sửa trực tiếp sĩng âm thanh ở dạng đồ họa, ... Tạo lại bảng chỉ mục để tìm kiếm nhanh hơn PHẦN 5 KẾT LUẬN Chương trình “Thơng báo kết quả học tập của học sinh qua điện thoại” đã được hồn thiện, cĩ thể cài đặt để chạy trên bất kỳ hệ điều hành Windows 32-bit nào. Với những yêu cầu đặt ra của đề tài, chương trình đã giải quyết được và cho ra kết quả như mong muốn. Chương trình này cĩ thể ứng dụng cho các trường học phổ thơng. Đề tài “Thơng báo kết quả học tập của học sinh qua điện thoại” là một đề tài rất hay và thiết thực. Trong quá trình nghiên cứu, tìm hiểu, em đã cĩ dịp ơn lại rất nhiều kiến thức đã học như : phân tích thiết kế hệ thống thơng tin quản lý, cài đặt, kết nối và truy xuất cơ sở dữ liệu, tạo và xử lý file âm thanh và các kỹ thuật lập trình trong Visual Basic. Song song đĩ, em cũng được biết thêm nhiều điều mới như các kiến thức liên quan đến lập trình giao tiếp giữa điện thoại và máy tính (TAPI), lập trình giao tiếp với multimedia. Từ những kiến thức thu thập được , em đã hiểu được phần nào về hoạt động của các hộp thư thoại ( voice mail) và các hệ thống trả lời tự động (answering machine) mà hiện nay được sử dụng rất nhiều. Tuy đề tài đã được khép lại nhưng vẫn cịn nhiều vấn đề cần được nghiên cứu và phát triển thêm nhằm mở rộng chương trình như : sử dụng telephony card để trả lời nhiều cuộc gọi ở cùng thời điểm, mở rộng cơ sở dữ liệu và tăng cường chức năng bảo mật, xử lý nhiều hơn tiếng nĩi được thu vào nhằm cho chất lượng cao hơn, vv... Đĩ là những mục tiêu phát triển mà bất cứ một chương trình nào cũng cĩ. PHỤ LỤC MÃ NGUỒN THỰC HIỆN MỘT SỐ CƠNG VIỆC CHÍNH 1. CHƯƠNG TRÌNH CHÍNH Mở cơ sở dữ liệu : 'Mo CSDL san sang cho viec tra loi 'Tra ve True neu mo thanh cong Private Function Open_Database() As Boolean 'Load database If File_Exist(SourcePath + "KQHT.mdb") Then Set DB = OpenDatabase(SourcePath + DBName) Set VRS = DB.OpenRecordset("tblVOICEINDEX", dbOpenTable) VRS.Index = "idxChuoi" Open_Database = True Else Open_Database = False End If End Function Đĩng cơ sở dữ liệu : Private Sub Close_Database() VRS.Close DB.Close End Sub Khởi tạo TAPI : 'Khoi tao TAPI 'Tra ve False neu co loi Private Function Init_TAPI() As Boolean Dim Loi As Long Loi = lineInitialize(hTAPI, App.hInstance, AddressOf LineCallBack, App.EXEName, TotalLines) If Loi < 0 Then MsgBox "Khơng thể khởi tạo thư viện TAPI !", vbCritical, Title Init_TAPI = False Else Init_TAPI = True End If End Function Chờ cuộc gọi tới : 'Cho doi 1 cuoc goi toi 'Tra ve thong bao loi neu co Public Function Wait_Call() As String Dim Loi As Long Wait_Call = vbNullString 'Mo Line If Not Open_Line() Then Wait_Call = "Khơng thể dùng modem được chọn !" Exit Function End If 'Dang ky cac Message cho Line Loi = lineSetStatusMessages(hLine, ALL_TAPIMESSAGES, 0) If Loi < 0 Then Wait_Call = "Khơng thể tạo sự kiện để nhận cuộc gọi !" Call Close_Line Exit Function End If frmKQHT.imgStatus.Picture = LoadResPicture("System_On", vbResBitmap) 'Function lineCallBack se duoc goi khi chuong reo End Function Mở line hiện tại : 'Mo Line hien tai voi CurLineID ‘Tra ve True neu thanh cong Private Function Open_Line() As Boolean Dim Loi As Long Dim NegoVersion As Long 'Version lay duoc sau khi Negotiate Dim plineExtenID As lineExtensionID Call lineNegotiateAPIVersion(hTAPI, CurLineID, LOW_TAPIVERSION, HIGH_TAPIVERSION, NegoVersion, plineExtenID) If lineOpen(hTAPI, CurLineID, hLine, NegoVersion, Unused, _ Unused, LINECALLPRIVILEGE_OWNER, _ LINEMEDIAMODE_AUTOMATEDVOICE, Unused) < 0 Then 'Error Open_Line = False Else Open_Line = True End If End Function Ngắt kết nối của cuộc gọi hiên tại : 'Ngat ket noi cuoc goi hien tai Public Sub Disconnect() If Playing Then Call Stop_Playing Call Wait End If Call Drop_Call Call Close_Line ' Dong file wave sau khi doc xong du lieu file wave If Not frmKQHT.mnuRecord.Checked Then Call Close_VoiceFiles frmKQHT.mnuRecord.Enabled = True 'Neu KHONG phai do nhan nut STOP de disconnect thi 'tao Line moi de nhan cuoc goi khac If frmKQHT.cmdStop.Tag "clicked" Then Call Wait_Call End Sub Hủy và giải phĩng cuộc gọi hiện tại : 'Huy bo cuoc goi hien tai Private Sub Drop_Call() If hCall 0 Then Call lineDrop(hCall, "", 0) Call lineDeallocateCall(hCall) hCall = 0 End If End Sub Đĩng line hiện tại : 'Dong Line hien tai Private Sub Close_Line() If hLine 0 Then Call lineClose(hLine) hLine = 0 End If End Sub Kết thúc TAPI : Private Sub ShutDown_TAPI() Call lineShutdown(hTAPI) End Sub Tiếp nhận các sự kiện của TAPI : 'Xu ly cac su kien TAPI Public Function LineCallBack(ByVal dwDevice As Long, ByVal dwMsg As Long, ByVal dwCallbackInstance As Long, ByVal dwParam1 As Long, ByVal dwParam2 As Long, ByVal dwParam3 As Long) As Long On Error GoTo Thoat Select Case dwMsg Case LINE_LINEDEVSTATE 'Thong diep cho trang thai cua LINE Call LineDevStateProc(dwDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3) Case LINE_CALLSTATE 'Thong diep cho trang thai cua CALL Call LineCallStateProc(dwDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3) Case LINE_MONITORDIGITS 'Thong diep cho tin hieu DTMF gui toi Call Receive_DTMF(dwParam1) End Select Exit Function Thoat: Call Disconnect End Function Tiếp nhận các sự kiện liên quan đến cuộc gọi (call) : 'Xu ly cac su kien trang thai cua CALL 'hCall = dwDevice 'hCallback = hCallbackInstance 'CallState = dwParam1 Private Sub LineCallStateProc(ByVal dwDevice As Long, ByVal hCallbackInstance As Long, ByVal dwParam1 As Long, ByVal dwParam2 As Long, ByVal dwParam3 As Long) Select Case dwParam1 Case LINECALLSTATE_OFFERING: 'Tin hieu co cuoc goi toi hCall = dwDevice Case LINECALLSTATE_CONNECTED: Call After_Connected Case LINECALLSTATE_DISCONNECTED: 'Xay ra khi cuoc goi bi ngat Call Disconnect Case LINECALLSTATE_IDLE Call Disconnect End Select End Sub Tiếp nhận các sự kiện liên quan đến line : 'Xu ly cac su lien trang thai cua LINE 'hLine = dwDevice 'hCallback = hCallbackInstance 'DeviceState = dwParam1 Private Sub LineDevStateProc(ByVal dwDevice As Long, ByVal hCallbackInstance As Long, ByVal dwParam1 As Long, ByVal dwParam2 As Long, ByVal dwParam3 As Long) Select Case dwParam1 Case LINEDEVSTATE_RINGING: 'Chuong reo --> So chuong = dwParam3 frmKQHT.imgStatus.Picture = LoadResPicture("System_Ring", vbResBitmap) If dwParam3 >= Rings Then Call Answer_Call End Select End Sub Kết nối với cuộc gọi tới : 'Tra loi cuoc goi toi Private Sub Answer_Call() Dim Loi As Long Loi = lineAnswer(hCall, "", 0) If Loi < 0 Then Call Disconnect End If End Sub Sau khi kết nối thành cơng : ‘Sau khi ket noi, mo file voice va phat loi chao Private Sub After_Connected() If Not frmKQHT.mnuRecord.Checked Then 'Neu KHONG dang chay ctr Record frmKQHT.mnuRecord.Enabled = False If Open_VoiceFiles() = True Then frmKQHT.imgStatus.Picture = LoadResPicture("System_Hangup", vbResBitmap) PhutHT = 0 frmKQHT.timCall.Enabled = True Call Welcome Else frmKQHT.cmdStop = True MsgBox "Khơng thể mở các file *.sam", vbSystemModal + vbCritical, Title End If Else 'Dang cap nhat tieng noi, thong bao busy frmKQHT.imgStatus.Picture = LoadResPicture("System_Hangup", vbResBitmap) If Load_WaitFile() = True Then Call Start_Playing(1000) End If End Sub Mở các file *.sam : 'Mo cac file Voice de doc du lieu ‘Tra ve True neu thanh cong Public Function Open_VoiceFiles() As Boolean Dim pmmIOInfo As mmIOInfo Dim c As Byte Dim Handle As Long Open_VoiceFiles = False For c = Asc("@") To Asc("Z") If Dir(SourcePath + Chr(c) + ".sam") = vbNullString Then Exit Function Handle = mmioOpen(SourcePath + Chr(c) + ".sam", pmmIOInfo, MMIO_READ) If Handle 0 Then hVoiceFile(c - 63) = Handle Else Exit Function Next Open_VoiceFiles = True End Function Nạp dữ liệu tiếng nĩi vào bộ nhớ : 'Load data from file into mem Public Function Load_VoiceFiles(Chuoi As String) As Boolean Dim Loi As Long, OldDataSize As Long, TotalDataSize As Long Dim arrChuoi() As ChuoiVoice 'Mang cac chuoi con va nhung thong tin cua chung Dim arrChuoiCon() As String 'Mang chuoi con, chi co ten chuoi Dim TenChuoi As String Dim i As Long, LastIndex As Long Dim Found As Boolean 'Bao hieu co tim thay 1 chuoi nao trong CSDL khong ? 'Tach chuoi me thanh cac chuoi con arrChuoiCon = Split(Chuoi, Cach, , vbTextCompare) Found = False Load_VoiceFiles = False LastIndex = UBound(arrChuoiCon) ReDim arrChuoi(LastIndex) TotalDataSize = 0 'Tim thong tin chuoi trong CSDL For i = LBound(arrChuoiCon) To LastIndex VRS.Seek "=", arrChuoiCon(i) If VRS.NoMatch = False Then 'Found arrChuoi(i).hVoiceFile = hVoiceFile(Asc(UCase(VRS!Nhom)) - 63) arrChuoi(i).FileOffset = VRS!FileOffset arrChuoi(i).DataSize = VRS!DataSize TotalDataSize = TotalDataSize + VRS!DataSize Found = True 'Chi can co 1 voice End If Next i 'Neu khong co voice nao thi thoat If Not Found Then Exit Function 'Cap phat bo nho hMem = GlobalAlloc(GMEM_ZEROINIT, TotalDataSize) pWaveBuffer = GlobalLock(hMem) TotalSamples = TotalDataSize 'Doc du lieu OldDataSize = 0 For i = LBound(arrChuoiCon) To LastIndex If (arrChuoi(i).hVoiceFile 0) Then 'Co tu nay Call mmioSeek(arrChuoi(i).hVoiceFile, arrChuoi(i).FileOffset, SEEK_SET) Loi = mmioRead(arrChuoi(i).hVoiceFile, pWaveBuffer + OldDataSize, arrChuoi(i).DataSize) If (Loi = -1) Then hMem = GlobalFree(hMem) Exit Function End If OldDataSize = OldDataSize + arrChuoi(i).DataSize 'Tong so byte da doc vao mem End If Next Load_VoiceFiles = True Thoat: End Function Phát tiếng nĩi : 'Bat dau phat voice da co trong mem Public Sub Start_Playing(LoopCount As Long) Dim OpenFlag As Long Dim Loi As Long Dim ErrMsg As String * 200 'Thiet lap flag de mo waveout device If WaveOutID = -1 Then 'Neu ra sound card OpenFlag = CALLBACK_FUNCTION Else OpenFlag = CALLBACK_FUNCTION Or WAVE_MAPPED End If 'Set format With pWaveFormat .cbSize = 0 .nAvgBytesPerSec = 11025 .nBlockAlign = 1 .nChannels = 1 .nSamplesPerSec = 11025 .wBitsPerSample = 8 .wFormatTag = 1 End With Loi = waveOutOpen(hWaveOut, WaveOutID, pWaveFormat, AddressOf waveOutProc, 0, OpenFlag) If Loi 0 Then hMem = GlobalFree(hMem) Exit Sub End If 'Chuan bi du lieu am thanh de phat ra pWaveHeader.lpData = pWaveBuffer pWaveHeader.dwBufferLength = TotalSamples * pWaveFormat.nBlockAlign pWaveHeader.dwFlags = 0 pWaveHeader.dwLoops = LoopCount - 1 'So lan lap lai , dem lui Loi = waveOutPrepareHeader(hWaveOut, pWaveHeader, Len(pWaveHeader)) If Loi 0 Then Call Close_WaveOut hMem = GlobalFree(hMem) Exit Sub End If 'Bat dau phat am thanh Loi = waveOutWrite(hWaveOut, pWaveHeader, Len(pWaveHeader)) If Loi 0 Then Call Close_WaveOut hMem = GlobalFree(hMem) Else Playing = True End If 'Sub waveOutProc se duoc goi khi phat xong End Sub Ngừng phát tiếng nĩi : Public Sub Stop_Playing() pWaveHeader.dwLoops = 0 Call waveOutReset(hWaveOut) 'Sub waveOutProc se duoc goi de tiep tuc End Sub Tiếp nhận các sự kiện của thiết bị phát âm thanh : 'Xu ly su kien cua WaveOut Private Sub waveOutProc(ByVal hwo As Long, ByVal uMsg As Long, ByVal dwInstance As Long, ByRef hdr As WAVEHDR, ByVal dwParam2 As Long) On Error Resume Next If uMsg = MM_WOM_DONE Then frmKQHT.timWaveOut.Enabled = True End If End Sub Lấy ID của thiết bị phát âm thanh : 'Lay ID cua thiet bi de phat am thanh Public Function Get_WaveOutID(DeviceClass As String) As Boolean Dim Loi As Long Dim pVarString As varString pVarString.dwTotalSize = Len(pVarString) Loi = lineGetID(hLine, 0, hCall, LINECALLSELECT_CALL, pVarString, DeviceClass) If Loi < 0 Then Get_WaveOutID = False Else If pVarString.dwStringOffset = 0 Then 'Nothing Get_WaveOutID = False Exit Function Else 'Lay ID WaveOutID = pVarString.dwData Get_WaveOutID = True End If End If End Function Nhận mã DTMF : 'Nhan cac ma DTMF tu lineCallBack Public Sub Receive_DTMF(Phim As Long) PhutHT = 0 'Reset thoi gian roi If Playing Then Call Stop_Playing 'Dinh nghia lai ma phim Select Case Phim Case &H30 To &H39: Phim = Phim And &HF Case &H2A: Phim = Phim_SAO '* If (Status STATUS_MaHS) Then Goto_Menu Exit Sub End If Case &H23: Phim = Phim_# '# End Select 'Cac thao tac khac Select Case Status Case STATUS_MaHS 'Neu dang nhan ma so Call Receive_MaHS(Phim) Case STATUS_NGHIHOC Call Receive_Thang(Phim) Case STATUS_VIPHAM Call Receive_Thang(Phim) Case STATUS_KQKIEMTRA Call Receive_Thang(Phim) Case STATUS_KQTHI Call Receive_HocKy(Phim) Case STATUS_KQTHANG Call Receive_Thang(Phim) Case STATUS_KQHOCKY Call Receive_HocKy(Phim) Case STATUS_KQNAMHOC Case STATUS_HOCSINH Case STATUS_NAMHOC Call Receive_NamHoc(Phim) Case STATUS_MENU Call Menu(Phim) End Select End Sub Menu với các phím bấm tương ứng : Private Sub Menu(Phim As Long) Select Case Phim Case Phim_# ''#: Nhap ma so khac Call Nhap_MaHS Case 1 Status = STATUS_NGHIHOC Call Nhap_Thang(Status) Case 2 Status = STATUS_VIPHAM Call Nhap_Thang(Status) Case 3 Status = STATUS_KQKIEMTRA Call Nhap_Thang(Status) Case 4 Status = STATUS_KQTHI Call Nhap_HocKy(Status) Case 5 Status = STATUS_KQTHANG Call Nhap_Thang(Status) Case 6 Status = STATUS_KQHOCKY Call Nhap_HocKy(Status) Case 7 Status = STATUS_KQNAMHOC Call Monitor_DTMF(False) Call Get_KQNamHoc Case 8 Status = STATUS_HOCSINH Call Monitor_DTMF(False) Call Get_Info_HS Case 9 Status = STATUS_NAMHOC Call Nhap_NamHoc Case Phim_SAO ' *: Thoat Call Play_Voice1("@tạm_biệt") Call Wait Call Disconnect End Select End Sub Nhận mã số học sinh : 'Nhan ma so hoc sinh Private Sub Receive_MaHS(Phim As Long) Dim Chuoi As String Select Case Phim Case 0 To 9 DTMFBuffer = DTMFBuffer & Phim If Len(DTMFBuffer) = 7 Then 'Neu ma so da du 7 ky tu Call Monitor_DTMF(False) If Check_MaHS() = True Then ' tim thay hoc sinh MaHS = DTMFBuffer Chuoi = "@đã_nhập_mã_số " + Convert_MaHS2VoiceString(MaHS) Call Play_Voice1(Chuoi) Call Wait Call Goto_Menu Else 'khong co hoc sinh Chuoi = "@khơng_cĩ_mã_số " + Convert_MaHS2VoiceString(DTMFBuffer) Call Play_Voice1(Chuoi) Call Wait Call Nhap_MaHS End If End If Case Phim_# '# 'Nhap lai Call Nhap_MaHS Case Phim_SAO '* If MaHS = vbNullString Then Call Play_Voice1("@chưa_nhập_mã_số") Call Wait Call Nhap_MaHS Else Call Goto_Menu End If End Select End Sub Nhận năm học : 'Nhan nam hoc mac dinh cho phien lam viec Private Sub Receive_NamHoc(Phim As Long) Select Case Phim Case 0 To 9 DTMFBuffer = DTMFBuffer & Phim If Len(DTMFBuffer) = 4 Then 'Neu year da du 4 chu so Call Monitor_DTMF(False) TenNamHoc = Check_NamHoc(DTMFBuffer) 'Ktra co nam hoc nay chua ? MaNH = DTMFBuffer If DTMFBuffer vbNullString Then 'Neu tim thay co nam hoc nay MaNH = DTMFBuffer 'Thiet lap MaNH mac dinh TenNH(0) = CInt(Left(TenNamHoc, 4)) TenNH(1) = CInt(Right(TenNamHoc, 4)) Chuoi = "@đã_chọn_năm_học " & Split_Number(TenNH(0)) & Cach _ & Split_Number(TenNH(1)) Call Play_Voice1(Chuoi) Call Wait Call Goto_Menu Else If TenNamHoc = "error" Then 'Neu nam hoc khong hop le DTMFBuffer = vbNullString Chuoi = "@lỗi_năm_học" Else 'Neu chua co nam hoc nay Chuoi = "@chưa_cĩ_năm_học " & Split_Number(CInt(TenNamHoc)) _ & Cach & Split_Number(CInt(TenNamHoc) + 1) End If 'TenNamHoc Call Play_Voice1(Chuoi) Call Wait Call Nhap_NamHoc End If 'DTMFBuffer End If 'len(DTMFBuffer) End Select End Sub Nhận tháng : 'Nhan ten thang Private Sub Receive_Thang(Phim As Long) Dim Thang As Byte Select Case Phim Case 0 To 9 DTMFBuffer = DTMFBuffer & Phim If Len(DTMFBuffer) = 2 Then Call Monitor_DTMF(False) Thang = CByte(DTMFBuffer) If ((Thang >= 1) And (Thang = 9) And (Thang <= 12)) Then Select Case Status Case STATUS_KQTHANG: Call Get_KQThang(Thang) Case STATUS_KQKIEMTRA: Call Get_KQKiemTra(Thang) Case STATUS_NGHIHOC: Call Get_NghiHoc(Thang) Case STATUS_VIPHAM: Call Get_ViPham(Thang) End Select Else Call Play_Voice1("@lỗi_tháng") Call Wait Call Nhap_Thang(Status) End If End If End Select End Sub Nhận học kỳ : 'Nhan ten hoc ky Private Sub Receive_HocKy(Phim As Long) 'Chi co the la hoc ky 1 hoac 2 Call Monitor_DTMF(False) Select Case Phim Case 1, 2 If Status = STATUS_KQHOCKY Then Call Get_KQHocKy(Phim) Else 'Status =STATUS_KQTHI Call Get_KQThi(Phim) End If Case Else Call Play_Voice1("@lỗi_học_kỳ") Call Wait Call Nhap_HocKy(Status) End Select End Sub Giám sát để thu nhận các mã DTMF : 'Giam sat cac ma DTMF 'dwDigitModes = 0 --> Ngung giam sat 'On=True: giam sat - Off=False: ngung giam sat Public Sub Monitor_DTMF(OnOff As Boolean) Dim Loi As Long Dim DigitModes As Long If OnOff = True Then DigitModes = LINEDIGITMODE_DTMF Else DigitModes = 0 Loi = lineMonitorDigits(hCall, DigitModes) If Loi < 0 Then 'Co the cuoc goi bi ngat Call Disconnect End If End Sub Lấy thơng tin về các lần nghỉ học : 'thong bao thong tin ve NGHI HOC Public Sub Get_NghiHoc(ByVal Thang As Byte) Dim RS As Recordset, RS1 As Recordset Dim SQL As String, GiayPhep As String Dim Chuoi As String Dim NgayNH As String Dim DauThang As String, CuoiThang$ If (Thang >= 9) Then DauThang = "#" & Thang & "/1/" & TenNH(0) & "#" If Thang < 12 Then CuoiThang = "#" & Thang + 1 & "/1/" & TenNH(0) & "#" Else CuoiThang = "#1/1/" & TenNH(1) & "#" End If Else DauThang = "#" & Thang & "/1/" & TenNH(1) & "#" CuoiThang = "#" & Thang + 1 & "/1/" & TenNH(1) & "#" End If 'Loc theo ma HS SQL = "SELECT tblLYDO.TenLD, tblNGHIHOC.SoNgayNH, " _ + " tblNGHIHOC.GiayPhep, tblNGHIHOC.NgayNH " _ + " FROM tblLYDO INNER JOIN tblNGHIHOC " _ + " ON tblLYDO.MaLD = tblNGHIHOC.MaLD " _ + " WHERE (tblNGHIHOC.MaHS = '" + MaHS + "')" Set RS = DB.OpenRecordset(SQL, dbOpenDynaset, dbReadOnly) 'Loc theo ngay nghi hoc SQL = "(tblNGHIHOC.NgayNH >= " + DauThang + ")" _ + " AND (tblNGHIHOC.NgayNH <= " + CuoiThang + ")" RS.Filter = SQL Set RS1 = RS.OpenRecordset RS.Close 'Sort RS1.Sort = "tblNGHIHOC.NgayNH " Set RS = RS1.OpenRecordset RS1.Close If RS.EOF Then 'Neu khong co nghi hoc vao ngay nay '@khơng_cĩ_nghỉ_học = @khơng_cĩ_nghỉ_học_trong_tháng Chuoi = "@học_sinh" + Im200 + HoTenHS + Im400 + "@khơng_cĩ_nghỉ_học " _ & Thang & Im400 + "@năm_học" + Im200 & TenNH(0) _ & Im400 & TenNH(1) Else '@các_lần_nghỉ_học = @các_lần_nghỉ_học_trong_tháng Chuoi = "@các_lần_nghỉ_học " & Thang & Im200 + "@của_học_sinh" _ + Im200 + HoTenHS Do While Not RS.EOF NgayNH = CStr(RS!NgayNH) If RS!GiayPhep = True Then GiayPhep = "@cĩ_phép" Else GiayPhep = "@khơng_phép" Chuoi = Chuoi + Im800 + "ngày" + Im200 & Day(NgayNH) _ & " tháng " & Month(NgayNH) & Im200 + "năm" _ + Im200 & Year(NgayNH) & Im400 + "@số_ngày_nghỉ" _ + Im200 & RS!SoNgayNH & Im200 & "ngày" _ + Im400 + GiayPhep + Im400 + "@lý_do" + Im200 + RS!TenLD RS.MoveNext Loop End If Chuoi = Chuoi + " @về_menu" RS.Close Call Monitor_DTMF(True) Call Play_Voice(Chuoi) End Sub Lấy thơng tin về các lần vi phạm nội quy : 'thong bao ve loi vi pham Public Sub Get_ViPham(ByVal Than

Các file đính kèm theo tài liệu này:

  • docKQHT.doc