全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3294
推到 Plurk!
推到 Facebook!

acmStreamConvert的使用問題

尚未結案
guybejude
一般會員


發表:2
回覆:0
積分:0
註冊:2004-12-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-07 21:38:52 IP:211.74.xxx.xxx 未訂閱
我參照了 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarmulmed/html/msdn_codec.asp 及 http://david.weekly.org/code/mp3acm.html    試圖將(預設)PCM的格式wave檔轉為(預設)G.711 ALAW的格式, 程式執行是順利,但所產生的wave,卻是無法開啟。    以下是我的code:
 
// convert a PCM wave to G.711 format
#include 
#include 
#include   // Multimedia registration
#include         // Audio Compression Manager
#include 
#include <math.h>
#include     #define INPUT_FILE "in.wav"
#define BLOCK_SIZE 1000
#define OUTPUT_FILE "out.wav"    // Locate a driver that supports a given format and return its ID
typedef struct {
        HACMDRIVERID hadid;
        WORD wFormatTag;
} FIND_DRIVER_INFO;    // callback function for format enumeration
BOOL CALLBACK find_format_enum(HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)
{
        FIND_DRIVER_INFO* pdi = (FIND_DRIVER_INFO*) dwInstance;
        if (pafd->dwFormatTag == (DWORD)pdi->wFormatTag) {
                // found it
                pdi->hadid = hadid;
                return FALSE; // stop enumerating
        }            return TRUE; // continue enumerating
}    // callback function for driver enumeration
BOOL CALLBACK find_driver_enum(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport)
{
        FIND_DRIVER_INFO* pdi = (FIND_DRIVER_INFO*) dwInstance;            // open the driver
        HACMDRIVER had = NULL;
        MMRESULT mmr = acmDriverOpen(&had, hadid, 0);
        if (mmr) {                    // some error
                return FALSE; // stop enumerating            }            // enumerate the formats it supports
        DWORD dwSize = 0;
        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 = pdi->wFormatTag;
        ACMFORMATDETAILS fd;
        memset(&fd, 0, sizeof(fd));
        fd.cbStruct = sizeof(fd);
        fd.pwfx = pwf;
        fd.cbwfx = dwSize;
        fd.dwFormatTag = pdi->wFormatTag;
        mmr = acmFormatEnum(had, &fd, find_format_enum, (DWORD)(VOID*)pdi, 0);  
        free(pwf);
        acmDriverClose(had, 0);
        if (pdi->hadid || mmr) {
                // found it or some error
                return FALSE; // stop enumerating
        }            return TRUE; // continue enumeration
}    // locate the first driver that supports a given format tag
HACMDRIVERID find_driver(WORD wFormatTag)
{
        FIND_DRIVER_INFO fdi;
        fdi.hadid = NULL;
        fdi.wFormatTag = wFormatTag;
        MMRESULT mmr = acmDriverEnum(find_driver_enum, (DWORD)(VOID*)&fdi, 0); 
        if (mmr) return NULL;
        return fdi.hadid;
}    // get a description of the first format supported for a given tag
WAVEFORMATEX* get_driver_format(HACMDRIVERID hadid, WORD wFormatTag)
{
        // open the driver
        HACMDRIVER had = NULL;
        MMRESULT mmr = acmDriverOpen(&had, hadid, 0);
        if (mmr) {
                return NULL;
        }            // allocate a structure for the info
        DWORD dwSize = 0;
        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 = wFormatTag;            ACMFORMATDETAILS fd;
        memset(&fd, 0, sizeof(fd));
        fd.cbStruct = sizeof(fd);
        fd.pwfx = pwf;
        fd.cbwfx = dwSize;
        fd.dwFormatTag = wFormatTag;            // set up a struct to control the enumeration
        FIND_DRIVER_INFO fdi;
        fdi.hadid = NULL;
        fdi.wFormatTag = wFormatTag;            mmr = acmFormatEnum(had, &fd, find_format_enum, (DWORD)(VOID*)&fdi, 0);  
        acmDriverClose(had, 0);
        if ((fdi.hadid == NULL) || mmr) {
                free(pwf);
                return NULL;
        }
        
        return pwf;
}    void PCMtoALAW()
{
        // Select a format to convert to
        WORD wFormatTag = WAVE_FORMAT_ALAW;            // Now we locate a CODEC that supports the destination format tag
        HACMDRIVERID hadid = find_driver(wFormatTag);
        if (hadid == NULL) {
                printf("No driver found\n");
                exit(1);
        }
        printf("Driver found (hadid: %4.4lXH)\n", hadid);            // show some information about the driver
        ACMDRIVERDETAILS dd;
        dd.cbStruct = sizeof(dd);
        MMRESULT mmr = acmDriverDetails(hadid, &dd, 0);
        printf("   Short name: %s\n", dd.szShortName);
        printf("   Long name:  %s\n", dd.szLongName);
        printf("   Copyright:  %s\n", dd.szCopyright);
        printf("   Licensing:  %s\n", dd.szLicensing);
        printf("   Features:   %s\n", dd.szFeatures);            // get the details of the format
        // Note: this is just the first of one or more possible formats for the given tag
        WAVEFORMATEX* pwfDrv = get_driver_format(hadid, wFormatTag);
        if (pwfDrv == NULL) {
                printf("Error getting format info\n");
                exit(1);
        }
        printf("Driver format: %u bits, %lu samples per second\n", pwfDrv->wBitsPerSample, pwfDrv->nSamplesPerSec);            // get a PCM format tag the driver supports
        // Note: we just pick the first supported PCM format which might not really
        // be the best choice.
        WAVEFORMATEX* pwfPCM = get_driver_format(hadid, WAVE_FORMAT_PCM);
        if (pwfPCM == NULL) {
                printf("Error getting PCM format info\n");
                exit(1);
        }
        printf("PCM format: %u bits, %lu samples per second\n", pwfPCM->wBitsPerSample, pwfPCM->nSamplesPerSec);            // open the driver
        HACMDRIVER had = NULL;
        mmr = acmDriverOpen(&had, hadid, 0);
        if (mmr) {
                printf("Failed to open driver\n");
                exit(1);
        }            // open the conversion stream
        // Note the use of the ACM_STREAMOPENF_NONREALTIME flag. Without this
        // some software compressors will report error 512 - not possible
        HACMSTREAM hstr = NULL;
        mmr = acmStreamOpen(&hstr,
                                                had, // driver handle
                                                pwfPCM, // source format
                                                pwfDrv, // destination format
                                                NULL, // no filter
                                                NULL, // no callback
                                                0, // instance data (not used)
                                                ACM_STREAMOPENF_NONREALTIME); // flags
        if (mmr) {
                printf("Failed to open a stream to do PCM to driver format conversion\n");
                exit(1);
        }    //--------------------------------------------------------------------------------
    // open file
    FILE *fpIn = fopen( INPUT_FILE, "rb" );
    if( fpIn == NULL ){
      assert( !"can't open WAVE file!" );
      return E_FAIL;
        }
  
    // find out how big the decompressed buffer will be
    unsigned long rawbufsize = 0;
    mmr = acmStreamSize( hstr, BLOCK_SIZE, &rawbufsize, ACM_STREAMSIZEF_SOURCE );
    assert( mmr == 0 );
    assert( rawbufsize > 0 );
  
    // allocate our I/O buffers
    LPBYTE srcbuf = (LPBYTE) LocalAlloc( LPTR, BLOCK_SIZE );
    LPBYTE rawbuf = (LPBYTE) LocalAlloc( LPTR, rawbufsize );
//--------------------------------------------------------------------------------            // fill in the conversion info
        ACMSTREAMHEADER strhdr;
        memset(&strhdr, 0, sizeof(strhdr));
        strhdr.cbStruct = sizeof(strhdr);
    strhdr.pbSrc = srcbuf;
    strhdr.cbSrcLength = BLOCK_SIZE;
    strhdr.pbDst = rawbuf;
        strhdr.cbDstLength = rawbufsize;            // prep the header
        mmr = acmStreamPrepareHeader(hstr, &strhdr, 0); 
    if (mmr) printf(" error : pre the header!!!\n");            // let's dump this data off to disk (for debug checking!)
    FILE *fpOut = fopen( OUTPUT_FILE, "wb" );
    if( fpOut == NULL ){
      assert( !"can't output output PCM!" );
      return E_FAIL;
        }            printf("Converting to final format...\n");            while(1) {
      // suck in some MP3 data
      int count = fread( srcbuf, 1, BLOCK_SIZE, fpIn );
      if( count != BLOCK_SIZE ) break;
          //if (count<=0) 
        
          // convert the data
          mmr = acmStreamConvert(hstr, &strhdr, 0);
          if (mmr) {
                  printf("Failed to do PCM to driver format conversion\n");
                  exit(1);
          }              // write the decoded PCM to disk
      count = fwrite( rawbuf, 1, strhdr.cbDstLengthUsed, fpOut );
          //printf("%d\n",strhdr.cbDstLengthUsed);
      assert( count == strhdr.cbDstLengthUsed );
        }            printf("Converted OK\n");            // close the stream and driver
        mmr = acmStreamClose(hstr, 0);
        mmr = acmDriverClose(had, 0);
        fclose( fpIn );
    fclose( fpOut );
    mmr = acmStreamUnprepareHeader( hstr, &strhdr, 0 );
    assert( mmr == 0 );
    LocalFree(rawbuf);
    LocalFree(srcbuf);
    mmr = acmStreamClose( hstr, 0 );
    assert( mmr == 0 );    }
期望好心的大大給予協助,謝謝 發表人 -
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-08-07 21:46:24 IP:218.168.xxx.xxx 未訂閱
您好:    PO程式碼的方式與版規說明請參考下面連結,煩請修改謝謝您的配合 >
系統時間:2024-05-03 13:37:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!