windows 里面waveOut*接口应用
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
/*
* some good values for block size and count
*/
#define BLOCK_SIZE 8192
#define BLOCK_COUNT 20
/*
* function prototypes
*/
static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
static WAVEHDR* allocateBlocks(int size, int count);
static void freeBlocks(WAVEHDR* blockArray);
static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);
/*
* module level variables
*/
static CRITICAL_SECTION waveCriticalSection;
static WAVEHDR* waveBlocks;
static volatile int waveFreeBlockCount;
static int waveCurrentBlock;
static void CALLBACK waveOutProc(
HWAVEOUT hWaveOut,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2
)
{
/*
* pointer to free block counter
*/
int* freeBlockCounter = (int*)dwInstance;
/*
* ignore calls that occur due to openining and closing the
* device.
*/
if(uMsg != WOM_DONE)
return;
EnterCriticalSection(&waveCriticalSection);
(*freeBlockCounter)++;
LeaveCriticalSection(&waveCriticalSection);
}
WAVEHDR* allocateBlocks(int size, int count)
{
unsigned char* buffer;
int i;
WAVEHDR* blocks;
DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
/*
* allocate memory for the entire set in one go
*/
if((buffer = (unsigned char*)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
totalBufferSize
)) == NULL)
{
fprintf(stderr, "Memory allocation error\n");
ExitProcess(1);
}
/*
* and set up the pointers to each bit
*/
blocks = (WAVEHDR*)buffer;
buffer += sizeof(WAVEHDR) * count;
for(i = 0; i < count; i++) {
blocks[i].dwBufferLength = size;
blocks[i].lpData = (LPSTR)buffer;
buffer += size;
}
return blocks;
}
void freeBlocks(WAVEHDR* blockArray)
{
/*
* and this is why allocateBlocks works the way it does
*/
HeapFree(GetProcessHeap(), 0, blockArray);
}
void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size)
{
WAVEHDR* current;
int remain;
current = &waveBlocks[waveCurrentBlock];
while(size > 0) {
/*
* first make sure the header we're going to use is unprepared
*/
if(current->dwFlags & WHDR_PREPARED)
waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
if(size < (int)(BLOCK_SIZE - current->dwUser)) {
memcpy(current->lpData + current->dwUser, data, size);
current->dwUser += size;
break;
}
remain = BLOCK_SIZE - current->dwUser;
memcpy(current->lpData + current->dwUser, data, remain);
size -= remain;
data += remain;
current->dwBufferLength = BLOCK_SIZE;
waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
EnterCriticalSection(&waveCriticalSection);
waveFreeBlockCount--;
LeaveCriticalSection(&waveCriticalSection);
/*
* wait for a block to become free
*/
while(!waveFreeBlockCount)
Sleep(10);
/*
* point to the next block
*/
waveCurrentBlock++;
waveCurrentBlock %= BLOCK_COUNT;
current = &waveBlocks[waveCurrentBlock];
current->dwUser = 0;
}
}
int main(int argc, char* argv[])
{
HWAVEOUT hWaveOut; /* device handle */
HANDLE hFile;/* file handle */
WAVEFORMATEX wfx; /* look this up in your documentation */
char buffer[1024]; /* intermediate buffer for reading */
int i;
/*
* quick argument check
*/
/*if(argc != 2) {
fprintf(stderr, "usage: %s \n", argv[0]);
ExitProcess(1);
}*/
/*
* initialise the module variables
*/
waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
waveFreeBlockCount = BLOCK_COUNT;
waveCurrentBlock= 0;
InitializeCriticalSection(&waveCriticalSection);
/*
* try and open the file
*/
if((hFile = CreateFile(
"C:\\Users\\Public\\Music\\Sample Music\\王菲 - 怀念 1.wav",//argv[1]
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
)) == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "%s: unable to open file '%s'\n", argv[0], argv[1]);
ExitProcess(1);
}
/*
* set up the WAVEFORMATEX structure.
*/
wfx.nSamplesPerSec = 44100; /* sample rate */
wfx.wBitsPerSample = 16; /* sample size */
wfx.nChannels= 1; /* channels*/
wfx.cbSize = 0; /* size of _extra_ info */
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
/*
* try to open the default wave device. WAVE_MAPPER is
* a constant defined in mmsystem.h, it always points to the
* default wave device on the system (some people have 2 or
* more sound cards).
*/
if(waveOutOpen(
&hWaveOut,
WAVE_MAPPER,
&wfx,
(DWORD_PTR)waveOutProc,
(DWORD_PTR)&waveFreeBlockCount,
CALLBACK_FUNCTION
) != MMSYSERR_NOERROR)
{
fprintf(stderr, "%s: unable to open wave mapper device\n", argv[0]);
ExitProcess(1);
}
/*
* playback loop
*/
while(1) {
DWORD readBytes;
if(!ReadFile(hFile, buffer, sizeof(buffer), &readBytes, NULL))
break;
if(readBytes == 0)
break;
if(readBytes < sizeof(buffer)) {
printf("at end of buffer\n");
memset(buffer + readBytes, 0, sizeof(buffer) - readBytes);
printf("after memcpy\n");
}
writeAudio(hWaveOut, buffer, sizeof(buffer));
}
/*
* wait for all blocks to complete
*/
while(waveFreeBlockCount < BLOCK_COUNT)
Sleep(10);
/*
* unprepare any blocks that are still prepared
*/
for(i = 0; i < waveFreeBlockCount; i++)
if(waveBlocks[i].dwFlags & WHDR_PREPARED)
waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
DeleteCriticalSection(&waveCriticalSection);
freeBlocks(waveBlocks);
waveOutClose(hWaveOut);
CloseHandle(hFile);
return 0;
}
windows 里面waveOut*接口应用的更多相关文章
- C# Windows Sockets (Winsock) 接口 (转)
在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现.System.Net 命名空间中 ...
- Windows数据库编程接口简介
数据库是计算机中一种专门管理数据资源的系统,目前几乎所有软件都需要与数据库打交道(包括操作系统,比如Windows上的注册表其实也是一种数据库),有些软件更是以数据库为核心因此掌握数据库系统的使用方法 ...
- 第四章 Windows的图形设备接口及Windows绘图 P83 4-6
实验(实习)名称 图形程序设计及其应用 实验(实习)日期 一.实验目的 1.熟悉图形设备接口的概念及其应用. 二.实验内容及步骤 实验任务 1.熟悉基于图形应用的程序设计: 2.掌握刷新技术及其 ...
- Windows的图形设备接口与Windows绘图
本次学习目标 理解DC, 映像模式, 坐标系统, 窗口和视口; 学习获取绘图工具(画笔/画刷)的句柄, 设置颜色, 能定义映像模式; 会使用常用的绘图函数. 编写程序: 在屏幕上出现一个圆心沿正弦曲线 ...
- Spyder清除Variable Explorer&&手动安装protobuf3.0(为了配置windows的python接口)
输入:reset 选择:y PS:建议在windows下,安装anaconda32bit版本的,可以兼容更多第三方包. Conda使用清华镜像 配置镜像 在conda安装好之后,默认的镜像是官方的 ...
- 转:Windows下USB接口驱动技术(二)
- 转:Windows下USB接口驱动技术(一)
- Windows消息过滤
在C#编程中,经常会遇到一些场景,如禁止鼠标拖动窗体,启用某些快捷键,禁止鼠标移动等.遇到这些需求,可以通过窗体的MouseMove事件,OnDragDrop,OnMove等事件来解决问题, 但是该方 ...
- Windows内核原理系列01 - 基本概念
1.Windows API Windows 应用编程接口(API)是针对WIndwos操作系统用户模式的系统编程接口,包含在WindwosSDK中. 2.关于.NET .NET由一个被称为FCL的类库 ...
随机推荐
- 使用MongoDB 记录业务日志
最近公司有个需求,要对业务日志进行记录并根据日志排查问题,以前都是使用log4net之类的日志组件来记录到文件,这种方式已经不能满足业务的需要,因为日志文件会很大,即使进行分割后,查找也是很不方便,何 ...
- Smart pointer 智能指针小总结
Smart pointer line 58之后smart pointer里的计数已经是0,所以会真正释放它引用的对象,调用被引用对象的析构函数.如果继续用指针访问,会出现如下图的内存访问异常.所以说如 ...
- 由浅到深理解ROS(2)
ROS文件系统 用户可以直接参看官网:http://wiki.ros.org/ROS/Tutorials/NavigatingTheFilesystem ROS文件系统中的两个最基本的概念:Packa ...
- LCD驱动程序(二)
上节我们主要是对fb_info结构体的配置,对fb_info结构体的配置主要分为一下步骤: static int lcd_init(void){ /* 1. 分配一个fb_info */ s3c_lc ...
- Apache禁止ip访问
网站突然让禁止ip访问,于是就通过配置Apache达到了想要的效果. 我们网站用的是Apache+tomcat集群,所以需要配置虚拟主机,虚拟主机我在这里就不说了,不明白的上网搜搜吧,这里只说禁止ip ...
- Android系统移植与调试之------->如何修改Android设备的桌面背景图片
1.切换到~/mx0831-0525/device/other/TBDG1073/overlay/frameworks/base/core/res/res目录 2.准备好一张相应尺寸的图片并且命名为d ...
- - symfony/icu v1.2.0 requires lib-icu >=4.4 -> the requested linked library icu has the wrong version installed or is missing from your system, ma
$ composer install Loading composer repositories with package information Installing dependencies (i ...
- SQL优化小结
一 背景 客户数据库经常出现死锁.超时.查询慢等问题,数据库mssql,数据量主要表大概上千W. 二 收集信息 首先是要找出IO大.查询慢.使用频率高的脚本.直接用Profiler ...
- Ubuntu 14.04 或者16.04开启root账户登录和图形界面登录root时候的报错解决方法
1.打开终端 2.输入sudo vi /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 3.添加一行:greeter-show-manual-login ...
- 小程序连接百度ai
function getTextFromImage(res) { var access_token = '24.c649256d2e*****0.282335-11449805'; var url = ...