CSoundIn Class

//////////////////////////////////////////////////////////////////////
// SoundIn.h: interface for the CSoundIn class.
//////////////////////////////////////////////////////////////////////////////////////////    
#pragma once

#include <mmsystem.h>

#define MAX_SAMPLES 8192   //
#define MAX_VOIE 2
#define MAX_SIZE_SAMPLES  1  // WORD
#define MAX_SIZE_INPUT_BUFFER   MAX_SAMPLES*MAX_VOIE*MAX_SIZE_SAMPLES 
#define DEFAULT_CAL_OFFSET 0 // >>>>> depends of you sound card
#define DEFAULT_CAL_GAIN   1.0

// buffers into which sound data is recorded 
#define NUM_LEVEL_BUFFERS   2 

class CSoundIn  
{
public:
  BOOL (*pParentProcessData)(LPVOID pUser, SHORT *pData, DWORD dwLen);
  LPVOID pParentUser;

protected:
  struct _HWWAVEDATA_STRUCT
  {
    WAVEHDR m_WaveHeader;
    SHORT   InputBuffer[MAX_SIZE_INPUT_BUFFER];
  }m_HWWaveStruct[NUM_LEVEL_BUFFERS];

  struct _WAVESAMPLED_STRUCT
  {
    ULONGLONG mTimesCount;
    BOOL    bSampleValid;
    BOOL    bIsReaded;
    BOOL    bIsCalculating;
    DWORD   m_SizeRecord;
    SHORT   InputBuffer[MAX_SIZE_INPUT_BUFFER];
  }m_SampledData[2];

  HWAVEIN       m_WaveIn;
  WAVEINCAPS    m_WaveInDevCaps;
  WAVEFORMATEX  m_WaveFormat;
  UINT m_WaveOutSampleRate;

  ULONGLONG m_SampledTimesIndex;
  short m_CalOffset;
  double m_CalGain;
  BOOL bTerminateFlage;

public :	
  void CloseMic();
  MMRESULT OpenMic(LPVOID pUser, LPVOID pProcessSamp);

//////////////////////////////////////////////////////
// functions members
  void WaveInitFormat(WORD    nCh, // number of channels (mono, stereo)
    DWORD   nSampleRate, // sample rate
    WORD    BitsPerSample);
  CSoundIn();
  virtual ~CSoundIn();

public :	
  static void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);     
};

/////////////////////////////////////////////////////////////////////////////////////////
// SoundIn.cpp: implementation of the CSoundIn class.
//////////////////////////////////////////////////////////////////////////////////////////    

#include "stdafx.h"
#include "SoundIn.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#pragma comment(lib, "winmm.lib ")

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSoundIn::CSoundIn()
{
  m_CalOffset = DEFAULT_CAL_OFFSET;
  m_CalGain = DEFAULT_CAL_GAIN;

  m_WaveIn = NULL;
  m_SampledTimesIndex = 0;
  m_WaveOutSampleRate = 44100;
  // init format 
  WaveInitFormat(1/* mono*/, m_WaveOutSampleRate /* hz */,16 /* bits */); 

  memset(&m_HWWaveStruct, 0, sizeof(m_HWWaveStruct));
  memset(&m_SampledData, 0, sizeof(m_SampledData));

  bTerminateFlage = FALSE;
  pParentUser = NULL;
  pParentProcessData = NULL;
}

CSoundIn::~CSoundIn()
{
	CloseMic();
}
///////////////////////////////////////////////////////////////////
MMRESULT CSoundIn::OpenMic(LPVOID pUser, LPVOID pProcessSamp)
{
  pParentUser = pUser;
  pParentProcessData = (BOOL (*)(LPVOID, SHORT *, DWORD))pProcessSamp;

  memset(&m_SampledData, 0, sizeof(m_SampledData));
  m_SampledTimesIndex = 0;

  MMRESULT result;

  result=waveInGetNumDevs(); 
  if (result == 0)
  {
    AfxMessageBox( _T("No Sound Device") );
    return result;
  }

  // test for Mic available   
  result=waveInGetDevCaps (0, &m_WaveInDevCaps, sizeof(WAVEINCAPS));

  if ( result!= MMSYSERR_NOERROR)
  {
    AfxMessageBox(_T("Cannot determine sound card capabilities !"));
  }

  // Open Input 
  //result = waveInOpen( &m_WaveIn,0, &m_WaveFormat,(DWORD)m_WaveInEvent , NULL, CALLBACK_EVENT); 
  result = waveInOpen(  &m_WaveIn, 0, &m_WaveFormat, (DWORD)waveInProc, (DWORD)this, CALLBACK_FUNCTION);
  if ( result!= MMSYSERR_NOERROR)
  {
    AfxMessageBox(_T("Cannot Open Sound Input Device!"));
    return result;
  }

  for(int i=0; i<NUM_LEVEL_BUFFERS; i++)
  {
    _HWWAVEDATA_STRUCT *pWaveStruct = &m_HWWaveStruct[i];

    pWaveStruct->m_WaveHeader.lpData = (CHAR *)&pWaveStruct->InputBuffer[0];
    pWaveStruct->m_WaveHeader.dwBufferLength = MAX_SAMPLES *2;
    pWaveStruct->m_WaveHeader.dwFlags = 0;
    result = waveInPrepareHeader( m_WaveIn, &pWaveStruct->m_WaveHeader, sizeof(WAVEHDR) ); 
    if ( (result!= MMSYSERR_NOERROR) || ( pWaveStruct->m_WaveHeader.dwFlags != WHDR_PREPARED) )
      AfxMessageBox(_T("Cannot Prepare Header !"));

    result = waveInAddBuffer( m_WaveIn, &pWaveStruct->m_WaveHeader, sizeof(WAVEHDR) );
    if  (result!= MMSYSERR_NOERROR) 
      AfxMessageBox(_T("Cannot Add Buffer !"));
  }

  bTerminateFlage = false;
  result = waveInStart( m_WaveIn );
  if  (result!= MMSYSERR_NOERROR) 
  {
    AfxMessageBox(_T("Cannot Start Wave In !"));
  }

  return result;
}

void CSoundIn:: WaveInitFormat(WORD nCh, // number of channels (mono, stereo)
								DWORD   nSampleRate, // sample rate
								WORD    BitsPerSample)
{
  m_WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
  m_WaveFormat.nChannels = nCh;
  m_WaveFormat.nSamplesPerSec = nSampleRate;
  m_WaveFormat.nAvgBytesPerSec = nSampleRate * nCh * BitsPerSample/8;
  m_WaveFormat.nBlockAlign = m_WaveFormat.nChannels * BitsPerSample/8;
  m_WaveFormat.wBitsPerSample = BitsPerSample;
  m_WaveFormat.cbSize = 0;
}   

void CSoundIn::CloseMic()
{
  bTerminateFlage = TRUE;
  if (m_WaveIn) 
  {
    waveInStop(m_WaveIn);
    waveInClose(m_WaveIn);
    m_WaveIn = NULL;
  }
}

void CSoundIn::waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
  CSoundIn *pSoundIn = (CSoundIn*)dwInstance;
  if(pSoundIn->bTerminateFlage)
    return;
  
  switch(uMsg)
  {
    case(WIM_OPEN):
    {
      break;
    }
    case(WIM_DATA):
    {
      MMRESULT result;
      WAVEHDR *pWaveHeader = (WAVEHDR  *)dwParam1;
      /*
      result = waveInUnprepareHeader( hwi, pWaveHeader, sizeof(WAVEHDR) ); 
      if  (result!= MMSYSERR_NOERROR) 
      {
        AfxMessageBox(_T("Cannot UnPrepareHeader !"));
      };
      */

      SHORT *pSampleValidBuffer = 0;
      DWORD dwSampledLength = 0;
      //处理数据
      {
        _WAVESAMPLED_STRUCT *pWaveSampled = 0;
        if(pSoundIn->m_SampledData[0].mTimesCount <= pSoundIn->m_SampledData[1].mTimesCount)
          pWaveSampled = &pSoundIn->m_SampledData[0];
        else
          pWaveSampled = &pSoundIn->m_SampledData[1];

        pWaveSampled->m_SizeRecord = pWaveHeader->dwBytesRecorded/2;
        SHORT *pSrc = (SHORT*)pWaveHeader->lpData;
        SHORT *pDst = pWaveSampled->InputBuffer;
        pWaveSampled->bIsCalculating = TRUE; //计算中
        if(pSoundIn->m_CalOffset != 0 || pSoundIn->m_CalGain != 1)
        {
          for (DWORD i = 0 ; i<pWaveSampled->m_SizeRecord ; i++) // scaling the input samples du to the sound card
          {
            pDst[i] = (SHORT)((double)(pSrc[i] + pSoundIn->m_CalOffset) * pSoundIn->m_CalGain);
          }
        }
        else
        {
          for (DWORD i = 0 ; i<pWaveSampled->m_SizeRecord ; i++) // scaling the input samples du to the sound card
          {
            pDst[i] = pSrc[i];
          }
        }
        pWaveSampled->bIsCalculating = false;

        pWaveSampled->bSampleValid = TRUE;
        pWaveSampled->mTimesCount = ++pSoundIn->m_SampledTimesIndex;//采样次数增加

        pSampleValidBuffer = pDst;
        dwSampledLength = pWaveSampled->m_SizeRecord;
      }
      // put the buffer back on the queue 
      result = waveInAddBuffer( hwi, pWaveHeader, sizeof(WAVEHDR) );
      if  (result!= MMSYSERR_NOERROR) 
      {
        AfxMessageBox(_T("Cannot Add Buffer !"));//WAVERR_UNPREPARED
      }

      if(pSoundIn->pParentUser && pSoundIn->pParentProcessData)
      {
        pSoundIn->pParentProcessData(pSoundIn->pParentUser, pSampleValidBuffer, dwSampledLength);
      }
    }
    case(WIM_CLOSE): 
      break;
    default:
      break;
  }
}


 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值