部分源代码资料

来源:互联网 发布:e。target js 编辑:程序博客网 时间:2024/05/16 14:23
//// Wma2Mp3: A basic audio file converter that uses the Windows Media Format SDK // and the GPL "Lame" MPEG library to convert a Windows Media Audio file to an// MP3.  This was quickly hacked together from all kinds of sample code from all// kinds of places.  I take no credit for anything...  and no responsibility// either :).//#include <windows.h>#include <string.h>#include <stdio.h>#include <io.h>#include <fcntl.h>#include <sys/stat.h>//// The wmsdk.h header file comes with the Windows Media Format SDK.// This code compiles with the Windows Media Format SDK v9.  It will// probably compile fine with later versions as well.  You need// to have installed Windows Media Player 9 or the Windows Media// Format Runtime v9 to use this utilit.//#include <wmsdk.h>//// The BladeMP3EncDll.h header file comes with the Lame MP3 library.// More info can be found at http://www.mp3dev.org/.//#include "BladeMP3EncDll.h"BEINITSTREAM        beInitStream=NULL;BEENCODECHUNK       beEncodeChunk=NULL;BEDEINITSTREAM      beDeinitStream=NULL;BECLOSESTREAM       beCloseStream=NULL;BEVERSION           beVersion=NULL;BEWRITEVBRHEADER    beWriteVBRHeader=NULL;BEWRITEINFOTAG      beWriteInfoTag=NULL;IWMSyncReader*      gpSyncReader=NULL;INSSBuffer*         gpWmaBuffer=NULL;PSHORT              gpBufferHead=NULL;PSHORT              gpBufferNow=NULL;DWORD               gdwBytesRemaining=0;bool                gWmaDone=false;WCHAR               g_wszSourceFileName[1024];WCHAR               g_wszDestFileName[1024];bool CreateAndOpenSyncReader();void CloseSyncReader();DWORD FillAudioBuffer( PSHORT pAudioBuffer, DWORD dwSamplesWanted );void TransferMetadata();HRESULT TransferSingleItem( IWMHeaderInfo *pSrc, IWMHeaderInfo *pDest, WCHAR *pwszName );////////////////////////////////////////////////////////////////////////////////int main( int argc, char *argv[] ){       HINSTANCE   hDLL            =NULL;    FILE*       pFileIn         =NULL;    FILE*       pFileOut        =NULL;    BE_VERSION  Version         ={0,};    BE_CONFIG   beConfig        ={0,};    CHAR        strFileIn[255]  ={'0',};    CHAR        strFileOut[255] ={'0',};    DWORD       dwBitrate       =0;    DWORD       dwSamples       =0;    DWORD       dwMP3Buffer     =0;    HBE_STREAM  hbeStream       =0;    BE_ERR      err             =0;    PBYTE       pMP3Buffer      =NULL;    PSHORT      pWAVBuffer      =NULL;    HRESULT hr = S_OK;    CoInitialize(NULL);    if(argc != 3)    {        fprintf(stderr, "Wma2Mp3: Please specify a WMA file to convert./n");        fprintf(stderr, "Usage: %s <filename> <target bitrate in kbs>/n", argv[0] );        return -1;    }    //    // Get the bitrate and make it something useful.    //    dwBitrate = atoi(argv[2]);    if( dwBitrate <= 56 ) dwBitrate = 56;    else if( (56 < dwBitrate) && (dwBitrate <= 128) ) dwBitrate = 128;    else if( (128 < dwBitrate) && (dwBitrate <= 256) ) dwBitrate = 256;    else if( dwBitrate > 256 ) dwBitrate = 320;    //    // Set up the file names.  If there's an extention on the input    // file, replace it with mp3.  Otherwise, just append mp3.    //    ZeroMemory( g_wszSourceFileName, sizeof( g_wszSourceFileName ) );    ZeroMemory( g_wszDestFileName, sizeof( g_wszDestFileName ) );    strcpy(strFileIn ,argv[1]);    if( 0 == MultiByteToWideChar( CP_ACP, 0, strFileIn, (int)strlen(strFileIn) + 1,                 g_wszSourceFileName, sizeof( g_wszSourceFileName ) / sizeof(WCHAR) ) )    {        return -1;    }    char* cCurrent = &(strFileOut[254]);    ZeroMemory( strFileOut, sizeof( strFileOut ) );    strcpy(strFileOut,argv[1]);    while( *cCurrent != '.' && (cCurrent >= strFileOut) ) cCurrent--;    if( *cCurrent == '.' ) *cCurrent = 0;    strcat(strFileOut,".mp3");    if( 0 == MultiByteToWideChar( CP_ACP, 0, strFileOut, (int)strlen(strFileOut) + 1,                 g_wszDestFileName, sizeof( g_wszDestFileName ) / sizeof(WCHAR) ) )    {        return -1;    }    //    // Load the lame_enc.dll library.    //    hDLL = LoadLibrary("lame_enc.dll");    if( NULL == hDLL )    {        fprintf(stderr,"Error loading lame_enc.DLL - you can probably find this somewhere on the web./n");        return -1;    }    beInitStream    = (BEINITSTREAM) GetProcAddress(hDLL, TEXT_BEINITSTREAM);    beEncodeChunk   = (BEENCODECHUNK) GetProcAddress(hDLL, TEXT_BEENCODECHUNK);    beDeinitStream  = (BEDEINITSTREAM) GetProcAddress(hDLL, TEXT_BEDEINITSTREAM);    beCloseStream   = (BECLOSESTREAM) GetProcAddress(hDLL, TEXT_BECLOSESTREAM);    beVersion       = (BEVERSION) GetProcAddress(hDLL, TEXT_BEVERSION);    beWriteVBRHeader= (BEWRITEVBRHEADER) GetProcAddress(hDLL,TEXT_BEWRITEVBRHEADER);    beWriteInfoTag  = (BEWRITEINFOTAG) GetProcAddress(hDLL,TEXT_BEWRITEINFOTAG);    if( !beInitStream || !beEncodeChunk || !beDeinitStream ||         !beCloseStream || !beVersion || !beWriteVBRHeader )    {        printf("Unable to get LAME interfaces: your lame_enc.dll is bad?/n");        return -1;    }    beVersion( &Version );    //    // Print out an informative welcome.    //    printf( "Wma2Mp3 v1.0/n/n"            "lame_enc.dll version %u.%02u (%u/%u/%u)/n"            "lame_enc Engine %u.%02u/n"            "lame_enc homepage at %s/n/n"            "source file: %s/n"            "dest file: %s/n"            "bitrate: %d kbs/n/n",              Version.byDLLMajorVersion, Version.byDLLMinorVersion,            Version.byDay, Version.byMonth, Version.wYear,            Version.byMajorVersion, Version.byMinorVersion,            Version.zHomepage,            strFileIn,            strFileOut,            dwBitrate );        if( !CreateAndOpenSyncReader() )    {        fprintf( stderr, "Error opening input file %s", argv[1] );        return -1;    }    //    // Open the output MP3 file.    //    pFileOut= fopen(strFileOut,"wb+");    if(pFileOut == NULL)    {        fprintf( stderr, "Error creating output file %s/n", strFileOut );        return -1;    }    //    // Configure the LAME encoder the to do the conversion.    //    memset(&beConfig,0,sizeof(beConfig));    beConfig.dwConfig = BE_CONFIG_LAME;    beConfig.format.LHV1.dwStructVersion    = 1;    beConfig.format.LHV1.dwStructSize       = sizeof(beConfig);         beConfig.format.LHV1.dwSampleRate       = 44100;                // INPUT FREQUENCY    beConfig.format.LHV1.dwReSampleRate     = 0;                    // DON'T RESAMPLE    beConfig.format.LHV1.nMode              = BE_MP3_MODE_JSTEREO;  // OUTPUT IN STREO    beConfig.format.LHV1.dwBitrate          = dwBitrate;            // MINIMUM BIT RATE    beConfig.format.LHV1.nPreset            = LQP_VERYHIGH_QUALITY; // QUALITY PRESET SETTING    beConfig.format.LHV1.dwMpegVersion      = MPEG1;                // MPEG VERSION (I or II)    beConfig.format.LHV1.dwPsyModel         = 0;                    // USE DEFAULT PSYCHOACOUSTIC MODEL     beConfig.format.LHV1.dwEmphasis         = 0;                    // NO EMPHASIS TURNED ON    beConfig.format.LHV1.bOriginal          = TRUE;                 // SET ORIGINAL FLAG    beConfig.format.LHV1.bWriteVBRHeader    = TRUE;                 // Write INFO tag    beConfig.format.LHV1.bNoRes             = TRUE;                 // No Bit resorvoir    beConfig.format.LHV1.bCRC               = TRUE;                 // INSERT CRC    //  Other possibilities?    //  beConfig.format.LHV1.dwMaxBitrate       = 320;                  // MAXIMUM BIT RATE    //  beConfig.format.LHV1.bCopyright         = TRUE;                 // SET COPYRIGHT FLAG       //  beConfig.format.LHV1.bPrivate           = TRUE;                 // SET PRIVATE FLAG    //  beConfig.format.LHV1.bWriteVBRHeader    = TRUE;                 // YES, WRITE THE XING VBR HEADER    //  beConfig.format.LHV1.bEnableVBR         = TRUE;                 // USE VBR    //  beConfig.format.LHV1.nVBRQuality        = 5;                    // SET VBR QUALITY    err = beInitStream(&beConfig, &dwSamples, &dwMP3Buffer, &hbeStream);    if(err != BE_ERR_SUCCESSFUL)    {        fprintf(stderr,"Error opening encoding stream (%lu)/n", err);        return -1;    }    //    // Allocate the work buffers and do the conversion.    //    pMP3Buffer = new BYTE[dwMP3Buffer];    pWAVBuffer = new SHORT[dwSamples];    if( !pMP3Buffer || !pWAVBuffer )    {        printf("Out of memory/n");        return -1;    }    DWORD dwRead=0;    DWORD dwWrite=0;    DWORD dwDone=0;    DWORD dwClick = 80;    while ( (dwRead = FillAudioBuffer( pWAVBuffer, dwSamples )) > 0 )    {        dwClick--;        if( !dwClick )        {            printf(".");            dwClick = 80;        }        err = beEncodeChunk( hbeStream, dwRead, pWAVBuffer, pMP3Buffer, &dwWrite );        if(err != BE_ERR_SUCCESSFUL)        {            beCloseStream(hbeStream);            fprintf(stderr,"beEncodeChunk() failed (%lu)/n", err);            return -1;        }                if(fwrite(pMP3Buffer,1,dwWrite,pFileOut) != dwWrite)        {            fprintf(stderr,"Output file write error/n");            return -1;        }        dwDone += dwRead*sizeof(SHORT);    }    printf("/n");        //    // Complete the stream encode and shut down.  Note that de-initializing the    // stream may flush out a few final bytes.    //    err = beDeinitStream(hbeStream, pMP3Buffer, &dwWrite);    if(err != BE_ERR_SUCCESSFUL)    {        beCloseStream(hbeStream);        fprintf(stderr,"beExitStream failed (%lu)/n", err);        return -1;    }    if( dwWrite )    {        if( fwrite( pMP3Buffer, 1, dwWrite, pFileOut ) != dwWrite )        {            fprintf(stderr,"Output file write error/n");            return -1;        }    }    beCloseStream( hbeStream );    delete [] pWAVBuffer;    delete [] pMP3Buffer;    fclose( pFileOut );    if ( beWriteInfoTag )    {        beWriteInfoTag( hbeStream, strFileOut );    }    else    {        beWriteVBRHeader( strFileOut );    }    CloseSyncReader();    TransferMetadata();    return 0;}////////////////////////////////////////////////////////////////////////////////boolCreateAndOpenSyncReader(void){    HRESULT hr = S_OK;    //    // Create a sync reader object and open the file.    // We just assume we're going to have only a single ASF stream,     // and that it's an audio stream.  This could be smarter,    // of course...    //    hr = WMCreateSyncReader( NULL, 0, &gpSyncReader );    if( (S_OK != hr) || !gpSyncReader )    {        hr = E_UNEXPECTED;        goto CleanExit;    }        hr = gpSyncReader->Open( g_wszSourceFileName );    if( S_OK != hr )    {        hr = E_UNEXPECTED;        goto CleanExit;    }        IWMOutputMediaProps *pProps = NULL;    hr = gpSyncReader->GetOutputFormat( 0, 0, &pProps );    if( (S_OK != hr) || !pProps )    {        hr = E_UNEXPECTED;        goto CleanExit;    }    BYTE rgMediaProps[2048];    DWORD dwMediaType = 2048;    ZeroMemory( rgMediaProps, sizeof( rgMediaProps ) );    WM_MEDIA_TYPE *pMT = (WM_MEDIA_TYPE*)rgMediaProps;    hr = pProps->GetMediaType( pMT, &dwMediaType );    if( S_OK != hr )    {        hr = E_UNEXPECTED;        goto CleanExit;    }    //    // Validate the wave format.  Should we try and set the output    // format if it's not what we're expecting?  After all, the format    // SDK is capable of resampling both the sample rate and the    // bit depth if necessary.    //    WAVEFORMATEX *pWfEx = (WAVEFORMATEX*)pMT->pbFormat;        if( (pWfEx->wFormatTag != WAVE_FORMAT_PCM) ||        (pWfEx->nChannels != 2) ||        (pWfEx->nSamplesPerSec != 44100) ||        (pWfEx->wBitsPerSample != 16) )    {        hr = E_UNEXPECTED;        goto CleanExit;    }    DWORD dwMaxSampleSize = 0;    hr = gpSyncReader->GetMaxOutputSampleSize( 0, &dwMaxSampleSize );    if( S_OK != hr )    {        hr = E_UNEXPECTED;        goto CleanExit;    }CleanExit:    if( pProps ) pProps->Release();    if( S_OK != hr )    {        if( gpSyncReader ) gpSyncReader->Release();              return( false );    }    return( true );}////////////////////////////////////////////////////////////////////////////////DWORDFillAudioBuffer(    PSHORT pAudioBuffer,    DWORD dwSamplesWanted ){    HRESULT hr = S_OK;    DWORD dwBytesRemaining = dwSamplesWanted*sizeof(SHORT);    PSHORT pCurrentSample = pAudioBuffer;    DWORD dwSamplesWritten = 0;    if( gWmaDone ) return( 0 );    while( dwBytesRemaining )    {        //        // If we've consumed the sample we're currently working on,        // or if this is the first time around, grab the next sample.        //                     if( !gdwBytesRemaining || !gpWmaBuffer )        {            QWORD qwSampleTime = 0;            QWORD qwDuration = 0;            DWORD dwFlags = 0;            DWORD dwOutputNum = 0;            WORD wStream = 0;            if( gpWmaBuffer )                 gpWmaBuffer->Release();            hr = gpSyncReader->GetNextSample( 0, &gpWmaBuffer, &qwSampleTime, &qwDuration,                                              &dwFlags, &dwOutputNum, &wStream );            if( (S_OK != hr) || !gpWmaBuffer )            {                if( NS_E_NO_MORE_SAMPLES == hr )                {                    gWmaDone = true;                }                else                {                    hr = E_UNEXPECTED;                }                goto CleanExit;            }            hr = gpWmaBuffer->GetBufferAndLength( (BYTE**)&gpBufferHead, &gdwBytesRemaining );            if( S_OK != hr )            {                hr = E_UNEXPECTED;                goto CleanExit;            }            gpBufferNow = gpBufferHead;        }                //        // There are samples available so process them.        //        DWORD dwInputBytesReady = gdwBytesRemaining;        if( dwInputBytesReady > dwBytesRemaining )        {            dwInputBytesReady = dwBytesRemaining;        }        memcpy( (BYTE*)pCurrentSample, (BYTE*)gpBufferNow, dwInputBytesReady );        dwBytesRemaining -= dwInputBytesReady;        gdwBytesRemaining -= dwInputBytesReady;        gpBufferNow += (dwInputBytesReady/sizeof(SHORT));        pCurrentSample += (dwInputBytesReady/sizeof(SHORT));        dwSamplesWritten += (dwInputBytesReady/sizeof(SHORT));    }    CleanExit:    return( dwSamplesWritten );}////////////////////////////////////////////////////////////////////////////////voidCloseSyncReader(){    if( gpSyncReader )    {        gpSyncReader->Close();        gpSyncReader->Release();    }}////////////////////////////////////////////////////////////////////////////////void TransferMetadata(){    HRESULT hr = S_OK;    IWMMetadataEditor *pSrc = NULL;    IWMMetadataEditor *pDest = NULL;    IWMHeaderInfo *pHISrc = NULL;    IWMHeaderInfo *pHIDest = NULL;        do    {        //        // Open the source and destination file.        //        hr = WMCreateEditor( &pSrc );        if( SUCCEEDED( hr ) )        {            hr = pSrc->Open( g_wszSourceFileName );            if( SUCCEEDED( hr ) )            {                hr = pSrc->QueryInterface( IID_IWMHeaderInfo, (void**)&pHISrc );            }        }        if( FAILED( hr ) )        {            printf( "Failed to open source file for metadata transfer./n" );            break;        }        hr = WMCreateEditor( &pDest );        if( SUCCEEDED( hr ) )        {            hr = pDest->Open( g_wszDestFileName );            if( SUCCEEDED( hr ) )            {                hr = pDest->QueryInterface( IID_IWMHeaderInfo, (void**)&pHIDest );            }        }        if( FAILED( hr ) )        {            printf( "Failed to open destination file for metadata transfer./n" );            break;        }        //        // Migrate over the metadata items that the portable player can display.        //        TransferSingleItem( pHISrc, pHIDest, (WCHAR*)g_wszWMTitle );        TransferSingleItem( pHISrc, pHIDest, (WCHAR*)g_wszWMAuthor );        TransferSingleItem( pHISrc, pHIDest, (WCHAR*)g_wszWMDescription );        TransferSingleItem( pHISrc, pHIDest, (WCHAR*)g_wszWMAlbumTitle );        TransferSingleItem( pHISrc, pHIDest, (WCHAR*)g_wszWMTrack );        TransferSingleItem( pHISrc, pHIDest, (WCHAR*)g_wszWMTrackNumber );    }    while( FALSE );    if( pSrc )    {         pSrc->Close();        pSrc->Release();    }    if( pDest )    {        pDest->Flush();        pDest->Close();        pDest->Release();    }    return;}////////////////////////////////////////////////////////////////////////////////HRESULT TransferSingleItem( IWMHeaderInfo *pSrc, IWMHeaderInfo *pDest, WCHAR *pwszName ){    HRESULT hr = S_OK;    WORD wStream = -1;    WMT_ATTR_DATATYPE wmType = WMT_TYPE_STRING;    BYTE rgData[2048];    WORD wLen = 2048;    hr = pSrc->GetAttributeByName( &wStream,                                   pwszName,                                   &wmType,                                   rgData,                                   &wLen );    if( SUCCEEDED( hr ) )    {        hr = pDest->SetAttribute( wStream,                                  pwszName,                                  wmType,                                  rgData,                                  wLen );    }            return( hr );}////////////////////////////////////////////////////////////////////////////////
原创粉丝点击