📄 wave.cpp
字号:
//---------------------------------------------------------------------------
#include <stdio.h>
#pragma hdrstop
#include "DebugStr.h"
#include "Wave.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
#define SZ_AUDIO_FORMAT_FILE "AUDIO.FMT"
static LPWAVEFORMATEX Wave_AllocTmpFormat (t_wavedevice *pDevice);
static void Wave_FreeTmpFormat (t_wavedevice *pDevice);
//---------------------------------------------------------------------------
/*
Zero out the wave headers and initialize the data pointers and buffer lengths.
*/
void Wave_InitHeader (t_wavedevice *pDevice, DWORD dwReqWaveBufSize)
{
DWORD dwWaveBufSize;
SHORT nI;
// make the wave buffer size a multiple of the block align...
dwWaveBufSize = (dwReqWaveBufSize - dwReqWaveBufSize % pDevice->pWaveFmtEx->nBlockAlign );
pDevice->dwWaveBufSize = dwWaveBufSize;
// now init the data pointers and buffer lengths...
for (nI=0; nI<WAVE_BLOCKCNT; nI++) {
memset( pDevice->pWaveHdr[ nI ], 0, sizeof(WAVEHDR) );
pDevice->pWaveHdr[ nI ]->dwBufferLength = dwWaveBufSize;
pDevice->pWaveHdr[ nI ]->lpData = pDevice->pWaveMem[ nI ];
}
}
//---------------------------------------------------------------------------
BOOL Wave_AllocData (t_wavedevice *pDevice, DWORD dwWaveBufSize, bool bIsGSM610)
{
/*
Allocate and lock WAVEFORMATEX structure based on maximum format size
according to the ACM.
*/
// get the largest format size required from installed ACMs...
// maxFmtSize is the sum of sizeof(WAVEFORMATEX) + pwavefmtex->cbSize
if( acmMetrics( NULL, ACM_METRIC_MAX_SIZE_FORMAT, &pDevice->dwMaxFmtSize ) ) {
Log_String(LOG_NORMAL, "Error getting the max compression format size.");
return false;
}
// allocate the WAVEFMTEX structure...
if( (pDevice->hWaveFmtEx = GlobalAlloc( GMEM_MOVEABLE, (UINT)pDevice->dwMaxFmtSize )) == NULL ) {
Log_String(LOG_NORMAL, "Error allocating local memory for WaveFormatEx structure.");
return false;
}
if( (pDevice->pWaveFmtEx = (LPWAVEFORMATEX)GlobalLock( pDevice->hWaveFmtEx )) == NULL ) {
Log_String(LOG_NORMAL, "Error locking WaveFormatEx memory.");
return false;
}
ZeroMemory (pDevice->pWaveFmtEx, (size_t)pDevice->dwMaxFmtSize );
if ( bIsGSM610 ) {
// Initialize the format to standard GSM 6.10
pDevice->pWaveFmtEx->wFormatTag = WAVE_FORMAT_GSM610;
pDevice->pWaveFmtEx->nChannels = 1;
pDevice->pWaveFmtEx->nSamplesPerSec = 8000;
pDevice->pWaveFmtEx->nAvgBytesPerSec = 1625;
pDevice->pWaveFmtEx->nBlockAlign = 65;
pDevice->pWaveFmtEx->wBitsPerSample = 0;
pDevice->pWaveFmtEx->cbSize = 2;
FILE *fp;
fp = fopen (SZ_AUDIO_FORMAT_FILE, "rb");
if ( fp == NULL )
goto _JUMP1;
fread (pDevice->pWaveFmtEx, pDevice->dwMaxFmtSize, 1, fp);
fclose (fp);
} else {
_JUMP1 :
// initialize the format to standard PCM...
pDevice->pWaveFmtEx->wFormatTag = WAVE_FORMAT_PCM;
pDevice->pWaveFmtEx->nChannels = 1;
pDevice->pWaveFmtEx->nSamplesPerSec = 11025;
pDevice->pWaveFmtEx->nAvgBytesPerSec = 11025;
pDevice->pWaveFmtEx->nBlockAlign = 1;
pDevice->pWaveFmtEx->wBitsPerSample = 8;
pDevice->pWaveFmtEx->cbSize = 0;
}
/*
Allocate and lock header memory
*/
SHORT nI;
for (nI=0; nI<WAVE_BLOCKCNT; nI++ ) {
pDevice->hWaveHdr[ nI ] = GlobalAlloc( GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, (DWORD)sizeof(WAVEHDR) );
if( !pDevice->hWaveHdr[ nI ] ) {
Log_String (LOG_NORMAL, "Error allocating wave header memory.");
return false;
}
pDevice->pWaveHdr[ nI ] = (LPWAVEHDR) GlobalLock( pDevice->hWaveHdr[ nI ] );
if( !pDevice->pWaveHdr[ nI ] ) {
Log_String (LOG_NORMAL, "Couldn't lock header memory for recording.");
return false;
}
}
/*
Allocate and lock wave memory
*/
for (nI=0; nI<WAVE_BLOCKCNT; nI++ ) {
if( ( pDevice->hWaveMem[ nI ] = GlobalAlloc( GMEM_MOVEABLE | GMEM_SHARE, dwWaveBufSize )) == NULL ) {
Log_String (LOG_NORMAL, "Error allocating wave buffer memory." );
return false;
}
pDevice->pWaveHdr[ nI ]->lpData =
pDevice->pWaveMem[ nI ] = (LPSTR)GlobalLock( pDevice->hWaveMem[ nI ] );
}
/*
// store the format and tag decription strings...
GetFormatTagDetails ( pDevice->pWaveFmtEx->wFormatTag );
GetFormatDetails ( pDevice->pWaveFmtEx );
*/
return true;
}
//---------------------------------------------------------------------------
bool Wave_FreeData (t_wavedevice *pDevice)
{
/*
Free the WAVEFORMATEX buffer.
*/
GlobalUnlock( pDevice->hWaveFmtEx );
GlobalFree ( pDevice->hWaveFmtEx );
pDevice->pWaveFmtEx = NULL;
/*
Free the wave header memory.
*/
SHORT nI;
for (nI=0; nI<WAVE_BLOCKCNT; nI++ ) {
GlobalUnlock( pDevice->hWaveHdr[ nI ] );
GlobalFree ( pDevice->hWaveHdr[ nI ] );
}
/*
Free the wave memory.
*/
for (nI=0; nI<WAVE_BLOCKCNT; nI++) {
GlobalUnlock( pDevice->hWaveMem[ nI ] );
GlobalFree ( pDevice->hWaveMem[ nI ] );
}
return true;
}
//---------------------------------------------------------------------------
/*
Call the ACM dialog compression enumeration functions which allows the user to
select a compression based on the current wave format.
*/
bool Wave_GetFormat(t_wavedevice *pDevice, HWND hWnd)
{
ACMFORMATCHOOSE acmopt;
MMRESULT mmResult;
LPWAVEFORMATEX pWaveFormatEx;
// store the format temporarily...
pWaveFormatEx = Wave_AllocTmpFormat (pDevice);
if( pWaveFormatEx == NULL ) {
Log_String (LOG_NORMAL, "Error allocating temporary format buffer.");
return false;
}
memcpy (pWaveFormatEx, pDevice->pWaveFmtEx, (size_t)pDevice->dwMaxFmtSize);
// setup ACM choose fields and display the dialog...
memset( &acmopt, 0, sizeof(acmopt) );
acmopt.cbStruct = sizeof(acmopt);
acmopt.fdwStyle = ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT;
acmopt.hwndOwner = hWnd;
acmopt.pwfx = pDevice->pWaveFmtEx;
acmopt.cbwfx = pDevice->dwMaxFmtSize;
acmopt.pszTitle = "Select Compression CODEC";
acmopt.fdwEnum = ACM_FORMATENUMF_INPUT;
mmResult = acmFormatChoose( &acmopt );
// if the same format was selected we don't want to reset dwTotalwavesize below,
// so act like a cancel...
if( !memcmp(pDevice->pWaveFmtEx, pWaveFormatEx, sizeof(WAVEFORMATEX) ) )
mmResult = ACMERR_CANCELED;
if ( mmResult ) {
memcpy (pDevice->pWaveFmtEx, pWaveFormatEx, (size_t)pDevice->dwMaxFmtSize);
Wave_FreeTmpFormat (pDevice);
if ( mmResult == ACMERR_CANCELED ) return true;
Log_String (LOG_NORMAL, "Error in FormatChoose function");
return false;
}
FILE *fp;
fp = fopen (SZ_AUDIO_FORMAT_FILE, "wb");
if ( fp != NULL ) {
fwrite (pDevice->pWaveFmtEx, pDevice->dwMaxFmtSize, 1, fp);
fclose (fp);
}
Wave_FreeTmpFormat (pDevice);
return true;
}
//---------------------------------------------------------------------------
/*
Allocate a temporary buffer sufficient to contain a max size
WAVEFORMATEX structure.
*/
static LPWAVEFORMATEX Wave_AllocTmpFormat (t_wavedevice *pDevice)
{
LPWAVEFORMATEX pTmpWaveFmtEx;
// allocate temporary WAVEFMTEX structure...
if( (pDevice->hTmpWaveFmtEx = GlobalAlloc( GMEM_MOVEABLE, (UINT)pDevice->dwMaxFmtSize)) == NULL )
return NULL;
if( (pTmpWaveFmtEx = (LPWAVEFORMATEX) GlobalLock( pDevice->hTmpWaveFmtEx )) == NULL ) {
GlobalFree (pDevice->hTmpWaveFmtEx);
return NULL;
}
return pTmpWaveFmtEx;
}
//---------------------------------------------------------------------------
static void Wave_FreeTmpFormat (t_wavedevice *pDevice)
{
GlobalUnlock (pDevice->hTmpWaveFmtEx);
GlobalFree (pDevice->hTmpWaveFmtEx);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -