有一个GSM压缩程序,运行后总是无法结束,请朋友帮忙指点一下
Private Sub cmd_Finish_Click()
record_finished = 1
End Sub
Private Sub cmd_Record_Click()
Dim rst As Long
Dim str As String * 256
cmd_Record.Enabled = False
format_GSM610.wFormatTag = WAVE_FORMAT_GSM610
format_GSM610.nChannels = 1
format_GSM610.nSamplesPerSec = 8000
format_GSM610.wBitsPerSample = 0
format_GSM610.nBlockAlign = 65
format_GSM610.nAvgBytesPerSec = 1625
format_GSM610.cbSize = 2
format_GSM610.wSamplesPerBlock = 320
gsm_fheader.GSM_flag = "GSM "
gsm_fheader.wFormatTag = WAVE_FORMAT_GSM610
gsm_fheader.nChannels = 1
gsm_fheader.nSamplesPerSec = 8000
gsm_fheader.nAvgBytesPerSec = 1625
gsm_fheader.nBlockAlign = 65
gsm_fheader.wBitsPerSample = 0
gsm_fheader.cbSize = 2
gsm_fheader.wSamplesPerBlock = 320
gsm_fheader.recBufferSize = 1625
gsm_fheader.recBufferCount = -1
fHandle = lcreat(App.Path & "\buffer", 0)
rst = waveInOpen(hWaveIn, WAVE_MAPPER, format_GSM610, AddressOf waveInProc, 0, CALLBACK_FUNCTION)
'以下方式也可以正确的打开放音设备!
'rst = waveInOpen(hWaveIn, 0, format_GSM610, AddressOf waveInProc, 0, CALLBACK_FUNCTION or WAVE_MAPPED)
Call waveInGetErrorText(rst, str, Len(str))
Call waveInGetID(hWaveIn, deviceID)
Text1.Text = Text1.Text & str & vbCrLf
Text1.Text = Text1.Text & "device: " & deviceID & vbCrLf
hmem1 = GlobalAlloc(&H40, BUFFER_SIZE)
lpBufferIn1 = GlobalLock(hmem1)
hmem2 = GlobalAlloc(&H40, BUFFER_SIZE)
lpBufferIn2 = GlobalLock(hmem2)
inHdr1.lpData = lpBufferIn1
inHdr1.dwBufferLength = BUFFER_SIZE
inHdr2.lpData = lpBufferIn2
inHdr2.dwBufferLength = BUFFER_SIZE
rst = waveInPrepareHeader(hWaveIn, inHdr1, Len(inHdr1))
Text1.Text = Text1.Text & "prepare header1 rst: " & rst & vbCrLf
rst = waveInPrepareHeader(hWaveIn, inHdr2, Len(inHdr2))
Text1.Text = Text1.Text & "prepare header2 rst: " & rst & vbCrLf
current_buffer = 1
rst = waveInAddBuffer(hWaveIn, inHdr1, Len(inHdr1))
Text1.Text = Text1.Text & "add buffer1 rst: " & rst & vbCrLf
cmd_Finish.Enabled = True
record_finished = 0
buffer_count = 0
callback_count = 0
Call waveInStart(hWaveIn)
End Sub
Private Sub Form_Load()
buffer_count = 0
callback_count = 0
record_finished = 0
cmd_Finish.Enabled = False
cmd_Record.Enabled = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
waveInStop (hWaveIn)
waveInReset (hWaveIn)
Call waveInUnprepareHeader(hWaveIn, inHdr1, Len(inHdr1))
Call waveInUnprepareHeader(hWaveIn, inHdr2, Len(inHdr2))
waveInClose (hWaveIn)
End Sub
下面的是该工程里的一个模块
'通过双缓冲实现录音
Public Const CALLBACK_FUNCTION = &H30000
Public Const MM_WOM_DONE = &H3BD
Public Const BUFFER_SIZE = 1625
Public Const MM_WIM_DATA = &H3C0
Public Const WAVE_FORMAT_GSM610 = &H31
Public Const WAVE_MAPPER = -1
Public Const WAVE_FORMAT_QUERY = &H1
Public Const WAVE_MAPPED = &H4
Type WAVEHDR
lpData As Long
dwBufferLength As Long
dwBytesRecorded As Long
dwUser As Long
dwFlags As Long
dwLoops As Long
lpNext As Long
Reserved As Long
End Type
Type WAVEINCAPS
wMid As Integer
wPid As Integer
vDriverVersion As Long
szPname As String * 32
dwFormats As Long
wChannels As Integer
End Type
Type WAVEFORMAT
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
cbSize As Integer
End Type
Type WAVEFORMAT_GSM610
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
cbSize As Integer
wSamplesPerBlock As Integer
End Type
Type GSM_FILE_HEADER
GSM_flag As String * 4
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
cbSize As Integer
wSamplesPerBlock As Integer
recBufferSize As Long
recBufferCount As Long
End Type
Public current_buffer As Integer
Public fHandle As Long
Public fGSM_Handle As Long
Public lpBufferIn1 As Long
Public lpBufferIn2 As Long
Public hWaveIn As Long
Public deviceID As Long
Public hmem1 As Long
Public hmem2 As Long
Public format As WAVEFORMAT
Public format_GSM610 As WAVEFORMAT_GSM610
Public gsm_fheader As GSM_FILE_HEADER
Public inHdr1 As WAVEHDR
Public inHdr2 As WAVEHDR
Public buffer_count As Long
Public callback_count As Long
Public fBuffHandle As Long
Public record_finished As Long
Public Declare Function lread Lib "kernel32" Alias "_lread" (ByVal hFile As Long, lpBuffer As Any, ByVal wBytes As Long) As Long
Public Declare Function fRead_lp Lib "kernel32" Alias "_lread" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal wBytes As Long) As Long
Public Declare Function lcreat Lib "kernel32" Alias "_lcreat" (ByVal lpPathName As String, ByVal iAttribute As Long) As Long
Public Declare Function fWrite_var Lib "kernel32" Alias "_lwrite" (ByVal hFile As Long, Buffer As Any, ByVal wBytes As Long) As Long
Public Declare Function fWrite_lp Lib "kernel32" Alias "_lwrite" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal wBytes As Long) As Long
Public Declare Function lopen Lib "kernel32" Alias "_lopen" (ByVal lpPathName As String, ByVal iReadWrite As Long) As Long
Public Declare Function llseek Lib "kernel32" Alias "_llseek" (ByVal hFile As Long, ByVal lOffset As Long, ByVal iOrigin As Long) As Long
Public Declare Function lclose Lib "kernel32" Alias "_lclose" (ByVal hFile As Long) As Long
Public Declare Function waveInOpen Lib "winmm.dll" (lphWaveIn As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMAT_GSM610, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Public Declare Function waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInGetDevCaps Lib "winmm.dll" Alias "waveInGetDevCapsA" (ByVal uDeviceID As Long, lpCaps As WAVEINCAPS, ByVal uSize As Long) As Long
Public Declare Function waveInGetErrorText Lib "winmm.dll" Alias "waveInGetErrorTextA" (ByVal err As Long, ByVal lpText As String, ByVal uSize As Long) As Long
Public Declare Function waveInGetNumDevs Lib "winmm.dll" () As Long
Public Declare Function waveInPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInStop Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInReset Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInGetID Lib "winmm.dll" (ByVal hWaveIn As Long, lpuDeviceID As Long) As Long
Public Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Public Declare Function GlobalLock Lib "kernel32" (ByVal hmem As Long) As Long
Public Declare Function GlobalFree Lib "kernel32" (ByVal hmem As Long) As Long
Sub waveInProc(ByVal hwi As Long, ByVal uMsg As Long, ByVal dwInstance As Long, ByRef hdr As WAVEHDR, ByVal dwParam2 As Long)
Dim i As Long
Debug.Print uMsg
'Debug.Print record_finished
callback_count = callback_count + 1
If uMsg = MM_WIM_DATA Then
If record_finished = 0 Then
If current_buffer = 1 Then
Call waveInAddBuffer(hWaveIn, inHdr2, Len(inHdr2))
Call waveInStart(hWaveIn)
Else
Call waveInAddBuffer(hWaveIn, inHdr1, Len(inHdr1))
Call waveInStart(hWaveIn)
End If
If current_buffer = 1 Then
Call fWrite_lp(fHandle, lpBufferIn1, BUFFER_SIZE)
current_buffer = 2
Else
Call fWrite_lp(fHandle, lpBufferIn2, BUFFER_SIZE)
current_buffer = 1
End If
buffer_count = buffer_count + 1
Else
'stop recording
waveInStop (hWaveIn)
waveInReset (hWaveIn)
lclose (fHandle)
'save GSM data to file
fGSM_Handle = lcreat(App.Path & "\1.gsm", 0)
fHandle = lopen(App.Path & "\buffer", 0)
gsm_fheader.recBufferCount = buffer_count
Call fWrite_var(fGSM_Handle, gsm_fheader, Len(gsm_fheader))
For i = 0 To buffer_count - 1
Call fRead_lp(fHandle, lpBufferIn1, BUFFER_SIZE)
Call fWrite_lp(fGSM_Handle, lpBufferIn1, BUFFER_SIZE)
Next i
Call lclose(fHandle)
Call lclose(fGSM_Handle)
Call waveInUnprepareHeader(hWaveIn, inHdr1, Len(inHdr1))
Call waveInUnprepareHeader(hWaveIn, inHdr2, Len(inHdr2))
GlobalFree (hmem1)
GlobalFree (hmem2)
waveInClose (hWaveIn)
Form1.cmd_Record.Enabled = True
Form1.cmd_Finish.Enabled = False
Form1.Text1.Text = Form1.Text1.Text & "recorded buffer count: " & buffer_count & vbCrLf
Form1.Text1.Text = Form1.Text1.Text & "callback count: " & callback_count & vbCrLf
End If
End If
End Sub
多谢指点