none
(VB6)調用錄音的API RRS feed

  • 問題

  • 我在使用錄音API的時候
    用API呼叫做錄音buffer迴圈
    程式在除錯模式(IDE)下執行正常
    可是製作成exe檔去執行卻會當機(執行到waveInStart後面)
    我試了一下,在WaveInProc裡面就算是執行MsgBox還是Binary File put都不行(只要是waveInStart之後)
    可以幫我看一下嗎,謝謝(我VB有重灌過還是不行)

    form的兩個button: cmdStart跟cmdStop兩個
    -------模組code start
    Public Const WAVE_FORMAT_PCM = 1
    Public Const WAVE_MAPPER = -1&
    Public Const CALLBACK_FUNCTION As Long = &H30000
    Public Const MM_WIM_DATA = &H3C0
    Public Const BuffSec = 0.2, CountOfBuff = 2

    Public 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
    Public 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
    Public Type PCMFORM
      yRiffFormatTag As String * 4
      yfdataSize As Long
      yWaveTag As String * 4
      yWavetName As String * 4
      yWaveSize As Long
      wFormatTag As Integer
      wChannels As Integer
      wSamplesPerSec As Long
      xAvgBytesPerSec As Long
      xBlockAlign As Integer
      wBitsPerSample As Integer
      yData As String * 4
      wDataSize As Long
    End Type
    Public Declare Function waveInOpen Lib "winmm.dll" (lphWaveIn As Long, ByVal uDeviceID As Long, lpFormat As WaveFormat, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) 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 waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WaveHdr, ByVal uSize As Long) As Long
    Public Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn 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 waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
    Public Declare Function waveInStop Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
    Public Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
    Public Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
    Public Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
    Public Declare Function GlobalFree Lib "kernel32.dll" (ByVal hMem As Long) As Long
    Public Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long) As Long

    Public pWaveInBuff() As Long, pWaveInAllBuff() As Byte, pFileN As Long, pPCM As PCMFORM
    Public pWaveInHead() As WaveHdr, pDevHandle As Long
    Option Explicit

    Public Sub WaveInProc(ByVal wave_in As Long, ByVal uMsg As Long, ByVal dwInstance As Long, hdr As WaveHdr, ByVal dwParam2 As Long)
    Dim mWaveByte() As Byte, mLen As Long, mSeek As Long
    'MsgBox pFileN
    'Exit Sub
    If uMsg = MM_WIM_DATA Then
      If pFileN > 0 Then
        mLen = hdr.dwBufferLength
        ReDim mWaveByte(mLen - 1)
        CopyMemory mWaveByte(0), ByVal hdr.lpData, mLen
        mSeek = LOF(pFileN) + 1
        If mSeek < Len(pPCM) Then mSeek = Len(pPCM) + 1
        Put pFileN, mSeek, mWaveByte
        With pPCM
          .yfdataSize = LOF(pFileN)
          .wDataSize = LOF(pFileN) - 44
        End With
        Put pFileN, pFileN, pPCM
      End If
      waveInAddBuffer wave_in, hdr, Len(hdr)
    End If
    End Sub
    ---------模組End


    -----------Form1 Start
    Option Explicit

    Private Sub cmdStart_Click()
    Dim waveLen As Long, Re As Long, WaveFmt As WaveFormat
    Dim i As Long, mFileName As String
    mFileName = App.Path & "\Sound.wav"

    WaveFmt.wFormatTag = WAVE_FORMAT_PCM
    WaveFmt.nChannels = 2
    WaveFmt.wBitsPerSample = 16
    WaveFmt.nSamplesPerSec = 44100
    WaveFmt.nBlockAlign = (WaveFmt.nChannels * WaveFmt.wBitsPerSample) / 8
    WaveFmt.nAvgBytesPerSec = WaveFmt.nBlockAlign * WaveFmt.nSamplesPerSec
    WaveFmt.cbSize = 0
    Re = waveInOpen(pDevHandle, WAVE_MAPPER, WaveFmt, AddressOf WaveInProc, 0, CALLBACK_FUNCTION)
    If pDevHandle = 0 Then
      MsgBox "waveInOpen 呼叫錯誤", vbExclamation
      Exit Sub
    End If
    waveLen = WaveFmt.nAvgBytesPerSec * BuffSec
    ReDim pWaveInBuff(CountOfBuff - 1)
    ReDim pWaveInHead(UBound(pWaveInBuff))
    ReDim pWaveInBuff(UBound(pWaveInHead))

    ReDim pWaveInAllBuff(WaveFmt.nAvgBytesPerSec * BuffSec * CountOfBuff - 1)

    For i = 0 To UBound(pWaveInBuff)
      pWaveInBuff(i) = VarPtr(pWaveInAllBuff((UBound(pWaveInAllBuff) + 1) / CountOfBuff * i))
    Next

    With pWaveInHead(0)
      .lpData = pWaveInBuff(0)
      .dwBufferLength = waveLen
      .dwBytesRecorded = 0
      .dwFlags = 0
      .dwLoops = 1
    End With
    For i = 1 To UBound(pWaveInHead)
      pWaveInHead(i) = pWaveInHead(0)
      pWaveInHead(i).lpData = pWaveInBuff(i)
    Next
    With pPCM
      .yRiffFormatTag = "RIFF"
      .yWaveTag = "WAVE"
      .yWavetName = "fmt "
      .yWaveSize = &H10
      .wFormatTag = WaveFmt.wFormatTag
      .wChannels = WaveFmt.nChannels
      .wSamplesPerSec = WaveFmt.nSamplesPerSec
      .xAvgBytesPerSec = WaveFmt.nAvgBytesPerSec
      .xBlockAlign = WaveFmt.nBlockAlign
      .wBitsPerSample = WaveFmt.wBitsPerSample
      .yData = "data"
    End With
    If Dir(mFileName) <> "" Then Kill mFileName
    pFileN = FreeFile
    Open mFileName For Binary As pFileN
    For i = 0 To UBound(pWaveInHead)
      Re = waveInPrepareHeader(pDevHandle, pWaveInHead(i), Len(pWaveInHead(i)))
    Next
    For i = 0 To UBound(pWaveInHead)
      Re = waveInAddBuffer(pDevHandle, pWaveInHead(i), Len(pWaveInHead(i)))
    Next
    Re = waveInStart(pDevHandle)
    End Sub

    Private Sub cmdStop_Click()
    Dim i As Long, Re As Long
    If pDevHandle <> 0 Then
      Re = waveInStop(pDevHandle)
      For i = 0 To UBound(pWaveInHead)
        Re = waveInUnprepareHeader(pDevHandle, pWaveInHead(i), Len(pWaveInHead(i)))
      Next
      Re = waveInClose(pDevHandle)
      pDevHandle = 0
    End If
    For i = 0 To UBound(pWaveInBuff)
      If pWaveInBuff(i) > 0 Then
        pWaveInBuff(i) = 0
      End If
    Next
    If pFileN > 0 Then
      Close pFileN
      pFileN = 0
    End If
    ReDim pWaveInBuff(-1 To -1)
    ReDim pWaveInAllBuff(-1 To -1)
    End Sub

    Private Sub Form_Load()
    ReDim pWaveInBuff(-1 To -1)
    ReDim pWaveInAllBuff(-1 To -1)
    End Sub

    -------------Form1 End
    2010年1月20日 上午 11:19

解答

所有回覆