现在的位置: 首页 > 综合 > 正文

WaveOutXX 播放PCM流

2014年08月29日 ⁄ 综合 ⁄ 共 2163字 ⁄ 字号 评论关闭

      最新在WM上开发音频想关的东西, 遇到的麻烦是播放流文件的时候会一顿一顿的,网上找了找答案,是由于没有用到双缓冲。网上遇到了一段代码,给了我很大帮助。在此分享。。。。

 

//waveout.h

#ifndef waveout_h
#define waveout_h

#pragma once

#include <mmsystem.h>
#include <list>
using namespace std;

#define BUFFER_SIZE 16
#define BLOCK_SIZE 1280 + sizeof(WAVEHDR)

class waveout 
{
 WAVEFORMATEX wave_format;
 HWAVEOUT h_waveout;
public:
 char m_buf[BUFFER_SIZE][BLOCK_SIZE];
 list<char*>m_buf_free;

 waveout();
 ~waveout();

 bool start();
 bool stop();
 int input(unsigned char* buf);
 bool inlineis_start(){return (h_waveout != NULL);}
};

#endif

//waveout.cpp
#include "stdafx.h"
#include "waveout.h"

waveout::waveout(){
 wave_format.wFormatTag= WAVE_FORMAT_PCM;
 wave_format.nChannels= 1;
 wave_format.nSamplesPerSec= 16000;
 wave_format.wBitsPerSample= 16;
 wave_format.nAvgBytesPerSec= 32000;
 wave_format.nBlockAlign= 2;
 wave_format.cbSize= 0;

 h_waveout = NULL;
}

waveout::~waveout(){
 stop();
}

void __stdcall waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,DWORD dwParam1, DWORD dwParam2){
 if(uMsg == WOM_DONE){
  WAVEHDR* p_wavehdr = (WAVEHDR *) dwParam1;
  waveout* p_wvo = (waveout *) dwInstance;
  p_wvo->m_buf_free.push_back((char *) p_wavehdr);
 }
}

int waveout::input(unsigned char* buf){
 size_t nSize = m_buf_free.size();
 if(nSize == 0)
  return 0;

 WAVEHDR *p_wavehdr = (WAVEHDR *) m_buf_free.front();
 m_buf_free.pop_front();

 memcpy(p_wavehdr->lpData, buf, 1280);
 waveOutWrite(h_waveout, p_wavehdr, sizeof(WAVEHDR));

 return 0;
}

bool waveout::start(){
 if(h_waveout != NULL)
  return true;

 MMRESULT nRet = waveOutOpen(&h_waveout, WAVE_MAPPER, &wave_format, (DWORD) waveOutProc, (DWORD) this, CALLBACK_FUNCTION);
 if(nRet != MMSYSERR_NOERROR)
  return false;

 for(int i = 0; i < BUFFER_SIZE; ++ i)
 {
  WAVEHDR *p_wavehdr = (WAVEHDR *)m_buf[i];
  p_wavehdr->dwBufferLength = 1280;
  p_wavehdr->lpData = m_buf[i] + sizeof(WAVEHDR);
  p_wavehdr->dwFlags = 0;

  waveOutPrepareHeader(h_waveout, p_wavehdr, sizeof(WAVEHDR));
  m_buf_free.push_back((char *) p_wavehdr);
 }

 return true;
}

bool waveout::stop(){
 if(h_waveout != NULL){
  while(m_buf_free.size() != BUFFER_SIZE)
   Sleep(80);
  m_buf_free.clear();
  waveOutReset(h_waveout);

  for(int i = 0; i < BUFFER_SIZE; ++ i){
   WAVEHDR *p_wavehdr = (WAVEHDR *)m_buf[i];
   waveOutUnprepareHeader(h_waveout, p_wavehdr, sizeof(WAVEHDR));
  }

  waveOutClose(h_waveout);
  h_waveout = NULL;
 }
 return true;
}

抱歉!评论已关闭.