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;
}
}
转载于:https://blog.51cto.com/2339637/1354925
Windows音频编程:Win32 Wave API 的使用相关推荐
- windows 音频编程
windows 音频编程主要有三种方式: 1.MCI,这种方式很简单,但是不够灵活 2.waveXXXX等低阶的声音API 3.DirectSound 编写一个功能较强大的音频处理程序,那就必须使 ...
- Windows Mobile 编程 (Win32) - 获取设备能力
<Windows 程序设计>第五章重点讲述图形基础.首先一个示例代码是获取设备描述表信息.代码与Windows Mobile 编程 (Win32) - 输出文本中的代码类似. #inclu ...
- Windows SDK编程 API入门系列(转)
之一 -那'烦人'的Windows数据类型 原创文章,转载请注明作者及出处. 首发 http://blog.csdn.net/beyondcode http://www.cnblogs.com/bey ...
- 插入DLL和挂接API——Windows核心编程学习手札之二十二
插入DLL和挂接API --Windows核心编程学习手札之二十二 如下情况,可能要打破进程的界限,访问另一个进程的地址空间: 1)为另一个进程创建的窗口建立子类时: 2)需要调试帮助时,如需要确定另 ...
- Windows界面编程_Miniblink(2) 嵌入到Win32窗口里
这里博主不教关于Miniblink其它功能,只教对UI界面编程相关的API! 第一步如何在Win32的窗口里嵌入Miniblink? 第一步先创建一个Win32工程 第二步包含wke头文件: #inc ...
- Windows核心编程 - API HOOK应用
#Windows核心编程 - API HOOK应用 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:129518033 目录 文章目录 #Windows核 ...
- windows下实现win32俄罗斯方块练手,编程的几点心得
编程珠玑2阅读笔记: 1.使用c语言性能监视器,完成对代码的调优工作 2.关联数组: 拓扑排序算法,可以用于当存在遮挡的时候决定三维场景的绘制顺序. 3.小型算法中的测试与调试工具 脚手架程序:&l ...
- 2、从汇编语言到Windows内核编程笔记(2)
内核线程 在驱动中生成的线程一般是系统线程.系统线程所在的进程名为"System". NTSTATUS PsCreateSystemThread( OUT PHANDLE Thre ...
- [转]Windows CE 编程的十点忠告(by pdasky)
最近两周我们花了大部分时间将已有的应用程序移植到Microsoft Windows CE中.一般说来,这个计划不是太难.我们起步于Microsoft Win32代码,当然 Windows CE是基于W ...
最新文章
- mac redis 链接_在Ubunt/Mac系统安装Redis以及设置Redis密码并且允许远程连接 - Laravel学习网...
- 同期及上期数据对比处理示例.sql
- Kaggle 入门练习 -- Titanic
- 树莓派3 kali linux很卡,树莓派3装kali Linux 成功写入 但是点不亮 为什么?
- 经常和电脑、信息化设备打交道,食品保健养生非常重要!
- Android 系统(219)---Android O上networkAttributes的说明
- Android 8.0学习(27)--- SystemUI(二)启动流程和初始化
- 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(二):Apache安装和配置
- 虚拟机安装VMware ESXi 6.7安装过程介绍
- Java 集合系列18之 Iterator和Enumeration比较
- vue引入阿里云图标
- Oracle查询被锁表和解锁方法
- VxWorks的漏洞分析与解决方案
- [Jetson TX2] NVIDIA Jetson TX2 参数介绍
- 数据库kettle,datax,DBMigration,RazorSQL几款迁移工具使用感受(以及如何迁移表的结构如主键,索引,约束等)
- 计算机图形学学习:GAMES101
- 马士兵网络安全大师班薪选课程
- 系统渗透与防护——网络安全
- 2021-4-19课程——第5章例题【续】触发器+存储过程和函数
- tableau数据分析实战:明星艺人数据分析
热门文章
- c svchost 服务 dll_小机巧丨如何解决svchost一直占用网速和内存?
- java web前端邮件,javaweb之javamail
- mysql第四步安装失败_MySQL8.0版本的安装以及解决安装后MySQL服务无法启动的问题...
- Java SpringBoot 页面渲染
- Java Servlet request
- numpy.core.defchararray.join
- 2021年量子计算机奖,中兴通讯携手中国移动共获“2021年未来网络领先创新科技成果”奖...
- java程序员内功_Java程序员如何成为内功深厚的架构师
- go数据结构与算法| 稀疏数组
- 基于VMware vSphere的虚拟化平台,内存分配是如何实现的?