⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpi_player_codec_wav.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
字号:
#include "stdafx.h"
#include "globals.h"
#include "CPI_Player_CoDec.h"
#include "CP_RIFFStructs.h"
#include "CPI_ID3.h"


void CPP_OMWAV_Uninitialise(CPs_CoDecModule* pModule);
BOOL CPP_OMWAV_OpenFile(CPs_CoDecModule* pModule, const char* pcFilename, DWORD dwCookie, HWND hWndOwner);
void CPP_OMWAV_CloseFile(CPs_CoDecModule* pModule);
void CPP_OMWAV_Seek(CPs_CoDecModule* pModule, const int iNumerator, const int iDenominator);
void CPP_OMWAV_GetFileInfo(CPs_CoDecModule* pModule, CPs_FileInfo* pInfo);
//
BOOL CPP_OMWAV_GetPCMBlock(CPs_CoDecModule* pModule, void* pBlock, DWORD* pdwBlockSize);
int CPP_OMWAV_GetCurrentPos_secs(CPs_CoDecModule* pModule);

typedef struct __CPs_CoDec_Wave
{
    HANDLE m_hFile;
    unsigned int m_iStartOfWavData;
    unsigned int m_iLengthOfWavData;

    CPs_FileInfo m_FileInfo;
    int m_iBytesPerSecond;

    int m_iCurrentOffset_Secs;
    int m_iCurrentOffset_Fraction_Bytes;
} CPs_CoDec_Wave;

BOOL SkipToChunk(HANDLE hFile, CPs_RIFFChunk* pChunk, const char cChunkID[4]);
//
void CP_InitialiseCodec_WAV(CPs_CoDecModule* pCoDec)
{
    CPs_CoDec_Wave *pContext;

    pCoDec->Uninitialise = CPP_OMWAV_Uninitialise;
    pCoDec->OpenFile = CPP_OMWAV_OpenFile;
    pCoDec->CloseFile = CPP_OMWAV_CloseFile;
    pCoDec->Seek = CPP_OMWAV_Seek;
    pCoDec->GetFileInfo = CPP_OMWAV_GetFileInfo;

    pCoDec->GetPCMBlock = CPP_OMWAV_GetPCMBlock;
    pCoDec->GetCurrentPos_secs = CPP_OMWAV_GetCurrentPos_secs;

    pCoDec->m_pModuleCookie = malloc(sizeof(CPs_CoDec_Wave));
    pContext = (CPs_CoDec_Wave*)pCoDec->m_pModuleCookie;
    pContext->m_hFile = INVALID_HANDLE_VALUE;

    CPFA_InitialiseFileAssociations(pCoDec);
    CPFA_AddFileAssociation(pCoDec, "WAV", 0L);
}
//
void CPP_OMWAV_Uninitialise(CPs_CoDecModule* pModule)
{
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);
    CP_ASSERT(pContext->m_hFile == INVALID_HANDLE_VALUE)

    free(pContext);
    CPFA_EmptyFileAssociations(pModule);
}
//
BOOL CPP_OMWAV_OpenFile(CPs_CoDecModule* pModule, const char* pcFilename, DWORD dwCookie, HWND hWndOwner)
{
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);

    if(pContext->m_hFile)
    {
        CloseHandle(pContext->m_hFile);
        pContext->m_hFile = INVALID_HANDLE_VALUE;
    }

    CP_TRACE1("Openfile \"%s\"", pcFilename);

    pContext->m_hFile = CreateFile(pcFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
    if(pContext->m_hFile == INVALID_HANDLE_VALUE)
    {
        CP_TRACE0("Failed to open file");
        return FALSE;	
    }

    {
        CIs_ID3v2Tag tag;
        DWORD dwBytesRead;
        int iStreamStart = 0;

        memset(&tag, 0, sizeof(tag));
        ReadFile(pContext->m_hFile, &tag, sizeof(tag), &dwBytesRead, NULL);

        if(memcmp(tag.m_cTAG, "ID3", 3) == 0)
        {
            iStreamStart = sizeof(CIs_ID3v2Tag);
            iStreamStart += (tag.m_cSize_Encoded[0] << 21)
                            | (tag.m_cSize_Encoded[1] << 14)
                            | (tag.m_cSize_Encoded[2] << 7)
                            | tag.m_cSize_Encoded[3];
        }

        SetFilePointer(pContext->m_hFile, iStreamStart, NULL, FILE_BEGIN);
    }

    {
        CPs_RIFFHeader RIFFHeader;
        DWORD dwBytesRead;
        ReadFile(pContext->m_hFile, &RIFFHeader, sizeof(RIFFHeader), &dwBytesRead, NULL);

        if(memcmp(RIFFHeader.m_cID, "RIFF", 4) || memcmp(RIFFHeader.m_cFileType, "WAVE", 4))
        {
            CP_TRACE0("File not of RIFF WAVE type");
            CloseHandle(pContext->m_hFile);
            pContext->m_hFile = INVALID_HANDLE_VALUE;
            return FALSE;	
        }
    }

    {
        CPs_RIFFChunk chunk;
        PCMWAVEFORMAT* pFormat;
        DWORD dwBytesRead;
        BOOL bSuccess = SkipToChunk(pContext->m_hFile, &chunk, "fmt ");
        if( bSuccess == FALSE || chunk.m_dwLength < sizeof(PCMWAVEFORMAT) )
        {
            CP_TRACE0("Failed to find FMT chunk");
            CloseHandle(pContext->m_hFile);
            pContext->m_hFile = INVALID_HANDLE_VALUE;
            return FALSE;	
        }

        pFormat = (PCMWAVEFORMAT*)malloc(chunk.m_dwLength);
        ReadFile(pContext->m_hFile, pFormat, chunk.m_dwLength, &dwBytesRead, NULL);

       
        if(dwBytesRead != chunk.m_dwLength || pFormat->wf.wFormatTag != WAVE_FORMAT_PCM)
        {
            CP_TRACE0("Only PCM data supported!");
            free(pFormat);
            CloseHandle(pContext->m_hFile);
            pContext->m_hFile = INVALID_HANDLE_VALUE;
            return FALSE;	
        }

        pContext->m_FileInfo.m_iBitRate_Kbs = 0;		
        pContext->m_FileInfo.m_iFreq_Hz = pFormat->wf.nSamplesPerSec;
        pContext->m_FileInfo.m_bStereo = pFormat->wf.nChannels == 2 ? TRUE : FALSE;
        pContext->m_FileInfo.m_b16bit = pFormat->wBitsPerSample == 16 ? TRUE : FALSE;
        pContext->m_iBytesPerSecond = pContext->m_FileInfo.m_iFreq_Hz
                                      * (pContext->m_FileInfo.m_bStereo == TRUE ? 2 : 1)
                                      * (pContext->m_FileInfo.m_b16bit == TRUE ? 2: 1);

        free(pFormat);
    }

    {
        CPs_RIFFChunk chunk;
        BOOL bSuccess = SkipToChunk(pContext->m_hFile, &chunk, "data");
        if( bSuccess == FALSE)
        {
            CP_TRACE0("Failed to find WAVE chunk");
            CloseHandle(pContext->m_hFile);
            pContext->m_hFile = INVALID_HANDLE_VALUE;
            return FALSE;
        }

        pContext->m_iLengthOfWavData = chunk.m_dwLength;
        pContext->m_iStartOfWavData = SetFilePointer(pContext->m_hFile, 0, NULL, FILE_CURRENT);
    }

    pContext->m_FileInfo.m_iFileLength_Secs = pContext->m_iLengthOfWavData / pContext->m_iBytesPerSecond;
    pContext->m_iCurrentOffset_Secs = 0;
    pContext->m_iCurrentOffset_Fraction_Bytes = 0;
    return TRUE;	
}

//
void CPP_OMWAV_CloseFile(CPs_CoDecModule* pModule)
{
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);

    if(pContext->m_hFile != INVALID_HANDLE_VALUE)
    {
        CP_TRACE0("Close WAV file");
        CloseHandle(pContext->m_hFile);
        pContext->m_hFile = INVALID_HANDLE_VALUE;
    }
}
//

BOOL SkipToChunk(HANDLE hFile, CPs_RIFFChunk* pChunk, const char cChunkID[4])
{
    DWORD dwBytesRead;
    while(ReadFile(hFile, pChunk, sizeof(*pChunk), &dwBytesRead, NULL)
            && dwBytesRead == sizeof(*pChunk) )
    {
        if(memcmp(pChunk->m_cID, cChunkID, 4) == 0)
            return TRUE;
        SetFilePointer(hFile, pChunk->m_dwLength, NULL, FILE_CURRENT);
    }

    return FALSE;
}
//
void CPP_OMWAV_Seek(CPs_CoDecModule* pModule, const int iNumerator, const int iDenominator)
{
    unsigned int iSeekPos;
    div_t progress;
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);

    iSeekPos = (int)( ((float)iNumerator/(float)iDenominator) * (float)pContext->m_iLengthOfWavData);

    iSeekPos &= ~0x3;

    progress = div(iSeekPos, pContext->m_iBytesPerSecond);
    pContext->m_iCurrentOffset_Secs = progress.quot;
    pContext->m_iCurrentOffset_Fraction_Bytes = progress.rem;

    SetFilePointer(pContext->m_hFile, pContext->m_iStartOfWavData + iSeekPos, NULL, FILE_BEGIN);
}

//
BOOL CPP_OMWAV_GetPCMBlock(CPs_CoDecModule* pModule, void* pBlock, DWORD* pdwBlockSize)
{
    BOOL bSuccess;
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);
    CP_ASSERT(pContext->m_hFile != INVALID_HANDLE_VALUE);

    bSuccess = ReadFile(pContext->m_hFile, pBlock, *pdwBlockSize, pdwBlockSize, NULL);
    if(bSuccess == FALSE || *pdwBlockSize == 0)
        return FALSE;

    pContext->m_iCurrentOffset_Fraction_Bytes += *pdwBlockSize;
    if(pContext->m_iCurrentOffset_Fraction_Bytes > pContext->m_iBytesPerSecond)
    {
        pContext->m_iCurrentOffset_Secs++;
        pContext->m_iCurrentOffset_Fraction_Bytes -= pContext->m_iBytesPerSecond;
    }

    return TRUE;
}
//
void CPP_OMWAV_GetFileInfo(CPs_CoDecModule* pModule, CPs_FileInfo* pInfo)
{
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);

    memcpy(pInfo, &pContext->m_FileInfo, sizeof(*pInfo));
}
//
int CPP_OMWAV_GetCurrentPos_secs(CPs_CoDecModule* pModule)
{
    CPs_CoDec_Wave *pContext = (CPs_CoDec_Wave*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);

    return pContext->m_iCurrentOffset_Secs;
}
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -