WINEAPI VB录音 程序 X64,然后请教下WIN10下为何10多分钟产生UNPREPARE错误

2017-12-22 18:49:22来源:CSDN作者:qq_39239990人点击

分享

WINDOWS 64位下 VB 录音程序,可用,但10分钟后会产生UNPREPARE 错误,若能回复者,十分感谢!

#Region "wave定义结构与声明"    Private Const MM_WIM_OPEN As Integer = &H3BE    Private Const MM_WIM_CLOSE As Integer = &H3BF    Private Const MM_WIM_DATA As Integer = &H3C0    Private Const WAVE_MAPPER As Integer = -1    Private Const WAVE_FORMAT_PCM As Integer = 1    Private Const MMSYSERR_NOERROR As Integer = 0    '所有的引用地址 函数查询 PINVOKE网址    '录音    Delegate Sub CallBackFUN(<MarshalAs(UnmanagedType.I4)> ByVal hwi As Integer, ByVal uMsg As WIMMessages, ByVal dwInstance As IntPtr, ByVal dwParam1 As IntPtr, ByVal dwParam2 As IntPtr)    Private Declare Function waveInOpen Lib "winmm.dll" (ByRef phwi As IntPtr, ByVal uDeviceID As IntPtr, ByRef pwfx As WAVEFORMATEX, _          ByVal dwCallback As CallBackFUN, ByVal dwCallbackInstance As IntPtr, ByVal fdwOpen As WaveInOpenFlags) As MMRESULT    Private Declare Function waveInOpen Lib "winmm.dll" (ByRef phwi As IntPtr, ByVal uDeviceID As IntPtr, ByRef pwfx As WAVEFORMATEX, _        ByVal dwCallback As IntPtr, ByVal dwCallbackInstance As IntPtr, ByVal fdwOpen As WaveInOpenFlags) As MMRESULT    Declare Function waveInUnprepareHeader Lib "winmm.dll" (ByVal hwi As IntPtr, ByRef pwh As WAVEHDR, ByVal cbwh As UInteger) As MMRESULT    Declare Function waveInReset Lib "winmm.dll" (ByVal hwi As IntPtr) As MMRESULT    Private Declare Function waveInUnprepareHeader Lib "winmm.dll" _        (ByVal hWaveIn As Integer, ByRef lpWaveInHdr As WAVEHDR, ByVal uSize As Integer) As MMRESULT    Private Declare Function waveInPrepareHeader Lib "winmm.dll" _        (ByVal hWaveIn As IntPtr, ByRef lpWaveInHdr As WAVEHDR, ByVal uSize As Integer) As Integer    Private Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn As IntPtr) As MMRESULT    Private Declare Function waveInStop Lib "winmm.dll" (ByVal hWaveIn As IntPtr) As Integer    Private Declare Function waveInClose Lib "winmm.dll" (ByVal hWaveIn As IntPtr) As Integer    Private Declare Function waveInAddBuffer Lib "winmm.dll" _(ByVal hwi As IntPtr, pwh As IntPtr, ByVal cbwh As UInteger) As MMRESULT    Private Declare Function waveInAddBuffer Lib "winmm.dll" _(ByVal hwi As IntPtr, ByRef pwh As WAVEHDR, ByVal cbwh As UInteger) As MMRESULT    '播放    Private Declare Function waveOutBreakLoop Lib "winmm.dll" (ByVal hWaveOut As Integer) As Integer    Private Declare Function waveOutClose Lib "winmm.dll" (ByVal hWaveOut As Integer) As Integer    Private Declare Function waveOutPrepareHeader Lib "winmm.dll" (ByVal hWaveOut As Integer, ByRef lpWaveOutHdr As WAVEHDR, ByVal uSize As Integer) As Integer    Private Declare Function waveOutOpen Lib "winmm.dll" (ByRef phwi As IntPtr, ByVal uDeviceID As IntPtr, ByRef pwfx As WAVEFORMATEX, _          dwCallback As IntPtr, ByVal dwCallbackInstance As IntPtr, ByVal fdwOpen As WaveInOpenFlags) As MMRESULT    Private Declare Function waveOutUnprepareHeader Lib "winmm.dll" (ByVal hWaveOut As Integer, ByRef lpWaveOutHdr As WAVEHDR, ByVal uSize As Integer) As Integer    Private Declare Function waveOutWrite Lib "winmm.dll" (ByVal hWaveOut As Integer, ByRef lpWaveOutHdr As WAVEHDR, ByVal uSize As Integer) As Integer    Private Declare Function waveOutReset Lib "winmm.dll" (ByVal hWaveOut As Integer) As Integer    '函数定义未正确 PINVOKE网站上正确    ' Public Declare Function waveInGetDevCaps Lib "winmm.dll" Alias "waveInGetDevCapsA" (ByVal uDeviceID As Integer, lpCaps As WAVEINCAPS, ByVal uSize As Integer) As Integer    'Public Declare Function waveInGetErrorText Lib "winmm.dll" Alias "waveInGetErrorTextA" (ByVal err As Integer, ByVal lpText As String, ByVal uSize As Integer) As Integer    ' Public Declare Function waveInGetID Lib "winmm.dll" (ByVal hWaveIn As Integer, lpuDeviceID As Integer) As Integer    '  Public Declare Function waveInGetNumDevs Lib "winmm.dll" () As Integer    '  Public Declare Function waveInGetPosition Lib "winmm.dll" (ByVal hWaveIn As Integer, lpInfo As MMTIME, ByVal uSize As Integer) As Integer    ' Public Declare Function waveInMessage Lib "winmm.dll" (ByVal hWaveIn As Integer, ByVal msg As Integer, ByVal dw1 As Integer, ByVal dw2 As Integer) As Integer    ' Public Declare Function waveOutGetDevCaps Lib "winmm.dll" Alias "waveOutGetDevCapsA" (ByVal uDeviceID As Integer, lpCaps As WAVEOUTCAPS, ByVal uSize As Integer) As Integer    ' Public Declare Function waveOutGetErrorText Lib "winmm.dll" Alias "waveOutGetErrorTextA" (ByVal err As Integer, ByVal lpText As String, ByVal uSize As Integer) As Integer    ' Public Declare Function waveOutGetID Lib "winmm.dll" (ByVal hWaveOut As Integer, lpuDeviceID As Integer) As Integer    ' Public Declare Function waveOutGetNumDevs Lib "winmm.dll" () As Integer    ' Public Declare Function waveOutGetPitch Lib "winmm.dll" (ByVal hWaveOut As Integer, lpdwPitch As Integer) As Integer    ' Public Declare Function waveOutGetPlaybackRate Lib "winmm.dll" (ByVal hWaveOut As Integer, lpdwRate As Integer) As Integer    ' Public Declare Function waveOutGetPosition Lib "winmm.dll" (ByVal hWaveOut As Integer, lpInfo As MMTIME, ByVal uSize As Integer) As Integer    ' Public Declare Function waveOutGetVolume Lib "winmm.dll" (ByVal uDeviceID As Integer, lpdwVolume As Integer) As Integer    ' Public Declare Function waveOutMessage Lib "winmm.dll" (ByVal hWaveOut As Integer, ByVal msg As Integer, ByVal dw1 As Integer, ByVal dw2 As Integer) As Integer    ' Public Declare Function waveOutPause Lib "winmm.dll" (ByVal hWaveOut As Integer) As Integer    ' Public Declare Function waveOutRestart Lib "winmm.dll" (ByVal hWaveOut As Integer) As Integer    ' Public Declare Function waveOutSetPitch Lib "winmm.dll" (ByVal hWaveOut As Integer, ByVal dwPitch As Integer) As Integer    ' Public Declare Function waveOutSetPlaybackRate Lib "winmm.dll" (ByVal hWaveOut As Integer, ByVal dwRate As Integer) As Integer    ' Public Declare Function waveOutSetVolume Lib "winmm.dll" (ByVal uDeviceID As Integer, ByVal dwVolume As Integer) As Integer#End Region#Region "线程与消息的定义"    <StructLayout(LayoutKind.Sequential)> _    Public Structure NativeMessage        Public handle As IntPtr        Public msg As UInteger        Public wParam As IntPtr        Public lParam As IntPtr        Public time As UInteger        Public p As System.Drawing.Point    End Structure    Public Declare Function GetMessage Lib "user32" Alias "GetMessageA" (ByRef lpMsg As NativeMessage, ByVal hwnd As Integer, ByVal wMsgFilterMin As Integer, ByVal wMsgFilterMax As Integer) As Integer    Public Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (ByRef message As NativeMessage, ByVal handle As IntPtr, _ ByVal filterMin As UInteger, ByVal filterMax As UInteger, ByVal flags As UInteger) _ As <MarshalAs(UnmanagedType.Bool)> Boolean#Const _win64 = 1#If _win32 Then    Delegate Function delgwaveThread(lparam As IntPtr) As Integer    Public Declare Function CreateThread Lib "kernel32.dll" (ByRef lpThreadAttributes As Integer, _        dwStackSize As Integer, lpStartAddress As delgwaveThread, ByRef lpParameter As Integer, _   dwCreationFlags As Integer, ByRef lpThreadId As Integer) As Integer#ElseIf _win64 Then    Delegate Sub delgwaveThread()    Public Declare Function CreateThread Lib "kernel32.dll" (ByRef lpThreadAttributes As Int64, _        dwStackSize As Int64, lpStartAddress As delgwaveThread, ByRef lpParameter As Int64, _   dwCreationFlags As Int64, ByRef lpThreadId As Int64) As Int64#End If#End Region    Public Shared BUFFSIZE As Integer = 6400  '缓存区大小    '添加回调函数    Delegate Sub Delg_DataArriva(lpdata As IntPtr, len As Integer)    Dim dataArriva As Delg_DataArriva    Public Sub AddDataArrivaEvent(dataArri As Delg_DataArriva)        dataArriva = dataArri    End Sub#Region "线程式回调函数"    <DllImport("kernel32.dll")>    Public Shared Sub CopyMemory(dest As IntPtr, src As IntPtr, count As Integer)    End Sub    Private ThreadId As Integer = 0    'THREAD线程回调函数    Private Sub waveThread()        Monitor.Enter(Me)        Dim msg As NativeMessage        Dim bRet As Boolean        ThreadId = AppDomain.GetCurrentThreadId()        Dim buffptr As IntPtr = Marshal.AllocHGlobal(BUFFSIZE)        While True            bRet = GetMessage(msg, vbNull, 0, 0)            Select Case msg.msg                Case MM_WIM_CLOSE                    Debug.Print("CLOSE")                Case MM_WIM_DATA                    If (luyin = False) Then                        Exit Select                    End If                    Dim S1 As WAVEHDR = Marshal.PtrToStructure(msg.lParam, GetType(WAVEHDR))                    '数据发送至处理程序                    If (Not dataArriva Is Nothing) Then                        CopyMemory(S1.lpData, buffptr, S1.dwBytesRecorded)                        dataArriva(buffptr, S1.dwBytesRecorded)                    End If#If _WriteFile Then                    WaveWriteFile(S1.lpData, S1.dwBytesRecorded) '将声音写入文件#End If                    '错误 MMSYSERR_INVALPARAM  WAVERR_UNPREPARED                    res = waveInAddBuffer(hWaveIn, msg.lParam, Marshal.SizeOf(S1))  '注意此处 由于非托管代码 必须用INTPTR否则产生读写内存错误                    If (res <> 0) Then                        Debug.Print("waveInAddBuffer " & CType(res, MMRESULT).ToString("g"))                        Throw New Exception("waveInAddBuffer error")                    End If                    ' debug.print("DATA") 放在后部会干扰运行?                    Exit Select                Case MM_WIM_OPEN                    Debug.Print("wim open" & Now.Millisecond)                    '   debug.print("OPEN")                    Exit Select            End Select        End While        Marshal.FreeHGlobal(buffptr)        Monitor.Exit(Me)    End Sub#End Region    Dim luyin As Boolean = False    Dim res As Integer    Dim hWaveIn As IntPtr    Dim whdr1 As WAVEHDR    Dim whdr2 As WAVEHDR    Dim whdr3 As WAVEHDR    Dim udtWFX As WAVEFORMATEX    Dim T1 As Thread    '录音结构初始化    Public Sub New()        With udtWFX            .wFormatTag = WAVE_FORMAT_PCM            .nChannels = 1            .nSamplesPerSec = 16000            .nAvgBytesPerSec = 32000            .nBlockAlign = 2            .wBitsPerSample = 16            .cbSize = 0        End With        '定义缓冲区        With whdr1            .lpData = Marshal.AllocHGlobal(BUFFSIZE)            .dwBufferLength = BUFFSIZE            .dwUser = 1            .dwFlags = 0            '   .dwLoops = 1        End With        With whdr2            .lpData = Marshal.AllocHGlobal(BUFFSIZE)            .dwBufferLength = BUFFSIZE            .dwUser = 2            .dwFlags = 0            '   .dwLoops = 1        End With        With whdr3            .lpData = Marshal.AllocHGlobal(BUFFSIZE)            .dwBufferLength = BUFFSIZE            .dwUser = 3            .dwFlags = 0            '    .dwLoops = 1        End With        hWaveIn = IntPtr.Zero        T1 = New Thread(New ThreadStart(AddressOf waveThread))        T1.Start()        Thread.Sleep(100)        res = waveInOpen(hWaveIn, WAVE_MAPPER, udtWFX, ThreadId, 0, WaveInOpenFlags.CALLBACK_THREAD)  '线程式调用回调函数THREAD        If res <> MMSYSERR_NOERROR Then            Debug.Print("WAVE IN OPEN " & CType(res, MMRESULT).ToString("G"))            Exit Sub        End If        res = waveInPrepareHeader(hWaveIn, whdr1, Marshal.SizeOf(whdr1))        res = waveInPrepareHeader(hWaveIn, whdr2, Marshal.SizeOf(whdr2))        res = waveInPrepareHeader(hWaveIn, whdr3, Marshal.SizeOf(whdr3))    End Sub    '开始录音     Public Sub StartRecord()#If _WriteFile Then        WaveSaveFile("d:/tts.wav")  '保存录音文件#End If        luyin = True        '打开录音设备        ' 准备数据结构()        res = waveInAddBuffer(hWaveIn, whdr1, Marshal.SizeOf(whdr1))   '实时录音 即【开头处】能被录进去 不能使用INTPTR结构转换,否则DATA数据缺少一部份 非BUFFSIZE 而是只有212或100        res = waveInAddBuffer(hWaveIn, whdr2, Marshal.SizeOf(whdr2))        res = waveInAddBuffer(hWaveIn, whdr3, Marshal.SizeOf(whdr3))        res = waveInStart(hWaveIn)        If res <> MMSYSERR_NOERROR Then            Debug.Print("WAVE INSTART" & res.ToString)            waveInClose(hWaveIn)            hWaveIn = 0            Exit Sub        End If    End Sub    '结束录音     Public Sub StopRecord()  '未关闭线程 ,为下次录音做准备        luyin = False        'res = waveInUnprepareHeader(hWaveIn, whdr1, Marshal.SizeOf(whdr1))        'res = waveInUnprepareHeader(hWaveIn, whdr2, Marshal.SizeOf(whdr2))        'res = waveInUnprepareHeader(hWaveIn, whdr3, Marshal.SizeOf(whdr3))        res = waveInReset(hWaveIn)  '会触发WM_DATA 事件 然后

产生死锁 使用luyin标志在回调函数中 判断是否关闭
’ res = waveInClose(hWaveIn)
’ debug.print(“close”)
’#If _WriteFile Then
CloseWaveFile()
‘#End If
End Sub这里写代码片

Region “窗口式回调函数”

''' 'Dim GBUF As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(WAVEHDR)))'Dim S1 As WAVEHDR'Protected Overrides Sub WndProc(ByRef m As Message)'    Select Case m.Msg'        Case MM_WIM_DATA'            'Try'            If (luyin = False) Then'                Return'            End If'            S1 = m.GetLParam(GetType(WAVEHDR))'            WaveWriteFile(S1.lpData, S1.dwBytesRecorded)'            Marshal.StructureToPtr(S1, GBUF, True)'            res = waveInAddBuffer(hWaveIn, GBUF, Marshal.SizeOf(S1))'            Debug.Print("in record")'        Case MM_WIM_CLOSE'            '  debug.print("close")'            waveInStop(hWaveIn)'            waveInReset(hWaveIn)'            waveInClose(hWaveIn)'        Case MM_WIM_OPEN'            '    WaveSaveFile("D:/V4.WAV")'            '     debug.print("open")'    End Select'    MyBase.WndProc(m)'End Sub''窗口式调用' res = waveInOpen(hWaveIn, WAVE_MAPPER, udtWFX, Me.Handle, 0, WaveInOpenFlags.CALLBACK_WINDOW) 

End Region

Region “函数式回调函数FUN”

Public Sub CallBack_Fun(hwI As Integer, umsg As Integer, dwinstance As Integer, dwparam1 As IntPtr, dwparam2 As Integer)    Select Case umsg        Case MM_WIM_DATA            If (luyin = False) Then                Exit Select            End If            Dim S1 As WAVEHDR = Marshal.PtrToStructure(dwparam1, GetType(WAVEHDR))            If (Not dataArriva Is Nothing) Then                dataArriva(S1.lpData, S1.dwBytesRecorded)            End If

’#If _WriteFile Then
WaveWriteFile(S1.lpData, S1.dwBytesRecorded) ‘将声音写入文件
‘#End If

            res = waveInAddBuffer(hWaveIn, dwparam1, Marshal.SizeOf(S1))  '注意此处 由于非托管代码 必须用INTPTR否则产生读写内存错误            If (res <> 0) Then                Debug.Print(CType(res, MMRESULT).ToString("g"))            End If            ' debug.print("DATA") 放在后部会干扰运行?            Exit Select        Case MM_WIM_CLOSE            '  debug.print("close")            'waveInStop(hWaveIn)            'waveInReset(hWaveIn)            'waveInClose(hWaveIn)            Exit Select        Case MM_WIM_OPEN            '   debug.print("open")            Exit Select    End SelectEnd Sub

End Region

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台