您的位置:首页 > 编程语言

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

2011-11-01 11:25 543 查看
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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: