wavemain.cpp
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:19k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. // -----------------------------------------------------------------------------
  2. //
  3. //      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  4. //      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  5. //      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  6. //      PARTICULAR PURPOSE.
  7. //      Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
  8. //
  9. // -----------------------------------------------------------------------------
  10. #include "wavemain.h"
  11. /*
  12. #ifdef DEBUG
  13. DBGPARAM dpCurSettings = {
  14.     TEXT("WaveDriver"), {
  15.          TEXT("Test")           //  0
  16.         ,TEXT("Params")         //  1
  17.         ,TEXT("Verbose")        //  2
  18.         ,TEXT("Interrupt")      //  3
  19.         ,TEXT("WODM")           //  4
  20.         ,TEXT("WIDM")           //  5
  21.         ,TEXT("PDD")            //  6
  22.         ,TEXT("MDD")            //  7
  23.         ,TEXT("Regs")           //  8
  24.         ,TEXT("Misc")           //  9
  25.         ,TEXT("Init")           // 10
  26.         ,TEXT("IOcontrol")      // 11
  27.         ,TEXT("Alloc")          // 12
  28.         ,TEXT("Function")       // 13
  29.         ,TEXT("Warning")        // 14
  30.         ,TEXT("Error")          // 15
  31.     }
  32.     ,
  33.         (1 << 15)   // Errors
  34.     |   (1 << 14)   // Warnings
  35. };
  36. #endif
  37. */
  38. BOOL CALLBACK DllMain(HANDLE hDLL,
  39.                       DWORD dwReason,
  40.                       LPVOID lpvReserved)
  41. {
  42.     if ( dwReason==DLL_PROCESS_ATTACH )
  43.     {
  44.         DEBUGREGISTER((HMODULE)hDLL);
  45.     }
  46.     return TRUE;
  47. }
  48. // -----------------------------------------------------------------------------
  49. //
  50. // @doc     WDEV_EXT
  51. //
  52. // @topic   WAV Device Interface | Implements the WAVEDEV.DLL device
  53. //          interface. These functions are required for the device to
  54. //          be loaded by DEVICE.EXE.
  55. //
  56. // @xref                          <nl>
  57. //          <f WAV_Init>,         <nl>
  58. //          <f WAV_Deinit>,       <nl>
  59. //          <f WAV_Open>,         <nl>
  60. //          <f WAV_Close>,        <nl>
  61. //          <f WAV_Read>,         <nl>
  62. //          <f WAV_Write>,        <nl>
  63. //          <f WAV_Seek>,         <nl>
  64. //          <f WAV_PowerUp>,      <nl>
  65. //          <f WAV_PowerDown>,    <nl>
  66. //          <f WAV_IOControl>     <nl>
  67. //
  68. // -----------------------------------------------------------------------------
  69. //
  70. // @doc     WDEV_EXT
  71. //
  72. // @topic   Designing a Waveform Audio Driver |
  73. //          A waveform audio driver is responsible for processing messages
  74. //          from the Wave API Manager (WAVEAPI.DLL) to playback and record
  75. //          waveform audio. Waveform audio drivers are implemented as
  76. //          dynamic link libraries that are loaded by DEVICE.EXE The
  77. //          default waveform audio driver is named WAVEDEV.DLL (see figure).
  78. //          The messages passed to the audio driver are similar to those
  79. //          passed to a user-mode Windows NT audio driver (such as mmdrv.dll).
  80. //
  81. //          <bmp blk1_bmp>
  82. //
  83. //          Like all device drivers loaded by DEVICE.EXE, the waveform
  84. //          audio driver must export the standard device functions,
  85. //          XXX_Init, XXX_Deinit, XXX_IoControl, etc (see
  86. //          <t WAV Device Interface>). The Waveform Audio Drivers
  87. //          have a device prefix of "WAV".
  88. //
  89. //          Driver loading and unloading is handled by DEVICE.EXE and
  90. //          WAVEAPI.DLL. Calls are made to <f WAV_Init> and <f WAV_Deinit>.
  91. //          When the driver is opened by WAVEAPI.DLL calls are made to
  92. //          <f WAV_Open> and <f WAV_Close>.  On system power up and power down
  93. //          calls are made to <f WAV_PowerUp> and <f WAV_PowerDown>. All
  94. //          other communication between WAVEAPI.DLL and WAVEDEV.DLL is
  95. //          done by calls to <f WAV_IOControl>. The other WAV_xxx functions
  96. //          are not used.
  97. //
  98. // @xref                                          <nl>
  99. //          <t Designing a Waveform Audio PDD>    <nl>
  100. //          <t WAV Device Interface>              <nl>
  101. //          <t Wave Input Driver Messages>        <nl>
  102. //          <t Wave Output Driver Messages>       <nl>
  103. //
  104. // -----------------------------------------------------------------------------
  105. // -----------------------------------------------------------------------------
  106. //
  107. //  @doc    WDEV_EXT
  108. //
  109. //  @func   PVOID | WAV_Init | Device initialization routine
  110. //
  111. //  @parm   DWORD | dwInfo | info passed to RegisterDevice
  112. //
  113. //  @rdesc  Returns a DWORD which will be passed to Open & Deinit or NULL if
  114. //          unable to initialize the device.
  115. //
  116. // -----------------------------------------------------------------------------
  117. DWORD WAV_Init(DWORD Index)
  118. {
  119.     return (DWORD)HardwareContext::CreateHWContext(Index);
  120. }
  121. // -----------------------------------------------------------------------------
  122. //
  123. //  @doc    WDEV_EXT
  124. //
  125. //  @func   PVOID | WAV_Deinit | Device deinitialization routine
  126. //
  127. //  @parm   DWORD | dwData | value returned from WAV_Init call
  128. //
  129. //  @rdesc  Returns TRUE for success, FALSE for failure.
  130. //
  131. // -----------------------------------------------------------------------------
  132. BOOL WAV_Deinit(DWORD dwData)
  133. {
  134.     return g_pHWContext->Deinit();
  135. }
  136. // -----------------------------------------------------------------------------
  137. //
  138. //  @doc    WDEV_EXT
  139. //
  140. //  @func   PVOID | WAV_Open    | Device open routine
  141. //
  142. //  @parm   DWORD | dwData      | Value returned from WAV_Init call (ignored)
  143. //
  144. //  @parm   DWORD | dwAccess    | Requested access (combination of GENERIC_READ
  145. //                                and GENERIC_WRITE) (ignored)
  146. //
  147. //  @parm   DWORD | dwShareMode | Requested share mode (combination of
  148. //                                FILE_SHARE_READ and FILE_SHARE_WRITE) (ignored)
  149. //
  150. //  @rdesc  Returns a DWORD which will be passed to Read, Write, etc or NULL if
  151. //          unable to open device.
  152. //
  153. // -----------------------------------------------------------------------------
  154. DWORD WAV_Open( DWORD dwData,
  155.               DWORD dwAccess,
  156.               DWORD dwShareMode)
  157. {
  158.     return 4;
  159. }
  160. // -----------------------------------------------------------------------------
  161. //
  162. //  @doc    WDEV_EXT
  163. //
  164. //  @func   BOOL | WAV_Close | Device close routine
  165. //
  166. //  @parm   DWORD | dwOpenData | Value returned from WAV_Open call
  167. //
  168. //  @rdesc  Returns TRUE for success, FALSE for failure
  169. //
  170. // -----------------------------------------------------------------------------
  171. BOOL WAV_Close(DWORD dwData)
  172. {
  173.     return TRUE;
  174. }
  175. // -----------------------------------------------------------------------------
  176. //
  177. //  @doc    WDEV_EXT
  178. //
  179. //  @func   DWORD | WAV_Read | Device read routine
  180. //
  181. //  @parm   DWORD | dwOpenData | Value returned from WAV_Open call (ignored)
  182. //
  183. //  @parm   LPVOID | pBuf | Buffer to receive data (ignored)
  184. //
  185. //  @parm   DWORD | len | Maximum length to read (ignored)
  186. //
  187. //  @rdesc  Returns 0 always. WAV_Read should never get called and does
  188. //          nothing. Required DEVICE.EXE function, but all data communication
  189. //          is handled by <f WAV_IOControl>.
  190. //
  191. // -----------------------------------------------------------------------------
  192. DWORD WAV_Read(DWORD dwData,
  193.                LPVOID pBuf,
  194.                DWORD Len)
  195. {
  196.     // Return length read
  197.     return 0;
  198. }
  199. // -----------------------------------------------------------------------------
  200. //
  201. //  @doc    WDEV_EXT
  202. //
  203. //  @func   DWORD | WAV_Write | Device write routine
  204. //
  205. //  @parm   DWORD | dwOpenData | Value returned from WAV_Open call (ignored)
  206. //
  207. //  @parm   LPCVOID | pBuf | Buffer containing data (ignored)
  208. //
  209. //  @parm   DWORD | len | Maximum length to write (ignored)
  210. //
  211. //  @rdesc  Returns 0 always. WAV_Write should never get called and does
  212. //          nothing. Required DEVICE.EXE function, but all data communication
  213. //          is handled by <f WAV_IOControl>.
  214. //
  215. // -----------------------------------------------------------------------------
  216. DWORD WAV_Write(DWORD dwData,
  217.                 LPCVOID pBuf,
  218.                 DWORD Len)
  219. {
  220.     // return number of bytes written (or -1 for error)
  221.     return 0;
  222. }
  223. // -----------------------------------------------------------------------------
  224. //
  225. //  @doc    WDEV_EXT
  226. //
  227. //  @func   DWORD | WAV_Seek | Device seek routine
  228. //
  229. //  @parm   DWORD | dwOpenData | Value returned from WAV_Open call (ignored)
  230. //
  231. //  @parm   long | pos | Position to seek to (relative to type) (ignored)
  232. //
  233. //  @parm   DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END (ignored)
  234. //
  235. //  @rdesc  Returns -1 always. WAV_Seek should never get called and does
  236. //          nothing. Required DEVICE.EXE function, but all data communication
  237. //          is handled by <f WAV_IOControl>.
  238. //
  239. // -----------------------------------------------------------------------------
  240. DWORD WAV_Seek(DWORD dwData,
  241.                long pos,
  242.                DWORD type)
  243. {
  244.     // return an error
  245.     return (DWORD)-1;
  246. }
  247. // -----------------------------------------------------------------------------
  248. //
  249. //  @doc    WDEV_EXT
  250. //
  251. //  @func   void | WAV_PowerUp | Device powerup routine
  252. //
  253. //  @comm   Called to restore device from suspend mode.  Cannot call any
  254. //          routines aside from those in the dll in this call.
  255. //
  256. // -----------------------------------------------------------------------------
  257. VOID WAV_PowerUp(VOID)
  258. {
  259.     g_pHWContext->PowerUp();
  260.     return;
  261. }
  262. // -----------------------------------------------------------------------------
  263. //
  264. //  @doc    WDEV_EXT
  265. //
  266. //  @func   void | WAV_PowerDown | Device powerdown routine
  267. //
  268. //  @comm   Called to suspend device.  Cannot call any routines aside from
  269. //          those in the dll in this call.
  270. //
  271. // -----------------------------------------------------------------------------
  272. VOID WAV_PowerDown(VOID)
  273. {
  274.     g_pHWContext->PowerDown();
  275.     return;
  276. }
  277. BOOL HandleWaveMessage(PMMDRV_MESSAGE_PARAMS pParams, DWORD *pdwResult)
  278. {
  279.     //  set the error code to be no error first
  280.     SetLastError(MMSYSERR_NOERROR);
  281.     UINT uMsg = pParams->uMsg;
  282.     UINT uDeviceId = pParams->uDeviceId;
  283.     DWORD dwParam1 = pParams->dwParam1;
  284.     DWORD dwParam2 = pParams->dwParam2;
  285.     DWORD dwUser   = pParams->dwUser;
  286.     StreamContext *pStreamContext = (StreamContext *)dwUser;
  287.     DWORD dwRet;
  288.     g_pHWContext->Lock();
  289.     switch (uMsg)
  290.     {
  291.     case WODM_GETNUMDEVS:
  292.         {
  293.             dwRet = g_pHWContext->GetNumOutputDevices();
  294.             break;
  295.         }
  296.     case WIDM_GETNUMDEVS:
  297.         {
  298.             dwRet = g_pHWContext->GetNumInputDevices();
  299.             break;
  300.         }
  301.     case WODM_GETDEVCAPS:
  302.         {
  303.             DeviceContext *pDeviceContext;
  304.             UINT NumDevs = g_pHWContext->GetNumOutputDevices();
  305.             if (pStreamContext)
  306.             {
  307.                 pDeviceContext=pStreamContext->GetDeviceContext();
  308.             }
  309.             else
  310.             {
  311.                 pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
  312.             }
  313.             dwRet = pDeviceContext->GetDevCaps((PVOID)dwParam1,dwParam2);
  314.             break;
  315.         }
  316.     case WIDM_GETDEVCAPS:
  317.         {
  318.             DeviceContext *pDeviceContext;
  319.             UINT NumDevs = g_pHWContext->GetNumInputDevices();
  320.             if (pStreamContext)
  321.             {
  322.                 pDeviceContext=pStreamContext->GetDeviceContext();
  323.             }
  324.             else
  325.             {
  326.                 pDeviceContext = g_pHWContext->GetInputDeviceContext(uDeviceId);
  327.             }
  328.             dwRet = pDeviceContext->GetDevCaps((PVOID)dwParam1,dwParam2);
  329.             break;
  330.         }
  331.     case WODM_GETEXTDEVCAPS:
  332.         {
  333.             DeviceContext *pDeviceContext;
  334.             UINT NumDevs = g_pHWContext->GetNumOutputDevices();
  335.             if (pStreamContext)
  336.             {
  337.                 pDeviceContext=pStreamContext->GetDeviceContext();
  338.             }
  339.             else
  340.             {
  341.                 pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
  342.             }
  343.             dwRet = pDeviceContext->GetExtDevCaps((PVOID)dwParam1,dwParam2);
  344.             break;
  345.         }
  346.     case WODM_OPEN:
  347.         {
  348.             // DEBUGMSG(1, (TEXT("WODM_OPENrn"));
  349.             DeviceContext *pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
  350.             dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);
  351.             break;
  352.         }
  353.     case WIDM_OPEN:
  354.         {
  355.             // DEBUGMSG(1, (TEXT("WIDM_OPENrn"));
  356.             DeviceContext *pDeviceContext = g_pHWContext->GetInputDeviceContext(uDeviceId);
  357.             dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);
  358.             break;
  359.         }
  360.     case WODM_CLOSE:
  361.     case WIDM_CLOSE:
  362.         {
  363.             // DEBUGMSG(1, (TEXT("WIDM_CLOSE/WODM_CLOSErn"));
  364.             dwRet = pStreamContext->Close();
  365.             // Release stream context here, rather than inside StreamContext::Close, so that if someone
  366.             // (like CMidiStream) has subclassed Close there's no chance that the object will get released
  367.             // out from under them.
  368.             if (dwRet==MMSYSERR_NOERROR)
  369.             {
  370.                 pStreamContext->Release();
  371.             }
  372.             break;
  373.         }
  374.     case WODM_RESTART:
  375.     case WIDM_START:
  376.         {
  377.             dwRet = pStreamContext->Run();
  378.             break;
  379.         }
  380.     case WODM_PAUSE:
  381.     case WIDM_STOP:
  382.         {
  383.             dwRet = pStreamContext->Stop();
  384.             break;
  385.         }
  386.     case WODM_GETPOS:
  387.     case WIDM_GETPOS:
  388.         {
  389.             dwRet = pStreamContext->GetPos((PMMTIME)dwParam1);
  390.             break;
  391.         }
  392.     case WODM_RESET:
  393.     case WIDM_RESET:
  394.         {
  395.             dwRet = pStreamContext->Reset();
  396.             break;
  397.         }
  398.     case WODM_WRITE:
  399.     case WIDM_ADDBUFFER:
  400.         {
  401.             // DEBUGMSG(1, (TEXT("WODM_WRITE/WIDM_ADDBUFFER, Buffer=0x%xrn"),dwParam1);
  402.             dwRet = pStreamContext->QueueBuffer((LPWAVEHDR)dwParam1);
  403.             break;
  404.         }
  405.     case WODM_GETVOLUME:
  406.         {
  407.             PULONG pdwGain = (PULONG)dwParam1;
  408.             UINT NumDevs = g_pHWContext->GetNumOutputDevices();
  409.             if (pStreamContext)
  410.             {
  411.                 *pdwGain = pStreamContext->GetGain();
  412.             }
  413.             else
  414.             {
  415.                 DeviceContext *pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
  416.                 *pdwGain = pDeviceContext->GetGain();
  417.             }
  418.             dwRet = MMSYSERR_NOERROR;
  419.             break;
  420.         }
  421.     case WODM_SETVOLUME:
  422.         {
  423.             UINT NumDevs = g_pHWContext->GetNumOutputDevices();
  424.             LONG dwGain = dwParam1;
  425.             if (pStreamContext)
  426.             {
  427.                 dwRet = pStreamContext->SetGain(dwGain);
  428.             }
  429.             else
  430.             {
  431.                 DeviceContext *pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
  432.                 dwRet = pDeviceContext->SetGain(dwGain);
  433.             }
  434.             break;
  435.         }
  436.     case WODM_BREAKLOOP:
  437.         {
  438.             dwRet = pStreamContext->BreakLoop();
  439.             break;
  440.         }
  441.     case WODM_SETPLAYBACKRATE:
  442.         {
  443.             WaveStreamContext *pWaveStream = (WaveStreamContext *)dwUser;
  444.             dwRet = pWaveStream->SetRate(dwParam1);
  445.             break;
  446.         }
  447.     case WODM_GETPLAYBACKRATE:
  448.         {
  449.             WaveStreamContext *pWaveStream = (WaveStreamContext *)dwUser;
  450.             dwRet = pWaveStream->GetRate((DWORD *)dwParam1);
  451.             break;
  452.         }
  453.     case MM_WOM_SETSECONDARYGAINCLASS:
  454.         {
  455.             dwRet = pStreamContext->SetSecondaryGainClass(dwParam1);
  456.             break;
  457.         }
  458.     case MM_WOM_SETSECONDARYGAINLIMIT:
  459.         {
  460.             DeviceContext *pDeviceContext;
  461.             if (pStreamContext)
  462.             {
  463.                 pDeviceContext = pStreamContext->GetDeviceContext();
  464.             }
  465.             else
  466.             {
  467.                 pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
  468.             }
  469.             dwRet = pDeviceContext->SetSecondaryGainLimit(dwParam1,dwParam2);
  470.             break;
  471.         }
  472. /*
  473.     case MM_WOM_FORCESPEAKER:
  474.         {
  475.             if (pStreamContext)
  476.             {
  477.                 dwRet = pStreamContext->ForceSpeaker((BOOL)dwParam1);
  478.             }
  479.             else
  480.             {
  481.                 dwRet = g_pHWContext->ForceSpeaker((BOOL)dwParam1);
  482.             }
  483.             break;
  484.         }
  485. */
  486.     case MM_MOM_MIDIMESSAGE:
  487.         {
  488.             CMidiStream *pMidiStream = (CMidiStream *)dwUser;
  489.             dwRet = pMidiStream->MidiMessage(dwParam1);
  490.             break;
  491.         }
  492.     case WODM_GETPITCH:
  493.     case WODM_SETPITCH:
  494.     case WODM_PREPARE:
  495.     case WODM_UNPREPARE:
  496.     case WIDM_PREPARE:
  497.     case WIDM_UNPREPARE:
  498.         default:
  499.         dwRet  = MMSYSERR_NOTSUPPORTED;
  500.     }
  501.     g_pHWContext->Unlock();
  502.     // Pass the return code back via pBufOut
  503.     if (pdwResult)
  504.     {
  505.         *pdwResult = dwRet;
  506.     }
  507.     return TRUE;
  508. }
  509. // -----------------------------------------------------------------------------
  510. //
  511. //  @doc    WDEV_EXT
  512. //
  513. //  @func   BOOL | WAV_IOControl | Device IO control routine
  514. //
  515. //  @parm   DWORD | dwOpenData | Value returned from WAV_Open call
  516. //
  517. //  @parm   DWORD | dwCode |
  518. //          IO control code for the function to be performed. WAV_IOControl only
  519. //          supports one IOCTL value (IOCTL_WAV_MESSAGE)
  520. //
  521. //  @parm   PBYTE | pBufIn |
  522. //          Pointer to the input parameter structure (<t MMDRV_MESSAGE_PARAMS>).
  523. //
  524. //  @parm   DWORD | dwLenIn |
  525. //          Size in bytes of input parameter structure (sizeof(<t MMDRV_MESSAGE_PARAMS>)).
  526. //
  527. //  @parm   PBYTE | pBufOut | Pointer to the return value (DWORD).
  528. //
  529. //  @parm   DWORD | dwLenOut | Size of the return value variable (sizeof(DWORD)).
  530. //
  531. //  @parm   PDWORD | pdwActualOut | Unused
  532. //
  533. //  @rdesc  Returns TRUE for success, FALSE for failure
  534. //
  535. //  @xref   <t Wave Input Driver Messages> (WIDM_XXX) <nl>
  536. //          <t Wave Output Driver Messages> (WODM_XXX)
  537. //
  538. // -----------------------------------------------------------------------------
  539. BOOL WAV_IOControl(DWORD  dwOpenData,
  540.                    DWORD  dwCode,
  541.                    PBYTE  pBufIn,
  542.                    DWORD  dwLenIn,
  543.                    PBYTE  pBufOut,
  544.                    DWORD  dwLenOut,
  545.                    PDWORD pdwActualOut)
  546. {
  547.     _try
  548.     {
  549.         switch (dwCode)
  550.         {
  551.         case IOCTL_WAV_MESSAGE:
  552.             return HandleWaveMessage((PMMDRV_MESSAGE_PARAMS)pBufIn, (DWORD *)pBufOut);
  553.         default:
  554.             return g_pHWContext->IOControl(dwOpenData, dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
  555.         }
  556.     }
  557.     _except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  558.     {
  559.         RETAILMSG(1, (TEXT("EXCEPTION IN WAV_IOControl!!!!rn")));
  560.         SetLastError(E_FAIL);
  561.     }
  562.     return FALSE;
  563. }