• 播放音频PCM


    1、如果是wav的文件,可以直接用playsound播放。

    2、如果是PCM的流,使用waveout的一系列接口播放。下面的代码从网上看到的(重点是waveoutopen的时候使用了回调函数,waveoutwrite的时候,使用了双缓冲技术):

    //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;
    }

  • 相关阅读:
    HDU 4686
    二叉索引树——树状数组
    poj 3548 Restoring the digits(DFS)
    poj 2062 Card Game Cheater(排序+模拟)
    poj 2570 Fiber Network(floyd)
    hdu 1080 Human Gene Functions
    hdu 4512 吉哥系列故事——完美队形I(最长公共上升自序加强版)
    2015 Multi-University Training Contest 2
    poj 1258 Agri-Net(最小生成树)
    2015 Multi-University Training Contest 1记录
  • 原文地址:https://www.cnblogs.com/frkang/p/3337655.html
Copyright © 2020-2023  润新知