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

 
Windows音频编程:Win32 Wave API 的使用
2011-10-27 10:34

//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; 
    } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值