C++ 播放音频流(PCM裸流)

来源:互联网 发布:网络公安报警 编辑:程序博客网 时间:2024/05/18 18:42

直接上代码,如果有需要可以直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用了(注意将声道和频率与你自己的文件对应哦)。当然我自己也用VS2008(VS2013好用太多,强烈推荐还是用VS2013,只是它的工程太大,上传起来相当费劲,所以还是用VS2008重写了。。)写了个例子上传了,如果有需要下载地址如下(自己没什么下载分了,所以弄了3分,见谅哈哈):点击打开链接

这份代码是打开文件截取一段数据然后播放的,可以轻松的经过加一条线程的方式改成网络传输的形式,但是经过本人测试因为没有缓存机制会有“哒哒”的噪声,也就是说这份代码在网络实时音频上的表现并不太好。为了解决这个问题,可以加上缓存机制,本人因为一开始用的是事件响应方式,所以一直困在这个框架里,不能很好的利用缓存的机制解决上面提到的问题,后来尝试了用回调函数的方式来响应数据播放完成的消息,问题就轻松的解决了。那部分的代码会在稍候放上去。

[cpp] view plaincopy
  1. #include "stdafx.h"  
  2. #include <stdio.h>  
  3. #include <Windows.h>  
  4. #pragma comment(lib, "winmm.lib")  
  5.   
  6. char buf[1024 * 1024 * 4];  
  7.   
  8. int _tmain(int argc, _TCHAR* argv[]) {  
  9.     FILE*           thbgm;//文件  
  10.     int             cnt;  
  11.     HWAVEOUT        hwo;  
  12.     WAVEHDR         wh;  
  13.     WAVEFORMATEX    wfx;  
  14.     HANDLE          wait;  
  15.   
  16.     wfx.wFormatTag = WAVE_FORMAT_PCM;//设置波形声音的格式  
  17.     wfx.nChannels = 1;//设置音频文件的通道数量  
  18.     wfx.nSamplesPerSec = 8000;//设置每个声道播放和记录时的样本频率  
  19.     wfx.nAvgBytesPerSec = 16000;//设置请求的平均数据传输率,单位byte/s。这个值对于创建缓冲大小是很有用的  
  20.     wfx.nBlockAlign = 2;//以字节为单位设置块对齐  
  21.     wfx.wBitsPerSample = 16;  
  22.     wfx.cbSize = 0;//额外信息的大小  
  23.     wait = CreateEvent(NULL, 0, 0, NULL);  
  24.     waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);//打开一个给定的波形音频输出装置来进行回放  
  25.     fopen_s(&thbgm, "paomo.pcm""rb");  
  26.     cnt = fread(buf, sizeof(char), 1024 * 1024 * 4, thbgm);//读取文件4M的数据到内存来进行播放,通过这个部分的修改,增加线程可变成网络音频数据的实时传输。当然如果希望播放完整的音频文件,也是要在这里稍微改一改  
  27.     int dolenght = 0;  
  28.     int playsize = 1024;  
  29.     while (cnt) {//这一部分需要特别注意的是在循环回来之后不能花太长的时间去做读取数据之类的工作,不然在每个循环的间隙会有“哒哒”的噪音  
  30.         wh.lpData = buf + dolenght;  
  31.         wh.dwBufferLength = playsize;  
  32.         wh.dwFlags = 0L;  
  33.         wh.dwLoops = 1L;  
  34.         waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR));//准备一个波形数据块用于播放  
  35.         waveOutWrite(hwo, &wh, sizeof(WAVEHDR));//在音频媒体中播放第二个函数wh指定的数据  
  36.         WaitForSingleObject(wait, INFINITE);//用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的INFINITE毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回  
  37.         dolenght = dolenght + playsize;  
  38.         cnt = cnt - playsize;  
  39.     }  
  40.     waveOutClose(hwo);  
  41.     fclose(thbgm);  
  42.     return 0;  
  43. }  
链接:http://blog.csdn.net/weixinhum/article/details/29943973
0 0