VÀ PHÁT FILE TIẾNG NĨI
XIX.Chưong trình chính :
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” :
XX. Chưong trình cập nhật dữ liệu :
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ấ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
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 đĩ.
II. Đá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, ...
PHẦN 5
KẾT LUẬN 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 MÃ NGUỒN THỰC HIỆN THỰC HIỆN MỘT SỐ MỘT SỐ CƠNG VIỆC CƠNG VIỆC CHÍNH 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 :
'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
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
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