Автор: Вадим, <diduk@yandex.ru>
Россия, 03 ноября 2003 года в 19:33:15
Помогите, пожалуйста, есть проблема при конвертации WMA в WAV(PCM).Функция acmStreamConvert на некоторых блоках возвращает код ошибки. Нет ли у кого работающего кода, очень надо... #include #include #include #include #include #define WMA_BLOCK_SIZE 1000 #define SOURCE_WMA "d:wma_simple.wma" #define OUTPUT_PCM_FILE "d:wma_simple.wav" HACMDRIVERID WMADriverID[16]; int nWMADriverID=0; BOOL CALLBACK acmDriverEnumCallback( HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport ) { if( fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC ) { MMRESULT mmr; ACMDRIVERDETAILS details; details.cbStruct = sizeof(ACMDRIVERDETAILS); mmr = acmDriverDetails( hadid, &details, 0 ); HACMDRIVER driver; mmr = acmDriverOpen( &driver, hadid, 0 ); for (int i = 0; i cbSize;i++) { printf("%02x ",*(wmaFormat+sizeof(WAVEFORMATEX)+i)); } printf("\n"); } convertWMA() { MMRESULT mmr; acmDriverEnum( acmDriverEnumCallback, 0, 0 ); if(nWMADriverID == 0) { OutputDebugString( "No WMA decoders found!\n" ); return E_FAIL; } HACMDRIVER hWMADriver; int index=1; acmDriverOpen(&hWMADriver,WMADriverID[index],0); DWORD maxFormatSize = 0; mmr = acmMetrics( NULL, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize ); LPWAVEFORMATEX wmaFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR, maxFormatSize ); memset(wmaFormat,0,maxFormatSize); LPWAVEFORMATEX wavFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR, maxFormatSize ); memset(wavFormat,0,maxFormatSize); wavFormat->wFormatTag = WAVE_FORMAT_PCM; wavFormat->nChannels = 2; wavFormat->nSamplesPerSec = 44100; wavFormat->nAvgBytesPerSec = 4 * 44100; wavFormat->nBlockAlign = 4; wavFormat->wBitsPerSample = 16; wavFormat->cbSize = 0; ChooseFormat(wmaFormat, wavFormat); g_wmastream = NULL; mmr = acmStreamOpen( &g_wmastream, hWMADriver, (LPWAVEFORMATEX) wmaFormat, wavFormat, NULL, 0, 0, 0 ); 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( SOURCE_WMA, "rb" ); if( fpIn == NULL ) { assert( !"can't open input WMA file!" ); return E_FAIL; } // find out how big the decompressed buffer will be unsigned long rawbufsize = 0; mmr = acmStreamSize( g_wmastream, WMA_BLOCK_SIZE, &rawbufsize, ACM_STREAMSIZEF_SOURCE ); assert( mmr == 0 ); assert( rawbufsize > 0 ); // allocate our I/O buffers LPBYTE wmabuf = (LPBYTE) LocalAlloc( LPTR, WMA_BLOCK_SIZE ); LPBYTE rawbuf = (LPBYTE) LocalAlloc( LPTR, rawbufsize ); // prepare the decoder ACMSTREAMHEADER wmastreamHead; ZeroMemory( &wmastreamHead, sizeof(ACMSTREAMHEADER ) ); wmastreamHead.cbStruct = sizeof(ACMSTREAMHEADER ); wmastreamHead.pbSrc = wmabuf; wmastreamHead.cbSrcLength = WMA_BLOCK_SIZE; wmastreamHead.pbDst = rawbuf; wmastreamHead.cbDstLength = rawbufsize; mmr = acmStreamPrepareHeader( g_wmastream, &wmastreamHead, 0 ); assert( mmr == 0 ); // 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; } while(1) { // suck in some WMA data int count = fread( wmabuf, 1, WMA_BLOCK_SIZE, fpIn ); if( count != WMA_BLOCK_SIZE ) 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; break; } // write the decoded PCM to disk count = fwrite( rawbuf, 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(rawbuf); LocalFree(wmabuf); mmr = acmStreamClose( g_wmastream, 0 ); assert( mmr == 0 ); return S_OK; } void main() { convertWMA(); }
|