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

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. BOOL DeviceContext::IsSupportedFormat(LPWAVEFORMATEX lpFormat)
  12. {
  13.     if (lpFormat->wFormatTag != WAVE_FORMAT_PCM)
  14.         return FALSE;
  15.     if (  (lpFormat->nChannels!=1) && (lpFormat->nChannels!=2) )
  16.         return FALSE;
  17.     if (  (lpFormat->wBitsPerSample!=8) && (lpFormat->wBitsPerSample!=16) )
  18.         return FALSE;
  19.     if (lpFormat->nSamplesPerSec==0)
  20.         return FALSE;
  21.     return TRUE;
  22. }
  23. // We also support MIDI on output
  24. BOOL OutputDeviceContext::IsSupportedFormat(LPWAVEFORMATEX lpFormat)
  25. {
  26.     if (lpFormat->wFormatTag == WAVE_FORMAT_MIDI)
  27.     {
  28.         return TRUE;
  29.     }
  30.     return DeviceContext::IsSupportedFormat(lpFormat);
  31. }
  32. // Assumes lock is taken
  33. void DeviceContext::NewStream(StreamContext *pStreamContext)
  34. {
  35.     InsertTailList(&m_StreamList,&pStreamContext->m_Link);
  36. }
  37. // Assumes lock is taken
  38. void DeviceContext::DeleteStream(StreamContext *pStreamContext)
  39. {
  40.     RemoveEntryList(&pStreamContext->m_Link);
  41. }
  42. // Returns # of samples of output buffer filled
  43. // Assumes that g_pHWContext->Lock already held.
  44. PBYTE DeviceContext::TransferBuffer(PBYTE pBuffer, PBYTE pBufferEnd, DWORD *pNumStreams)
  45. {
  46.     PLIST_ENTRY pListEntry;
  47.     StreamContext *pStreamContext;
  48.     PBYTE pBufferLastThis;
  49.     PBYTE pBufferLast=pBuffer;
  50.     DWORD NumStreams=0;
  51.     pListEntry = m_StreamList.Flink;
  52.     while (pListEntry != &m_StreamList)
  53.     {
  54.         // Get a pointer to the stream context
  55.         pStreamContext = CONTAINING_RECORD(pListEntry,StreamContext,m_Link);
  56.         // Note: The stream context may be closed and removed from the list inside
  57.         // of Render, and the context may be freed as soon as we call Release.
  58.         // Therefore we need to grab the next Flink first in case the
  59.         // entry disappears out from under us.
  60.         pListEntry = pListEntry->Flink;
  61.         // Render buffers
  62.         pStreamContext->AddRef();
  63.         pBufferLastThis = pStreamContext->Render(pBuffer, pBufferEnd, pBufferLast);
  64.         pStreamContext->Release();
  65.         if (pBufferLastThis>pBuffer)
  66.         {
  67.             NumStreams++;
  68.         }
  69.         if (pBufferLast < pBufferLastThis)
  70.         {
  71.             pBufferLast = pBufferLastThis;
  72.         }
  73.     }
  74.     if (pNumStreams)
  75.     {
  76.         *pNumStreams=NumStreams;
  77.     }
  78.     return pBufferLast;
  79. }
  80. void DeviceContext::RecalcAllGains()
  81. {
  82.     PLIST_ENTRY pListEntry;
  83.     StreamContext *pStreamContext;
  84.     for (pListEntry = m_StreamList.Flink;
  85.         pListEntry != &m_StreamList;
  86.         pListEntry = pListEntry->Flink)
  87.     {
  88.         pStreamContext = CONTAINING_RECORD(pListEntry,StreamContext,m_Link);
  89.         pStreamContext->GainChange();
  90.     }
  91.     return;
  92. }
  93. void OutputDeviceContext::StreamReadyToRender(StreamContext *pStreamContext)
  94. {
  95.     g_pHWContext->StartOutputDMA();
  96.     return;
  97. }
  98. void InputDeviceContext::StreamReadyToRender(StreamContext *pStreamContext)
  99. {
  100.     g_pHWContext->StartInputDMA();
  101.     return;
  102. }
  103. DWORD OutputDeviceContext::GetDevCaps(LPVOID pCaps, DWORD dwSize)
  104. {
  105.     static const WAVEOUTCAPS wc =
  106.     {
  107.         MM_MICROSOFT,
  108.         24,
  109.         0x0001,
  110.         TEXT("Audio Output"),
  111.         WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 |
  112.         WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 |
  113.         WAVE_FORMAT_1M16 | WAVE_FORMAT_2M16 | WAVE_FORMAT_4M16 |
  114.         WAVE_FORMAT_1S16 | WAVE_FORMAT_2S16 | WAVE_FORMAT_4S16,
  115.         1,
  116.         0,
  117.         WAVECAPS_VOLUME | WAVECAPS_PLAYBACKRATE
  118.     };
  119.     memcpy( pCaps, &wc, min(dwSize,sizeof(wc)));
  120.     return MMSYSERR_NOERROR;
  121. }
  122. DWORD InputDeviceContext::GetDevCaps(LPVOID pCaps, DWORD dwSize)
  123. {
  124.     static const WAVEINCAPS wc =
  125.     {
  126.         MM_MICROSOFT,
  127.         23,
  128.         0x0001,
  129.         TEXT("Audio Input"),
  130.         WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 |
  131.         WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 |
  132.         WAVE_FORMAT_1M16 | WAVE_FORMAT_2M16 | WAVE_FORMAT_4M16 |
  133.         WAVE_FORMAT_1S16 | WAVE_FORMAT_2S16 | WAVE_FORMAT_4S16,
  134.         1,
  135.         0
  136.     };
  137.     memcpy( pCaps, &wc, min(dwSize,sizeof(wc)));
  138.     return MMSYSERR_NOERROR;
  139. }
  140. DWORD OutputDeviceContext::GetExtDevCaps(LPVOID pCaps, DWORD dwSize)
  141. {
  142.     static const WAVEOUTEXTCAPS wec =
  143.     {
  144.         0x0000FFFF,                         // max number of hw-mixed streams
  145.         0x0000FFFF,                         // available HW streams
  146.         0,                                  // preferred sample rate for software mixer (0 indicates no preference)
  147.         0,                                  // preferred buffer size for software mixer (0 indicates no preference)
  148.         0,                                  // preferred number of buffers for software mixer (0 indicates no preference)
  149.         8000,                               // minimum sample rate for a hw-mixed stream
  150.         48000                               // maximum sample rate for a hw-mixed stream
  151.     };
  152.     memcpy( pCaps, &wec, min(dwSize,sizeof(wec)));
  153.     return MMSYSERR_NOERROR;
  154. }
  155. DWORD InputDeviceContext::GetExtDevCaps(LPVOID pCaps, DWORD dwSize)
  156. {
  157.     return MMSYSERR_NOTSUPPORTED;
  158. }
  159. StreamContext *InputDeviceContext::CreateStream(LPWAVEOPENDESC lpWOD)
  160. {
  161.     return new InputStreamContext;
  162. }
  163. StreamContext *OutputDeviceContext::CreateStream(LPWAVEOPENDESC lpWOD)
  164. {
  165.     LPWAVEFORMATEX lpFormat=lpWOD->lpFormat;
  166.     if (lpWOD->lpFormat->wFormatTag == WAVE_FORMAT_MIDI)
  167.     {
  168.         return new CMidiStream;
  169.     }
  170.     if (lpFormat->nChannels==1)
  171.     {
  172.         if (lpFormat->wBitsPerSample==8)
  173.         {
  174.             return new OutputStreamContextM8;
  175.         }
  176.         else
  177.         {
  178.             return new OutputStreamContextM16;
  179.         }
  180.     }
  181.     else
  182.     {
  183.         if (lpFormat->wBitsPerSample==8)
  184.         {
  185.             return new OutputStreamContextS8;
  186.         }
  187.         else
  188.         {
  189.             return new OutputStreamContextS16;
  190.         }
  191.     }
  192. }
  193. DWORD DeviceContext::OpenStream(LPWAVEOPENDESC lpWOD, DWORD dwFlags, StreamContext **ppStreamContext)
  194. {
  195.     HRESULT Result;
  196.     StreamContext *pStreamContext;
  197.     if (lpWOD->lpFormat==NULL)
  198.     {
  199.         return WAVERR_BADFORMAT;
  200.     }
  201.     if (!IsSupportedFormat(lpWOD->lpFormat))
  202.     {
  203.         return WAVERR_BADFORMAT;
  204.     }
  205.     // Query format support only - don't actually open device?
  206.     if (dwFlags & WAVE_FORMAT_QUERY)
  207.     {
  208.         return MMSYSERR_NOERROR;
  209.     }
  210.     pStreamContext = CreateStream(lpWOD);
  211.     if (!pStreamContext)
  212.     {
  213.         return MMSYSERR_NOMEM;
  214.     }
  215.     Result = pStreamContext->Open(this,lpWOD,dwFlags);
  216.     if (FAILED(Result))
  217.     {
  218.         delete pStreamContext;
  219.         return MMSYSERR_ERROR;
  220.     }
  221.     *ppStreamContext=pStreamContext;
  222.     return MMSYSERR_NOERROR;
  223. }