MP3 в WAV конвертируется на ура, WMA в WAV, зараза, не хочет.
Функция acmStreamConvert слетает или дает не правилный результат.
Может кто-нибудь поможет, please...
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include <mmreg.h>
#include <msacm.h>
#define WAVE_FORMAT_WMA 0x160
#define INPUT_WMA_FILE "d:\\VE_SDK2_Public\\acm_test\\Debug\\wma_simple.wma"
#define OUTPUT_PCM_FILE "d:\\VE_SDK2_Public\\acm_test\\Debug\\wma_simple.wav"
BOOL CALLBACK acmFormatEnumCallback( HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport )
{
if( fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC )
{
if(pafd->pwfx->nChannels == 2)
if(pafd->pwfx->nSamplesPerSec == 44100)
if(pafd->pwfx->wBitsPerSample == 16)
return false;
}
return true;
}
HACMSTREAM g_wmastream = NULL;
convertWMA()
{
MMRESULT mmr;
// find the biggest format size
DWORD maxFormatSize = 0;
mmr = acmMetrics( NULL, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize );
// define WMA input format
LPWAVEFORMATEX wmaFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR, maxFormatSize );
memset(wmaFormat,0,maxFormatSize);
wmaFormat->wFormatTag = WAVE_FORMAT_WMA;
// define WAV output format
LPWAVEFORMATEX wavFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR, maxFormatSize );
memset(wavFormat,0,maxFormatSize);
wavFormat->wFormatTag = WAVE_FORMAT_PCM;
wavFormat->nChannels = 2; // stereo
wavFormat->nSamplesPerSec = 44100; // 44.1kHz
wavFormat->nAvgBytesPerSec = 4 * 44100; // byte-rate
wavFormat->nBlockAlign = 4; // 4 bytes of data at a time are useful (1 sample)
wavFormat->wBitsPerSample = 16; // 16 bits
wavFormat->cbSize = 0; // no more data to follow
ACMFORMATDETAILS pafd;
ZeroMemory( &pafd, sizeof(ACMFORMATDETAILS) );
pafd.cbStruct = sizeof(ACMFORMATDETAILS);
pafd.pwfx = wmaFormat;
pafd.cbwfx = maxFormatSize;
pafd.dwFormatTag = WAVE_FORMAT_WMA;
acmFormatEnum(NULL, &pafd, acmFormatEnumCallback, 0, ACM_FORMATENUMF_WFORMATTAG);
int wmabufsize = 1024;
mmr = acmStreamOpen( &g_wmastream, // open an ACM conversion stream
NULL, // querying all ACM drivers
(LPWAVEFORMATEX) wmaFormat, // converting from WMA
wavFormat, // to WAV
NULL, // with no filter
0, // or async callbacks
0, // (and no data for the callback)
0 // and no flags
);
LocalFree( wmaFormat );
LocalFree( wavFormat );
switch( mmr )
{
case MMSYSERR_NOERROR:
break; // success!
case MMSYSERR_INVALPARAM:
assert( !"Invalid parameters passed to acmStreamOpen" );
return E_FAIL;
case ACMERR_NOTPOSSIBLE:
assert( !"No ACM filter found capable of decoding WMA" );
return E_FAIL;
default:
assert( !"Some error opening ACM decoding stream!" );
return E_FAIL;
}
// WMA stream converter opened correctly
// now, let's open a file, read in a bunch of WMA data, and convert it!
// open file
FILE *fpIn = fopen( INPUT_WMA_FILE, "rb" );
if( fpIn == NULL )
{
assert( !"can't open input WMA file!" );
return E_FAIL;
}
// let's dump this data off to disk (for debug checking!)
FILE *fpOut = fopen( OUTPUT_PCM_FILE, "wb" );
if( fpOut == NULL )
{
assert( !"can't open output PCM file!" );
return E_FAIL;
}
// find out how big the decompressed buffer will be
unsigned long wavbufsize = 0;
mmr = acmStreamSize( g_wmastream, wmabufsize, &wavbufsize, ACM_STREAMSIZEF_SOURCE );
assert( mmr == 0 );
assert( wavbufsize > 0 );
// allocate our I/O buffers
LPBYTE wmabuf = (LPBYTE) LocalAlloc( LPTR, wmabufsize );
LPBYTE wavbuf = (LPBYTE) LocalAlloc( LPTR, wavbufsize );
// prepare the decoder
ACMSTREAMHEADER wmastreamHead;
ZeroMemory( &wmastreamHead, sizeof(ACMSTREAMHEADER ) );
wmastreamHead.cbStruct = sizeof(ACMSTREAMHEADER);
wmastreamHead.pbSrc = wmabuf;
wmastreamHead.cbSrcLength = wmabufsize;
wmastreamHead.pbDst = wavbuf;
wmastreamHead.cbDstLength = wavbufsize;
mmr = acmStreamPrepareHeader( g_wmastream, &wmastreamHead, 0 );
assert( mmr == 0 );
while(1)
{
// suck in some WMA data
int count = fread( wmabuf, 1, wmabufsize, fpIn );
if( count != wmabufsize )
break;
// convert the data
mmr = acmStreamConvert( g_wmastream, &wmastreamHead, ACM_STREAMCONVERTF_BLOCKALIGN );
switch( mmr )
{
case 0:
break; // success!
case ACMERR_BUSY:
printf( "acmStreamConvert FAILED\n" );
return E_FAIL;
case ACMERR_UNPREPARED:
printf( "acmStreamConvert FAILED\n" );
return E_FAIL;
case MMSYSERR_INVALFLAG:
printf( "acmStreamConvert FAILED\n" );
return E_FAIL;
case MMSYSERR_INVALHANDLE:
printf( "acmStreamConvert FAILED\n" );
return E_FAIL;
case MMSYSERR_INVALPARAM:
printf( "acmStreamConvert FAILED\n" );
return E_FAIL;
default:
assert( !"Some error opening ACM decoding stream!" );
return E_FAIL;
}
// write the decoded PCM to disk
count = fwrite( wavbuf, 1, wmastreamHead.cbDstLengthUsed, fpOut );
assert( count == (int)wmastreamHead.cbDstLengthUsed );
};
// clean up after yourself like a good little boy
fclose( fpIn );
fclose( fpOut );
mmr = acmStreamUnprepareHeader( g_wmastream, &wmastreamHead, 0 );
assert( mmr == 0 );
LocalFree(wavbuf);
LocalFree(wmabuf);
mmr = acmStreamClose( g_wmastream, 0 );
assert( mmr == 0 );
return S_OK;
}
void main()
{
convertWMA();
}