waveOutWrite函数, 只能够播放部分的WAV音频文件,怎么样才能播放全部的WAV音频文件

时间:2022-02-19 19:42:31
Option Explicit
'事件函数
Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As Any, ByVal bManualReset As Boolean, ByVal bInitialState As Boolean, ByVal lpName As String) As Long
Private Declare Function SetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Private Declare Function ResetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Private Declare Function PulseEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Const DELETE_CONTROL = &H10000
Private Const READ_CONTROL = &H20000
Private Const WRITE_DAC = &H40000
Private Const WRITE_OWNER = &H80000
Private Const SYNCHRONIZE = &H80000
Private Const EVENT_MODIFY_STATE = &H2
Private Const EVENT_ALL_ACCESS = &H1F0003


'Mem API
Private Declare Function LocalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal wBytes As Long) As Long
Private Declare Function LocalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function LocalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function LocalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
'File API
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal Handle As Long) As Long
Private Const GENERIC_ALL = &H10000000
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const CREATE_NEW = &H1
Private Const OPEN_EXISTING = &H3
Private Const OPEN_ALWAYS = &H4


'音频输出
Private Declare Function waveOutOpen Lib "winmm.dll" (lphWaveOut As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMAT, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Private Declare Function waveOutClose Lib "winmm.dll" (ByVal hWaveOut As Long) As Long
Private Declare Function waveOutPrepareHeader Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Private Declare Function waveOutUnprepareHeader Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Private Declare Function waveOutWrite Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Private Declare Function waveOutPause Lib "winmm.dll" (ByVal hWaveOut As Long) As Long
Private Declare Function waveOutRestart Lib "winmm.dll" (ByVal hWaveOut As Long) As Long
Private Declare Function waveOutReset Lib "winmm.dll" (ByVal hWaveOut As Long) As Long


'播放WAV音频文件
Public Sub PlayWaveAudioFile(ByVal srcFile As String)
Dim hSrcFile As Long, mFileSize As Long, mRet As Long
hSrcFile = CreateFile(srcFile, GENERIC_ALL, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)
If hSrcFile <> -1 Then
   mFileSize = GetFileSize(hSrcFile, 0)
   If mFileSize > 1024 Then
      Dim hData As Long, hEvent As Long, hWaveOut As Long, WaveSize As Long, TempSize As Long, mState As Long, mHeadData As Long, mWaveFormat As WAVEFORMAT, mWaveHead As WAVEHDR
      ReadFile hSrcFile, mHeadData, 4, TempSize, ByVal 0
      If mHeadData <> &H46464952 Then
         GoTo Jmp_Line
      End If
      ReadFile hSrcFile, mHeadData, 4, TempSize, ByVal 0
      If mHeadData <> mFileSize - 8 Then
         GoTo Jmp_Line
      End If
      ReadFile hSrcFile, mHeadData, 4, TempSize, ByVal 0
      If mHeadData <> &H45564157 Then
         GoTo Jmp_Line
      End If
      ReadFile hSrcFile, mHeadData, 4, TempSize, ByVal 0
      If mHeadData <> &H20746D66 Then
         GoTo Jmp_Line
      End If
      ReadFile hSrcFile, mHeadData, 4, TempSize, ByVal 0
      ReadFile hSrcFile, mWaveFormat, 16, TempSize, ByVal 0
      ReadFile hSrcFile, mHeadData, 4, TempSize, ByVal 0
      If mHeadData <> &H61746164 Then
         GoTo Jmp_Line
      End If
      ReadFile hSrcFile, WaveSize, 4, TempSize, ByVal 0
      If WaveSize > mFileSize - &H2C Then
         GoTo Jmp_Line
      End If
      hData = LocalAlloc(&H40, WaveSize)
      LocalLock hData
      ReadFile hSrcFile, ByVal hData, WaveSize, TempSize, ByVal 0
      With mWaveHead
          .dwBufferLength = WaveSize
          .lpData = hData
          .lpNext = 1
      End With
      hEvent = CreateEvent(ByVal 0, False, False, "Play Media")
      mRet = waveOutOpen(hWaveOut, WAVE_MAPPER, mWaveFormat, hEvent, 0, CALLBACK_EVENT)
      If mRet = MMSYSERR_NOERROR Then
         TempSize = Len(mWaveHead)
         waveOutPrepareHeader hWaveOut, mWaveHead, TempSize
         Do
            waveOutWrite hWaveOut, mWaveHead, TempSize
            mState = WaitForSingleObject(hEvent, 0)
         Loop Until mState = &H102
         waveOutUnprepareHeader hWaveOut, mWaveHead, TempSize
         waveOutClose hWaveOut
      End If
      CloseHandle hEvent
      LocalUnlock hData
      LocalFree hData
   End If
Jmp_Line:
   CloseHandle hSrcFile
End If
End Sub

2 个解决方案

#1


既然播放的是wav文件,干吗不用sndPlaySound()这个API?
这也是 winmm.dll中的导出函数,并且使用起来比你现在这个方便N个数量级…………
waveOutWrite函数, 只能够播放部分的WAV音频文件,怎么样才能播放全部的WAV音频文件

#2


推荐使用NCTAudioStudio控件处理音频。

#1


既然播放的是wav文件,干吗不用sndPlaySound()这个API?
这也是 winmm.dll中的导出函数,并且使用起来比你现在这个方便N个数量级…………
waveOutWrite函数, 只能够播放部分的WAV音频文件,怎么样才能播放全部的WAV音频文件

#2


推荐使用NCTAudioStudio控件处理音频。