直接上代码,如果有需要可以直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用了(注意将声道和频率与你自己的文件对应)。当然我自己也用VS2008写了个例子上传了,如果有需要下载地址如下:点击打开链接。
这份代码是打开文件截取一段数据然后播放的,可以轻松的经过加一条线程的方式改成网络传输的形式,但经过本人测试,因为没有缓存机制会有“哒哒”的噪声,也就是说这份代码在网络实时音频上的表现并不太好。为了解决这个问题,可以加上缓存机制,本人因为一开始用的是事件响应方式,所以一直困在这个框架里,不能很好的利用缓存的机制解决上面提到的问题,后来尝试了用回调函数的方式来响应数据播放完成的消息,问题就轻松的解决了。那部分的代码会在稍候放上去。
- #include "stdafx.h"
- #include <stdio.h>
- #include <Windows.h>
- #pragma comment(lib, "winmm.lib")
-
- char buf[1024 * 1024 * 4];
-
- int _tmain(int argc, _TCHAR* argv[]) {
- FILE* thbgm;
- int cnt;
- HWAVEOUT hwo;
- WAVEHDR wh;
- WAVEFORMATEX wfx;
- HANDLE wait;
-
- wfx.wFormatTag = WAVE_FORMAT_PCM;
- wfx.nChannels = 1;
- wfx.nSamplesPerSec = 8000;
- wfx.nAvgBytesPerSec = 16000;
- wfx.nBlockAlign = 2;
- wfx.wBitsPerSample = 16;
- wfx.cbSize = 0;
- wait = CreateEvent(NULL, 0, 0, NULL);
- waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);
- fopen_s(&thbgm, "paomo.pcm", "rb");
- cnt = fread(buf, sizeof(char), 1024 * 1024 * 4, thbgm);
- int dolenght = 0;
- int playsize = 1024;
- while (cnt) {
- wh.lpData = buf + dolenght;
- wh.dwBufferLength = playsize;
- wh.dwFlags = 0L;
- wh.dwLoops = 1L;
- waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR));
- waveOutWrite(hwo, &wh, sizeof(WAVEHDR));
- WaitForSingleObject(wait, INFINITE);
- dolenght = dolenght + playsize;
- cnt = cnt - playsize;
- }
- waveOutClose(hwo);
- fclose(thbgm);
- return 0;
- }
离写上面部分已经过了快一年,现在回看之前写的代码感觉略为坑爹,或许是进步了吧。之前说要把双缓存的代码放出来,哪知道后来忙别的项目去了,这部分就丢到一边,去老项目中提取代码感觉好烦一直没弄。在这一年中不少人发私信问我关于这部分代码如何写的事,没想到现在做音频的人还真不少呢。Ok,既然挖了坑就要填,今天乘着周末写了一个双缓存的Demo工程,代码如下:
- #include <stdio.h>
- #include <Windows.h>
-
- #pragma comment(lib, "winmm.lib")
-
- #define DATASIZE 1024*512 //分次截取数据大小
- FILE* pcmfile;
- HWAVEOUT hwo;
-
- void CALLBACK WaveCallback(HWAVEOUT hWave, UINT uMsg, DWORD dwInstance, DWORD dw1, DWORD dw2)
- {
- switch (uMsg)
- {
- case WOM_DONE:
- {
- LPWAVEHDR pWaveHeader = (LPWAVEHDR)dw1;
- pWaveHeader->dwBufferLength = fread(pWaveHeader->lpData, 1, DATASIZE, pcmfile);;
- waveOutPrepareHeader(hwo, pWaveHeader, sizeof(WAVEHDR));
- waveOutWrite(hwo, pWaveHeader, sizeof(WAVEHDR));
- break;
- }
- }
- }
-
- void main()
- {
- int cnt;
- WAVEHDR wh1;
- WAVEHDR wh2;
- WAVEFORMATEX wfx;
-
- fopen_s(&pcmfile, "paomo.pcm", "rb");
-
- wfx.wFormatTag = WAVE_FORMAT_PCM;
- wfx.nChannels = 1;
- wfx.nSamplesPerSec = 8000;
- wfx.nAvgBytesPerSec = 16000;
- wfx.nBlockAlign = 2;
- wfx.wBitsPerSample = 16;
- wfx.cbSize = 0;
-
- waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD)WaveCallback, 0L, CALLBACK_FUNCTION);
-
- wh1.dwLoops = 0L;
- wh1.lpData = new char[DATASIZE];
- wh1.dwBufferLength = DATASIZE;
- fread(wh1.lpData, 1, DATASIZE, pcmfile);
- wh1.dwFlags = 0L;
- waveOutPrepareHeader(hwo, &wh1, sizeof(WAVEHDR));
- waveOutWrite(hwo, &wh1, sizeof(WAVEHDR));
-
- wh2.dwLoops = 0L;
- wh2.lpData = new char[DATASIZE];
- wh2.dwBufferLength = DATASIZE;
- fread(wh2.lpData, 1, DATASIZE, pcmfile);
- wh2.dwFlags = 0L;
- waveOutPrepareHeader(hwo, &wh2, sizeof(WAVEHDR));
- waveOutWrite(hwo, &wh2, sizeof(WAVEHDR));
-
- while (wh1.dwBufferLength != 0 || wh2.dwBufferLength != 0)
- {
- Sleep(500);
- }
- waveOutUnprepareHeader(hwo, &wh1, sizeof(WAVEHDR));
- waveOutUnprepareHeader(hwo, &wh2, sizeof(WAVEHDR));
-
- delete []wh1.lpData;
- delete []wh2.lpData;
- fclose(pcmfile);
- return;
- }
同上面一样,如果想要这个工程的可以到这个链接去下载。不过提醒下,本人已然抛弃了VS2008,直接用VS2013,如果还在用老平台的话要用还是要折腾一会的。
from:http://blog.csdn.net/weixinhum/article/details/29943973?utm_source=tuicool&utm_medium=referral
|
请发表评论