CPI_Player_Output_Wave.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "globals.h"
  3. #include "CPI_Player.h"
  4. #include "CPI_Player_CoDec.h"
  5. #include "CPI_Player_Output.h"
  6. #include "CPI_Equaliser.h"
  7. #define CPC_NUMBEROFOUTPUTBLOCKS 16
  8. #define CPC_OUTPUTBLOCKSIZE 0x8000 
  9. typedef struct __CPs_OutputContext_Wave
  10. {
  11.     HWAVEOUT m_hWaveOut;
  12.     WAVEHDR m_aryWaveBlocks[CPC_NUMBEROFOUTPUTBLOCKS];
  13.     DWORD m_aryBlockSizes[CPC_NUMBEROFOUTPUTBLOCKS];
  14.     void* m_pBlockBase;
  15.     int m_iLastReadBlockIDX;
  16.     CPs_EqualiserModule* m_pEqualiser;
  17. } CPs_OutputContext_Wave;
  18. ////////////////////////////////////////////////////////////////////////////////
  19. void CPP_OMWV_Initialise(CPs_OutputModule* pModule, const CPs_FileInfo* pFileInfo, CP_HEQUALISER hEqualiser);
  20. void CPP_OMWV_Uninitialise(CPs_OutputModule* pModule);
  21. void CPP_OMWV_RefillBuffers(CPs_OutputModule* pModule);
  22. void CPP_OMWV_SetPause(CPs_OutputModule* pModule, const BOOL bPause);
  23. BOOL CPP_OMWV_IsOutputComplete(CPs_OutputModule* pModule);
  24. void CPP_OMWV_Flush(CPs_OutputModule* pModule);
  25. void CPP_OMWV_OnEQChanged(CPs_OutputModule* pModule);
  26. void CPP_OMWV_SetInternalVolume(CPs_OutputModule* pModule, const int iNewVolume);
  27. ////////////////////////////////////////////////////////////////////////////////
  28. void CPI_Player_Output_Initialise_WaveMapper(CPs_OutputModule* pModule)
  29. {
  30.     pModule->Initialise = CPP_OMWV_Initialise;
  31.     pModule->Uninitialise = CPP_OMWV_Uninitialise;
  32.     pModule->RefillBuffers = CPP_OMWV_RefillBuffers;
  33.     pModule->SetPause = CPP_OMWV_SetPause;
  34.     pModule->IsOutputComplete = CPP_OMWV_IsOutputComplete;
  35.     pModule->Flush = CPP_OMWV_Flush;
  36.     pModule->OnEQChanged = CPP_OMWV_OnEQChanged;
  37.     pModule->SetInternalVolume = CPP_OMWV_SetInternalVolume;
  38.     pModule->m_pModuleCookie = NULL;
  39.     pModule->m_pcModuleName = "Cooler Wave mapper";
  40.     pModule->m_pCoDec = NULL;
  41.     pModule->m_pEqualiser = NULL;
  42. }
  43. void CPP_OMWV_Initialise(CPs_OutputModule* pModule, const CPs_FileInfo* pFileInfo, CP_HEQUALISER hEqualiser)
  44. {
  45.     MMRESULT mmErr;
  46.     CPs_OutputContext_Wave* pContext;
  47.     CP_ASSERT(pModule->m_pModuleCookie == NULL);
  48.     pContext = (CPs_OutputContext_Wave*)malloc(sizeof(CPs_OutputContext_Wave));
  49.     pModule->m_pModuleCookie = pContext;
  50.     CP_TRACE0("Wave out initialising");
  51.     pModule->m_evtBlockFree = CreateEvent(NULL, FALSE, FALSE, NULL);
  52.     {
  53.         WAVEFORMATEX waveformatex;
  54.         waveformatex.wFormatTag = WAVE_FORMAT_PCM;
  55.         waveformatex.nChannels = pFileInfo->m_bStereo ? 2 : 1;
  56.         waveformatex.nSamplesPerSec = pFileInfo->m_iFreq_Hz;
  57.         waveformatex.wBitsPerSample = pFileInfo->m_b16bit ? 16 : 8;
  58.         waveformatex.nBlockAlign = (waveformatex.nChannels * waveformatex.wBitsPerSample)>>3;
  59.         waveformatex.nAvgBytesPerSec = waveformatex.nSamplesPerSec * waveformatex.nBlockAlign;
  60.         waveformatex.cbSize = 0;
  61.         mmErr = waveOutOpen( &pContext->m_hWaveOut,
  62.                              WAVE_MAPPER,
  63.                              &waveformatex,
  64.                              (DWORD)pModule->m_evtBlockFree,
  65.                              0, CALLBACK_EVENT);
  66.         if(mmErr != MMSYSERR_NOERROR)
  67.         {
  68.             CP_TRACE1("Wave Open error 0x%X", mmErr);
  69.             pContext->m_hWaveOut = NULL;
  70.             DeleteObject(pModule->m_evtBlockFree);
  71.         }
  72.     }
  73.     pContext->m_pBlockBase = VirtualAlloc( NULL,
  74.                                            CPC_OUTPUTBLOCKSIZE * (CPC_NUMBEROFOUTPUTBLOCKS<<1),
  75.                                            MEM_COMMIT, PAGE_READWRITE);
  76.     pContext->m_iLastReadBlockIDX = 0;
  77.     {
  78.         void* pBlockCursor = pContext->m_pBlockBase;
  79.         int iWaveBlockIDX;
  80.         for(iWaveBlockIDX=0; iWaveBlockIDX < CPC_NUMBEROFOUTPUTBLOCKS; iWaveBlockIDX++)
  81.         {
  82.             pContext->m_aryWaveBlocks[iWaveBlockIDX].dwFlags = 0;
  83.             pContext->m_aryWaveBlocks[iWaveBlockIDX].lpData = pBlockCursor;
  84.             pContext->m_aryWaveBlocks[iWaveBlockIDX].dwBufferLength = CPC_OUTPUTBLOCKSIZE;
  85.             waveOutPrepareHeader(pContext->m_hWaveOut, pContext->m_aryWaveBlocks + iWaveBlockIDX, sizeof(*pContext->m_aryWaveBlocks));
  86.             pBlockCursor = (void*)( (BYTE*)pBlockCursor + CPC_OUTPUTBLOCKSIZE);
  87.         }
  88.     }
  89.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  90.     pModule->m_pEqualiser = hEqualiser;
  91. }
  92. void CPP_OMWV_Uninitialise(CPs_OutputModule* pModule)
  93. {
  94.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  95.     CP_CHECKOBJECT(pContext);
  96.     CP_TRACE0("Wave out shutting down");
  97.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
  98.     if(pContext->m_hWaveOut)
  99.     {
  100.         waveOutRestart(pContext->m_hWaveOut);
  101.         waveOutReset(pContext->m_hWaveOut);
  102.         {
  103.             int iWaveBlockIDX;
  104.             for(iWaveBlockIDX=0; iWaveBlockIDX < CPC_NUMBEROFOUTPUTBLOCKS; iWaveBlockIDX++)
  105.                 waveOutUnprepareHeader(pContext->m_hWaveOut, pContext->m_aryWaveBlocks + iWaveBlockIDX, sizeof(*pContext->m_aryWaveBlocks));
  106.         }
  107.         VirtualFree(pContext->m_pBlockBase, 0, MEM_RELEASE);
  108.         waveOutClose(pContext->m_hWaveOut);
  109.         DeleteObject(pModule->m_evtBlockFree);
  110.     }
  111.     free(pContext);
  112.     pModule->m_pModuleCookie = NULL;
  113. }
  114. //
  115. void CPP_OMWV_RefillBuffers(CPs_OutputModule* pModule)
  116. {
  117.     int iBlockIDX;
  118.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  119.     CP_CHECKOBJECT(pContext);
  120.     if(!pContext->m_hWaveOut)
  121.         return;
  122.     for(iBlockIDX = 0; iBlockIDX < CPC_NUMBEROFOUTPUTBLOCKS; iBlockIDX++)
  123.     {
  124.         WAVEHDR* pOutputBlock = pContext->m_aryWaveBlocks + iBlockIDX;
  125.         if( (pOutputBlock->dwFlags & WHDR_INQUEUE) == 0)
  126.         {
  127.             BOOL bMoreData;
  128.             pOutputBlock->dwBufferLength = CPC_OUTPUTBLOCKSIZE;
  129.             bMoreData = pModule->m_pCoDec->GetPCMBlock(pModule->m_pCoDec, pOutputBlock->lpData, &pOutputBlock->dwBufferLength);
  130.             pContext->m_iLastReadBlockIDX = iBlockIDX;
  131.             pContext->m_aryBlockSizes[iBlockIDX] = pOutputBlock->dwBufferLength;
  132.             memcpy( ((BYTE*)pOutputBlock->lpData) + (CPC_OUTPUTBLOCKSIZE * CPC_NUMBEROFOUTPUTBLOCKS),
  133.                     pOutputBlock->lpData,
  134.                     pOutputBlock->dwBufferLength);
  135.             {
  136.                 CPs_EqualiserModule* pEQModule = (CPs_EqualiserModule*)pModule->m_pEqualiser;
  137.                 pEQModule->ApplyEQToBlock_Inplace(pEQModule, pOutputBlock->lpData, pOutputBlock->dwBufferLength);
  138.             }
  139.             if(pOutputBlock->dwBufferLength > 0)
  140.                 waveOutWrite(pContext->m_hWaveOut, pOutputBlock, sizeof(*pOutputBlock));
  141.             if(bMoreData == FALSE)
  142.             {
  143.                 pModule->m_pCoDec->CloseFile(pModule->m_pCoDec);
  144.                 pModule->m_pCoDec = NULL;
  145.                 break;
  146.             }
  147.         }
  148.     }
  149. }
  150. //
  151. void CPP_OMWV_SetPause(CPs_OutputModule* pModule, const BOOL bPause)
  152. {
  153.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  154.     CP_CHECKOBJECT(pContext);
  155.     if(!pContext->m_hWaveOut)
  156.         return;
  157.     if(bPause == TRUE)
  158.         waveOutPause(pContext->m_hWaveOut);
  159.     else
  160.         waveOutRestart(pContext->m_hWaveOut);
  161. }
  162. //
  163. BOOL CPP_OMWV_IsOutputComplete(CPs_OutputModule* pModule)
  164. {
  165.     int iBlockIDX;
  166.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  167.     CP_CHECKOBJECT(pContext);
  168.     if(!pContext->m_hWaveOut)
  169.         return TRUE;
  170.     for(iBlockIDX = 0; iBlockIDX < CPC_NUMBEROFOUTPUTBLOCKS; iBlockIDX++)
  171.     {
  172.         if( (pContext->m_aryWaveBlocks[iBlockIDX].dwFlags & WHDR_INQUEUE))
  173.             return FALSE;
  174.     }
  175.     return TRUE;
  176. }
  177. //
  178. void CPP_OMWV_OnEQChanged(CPs_OutputModule* pModule)
  179. {
  180.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  181.     int iBlockIDX;
  182.     CP_CHECKOBJECT(pContext);
  183.     if(!pContext->m_hWaveOut)
  184.         return;
  185.     for(iBlockIDX = pContext->m_iLastReadBlockIDX + 1; iBlockIDX < CPC_NUMBEROFOUTPUTBLOCKS; iBlockIDX++)
  186.     {
  187.         if( (pContext->m_aryWaveBlocks[iBlockIDX].dwFlags & (WHDR_INQUEUE | WHDR_DONE) ))
  188.         {
  189.             WAVEHDR* pOutputBlock = pContext->m_aryWaveBlocks + iBlockIDX;
  190.             pOutputBlock->dwBufferLength = pContext->m_aryBlockSizes[iBlockIDX];
  191.             memcpy( pOutputBlock->lpData,
  192.                     ((BYTE*)pOutputBlock->lpData) + (CPC_OUTPUTBLOCKSIZE * CPC_NUMBEROFOUTPUTBLOCKS),
  193.                     pOutputBlock->dwBufferLength);
  194.             {
  195.                 CPs_EqualiserModule* pEQModule = (CPs_EqualiserModule*)pModule->m_pEqualiser;
  196.                 pEQModule->ApplyEQToBlock_Inplace(pEQModule, pOutputBlock->lpData, pOutputBlock->dwBufferLength);
  197.             }
  198.         }
  199.     }
  200.     for(iBlockIDX = 0; iBlockIDX <= pContext->m_iLastReadBlockIDX; iBlockIDX++)
  201.     {
  202.         if( (pContext->m_aryWaveBlocks[iBlockIDX].dwFlags & (WHDR_INQUEUE | WHDR_DONE) ))
  203.         {
  204.             WAVEHDR* pOutputBlock = pContext->m_aryWaveBlocks + iBlockIDX;
  205.             pOutputBlock->dwBufferLength = pContext->m_aryBlockSizes[iBlockIDX];
  206.             memcpy( pOutputBlock->lpData,
  207.                     ((BYTE*)pOutputBlock->lpData) + (CPC_OUTPUTBLOCKSIZE * CPC_NUMBEROFOUTPUTBLOCKS),
  208.                     pOutputBlock->dwBufferLength);
  209.             {
  210.                 CPs_EqualiserModule* pEQModule = (CPs_EqualiserModule*)pModule->m_pEqualiser;
  211.                 pEQModule->ApplyEQToBlock_Inplace(pEQModule, pOutputBlock->lpData, pOutputBlock->dwBufferLength);
  212.             }
  213.         }
  214.     }
  215. }
  216. void CPP_OMWV_Flush(CPs_OutputModule* pModule)
  217. {
  218.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  219.     CP_CHECKOBJECT(pContext);
  220.     if(!pContext->m_hWaveOut)
  221.         return;
  222.     waveOutRestart(pContext->m_hWaveOut);
  223.     waveOutReset(pContext->m_hWaveOut);
  224.     CP_ASSERT(CPP_OMWV_IsOutputComplete(pModule));
  225. }
  226. //
  227. void CPP_OMWV_SetInternalVolume(CPs_OutputModule* pModule, const int iNewVolume)
  228. {
  229.     CPs_OutputContext_Wave* pContext = (CPs_OutputContext_Wave*)pModule->m_pModuleCookie;
  230.     int iNewVolume_DWORD;
  231.     CP_CHECKOBJECT(pContext);
  232.     if(!pContext->m_hWaveOut)
  233.         return;
  234.     iNewVolume_DWORD = iNewVolume * 656;
  235.     if(iNewVolume_DWORD > 0xFFFF)
  236.         iNewVolume_DWORD = 0xFFFF;
  237.     iNewVolume_DWORD |= (iNewVolume_DWORD<<16);
  238.     waveOutSetVolume(pContext->m_hWaveOut, iNewVolume_DWORD);
  239. }
  240. //