WindowsXP錄音模塊

//WindowsXP錄音模塊

 

//RecordToWavFile.h

////////////////////////////////////////////////////////////////

 

#ifndef __RECORD_TO_WAV_FILE_H__

#define __RECORD_TO_WAV_FILE_H__

 

////////////////////////////////////////////////////////////////

 

#define RECORD_TO_WAV_FILE_API __declspec(dllexport)

 

////////////////////////////////////////////////////////////////

 

#pragma warning(disable:4996)

 

////////////////////////////////////////////////////////////////

 

RECORD_TO_WAV_FILE_API int _StartRecord(

 const wchar_t* _lpszFileName,unsigned int _nChannels = 1,unsigned int _nSamplesPerSec = 16000,unsigned int _wBitsPerSample = 16);

RECORD_TO_WAV_FILE_API void _EndRecord();

 

////////////////////////////////////////////////////////////////

 

#endif//__RECORD_TO_WAV_FILE_H__

 

////////////////////////////////////////////////////////////////

//RecordToWavFile.cpp

////////////////////////////////////////////////////////////////

 

#include <windows.h>

#include <assert.h>

#include <stdio.h>

#include <string.h>

#include <mmsystem.h>   

 

#include "RecordToWavFile.h"

 

////////////////////////////////////////////////////////////////

 

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

 

////////////////////////////////////////////////////////////////

 

#define FRAGMENT_SIZE 1024//緩存區大小

#define FRAGMENT_NUM 4//緩存區個數

 

////////////////////////////////////////////////////////////////

 

#pragma pack(push,1)

 

typedef struct tagPcmWaveHeader

{

unsigned char riff[4];

unsigned long file_length;

unsigned char wave[4];

unsigned char fmt[4];

unsigned long format_length;

short wFormatTag; 

short nChannels; 

unsigned long nSamplesPerSec; 

unsigned long nAvgBytesPerSec; 

short nBlockAlign; 

short wBitsPerSample; 

unsigned char data[4];

unsigned long data_length;

}PCM_WAVE_HEADER,*PPCM_WAVE_HEADER;

 

#pragma pack(pop)

 

////////////////////////////////////////////////////////////////

 

static unsigned char s_byteBufferArrayForHdr[FRAGMENT_NUM][FRAGMENT_SIZE] = {0};

static WAVEHDR s_sWaveHdr[FRAGMENT_NUM] = {0};

static HANDLE s_hFile = INVALID_HANDLE_VALUE;

static HWAVEIN s_hWaveIn = NULL;

static long s_lWavDataLength = 0;

static PCM_WAVE_HEADER s_bpfh = {0};

 

////////////////////////////////////////////////////////////////

 

static void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2);

void FillAcmWavHeader(PPCM_WAVE_HEADER header,unsigned long length,

 unsigned short _nChannelsRes,unsigned long _nSamplesPerSecRes,short _wBitsPerSampleRes);

 

////////////////////////////////////////////////////////////////

 

RECORD_TO_WAV_FILE_API int _StartRecord(

const wchar_t* _lpszFileName,unsigned int _nChannels,unsigned int _nSamplesPerSec,unsigned int _wBitsPerSample)

{

int iCreateFileCount;

MMRESULT rel = MMSYSERR_NOERROR;

WAVEFORMATEX wavform = {0};

DWORD dwNumberOfBytesWritten = 0;

 

assert (NULL != _lpszFileName && 0 != _lpszFileName[0]);

assert (2 >= _nChannels && 48000 >= _nSamplesPerSec && 16 >= _wBitsPerSample);

 

if (NULL != _lpszFileName && 0 != _lpszFileName[0] &&

2 >= _nChannels && 48000 >= _nSamplesPerSec && 16 >= _wBitsPerSample &&

INVALID_HANDLE_VALUE == s_hFile)

{

iCreateFileCount = 0;

do

{

if (INVALID_HANDLE_VALUE != s_hFile)

{

CloseHandle(s_hFile);

s_hFile = INVALID_HANDLE_VALUE;

Sleep(5);

}

 

if (0 < iCreateFileCount)

{

Sleep(10);

}

s_hFile = CreateFile(_lpszFileName,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

iCreateFileCount ++;

}while (INVALID_HANDLE_VALUE == s_hFile && iCreateFileCount < 5);

#ifdef _DEBUG

int err = GetLastError();

#endif//_DEBUG

assert (INVALID_HANDLE_VALUE != s_hFile);

if (INVALID_HANDLE_VALUE != s_hFile)

{

wavform.wFormatTag      = WAVE_FORMAT_PCM;

wavform.nChannels       = _nChannels;

wavform.nSamplesPerSec  = _nSamplesPerSec;

wavform.wBitsPerSample  = _wBitsPerSample;

wavform.nBlockAlign     = wavform.nChannels * wavform.wBitsPerSample / 8;

wavform.nAvgBytesPerSec = wavform.nSamplesPerSec * wavform.nBlockAlign;

wavform.cbSize          = 0;

 

rel = waveInOpen(&s_hWaveIn,WAVE_MAPPER,&wavform,(DWORD_PTR)waveInProc,0,CALLBACK_FUNCTION);

if (MMSYSERR_NOERROR == rel)

{

for (int i=0;i<FRAGMENT_NUM;i++)

{

memset(&(s_sWaveHdr[i]),0,sizeof(WAVEHDR));

 

s_sWaveHdr[i].lpData = (LPSTR)(s_byteBufferArrayForHdr[i]);

s_sWaveHdr[i].dwBufferLength = FRAGMENT_SIZE;

s_sWaveHdr[i].dwLoops = 1;

 

waveInPrepareHeader(s_hWaveIn,&(s_sWaveHdr[i]),sizeof(WAVEHDR));

waveInAddBuffer(s_hWaveIn,&(s_sWaveHdr[i]),sizeof(WAVEHDR));

}

 

if (NULL != s_hFile)

{

s_lWavDataLength = 0;

FillAcmWavHeader(&s_bpfh,s_lWavDataLength,_nChannels,_nSamplesPerSec,_wBitsPerSample);

WriteFile(s_hFile,&s_bpfh,sizeof(s_bpfh),&dwNumberOfBytesWritten,NULL);

}

 

waveInStart(s_hWaveIn);

 

return 0;

}

else

{

CloseHandle(s_hFile);

s_hFile = INVALID_HANDLE_VALUE;

 

return -1;

}

}

else

{

return -2;

}

}

 

return -3;

}

 

RECORD_TO_WAV_FILE_API void _EndRecord()

{

int i;

DWORD dwNumberOfBytesWritten = 0;

 

if (INVALID_HANDLE_VALUE != s_hFile)

{

waveInStop(s_hWaveIn);

 

for (i=0; i<FRAGMENT_NUM; i++)

{  

waveInUnprepareHeader(s_hWaveIn, &s_sWaveHdr[i], sizeof(WAVEHDR));  

memset(&(s_sWaveHdr[i]),0,sizeof(WAVEHDR));

}

 

waveInClose(s_hWaveIn);

 

if (NULL != s_hFile)

{

SetFilePointer(s_hFile,0,0,FILE_BEGIN);

FillAcmWavHeader(&s_bpfh,s_lWavDataLength,s_bpfh.nChannels,s_bpfh.nSamplesPerSec,s_bpfh.wBitsPerSample);

WriteFile(s_hFile,&s_bpfh,sizeof(s_bpfh),&dwNumberOfBytesWritten,NULL);

s_lWavDataLength = 0;

}

 

if (NULL != s_hFile)

{

CloseHandle(s_hFile);

s_hFile = INVALID_HANDLE_VALUE;

}

}

}

 

////////////////////////////////////////////////////////////////

 

void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2)

{  

DWORD dwNumberOfBytesWritten = 0;

LPWAVEHDR lpsHdr = (LPWAVEHDR)dwParam1;

 

switch (uMsg)

{

case WIM_DATA:

if (INVALID_HANDLE_VALUE != s_hFile)

{

s_lWavDataLength += lpsHdr->dwBytesRecorded;

WriteFile(s_hFile,lpsHdr->lpData,lpsHdr->dwBytesRecorded,&dwNumberOfBytesWritten,NULL);

waveInAddBuffer(hwi,lpsHdr,sizeof(WAVEHDR));

}

break;

default:

break;

}

}

 

void FillAcmWavHeader(PPCM_WAVE_HEADER header,unsigned long length,

 unsigned short _nChannelsRes,unsigned long _nSamplesPerSecRes,short _wBitsPerSampleRes)

{

strncpy((char*)header->riff, "RIFF", 4);

header->file_length = sizeof(PCM_WAVE_HEADER) + length - 8;

strncpy((char*)header->wave, "WAVE", 4);

strncpy((char*)header->fmt,  "fmt ", 4);

 

header->format_length   = 16;

header->wFormatTag      = 1;

header->nChannels       = _nChannelsRes;

header->nSamplesPerSec  = _nSamplesPerSecRes;

header->wBitsPerSample  = _wBitsPerSampleRes;

header->nBlockAlign     = header->nChannels * header->wBitsPerSample / 8;

header->nAvgBytesPerSec = header->nSamplesPerSec * header->nBlockAlign;

 

strncpy((char*)header->data, "data", 4);

header->data_length = length;

}

 

////////////////////////////////////////////////////////////////

 

//TestRecordToWavFile.cpp

//////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include <Windows.h>

#include "../RecordToWavFile/RecordToWavFile.h"

 

///////////////////////////////////////////////////////////////////

 

int _tmain(int argc, _TCHAR* argv[]) 

{  

 int k = 0;

 _StartRecord(L".\\Hello1-16000-16.wav");

 

 k = 25;

 while (0 < k)

 {

  printf("Hello1-16000-16 Record...%d\n",k);

  Sleep(200);

 

  k --;

 }

 

 _EndRecord();

 

///////////////////////////////////////////////////////////////////

 

 _StartRecord(L".\\Hello2-44100-16.wav",2,44100,16);

 

 k = 25;

 while (0 < k)

 {

  printf("Hello2-44100-16 Record...%d\n",k);

  Sleep(200);

 

  k --;

 }

 

 _EndRecord();

 

 return 0;

 

///////////////////////////////////////////////////////////////////

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章