Windows音频编程:Win32 Wave API 的使用

//Windows音频编程:Win32 Wave API 的使用

//下面是一个Win32控制台程序的源码,环境VS2008,新建一个空的Win32控制台项目,加入此文件编译即可,功能为录制5秒并回放。注意不要选择Unicode字符集,不然设备名会出现乱码。
//  
//  WaveAPI.cpp  
//  
// by: 知秋一叶  
//  
// 转载:http://blog.csdn.net/zhi_qiu_yi_ye/article/details/6663366

#include <windows.h>  
#include <stdio.h>  
#include <mmsystem.h>  
#pragma comment(lib, "winmm.lib")  

#define BUFFER_SIZE (44100*16*2/8*5)    // 录制声音长度  
#define FRAGMENT_SIZE 1024              // 缓存区大小  
#define FRAGMENT_NUM 4                  // 缓存区个数  

static unsigned char buffer[BUFFER_SIZE] = {0};  
static int buf_count = 0;  

// 函数定义  
void CALLBACK waveInProc(HWAVEIN hwi,        
                        UINT uMsg,          
                        DWORD_PTR dwInstance,    
                        DWORD_PTR dwParam1,    
                        DWORD_PTR dwParam2     );  
void CALLBACK waveOutProc(  HWAVEOUT hwo,    
                         UINT uMsg,          
                         DWORD_PTR dwInstance,    
                         DWORD_PTR dwParam1,      
                         DWORD_PTR dwParam2     );  

// 入口  
int main()  
{  
   /* 录音 */  

   // Device  
   int nReturn = waveInGetNumDevs();  
   printf("输入设备数目:%d\n", nReturn);  
   for (int i=0; i<nReturn; i++)  
   {  
       WAVEINCAPS wic;  
       waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS));  
       printf("#%d\t设备名:%s\n", i, wic.szPname);  
   }  

   // open  
   HWAVEIN hWaveIn;  
   WAVEFORMATEX wavform;  
   wavform.wFormatTag = WAVE_FORMAT_PCM;  
   wavform.nChannels = 2;  
   wavform.nSamplesPerSec = 44100;  
   wavform.nAvgBytesPerSec = 44100*16*2/8;  
   wavform.nBlockAlign = 4;  
   wavform.wBitsPerSample = 16;  
   wavform.cbSize = 0;  

   waveInOpen(&hWaveIn, WAVE_MAPPER, &wavform, (DWORD_PTR)waveInProc, 0, CALLBACK_FUNCTION);  

   WAVEINCAPS wic;  
   waveInGetDevCaps((UINT_PTR)hWaveIn, &wic, sizeof(WAVEINCAPS));  
   printf("打开的输入设备:%s\n", wic.szPname);  

   // prepare buffer  
   static WAVEHDR wh[FRAGMENT_NUM];  
   for (int i=0; i<FRAGMENT_NUM; i++)  
   {  
       wh[i].lpData = new char[FRAGMENT_SIZE];  
       wh[i].dwBufferLength = FRAGMENT_SIZE;  
       wh[i].dwBytesRecorded = 0;  
       wh[i].dwUser = NULL;  
       wh[i].dwFlags = 0;  
       wh[i].dwLoops = 1;  
       wh[i].lpNext = NULL;  
       wh[i].reserved = 0;  

       waveInPrepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));  
       waveInAddBuffer(hWaveIn, &wh[i], sizeof(WAVEHDR));  
   }  

   // record  
   printf("Start to Record...\n");  

   buf_count = 0;  
   waveInStart(hWaveIn);  

   while (buf_count < BUFFER_SIZE)  
   {  
       Sleep(1);  
   }  

   printf("Record Over!\n\n");  

   // clean  
   waveInStop(hWaveIn);  
   waveInReset(hWaveIn);  
   for (int i=0; i<FRAGMENT_NUM; i++)  
   {  
       waveInUnprepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));  
       delete wh[i].lpData;  
   }  
   waveInClose(hWaveIn);  

   system("pause");  
   printf("\n");  

   /* 放音 */  

   // Device  
   nReturn = waveOutGetNumDevs();  
   printf("\n输出设备数目:%d\n", nReturn);  
   for (int i=0; i<nReturn; i++)  
   {  
       WAVEOUTCAPS woc;  
       waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS));  
       printf("#%d\t设备名:%s\n", i, wic.szPname);  
   }  

   // open  
   HWAVEOUT hWaveOut;  
   waveOutOpen(&hWaveOut, WAVE_MAPPER, &wavform, (DWORD_PTR)waveOutProc, 0, CALLBACK_FUNCTION);  

   WAVEOUTCAPS woc;  
   waveOutGetDevCaps((UINT_PTR)hWaveOut, &woc, sizeof(WAVEOUTCAPS));  
   printf("打开的输出设备:%s\n", wic.szPname);  

   // prepare buffer  
   WAVEHDR wavhdr;  
   wavhdr.lpData = (LPSTR)buffer;  
   wavhdr.dwBufferLength = BUFFER_SIZE;  
   wavhdr.dwFlags = 0;  
   wavhdr.dwLoops = 0;  

   waveOutPrepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR));  

   // play  
   printf("Start to Play...\n");  

   buf_count = 0;  
   waveOutWrite(hWaveOut, &wavhdr, sizeof(WAVEHDR));  
   while (buf_count < BUFFER_SIZE)  
   {  
       Sleep(1);  
   }  

   // clean  
   waveOutReset(hWaveOut);  
   waveOutUnprepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR));  
   waveOutClose(hWaveOut);  

   printf("Play Over!\n\n");  

   return 0;  
}  

// 录音回调函数  
void CALLBACK waveInProc(HWAVEIN hwi,        
                        UINT uMsg,          
                        DWORD_PTR dwInstance,    
                        DWORD_PTR dwParam1,    
                        DWORD_PTR dwParam2     )  
{  
   LPWAVEHDR pwh = (LPWAVEHDR)dwParam1;  

   if ((WIM_DATA==uMsg) && (buf_count<BUFFER_SIZE))  
   {  
       int temp = BUFFER_SIZE - buf_count;  
       temp = (temp>pwh->dwBytesRecorded) ? pwh->dwBytesRecorded : temp;  
       memcpy(buffer+buf_count, pwh->lpData, temp);  
       buf_count += temp;  

       waveInAddBuffer(hwi, pwh, sizeof(WAVEHDR));  
   }  
}  

// 放音回调函数  
void CALLBACK waveOutProc(  HWAVEOUT hwo,    
                         UINT uMsg,          
                         DWORD_PTR dwInstance,    
                         DWORD_PTR dwParam1,      
                         DWORD_PTR dwParam2     )  
{  
   if (WOM_DONE == uMsg)  
   {  
       buf_count = BUFFER_SIZE;  
   }  
}


你可能感兴趣的:(api,Wave,的使用)