Очень нужно!!! исходник конвертации WMA в WAV через acmStrea
От: diduk  
Дата: 06.11.03 10:13
Оценка:
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();
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.