设为首页 加入收藏

TOP

26.1.1 简单声音录制与播放
2013-10-07 13:11:53 来源: 作者: 【 】 浏览:62
Tags:26.1.1 简单 声音 录制 播放

26.1.1  简单声音录制与播放

Windows API中提供了可以简单地播放声音的函数PlaySound(),它可以播放声音文件、声音资源或系统声音。其函数原型如下:

  1. BOOL PlaySound( LPCSTR pszSound,    // 指定要播放的声音的名称  
  2. HMODULE hmod,           // 包含载入资源的可执行文件的句柄  
  3. DWORD fdwSound );       // 指定播放声音的选项 

其中fdwSound参数指定播放声音的选项,可以是下列选项的组合。

SND_APPLICATION:播放与应用程序相关的声音。

SND_ALIAS:播放的声音是系统定义的声音。

SND_ALIAS_ID:pszSound参数是预定义的声音标识符。

SND_ASYNC:声音播放是异步的,PlaySound()函数在开始播放声音后立即返回。要终止播放声音,则通过PlaySound()函数传入NULL参数实现。

SND_FILENAME:pszSound参数指定要播放的声音文件名称。

SND_LOOP:重复播放声音,必须与SND_ASYNC选项一起使用。

SND_MEMORY:系统声音文件装载入内存。

SND_NODEFAULT:不适用默认声音事件。如果要播放的声音没有查找到,函数不播放任何声音,直接返回。

SND_NOSTOP:如果正有其他程序在占用资源播放声音,则不会停止当前播放的声音,而直接返回。

SND_NOWAIT:如果设备正忙,则函数立即返回。

SND_PURGE:停止声音播放。

SND_RESOURCE:播放的声音是资源,必须包含在hmod参数中指定模块中。

SND_SYNC:异步播放声音。

播放声音文件成功,返回true;如果播放声音文件失败,则返回false。下面代码显示了如何播放Windows启动声音文件。

  1. void CSoundSampleDlg::OnButtonPlay()       
    // 播放声音示例  
  2. {  
  3.     if (!PlaySound("C:\\Windows XP 启动.wav", 
    NULL, SND_SYNC | SND_  
  4.     NODEFAULT))  
  5.         WriteLog("播放声音文件出现错误");  

使用waveIn系列的函数可以录制声音文件。代码如下:

  1. void CSoundSampleDlg::OnButtonRecord()     
    // 录制声音示例  
  2. {  
  3.     MMRESULT mmResult;                        
    // 定义操作结果变量  
  4.     WAVEFORMATEX m_waveformat;                 
    // 定义音频格式  
  5.     m_waveformat.wFormatTag=WAVE_FORMAT_PCM;   
    // 赋值为PCM格式  
  6.     m_waveformat.nChannels=1;                  
    // 赋值通道为1  
  7.     m_waveformat.nSamplesPerSec=11025;         
    // 设置每秒采样11025  
  8.     m_waveformat.nAvgBytesPerSec=11025;     
    // 设置每秒平均字节11025  
  9.     m_waveformat.nBlockAlign=1;               
    // 设置对齐方式  
  10.     m_waveformat.wBitsPerSample=8;         
    // 设置每个采样标本中的Bit位数  
  11.     m_waveformat.cbSize=0;                  // 设置结构长度  
  12.     // 播放音频  
  13.     if ((mmResult = waveInOpen(&m_hWaveIn, 0, 
    &m_waveformat,  
  14.         (DWORD)this->m_hWnd, NULL, CALLBACK_
    WINDOW))!= MMSYSERR_NOERROR)  
  15.     {  
  16.         if (mmResult == MMSYSERR_ALLOCATED) 
    WriteLog("音频设备已经被其他设备  
  17.         占用");  
  18.         else if (mmResult == MMSYSERR_BADDEVICEID)  
  19.             WriteLog("指定的音频设备标识符超出范围");  
  20.         else if (mmResult == MMSYSERR_NODRIVER) 
  21. WriteLog("没有准备好音频设备");  
  22.         else if (mmResult == MMSYSERR_NOMEM)   
    WriteLog("没有分配好内存");  
  23.         else if (mmResult == WAVERR_BADFORMAT)  
    WriteLog("错误的音频格式");  
  24.         else WriteLog("打开音频输入设备失败");  
  25.         return;  
  26.     }  
  27.         const int MAX_WAVEDATA_LENGTH = 90040;     
    // 定义音频数据的最大长度  
  28.     inbuf = new char[MAX_WAVEDATA_LENGTH];         
    // 定义音频数据缓冲区  
  29.     m_wavehdr.lpData=inbuf;                        
    // 赋值音频句柄数据缓冲区  
  30.         m_wavehdr.dwBufferLength=MAX_WAVEDATA_LENGTH
    // 赋值缓冲区长度  
  31.         m_wavehdr.dwBytesRecorded=0;                  
    // 赋值字节记录  
  32.         m_wavehdr.dwUser=0;  
  33.         m_wavehdr.dwFlags=0;  
  34.         m_wavehdr.dwLoops=0;  
  35.         m_wavehdr.lpNext=NULL;  
  36.         m_wavehdr.reserved=0;  
  37.     if (waveInPrepareHeader(m_hWaveIn, &m_wavehdr,
    sizeof(m_wavehdr))  
  38.             != MMSYSERR_NOERROR)                // 准备录音  
  39. {  
  40.         WriteLog("为录音设备准备缓存函数失败");  
  41.         return;  
  42.     }  
  43.     if (waveInAddBuffer(m_hWaveIn, &m_wavehdr, 
    sizeof(m_wavehdr))  
  44.                 != MMSYSERR_NOERROR)            
    // 为录音设备增加输入缓冲区  
  45.     {  
  46.         WriteLog("给输入设备增加一个缓存失败");  
  47.         return;  
  48.     }  
  49.     if (waveInStart(m_hWaveIn)!= MMSYSERR_NOERROR)  
  50.     {  
  51.         WriteLog("开始录音失败");  
  52.         return;  
  53.     }  
  54.     WriteLog("开始录音……");               
    // 输出提示信息  

上面代码中,首先调用waveInOpen()函数打开音频输入设备,然后调用waveInPrepareHeader()函数为录音设备准备缓存空间,调用waveInAddBuffer()函数为录音设备增加缓冲区,最后调用waveInStart()函数启动录音。录音完毕,可以调用waveIn系列函数停止录音,代码如下:

  1. void CSoundSampleDlg::OnButtonStoprecord()       
    // 停止录音代码  
  2. {  
  3.     if (waveInReset(m_hWaveIn)!= MMSYSERR_NOERROR)
    // 停止录音  
  4.     {  
  5.         WriteLog("停止录音失败");  
  6.         return;  
  7.     }  
  8.     MMRESULT mmResult;                               
    // 定义操作结果  
  9.     if ((mmResult = waveInUnprepareHeader(m_hWaveIn, 
    &m_wavehdr, sizeof  
  10.     (m_wavehdr)))  
  11.             != MMSYSERR_NOERROR)                   
    // 释放输入设备  
  12.     {  
  13.         if (mmResult == MMSYSERR_INVALHANDLE)   
    WriteLog("设备句柄无效");  
  14.         else if (mmResult == MMSYSERR_NODRIVER)
    WriteLog("没有准备好设备驱动");  
  15.         else if (mmResult == MMSYSERR_NOMEM) 
    WriteLog("没有分配或锁定内存");  
  16.         else if (mmResult == WAVERR_STILLPLAYING)
    WriteLog("正在播放声音");  
  17.         else WriteLog("清除缓存失败");  
  18.         return;  
  19.     }  
  20.     if (waveInClose(m_hWaveIn)!= MMSYSERR_NOERROR)
    // 关闭录音  
  21.     {  
  22.         WriteLog("关闭录音设备失败");  
  23.         return;  
  24.     }  
  25.     WriteLog("录制声音完成");  

上面代码中,首先调用waveInReset()函数停止录音,然后调用waveInUnprepareHeader()函数清除缓存,最后调用waveInClose()函数关闭录音设备。可以根据需要在调用waveInUnprepareHeader()函数前,保存录制好的声音。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇26.1.4 利用PC喇叭播放声音 下一篇26.1 多媒体声音控制

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: