腰间盘突出正确睡姿图:WINDOWS下的低级音频函数介绍

来源:百度文库 编辑:九乡新闻网 时间:2024/07/14 00:49:19
WINDOWS下的低级音频函数介绍     在WINDOWS下,音频函数有多种类型,如MCI、多媒体OLE控制、高级音频等,使用方法都比较简单。但如果想编写一个功能较强大的音频处理程序,那就必须使用低级音频函数和多媒体文件I/O来控制音频设备的输入和输出。因为低级音频函数可直接与音频驱动程序交互,通过窗口消息或回调(CALL BACK)函数来管理音频数据块的记录和播放,控制非常灵活。重要的一点是,低级音频函数为我们提供了一个设备无关的接口。

播放数字音频

  在使用音频设备之前,必须打开设备驱动程序。为可靠起见,在播放和记录音频之前,要确定系统音频设备的能力。在用完之后必须关闭音频设备。具体流程如下:

  1.查询设备数目和能力

    使用waveOutGetNumDevs和waveOutGetDevCaps来获取波形输出设备的个数和能力。只有在确定设备存在之后,才可以打开设备、使用设备。

  2.打开波形输出设备

    使用waveOutOpen为进行重放操作打开特定的波形设备。该函数打开与指定的设备ID相关联的设备,并以给出指定内存句柄的方法返回打开波形设备的句柄。

    当有多种波形输出设备时,建议使用WAVE_MAPPER常数作为设备ID,这使waveOutOpen函数会自动挑选最适合播放给定的数据格式的设备。

  3.准备音频数据块

    在波形重放之前,要准备好音频数据块。将数据块传递给设备驱动程序就实现了重放。使用的函数是waveOutPerpareHeader。在用完数据块之后,必须用waveOutUnPrepareHeader函数来清除对波形数据块的准备。

  4.发送音频数据块

    在成功打开波形输出设备之后,就可以进行波形重放,使用waveOutWrite函数。在调用该函数后,必须等到设备驱动程序使用完音频数据块之后才可以把该数据块释放掉。

  5.管理波形重放

    在使用低级音频函数播放音频时,应用程序必须不断地向设备驱动程序提供数据块,直到播放结束。WINDOWS提供两种方法管理波形重放:一是使用窗口消息管理,二是使用低级回调函数管理。另外,通过使用waveOutPause、waveOutRestart和waveOutReset来进行暂停、重新启动和停止播放。

  6.关闭波形设备

    用完设备之后,必须调用waveOutClose函数关闭波形输出设备,以便其他程序可以使用设备。

  记录数字音频

    记录数字音频的方法基本同播放过程,不同在于记录期间是不提供诸如暂停和重新开始这样的控制的。使用到的函数包括:waveInGetDevCaps、waveInOpen、waveInPrepareHeader、waveInUnPrepareHeader、waveInAddBuffer、waveInReset、waveInStart、waveInStop、waveInClose等。 



WIN32音频数据采集 WaveIn-Out实现 
    基本步骤及思想:设定音频采集参数(采样率、声道等),打开音频设备和开辟缓存,操作采集的数据。
1.  定义音频采集参数 

WAVEFORMATEX waveform;//WAVE波形的采集参数

typedef struct { 
    WORD  wFormatTag; 
    WORD  nChannels; 
    DWORD nSamplesPerSec; 
    DWORD nAvgBytesPerSec; 
    WORD  nBlockAlign; 
    WORD  wBitsPerSample; 
    WORD  cbSize; 
} WAVEFORMATEX;

 

waveform.wFormatTag=WAVE_FORMAT_PCM;

  waveform.nChannels=1;             //声道设为1

  waveform.nSamplesPerSec=11025;   //采样率11025

  waveform.nAvgBytesPerSec=11025;

  waveform.nBlockAlign=1;

  waveform.wBitsPerSample=8;        //数据位设为8位

  waveform.cbSize=0;

 

PWAVEHDR pWaveHdr1,pWaveHdr2; //WAVE波形的头信息

 

2.  打开音频采集设备并开辟缓存

 

if (waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {   //打开设备

     free(pBuffer1);
作者: 徜徉的天空  2006-6-8 14:41   回复此发言  
2 WINDOWS下的低级音频函数介绍
     free(pBuffer2);

     MessageBeep(MB_ICONEXCLAMATION);

     AfxMessageBox("Audio can not be open!");

}

pWaveHdr1->lpData=(LPTSTR)pBuffer1;

pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE;

pWaveHdr1->dwBytesRecorded=0;

pWaveHdr1->dwUser=0;

pWaveHdr1->dwFlags=0;

pWaveHdr1->dwLoops=1;

pWaveHdr1->lpNext=NULL;

pWaveHdr1->reserved=0;


waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));


pWaveHdr2->lpData=(LPTSTR)pBuffer2;

pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE;

pWaveHdr2->dwBytesRecorded=0;

pWaveHdr2->dwUser=0;

pWaveHdr2->dwFlags=0;

pWaveHdr2->dwLoops=1;

pWaveHdr2->lpNext=NULL;

pWaveHdr2->reserved=0;


waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));


//////////////////////////////////////////////////////////////////////////

pSaveBuffer = (PBYTE)realloc (pSaveBuffer, 1) ;

// Add the buffers


waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;

waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;

 

3.  操作采集的音频数据

 

在WAVEIN中有如下几个消息

MM_WOM_OPEN    //设备的打开

MM_WIM_DATA    //设备数据的采集及操作

MM_WIM_CLOSE   //设备的关闭

 

void CRecordHWndDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) 

{

// TODO: Add your message handler code here and/or call default

// Reallocate save buffer memory


//////////////////////////////////////////////////////////////////////////


pNewBuffer = (PBYTE)realloc (pSaveBuffer, dwDataLength +

     ((PWAVEHDR) lParam)->dwBytesRecorded) ;


if (pNewBuffer == NULL)

{

     waveInClose (hWaveIn) ;

     MessageBeep (MB_ICONEXCLAMATION) ;

     AfxMessageBox("erro memory");

     return ;

}
pSaveBuffer = pNewBuffer ;

 

//////////////////////////////////////////////////////////////////////////


CopyMemory (pSaveBuffer + dwDataLength, ((PWAVEHDR) lParam)->lpData,

     ((PWAVEHDR) lParam)->dwBytesRecorded) ;


dwDataLength += ((PWAVEHDR) lParam)->dwBytesRecorded ;


if (bEnding)

{

     waveInClose (hWaveIn) ;

     return ;

}

 

CFile file;

file.Open("data.txt",CFile::modeWrite|CFile::modeCreate);

file.Write(pSaveBuffer,dwDataLength);

file.Close();

 


// Send out a new buffer


waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;

TRACE("done input data\n");

return ;

 


}