BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid, 
 LPACMFORMATDETAILS pafd, 
 DWORD dwInstance, 
 DWORD fdwSupport)
{

if(pafd->dwFormatTag==WAVE_FORMAT_PCM)
{

DWORD sample=pafd->pwfx->nAvgBytesPerSec;

if((sample==22050))
{
pwfPCM=pafd->pwfx;
g_hadid=hadid;
return FALSE;
}

}

return TRUE;
}
BOOL CALLBACK CodecsEnumProc(HACMDRIVERID hadid,
 DWORD dwInstance,
 DWORD fdwSupport) 
{
DWORD dwSize = 0;

// if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
// AfxMessageBox("多格式转换\n");

ACMDRIVERDETAILS acmdd;
acmdd.cbStruct = sizeof(acmdd);
MMRESULT mmr = acmDriverDetails(hadid, &acmdd, 0);

if(mmr) 
{error(mmr);}

HACMDRIVER had = NULL;
mmr = acmDriverOpen(&had, hadid, 0); //打开驱动程序

if (mmr)
{error(mmr);}
else {
mmr = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
if (dwSize < sizeof(WAVEFORMATEX)) dwSize = sizeof(WAVEFORMATEX); // for MS-PCM
WAVEFORMATEX* pwf = (WAVEFORMATEX*) malloc(dwSize);

memset(pwf, 0, dwSize);
pwf->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
pwf->wFormatTag = WAVE_FORMAT_UNKNOWN;
ACMFORMATDETAILS fd;
memset(&fd, 0, sizeof(fd));
fd.cbStruct = sizeof(fd); 
fd.pwfx = pwf;
fd.cbwfx = dwSize;
fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;

mmr = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); 

if (mmr||g_hadid)
{
return FALSE;
}

free(pwf);
acmDriverClose(had, 0);
}
return TRUE; 
}DWORD dwDst1Bytes;void CMMTESTDlg::OnConvert(BYTE* pSrcData)
{

//////////////////////////////////////////////////////////
//Source format
memset(&m_wfSrc, 0, sizeof(m_wfSrc));
m_wfSrc.cbSize = 24932;
m_wfSrc.wFormatTag = WAVE_FORMAT_PCM; // pcm
m_wfSrc.nChannels = 1;//channels; // mono
m_wfSrc.nSamplesPerSec =22050;// samplerate; // 22.050kHz
m_wfSrc.wBitsPerSample = 8;//bitspersample; // 8 bit
m_wfSrc.nBlockAlign = m_wfSrc.nChannels *m_wfSrc.wBitsPerSample / 8;
m_wfSrc.nAvgBytesPerSec = m_wfSrc.nSamplesPerSec * m_wfSrc.nBlockAlign;

MMRESULT mmr;
HACMSTREAM hstr = NULL;
mmr = acmStreamOpen(&hstr,
NULL, // any driver
&m_wfSrc, // source format
pwfPCM, // destination format
NULL, // no filter
NULL, // no callback
0, // instance data (not used)
ACM_STREAMOPENF_NONREALTIME); // flags

if (mmr) {
AfxMessageBox("Failed to open a stream to do PCM to PCM conversion\n");
return;
}

// fill in the conversion info
ACMSTREAMHEADER strhdr;
memset(&strhdr, 0, sizeof(strhdr));
strhdr.cbStruct = sizeof(strhdr);
strhdr.pbSrc = pSrcData; // the source data to convert
strhdr.cbSrcLength = 2065580*3/2;//source data size; 
///////////////////////////////////////////////////////////////////////////////
//Caculate the destination size
DWORD dwDst1Samples =22050 * pwfPCM->nSamplesPerSec / m_wfSrc.nSamplesPerSec;
dwDst1Bytes =94* dwDst1Samples * pwfPCM->wBitsPerSample / 8;
////////////////////////////////////////////////////////////////////////////////
strhdr.cbDstLength = dwDst1Bytes;
strhdr.pbDst = pDstData;

// prep the header
mmr = acmStreamPrepareHeader(hstr, &strhdr, 0); 

// convert the data
TRACE("Converting to intermediate PCM format...\n");
mmr = acmStreamConvert(hstr, &strhdr, 0);

if (mmr) {
AfxMessageBox("Failed to do PCM to PCM conversion\n");
return ;
}
TRACE("Converted OK\n");

// close the stream
acmStreamClose(hstr, 0);

}void CMMTESTDlg::OnButton2() 
{
acmDriverEnum(CodecsEnumProc, 0, 0);

CFile fp;
fp.Open(_T("c:\\aaa.wav"),CFile::modeReadWrite);
DWORD dwDstBytes=fp.GetLength();
CFile fp2;
fp2.Open(_T("c:\\bbb.wav"),CFile::modeReadWrite|CFile::modeCreate);

pSrcData=new byte[2065580*3/2];
fp.Read(pSrcData,2065580*3/2);
OnConvert(pSrcData);

fp2.Write(pDstData,dwDst1Bytes);
delete [] pSrcData ;
delete [] pDstData;
fp.Close();
fp2.Close();
}