WAVEHDR结构和waveOutPrepareHeader及waveOutWrite函数介绍

 

<1> :WAVEHDR结构的介绍

根据MSDN说明文档

typedef struct {
    LPSTR  lpData; //波形缓冲数据(传入首地址)
    DWORD  dwBufferLength; //缓冲区长度
    DWORD  dwBytesRecorded; //指明录音时缓冲区容量
    DWORD  dwUser; //用户数据
    DWORD  dwFlags; //提供缓冲区标示
    DWORD  dwLoops; //循环次数
    struct wavehdr_tag * lpNext; //预留,NULL
    DWORD  reserved; //预留,0
} WAVEHDR;

比如:

WAVEHDR waveHdr ={ 
  0, 128, 0, 0, 0, 1, NULL, 0
 }; //音频数据信息头

其中lpData参数的数据获得方式:

char mute[128];

FillMemory(mute, 128, (BYTE)0x0E);//红色的数据即为将要填充播放缓冲区的数据,这里给出了一个音符.

常用来赋值的函数还有CopyMemory(*)等.

<2> : waveOutPrepareHeader函数:

这个函数在使用时,需要上传入上面的结构体,并且在使用前lpData, dwBufferLength, 和dwFlags三个参数必须在使用函数前设置好.

The lpData, dwBufferLength, and dwFlags members of the WAVEHDR structure must be set before calling this function (dwFlags must be zero).

MMRESULT waveOutPrepareHeader(
  HWAVEOUT
hwo //输出设备的句柄,这个句柄在设备打开函数waveOutOpen函数的第一个参数(传址)返回
  LPWAVEHDR pwh, //即<1> 所说的结构体
  UINT cbwh      //<1>结构体的大小,一般为sizeof(WAVEHDR)
);

<3> : 将<1>,<2>设置好的数据发送到波形输出设备,即播放.

MMRESULT waveOutWrite(
  HWAVEOUT
hwo, //输出设备句柄
  LPWAVEHDR pwh, //<1>点所说数据
  UINT cbwh      //sizeof(WAVEHDR)
);
返回值有四种:

ValueDescription
MMSYSERR_INVALHANDLESpecified device handle is invalid.
MMSYSERR_NODRIVERNo device driver is present.
MMSYSERR_NOMEMUnable to allocate or lock memory.
WAVERR_UNPREPAREDThe data block pointed to by the pwh parameter hasn't been prepared.

<4> : 综合上面和以前介绍的Audio部分,给出第一个播放音符的Demo :记住添加相关lib文件

#include <windows.h>
#include <stdio.h>
#include<mmsystem.h>
#define MUTE_LENGTH 128
#define SAMPLE_RATE 11025
void main(){
 HANDLE hEvent = CreateEvent(NULL , false , false , TEXT("PCM WRITE"));
 HWAVEOUT hWaveOut; //波形音频输出句柄
 char  mute[MUTE_LENGTH]; //静音符号串
 WAVEFORMATEX waveformat ={ 
  WAVE_FORMAT_PCM, 1, SAMPLE_RATE, SAMPLE_RATE, 1, 8, 0
 }; //设定波形音频的格式
 WAVEHDR waveHdr ={ 
  0, MUTE_LENGTH, 0, 0, 0, 1, NULL, 0
 }; //音频数据信息头
 
 FillMemory(mute, MUTE_LENGTH, (BYTE)0x0E); //0x0E将会提到BEEP声,用静音符号填充0x80将为无声
 waveHdr.lpData = mute; //初始化信息头指针
 //打开音频设备
 waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveformat, (DWORD)hEvent, 0, CALLBACK_EVENT);
 //准备信息头
 waveOutPrepareHeader(hWaveOut, &waveHdr, sizeof (WAVEHDR));
 while(1) { 
  //播放静音符号 
  waveOutWrite (hWaveOut, &waveHdr, sizeof (WAVEHDR)); 
  printf("."); 
  WaitForSingleObject(hEvent,INFINITE);
 }
}

转载于:https://www.cnblogs.com/MMLoveMeMM/articles/3105603.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // This material may not be duplicated in whole or in part, except for // personal use, without the express written consent of the author. // // Email: ianier@hotmail.com // // Copyright (C) 1999-2003 Ianier Munoz. All Rights Reserved. using System; using System.Threading; using System.Runtime.InteropServices; namespace WaveLib { internal class WaveOutHelper { public static void Try(int err) { if (err != WaveNative.MMSYSERR_NOERROR) throw new Exception(err.ToString()); } } public delegate void BufferFillEventHandler(IntPtr data, int size); internal class WaveOutBuffer : IDisposable { public WaveOutBuffer NextBuffer; private AutoResetEvent m_PlayEvent = new AutoResetEvent(false); private IntPtr m_WaveOut; private WaveNative.WaveHdr m_Header; private byte[] m_HeaderData; private GCHandle m_HeaderHandle; private GCHandle m_HeaderDataHandle; private bool m_Playing; internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2) { if (uMsg == WaveNative.MM_WOM_DONE) { try { GCHandle h = (GCHandle)wavhdr.dwUser; WaveOutBuffer buf = (WaveOutBuffer)h.Target; buf.OnCompleted(); } catch { } } } public WaveOutBuffer(IntPtr waveOutHandle, int size) { m_WaveOut = waveOutHandle; m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned); m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值