ReactOS  0.4.14-dev-854-gb9426a3
minwave.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2006-2008 dogbert <dogber1@gmail.com>
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include "minwave.hpp"
29 #include "minwavetables.hpp"
30 #include "ntddk.h"
31 
32 #ifdef _MSC_VER
33 #pragma code_seg("PAGE")
34 #endif
35 
37 {
38  PAGED_CODE();
39  ASSERT(Unknown);
40 #ifdef WAVERT
41  STD_CREATE_BODY_(CMiniportWaveCMI,Unknown,UnknownOuter,PoolType,PMINIPORTWAVERT);
42 #else
43  STD_CREATE_BODY_(CMiniportWaveCMI,Unknown,UnknownOuter,PoolType,PMINIPORTWAVECYCLIC);
44 #endif
45 }
46 
48 {
49  PAGED_CODE();
50  ASSERT (resourceList);
51  DBGPRINT(("CMiniportWaveCMI[%p]::ProcessResources(%p)", this, resourceList));
52 
53  if (resourceList->NumberOfInterrupts() < 1) {
54  DBGPRINT(("Unknown configuration for wave miniport"));
56  }
57  return STATUS_SUCCESS;
58 }
59 
60 #ifndef WAVERT
62 {
63  PAGED_CODE();
64  ASSERT(dmaChannel);
65  DBGPRINT(("CMiniportWaveCMI[%p]::newDMAChannel(%p)", this, dmaChannel));
66 
67  NTSTATUS ntStatus;
68 
69  ntStatus = Port->NewMasterDmaChannel(dmaChannel, NULL, NULL, bufferLength, TRUE, FALSE, (DMA_WIDTH)(-1), (DMA_SPEED)(-1));
70  if (NT_SUCCESS(ntStatus)) {
71  ULONG lDMABufferLength = bufferLength;
72  do {
73  ntStatus = (*dmaChannel)->AllocateBuffer(lDMABufferLength, NULL);
74  lDMABufferLength >>= 1;
75  } while (!NT_SUCCESS(ntStatus) && (lDMABufferLength > (PAGE_SIZE / 2)));
76  }
77  return ntStatus;
78 }
79 #endif
80 
81 //generic crap
82 STDMETHODIMP CMiniportWaveCMI::NonDelegatingQueryInterface(REFIID Interface, PVOID *Object)
83 {
84  PAGED_CODE();
85  ASSERT(Object);
86  DBGPRINT(("CMiniportWaveCMI[%p]::NonDelegatingQueryInterface"));
87 
89 #ifdef WAVERT
91 #else
93 #endif
94  } else if (IsEqualGUIDAligned(Interface,IID_IMiniport)) {
95  *Object = PVOID(PMINIPORT(this));
96 #ifdef WAVERT
97  } else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveRT)) {
98  *Object = PVOID(PMINIPORTWAVERT(this));
99 #else
100  } else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveCyclic)) {
101  *Object = PVOID(PMINIPORTWAVECYCLIC(this));
102 #endif
103  } else {
104  *Object = NULL;
105  }
106 
107  if (*Object) {
108  // We reference the interface for the caller.
109  PUNKNOWN(*Object)->AddRef();
110  return STATUS_SUCCESS;
111  }
112 
114 }
115 
117 {
118  PAGED_CODE();
119  DBGPRINT(("CMiniportWaveCMI[%p]::~CMiniportWaveCMI", this));
120 
121  storeChannelConfigToRegistry(); //or not. during system shutdown, this doesn't seem to work.
122 
123  if (CMIAdapter) {
124  CMIAdapter->Release();
125  CMIAdapter = NULL;
126  }
127 
128  for (int i=0;i<3;i++) {
129 #ifndef WAVERT
130  if (DMAChannel[i]) {
131  DMAChannel[i]->Release();
132  DMAChannel[i] = NULL;
133  }
134 #endif
135  if (isStreamRunning[i]) {
136  isStreamRunning[i] = false;
137  stream[i]->Release();
138  stream[i] = NULL;
139  }
140  }
141 
142  if (Port) {
143  Port->Release();
144  Port = NULL;
145  }
146 }
147 
148 #ifdef WAVERT
150 #else
152 #endif
153 {
154  PAGED_CODE();
155 
156  ASSERT(UnknownAdapter);
158  ASSERT(Port_);
159 
160  DBGPRINT(("CMiniportWaveCMI[%p]::Init(%p, %p, %p)", this, UnknownAdapter, ResourceList, Port_));
161 
162  Port = Port_;
163  Port->AddRef();
164 
165  NTSTATUS ntStatus = UnknownAdapter->QueryInterface(IID_ICMIAdapter, (PVOID *) &CMIAdapter);
166  if (!NT_SUCCESS(ntStatus)) {
167  DBGPRINT(("QueryInterface(CMIAdapter) failed"));
168  return ntStatus;
169  }
170 
171  //check for Vista, set the AC3 stuff accordingly
172  if (IoIsWdmVersionAvailable(0x06,0x00)) {
177  }
178 
179  cm = CMIAdapter->getCMI8738Info();
180  cm->regFUNCTRL0 = 0;
181  cm->WaveMiniport = this;
182 
183  loadChannelConfigFromRegistry();
184 
185  for (int i=0;i<3;i++)
186  {
187  isStreamRunning[i] = false;
188 
189 #ifndef WAVERT
190  ntStatus = newDMAChannel(&DMAChannel[i], MAXLEN_DMA_BUFFER);
191  if (!NT_SUCCESS(ntStatus)) {
192  DBGPRINT(("NewDmaChannel() failed"));
193  return ntStatus;
194  }
195 #endif
196  }
197 
199 
200  return processResources(ResourceList);
201 }
202 
203 #ifdef WAVERT
204 STDMETHODIMP_(NTSTATUS) CMiniportWaveCMI::GetDeviceDescription(PDEVICE_DESCRIPTION OutDeviceDescriptor)
205 {
206  PAGED_CODE();
207  ASSERT(OutDeviceDescriptor);
208  DBGPRINT(("CMiniportWaveCMI[%p]::GetDeviceDescription(%p)", this, OutDeviceDescriptor));
209 
210  RtlZeroMemory(OutDeviceDescriptor, sizeof(DEVICE_DESCRIPTION));
211  OutDeviceDescriptor->ScatterGather = false;
212  OutDeviceDescriptor->Master = true;
213  OutDeviceDescriptor->Dma32BitAddresses = true;
214  OutDeviceDescriptor->InterfaceType = PCIBus;
215  OutDeviceDescriptor->MaximumLength = MAXLEN_DMA_BUFFER-2;
216 
217  return STATUS_SUCCESS;
218 }
219 #endif
220 
221 STDMETHODIMP CMiniportWaveCMI::GetDescription(PPCFILTER_DESCRIPTOR *OutFilterDescriptor)
222 {
223  PAGED_CODE();
224  ASSERT(OutFilterDescriptor);
225  DBGPRINT(("CMiniportWaveCMI[%p]::GetDescription(%p)", this, OutFilterDescriptor));
226 
227  *OutFilterDescriptor = &WaveMiniportFilterDescriptor;
228 
229  return STATUS_SUCCESS;
230 }
231 
233 {
234  PAGED_CODE();
235  PREGISTRYKEY DriverKey;
236  PREGISTRYKEY SettingsKey;
239  PVOID KeyInfo;
240 
241  DBGPRINT(("CMiniportWaveCMI::loadChannelConfigFromRegistry()"));
242 
243  if ((!CMIAdapter) || (!(CMIAdapter->getDeviceObject()))) {
244  return STATUS_UNSUCCESSFUL;
245  }
246 
247  NTSTATUS ntStatus = PcNewRegistryKey(&DriverKey, NULL, DriverRegistryKey, KEY_ALL_ACCESS, CMIAdapter->getDeviceObject(), NULL, NULL, 0, NULL);
248 
249  if(!NT_SUCCESS(ntStatus)) {
250  DBGPRINT(("PcNewRegistryKey() failed"));
251  return STATUS_UNSUCCESSFUL;
252  }
253 
254  RtlInitUnicodeString(&KeyName, L"Settings");
255 
256  ntStatus = DriverKey->NewSubKey(&SettingsKey, NULL, KEY_ALL_ACCESS, &KeyName, REG_OPTION_NON_VOLATILE, NULL);
257  if(!NT_SUCCESS(ntStatus)) {
258  DBGPRINT(("DriverKey->NewSubKey() failed"));
259  return STATUS_UNSUCCESSFUL;
260  }
261 
262  KeyInfo = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), 'gnaa');
263  if (KeyInfo) {
264  RtlInitUnicodeString(&KeyName, L"ChannelCount");
265  ntStatus = SettingsKey->QueryValueKey(&KeyName, KeyValuePartialInformation, KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), &ResultLength);
266  if (NT_SUCCESS (ntStatus)) {
268  if (PartialInfo->DataLength == sizeof(DWORD)) {
269  requestedChannelCount = (*(PLONG)PartialInfo->Data);
270  }
271  } else {
273  }
274 
275  RtlInitUnicodeString(&KeyName, L"ChannelMask");
276  ntStatus = SettingsKey->QueryValueKey(&KeyName, KeyValuePartialInformation, KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), &ResultLength);
277  if (NT_SUCCESS (ntStatus)) {
279  if (PartialInfo->DataLength == sizeof(DWORD)) {
280  requestedChannelMask = (*(PLONG)PartialInfo->Data);
281  }
282  } else {
284  }
285  }
286  ExFreePoolWithTag(KeyInfo,'gnaa');
287 
288  SettingsKey->Release();
289  DriverKey->Release();
290 
291  return STATUS_SUCCESS;
292 }
293 
295 {
296  PAGED_CODE();
297  PREGISTRYKEY DriverKey;
298  PREGISTRYKEY SettingsKey;
300  DWORD Value;
301  DBGPRINT(("CMiniportWaveCMI::storeChannelConfigToRegistry()"));
302 
303  if ((!CMIAdapter) || (!(CMIAdapter->getDeviceObject()))) {
304  return STATUS_UNSUCCESSFUL;
305  }
306 
307  NTSTATUS ntStatus = PcNewRegistryKey(&DriverKey, NULL, DriverRegistryKey, KEY_ALL_ACCESS, CMIAdapter->getDeviceObject(), NULL, NULL, 0, NULL);
308 
309  if(!NT_SUCCESS(ntStatus)) {
310  DBGPRINT(("PcNewRegistryKey() failed"));
311  return STATUS_UNSUCCESSFUL;
312  }
313 
314  RtlInitUnicodeString(&KeyName, L"Settings");
315 
316  ntStatus = DriverKey->NewSubKey(&SettingsKey, NULL, KEY_ALL_ACCESS, &KeyName, REG_OPTION_NON_VOLATILE, NULL);
317  if(!NT_SUCCESS(ntStatus)) {
318  DBGPRINT(("DriverKey->NewSubKey() failed"));
319  return STATUS_UNSUCCESSFUL;
320  }
321 
323  RtlInitUnicodeString(&KeyName, L"ChannelCount");
324  ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
325  if (!NT_SUCCESS(ntStatus)) {
326  DBGPRINT(("SetValueKey() failed"));
327  }
329  RtlInitUnicodeString(&KeyName, L"ChannelMask");
330  ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
331  if (!NT_SUCCESS(ntStatus)) {
332  DBGPRINT(("SetValueKey() failed"));
333  }
334 
335  SettingsKey->Release();
336  DriverKey->Release();
337 
338  return STATUS_SUCCESS;
339 }
340 
341 
342 STDMETHODIMP_(void) CMiniportWaveCMI::powerUp(void)
343 {
344  PAGED_CODE();
345  DBGPRINT(("CMiniportWaveCMI[%p]::powerUp()", this));
346  KSSTATE oldState[3];
347 
348  for (int i=0;i<3;i++) {
349  if (isStreamRunning[i]) {
350  oldState[i] = stream[i]->state;
351  stream[i]->SetState(KSSTATE_STOP);
352  }
353  }
354 
355  if (cm->TopoMiniport) {
356  cm->TopoMiniport->loadMixerSettingsFromMemory();
357  }
358 
359  for (int i=0;i<3;i++) {
360  if (isStreamRunning[i]) {
361  stream[i]->prepareStream();
362  stream[i]->SetState(KSSTATE_ACQUIRE);
363  stream[i]->SetState(oldState[i]);
364  }
365  }
366 }
367 
368 STDMETHODIMP_(void) CMiniportWaveCMI::powerDown(void)
369 {
370  PAGED_CODE();
371  DBGPRINT(("CMiniportWaveCMI[%p]::powerDown()", this));
372 
373  if (cm->TopoMiniport) {
374  cm->TopoMiniport->storeMixerSettingsToMemory();
375  }
376 
377 }
378 
379 
381 {
382  PAGED_CODE();
383  ASSERT(sampleRate);
384  DBGPRINT(("CMiniportWaveCMI[%p]::isFormatAllowed(%d, %d, %d)", this, sampleRate, multiChan, AC3));
385 
386  if (multiChan) {
387  switch (sampleRate) {
388  case 44100: if (cm->formatMask & FMT_441_MULTI_PCM) return STATUS_SUCCESS; break;
389  case 48000: if (cm->formatMask & FMT_480_MULTI_PCM) return STATUS_SUCCESS; break;
390  case 88200: if (cm->formatMask & FMT_882_MULTI_PCM) return STATUS_SUCCESS; break;
391  case 96000: if (cm->formatMask & FMT_960_MULTI_PCM) return STATUS_SUCCESS; break;
392  }
394  }
395  if (AC3) {
396  switch (sampleRate) {
397  case 44100: if (cm->formatMask & FMT_441_DOLBY) return STATUS_SUCCESS; break;
398  case 48000: if (cm->formatMask & FMT_480_DOLBY) return STATUS_SUCCESS; break;
399  case 88200: if (cm->formatMask & FMT_882_DOLBY) return STATUS_SUCCESS; break;
400  case 96000: if (cm->formatMask & FMT_960_DOLBY) return STATUS_SUCCESS; break;
401  }
403  }
404  switch (sampleRate) {
405  case 44100: if (cm->formatMask & FMT_441_PCM) return STATUS_SUCCESS; break;
406  case 48000: if (cm->formatMask & FMT_480_PCM) return STATUS_SUCCESS; break;
407  case 88200: if (cm->formatMask & FMT_882_PCM) return STATUS_SUCCESS; break;
408  case 96000: if (cm->formatMask & FMT_960_PCM) return STATUS_SUCCESS; break;
409  }
411 }
412 
414 {
415  PAGED_CODE();
416  ASSERT(format);
417  DBGPRINT(("CMiniportWaveCMI[%p]::validateFormat(%p, %d, %d)", this, format, PinID, capture));
418 
419  PWAVEFORMATEX waveFormat = PWAVEFORMATEX(format + 1);
420  DBGPRINT(("---channels: %d, resolution: %d, sample rate: %d, pin: %d, formatMask: %x", waveFormat->nChannels, waveFormat->wBitsPerSample, waveFormat->nSamplesPerSec, PinID, cm->formatMask));
421 
422 //WaveFormatEx
423  if ( ( format->FormatSize >= sizeof(KSDATAFORMAT_WAVEFORMATEX))
426  switch (EXTRACT_WAVEFORMATEX_ID(&format->SubFormat)) {
427  case WAVE_FORMAT_PCM:
428  if ((PinID != PIN_WAVE_RENDER_SINK) && (PinID != PIN_WAVE_CAPTURE_SOURCE) && (PinID != ((ULONG)-1))) {
429  if ((PinID == PIN_WAVE_AC3_RENDER_SINK) && !IoIsWdmVersionAvailable(6,0)) {
431  }
432  }
433 
434  if ( ((waveFormat->wBitsPerSample == 16) || (waveFormat->wBitsPerSample == 32))
435  && ((waveFormat->nSamplesPerSec == 44100) || (waveFormat->nSamplesPerSec == 48000) || (waveFormat->nSamplesPerSec == 88200) || (waveFormat->nSamplesPerSec == 96000))
436  && (waveFormat->nChannels == 2) ) {
437  if ((capture) && (waveFormat->nSamplesPerSec > 48000) ) {
439  }
440  return isFormatAllowed(waveFormat->nSamplesPerSec, FALSE, FALSE);
441  }
442  if ( (waveFormat->wBitsPerSample == 16)
443  && ((waveFormat->nChannels >= 4) && (waveFormat->nChannels <= cm->maxChannels))
444  && ((waveFormat->nSamplesPerSec == 44100) || (waveFormat->nSamplesPerSec == 48000)) ) {
445 #if OUT_CHANNEL == 1
446  if ((PinID == PIN_WAVE_RENDER_SINK) || (PinID == ((ULONG)-1))) {
447  return isFormatAllowed(waveFormat->nSamplesPerSec, TRUE, FALSE);
448  }
449 #else
451 #endif
452  }
453  break;
455  if ((PinID != PIN_WAVE_AC3_RENDER_SINK) && (PinID != ((ULONG)-1))) {
457  }
458  if ( ((waveFormat->wBitsPerSample >= MIN_BITS_PER_SAMPLE_AC3) && (waveFormat->wBitsPerSample <= MAX_BITS_PER_SAMPLE_AC3))
459  && ((waveFormat->nSamplesPerSec >= MIN_SAMPLE_RATE_AC3) && (waveFormat->nSamplesPerSec <= MAX_SAMPLE_RATE_AC3))
460  && (waveFormat->nChannels == MAX_CHANNELS_AC3) ) {
461  return isFormatAllowed(waveFormat->nSamplesPerSec, FALSE, TRUE);
462  }
463  break;
465  if ((PinID != PIN_WAVE_AC3_RENDER_SINK) && (PinID != ((ULONG)-1))) {
467  }
468  if ( ((waveFormat->wBitsPerSample >= MIN_BITS_PER_SAMPLE_WMA) && (waveFormat->wBitsPerSample <= MAX_BITS_PER_SAMPLE_WMA))
469  && ((waveFormat->nSamplesPerSec >= MIN_SAMPLE_RATE_WMA) && (waveFormat->nSamplesPerSec <= MAX_SAMPLE_RATE_WMA))
470  && (waveFormat->nChannels == MAX_CHANNELS_WMA) ) {
471  return isFormatAllowed(waveFormat->nSamplesPerSec, FALSE, TRUE);
472  }
473  break;
474  }
475  }
476 
478 }
479 
480 // Tests a data range intersection
481 STDMETHODIMP CMiniportWaveCMI::DataRangeIntersection(ULONG PinId, PKSDATARANGE ClientDataRange, PKSDATARANGE MyDataRange, ULONG OutputBufferLength, PVOID ResultantFormat, PULONG ResultantFormatLength)
482 {
483  PAGED_CODE();
484  DBGPRINT(("CMiniportWaveCMI[%p]::DataRangeIntersection(%d, %p, %p, %d, %p, %p)", this, PinId, ClientDataRange, MyDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength));
485 
486  if (PinId == PIN_WAVE_AC3_RENDER_SINK) {
487  bool isAC3Pin = true;
488  // Under Windows 2000 and XP, the client's DataRange should be AC3 only.
489  // The AC3 pin is the SPDIF pin in Windows Vista, so 2ch stereo is going to be allowed.
490 
493  return STATUS_NO_MATCH;
494  }
495 
496 
500  // check for Vista
501  isAC3Pin = false;
502  if (IoIsWdmVersionAvailable(0x06,0x00)) {
505  return STATUS_NO_MATCH;
506  }
507  } else {
508  return STATUS_NO_MATCH;
509  }
510  }
511 
514  *ResultantFormatLength = sizeof(KSDATAFORMAT_WAVEFORMATEX);
515  } else
517  *ResultantFormatLength = sizeof(KSDATAFORMAT_DSOUND);
518  } else {
519  return STATUS_NO_MATCH;
520  }
521 
522  // Validate return buffer size, if the request is only for the
523  // size of the resultant structure, return it now.
524  if (!OutputBufferLength) {
525  *ResultantFormatLength = sizeof(KSDATAFORMAT_WAVEFORMATEX);
526  return STATUS_BUFFER_OVERFLOW;
527  } else
530  }
531 
532  PKSDATAFORMAT_WAVEFORMATEX resultantFormatWFX = (PKSDATAFORMAT_WAVEFORMATEX) ResultantFormat;
533  PWAVEFORMATEX pWaveFormatEx;
534 
535  // Return the best (only) available format.
536  resultantFormatWFX->DataFormat.FormatSize = *ResultantFormatLength;
537  resultantFormatWFX->DataFormat.Flags = 0;
538  resultantFormatWFX->DataFormat.SampleSize = 4; // must match nBlockAlign
539  resultantFormatWFX->DataFormat.Reserved = 0;
540 
541  resultantFormatWFX->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
543 
544  // Extra space for the DSound specifier
546 
547  PKSDATAFORMAT_DSOUND resultantFormatDSound = (PKSDATAFORMAT_DSOUND)ResultantFormat;
548 
549  resultantFormatDSound->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_DSOUND;
550 
551  // DSound format capabilities are not expressed
552  // this way in KS, so we express no capabilities.
553  resultantFormatDSound->BufferDesc.Flags = 0 ;
554  resultantFormatDSound->BufferDesc.Control = 0 ;
555 
556  pWaveFormatEx = &resultantFormatDSound->BufferDesc.WaveFormatEx;
557  } else {
558  // WAVEFORMATEX or WILDCARD (WAVEFORMATEX)
560 
561  pWaveFormatEx = (PWAVEFORMATEX)((PKSDATAFORMAT)resultantFormatWFX + 1);
562  }
563 
564  pWaveFormatEx->nChannels = 2;
565  pWaveFormatEx->wBitsPerSample = 16; // SPDIF
566  pWaveFormatEx->cbSize = 0;
567  if (isAC3Pin) {
569  pWaveFormatEx->wFormatTag = WAVE_FORMAT_WMA_SPDIF;
570  pWaveFormatEx->nSamplesPerSec = min( ((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumSampleFrequency, MAX_SAMPLE_RATE_WMA);
571  } else {
572  pWaveFormatEx->wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
573  pWaveFormatEx->nSamplesPerSec = 48000;
574  }
575  } else {
576  pWaveFormatEx->wFormatTag = WAVE_FORMAT_PCM;
577  pWaveFormatEx->nSamplesPerSec = min( ((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumSampleFrequency, MAX_SAMPLE_RATE);
578  }
579  pWaveFormatEx->nBlockAlign = pWaveFormatEx->nChannels * pWaveFormatEx->wBitsPerSample / 8;
580  pWaveFormatEx->nAvgBytesPerSec = pWaveFormatEx->nSamplesPerSec * pWaveFormatEx->nBlockAlign;
581 
582  return STATUS_SUCCESS;
583  }
584  if ((PinId == PIN_WAVE_RENDER_SINK) || (PinId == PIN_WAVE_CAPTURE_SINK)) {
585 
586  if (!IsEqualGUIDAligned(ClientDataRange->SubFormat, KSDATAFORMAT_SUBTYPE_PCM) &&
588  return STATUS_NO_MATCH;
589  }
590 
591  if (!IsEqualGUIDAligned(ClientDataRange->MajorFormat, KSDATAFORMAT_TYPE_AUDIO) &&
593  return STATUS_NO_MATCH;
594  }
595 
598  *ResultantFormatLength = sizeof(KSDATAFORMAT_WAVEFORMATEX);
599  } else
601  *ResultantFormatLength = sizeof(KSDATAFORMAT_DSOUND);
602  } else {
603  return STATUS_NO_MATCH;
604  }
605 
606 
607  ULONG sampleRate = 0;
608  ULONG nMaxChannels = min(((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumChannels, requestedChannelCount);
609 
610  // check for Vista
611  if (IoIsWdmVersionAvailable(6,0) && (PinId == PIN_WAVE_RENDER_SINK)) {
612  nMaxChannels = ((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumChannels;
613  }
614  if (nMaxChannels & 0x01) {
615  nMaxChannels--;
616  }
617  if (!nMaxChannels) {
618  return STATUS_NO_MATCH;
619  }
620 
622  sampleRate = stream[PCM_OUT_STREAM]->currentSampleRate;
623  } else
625  sampleRate = stream[PCM_IN_STREAM]->currentSampleRate;
626  }
627  if (sampleRate == 0) {
628  if ((nMaxChannels > 2) && (((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumSampleFrequency > MAX_SAMPLE_RATE_MULTI)) {
629  sampleRate = MAX_SAMPLE_RATE_MULTI;
630  } else
631  if ((nMaxChannels == 2) && (((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumSampleFrequency > MAX_SAMPLE_RATE)) {
632  sampleRate = MAX_SAMPLE_RATE;
633  } else {
634  sampleRate = ((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumSampleFrequency;
635  }
636  }
637 
638  if ((((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumSampleFrequency < sampleRate)
639  || (((PKSDATARANGE_AUDIO)ClientDataRange)->MinimumSampleFrequency > sampleRate)) {
640  return STATUS_NO_MATCH;
641  }
642 
643  if (PinId == PIN_WAVE_RENDER_SINK) {
644  if (!OutputBufferLength) {
645  *ResultantFormatLength = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX);
646  return STATUS_BUFFER_OVERFLOW;
647  } else
648  if (OutputBufferLength < sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX)) {
650  }
651 
652  if (((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumChannels < 2) {
653  DBGPRINT(("[[DataRangeIntersection] mono format not supported"));
654  return STATUS_NO_MATCH;
655  }
656 
657  PWAVEFORMATPCMEX WaveFormat = (PWAVEFORMATPCMEX)((PKSDATAFORMAT)ResultantFormat + 1);
658  if (IsEqualGUIDAligned(ClientDataRange->Specifier, KSDATAFORMAT_SPECIFIER_DSOUND)) {
659  return STATUS_NOT_SUPPORTED;
660  }
661  *(PKSDATAFORMAT)ResultantFormat = *MyDataRange;
662  ((PKSDATAFORMAT)ResultantFormat)->FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX);
663 
664 
666  WaveFormat->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
667  WaveFormat->Format.nChannels = (WORD)nMaxChannels;
668  WaveFormat->Format.wBitsPerSample = 16;
669  WaveFormat->Format.nBlockAlign = (WaveFormat->Format.wBitsPerSample >> 3) * WaveFormat->Format.nChannels;
670  WaveFormat->Format.nAvgBytesPerSec = WaveFormat->Format.nSamplesPerSec * WaveFormat->Format.nBlockAlign;
671  WaveFormat->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
672  WaveFormat->Format.nSamplesPerSec = sampleRate;
673  WaveFormat->Samples.wValidBitsPerSample = WaveFormat->Format.wBitsPerSample;
674  switch (nMaxChannels) {
675  case 8: WaveFormat->dwChannelMask = KSAUDIO_SPEAKER_7POINT1; break;
676  case 6: WaveFormat->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break;
677  case 4: WaveFormat->dwChannelMask = KSAUDIO_SPEAKER_QUAD; break;
678  case 2: WaveFormat->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break;
679  }
680  if (nMaxChannels == requestedChannelCount) {
681  WaveFormat->dwChannelMask = requestedChannelMask;
682  }
683  ((PKSDATAFORMAT)ResultantFormat)->SampleSize = WaveFormat->Format.nBlockAlign;
684 
685  *ResultantFormatLength = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX);
686  DBGPRINT(("[DataRangeIntersection] MultiChannel Renderer: SampleRate: %d, ClientDataRange->MaxChans: %d, Channels: %d, BitPerSample: %d, BlockAlign: %d, AvgBytesPerSec: %d, ChannelMask: %08X", WaveFormat->Format.nSamplesPerSec, ((PKSDATARANGE_AUDIO)ClientDataRange)->MaximumChannels, WaveFormat->Format.nChannels, WaveFormat->Format.wBitsPerSample, WaveFormat->Format.nBlockAlign, WaveFormat->Format.nAvgBytesPerSec, WaveFormat->dwChannelMask));
687  } else
688  if (PinId == PIN_WAVE_CAPTURE_SINK) {
689  PKSDATAFORMAT_WAVEFORMATEX resultantFormatWFX;
690  PWAVEFORMATEX pWaveFormatEx;
691 
692  if (!OutputBufferLength) {
693  *ResultantFormatLength = sizeof(KSDATAFORMAT_WAVEFORMATEX);
694  return STATUS_BUFFER_OVERFLOW;
695  } else
698  }
699 
700  if (nMaxChannels > 2) {
701  nMaxChannels = 2;
702  }
703 
704  resultantFormatWFX = (PKSDATAFORMAT_WAVEFORMATEX) ResultantFormat;
705  resultantFormatWFX->DataFormat.FormatSize = *ResultantFormatLength;
706  resultantFormatWFX->DataFormat.Flags = 0;
707  resultantFormatWFX->DataFormat.SampleSize = 4;
708  resultantFormatWFX->DataFormat.Reserved = 0;
709  resultantFormatWFX->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
711 
712  if (IsEqualGUIDAligned(ClientDataRange->Specifier, KSDATAFORMAT_SPECIFIER_DSOUND)) {
713  PKSDATAFORMAT_DSOUND resultantFormatDSound;
714  resultantFormatDSound = (PKSDATAFORMAT_DSOUND)ResultantFormat;
715  resultantFormatDSound->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_DSOUND;
716  resultantFormatDSound->BufferDesc.Flags = 0 ;
717  resultantFormatDSound->BufferDesc.Control = 0 ;
718  pWaveFormatEx = &resultantFormatDSound->BufferDesc.WaveFormatEx;
719  } else {
721  pWaveFormatEx = (PWAVEFORMATEX)((PKSDATAFORMAT)resultantFormatWFX + 1);
722  }
723  pWaveFormatEx->wFormatTag = WAVE_FORMAT_PCM;
724  pWaveFormatEx->nChannels = nMaxChannels;
725  pWaveFormatEx->nSamplesPerSec = sampleRate;
726  pWaveFormatEx->wBitsPerSample = 16;
727  pWaveFormatEx->cbSize = 0;
728  pWaveFormatEx->nBlockAlign = 4;
729  pWaveFormatEx->nAvgBytesPerSec = 192000;
730  }
731  return STATUS_SUCCESS;
732  }
733  return STATUS_NO_MATCH;
734 }
735 
736 //from IMiniportWaveCyclic::NewStream()
737 #ifdef WAVERT
738 STDMETHODIMP CMiniportWaveCMI::NewStream(PMINIPORTWAVERTSTREAM *OutStream, PPORTWAVERTSTREAM OuterUnknown, ULONG PinID, BOOLEAN Capture, PKSDATAFORMAT DataFormat)
739 #else
740 STDMETHODIMP CMiniportWaveCMI::NewStream(PMINIPORTWAVECYCLICSTREAM *OutStream, PUNKNOWN OuterUnknown, POOL_TYPE PoolType, ULONG PinID, BOOLEAN Capture, PKSDATAFORMAT DataFormat, PDMACHANNEL* OutDmaChannel, PSERVICEGROUP* OutServiceGroup)
741 #endif
742 {
743  PAGED_CODE();
744  ASSERT(OutStream);
746 #ifdef WAVERT
747  DBGPRINT(("CMiniportWaveCMI[%p]::NewStream(%p, %p, %d, %d, %p)", this, OutStream, OuterUnknown, PinID, Capture, DataFormat));
748 #else
749  ASSERT(OutDmaChannel);
750  ASSERT(OutServiceGroup);
751  DBGPRINT(("CMiniportWaveCMI[%p]::NewStream(%p, %p, %p, %d, %d, %p, %p, %p)", this, OutStream, OuterUnknown, PoolType, PinID, Capture, DataFormat, OutDmaChannel, OutServiceGroup));
752 #endif
753 
754  NTSTATUS ntStatus = STATUS_SUCCESS;
755  PWAVEFORMATEX waveFormat = PWAVEFORMATEX(DataFormat + 1);
756  UInt32 streamIndex = PCM_OUT_STREAM;
757 
758  ntStatus = validateFormat(DataFormat, PinID, Capture);
759  if (!NT_SUCCESS(ntStatus)) {
760  DBGPRINT(("invalid stream format"));
761  return STATUS_UNSUCCESSFUL;
762  }
763  if (cm->enableSPDIFInMonitor) {
764  CMIAdapter->setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
765  }
766 
767  if (Capture) {
768  streamIndex = PCM_IN_STREAM;
769  } else
771  streamIndex = AC3_OUT_STREAM;
772  }
773 
774  // make sure the hardware is not already in use
775  if (isStreamRunning[streamIndex]) {
776  DBGPRINT(("Stream %d running, exiting...", streamIndex));
777  return STATUS_UNSUCCESSFUL;
778  }
779  if ((streamIndex == AC3_OUT_STREAM) && isStreamRunning[PCM_OUT_STREAM]) {
780 #ifdef WAVERT
781  stream[PCM_OUT_STREAM]->SetState(KSSTATE_STOP);
782 #else
784 #endif
785  }
786  if ((streamIndex == PCM_OUT_STREAM) && isStreamRunning[AC3_OUT_STREAM]) {
787  return STATUS_UNSUCCESSFUL;
788  }
789 
790  DBGPRINT(("---StreamNo: %d, Bits: %d, Sample Rate: %d, Channels: %d, AC3: %d", streamIndex,
791  waveFormat->wBitsPerSample, waveFormat->nSamplesPerSec, waveFormat->nChannels,
793 
794  // the DAC and ADC can only run at the same sample rate simultaneously
795  if ((streamIndex == PCM_IN_STREAM) && isStreamRunning[PCM_OUT_STREAM]) {
796  if (waveFormat->nSamplesPerSec != stream[PCM_OUT_STREAM]->currentSampleRate) {
797  return STATUS_UNSUCCESSFUL;
798  }
799  }
800  if ((streamIndex == PCM_OUT_STREAM) && isStreamRunning[PCM_IN_STREAM]) {
801  if (waveFormat->nSamplesPerSec != stream[PCM_IN_STREAM]->currentSampleRate) {
802  return STATUS_UNSUCCESSFUL;
803  }
804  }
805 
806  // instantiate a stream
807 #ifdef WAVERT
808  ntStatus = CreateMiniportWaveStreamCMI(&stream[streamIndex], OuterUnknown, NonPagedPool);
809 #else
810  ntStatus = CreateMiniportWaveStreamCMI(&stream[streamIndex], OuterUnknown, PoolType);
811 #endif
812  if (!NT_SUCCESS (ntStatus)) {
813  DBGPRINT(("Failed to create stream"));
814  return ntStatus;
815  }
816 
817  // initialize it
818 #ifdef WAVERT
819  ntStatus = stream[streamIndex]->Init(this, streamIndex, Capture, DataFormat, OuterUnknown);
820 #else
821  ntStatus = stream[streamIndex]->Init(this, streamIndex, Capture, DataFormat, DMAChannel[streamIndex], OutServiceGroup);
822 #endif
823  if (!NT_SUCCESS(ntStatus)) {
824  DBGPRINT(("Failed to init stream"));
825  stream[streamIndex]->Release();
826  stream[streamIndex] = NULL;
827  *OutStream = NULL;
828 #ifndef WAVERT
829  *OutServiceGroup = NULL;
830  *OutDmaChannel = NULL;
831 #endif
832  return ntStatus;
833  }
834 
835 #ifdef WAVERT
836 //this has been referenced in CreateMiniportWaveStreamCMI() already
837  *OutStream = (PMINIPORTWAVERTSTREAM)stream[streamIndex];
838 #else
839  *OutDmaChannel = DMAChannel[streamIndex];
840  DMAChannel[streamIndex]->AddRef();
841  *OutStream = (PMINIPORTWAVECYCLICSTREAM)stream[streamIndex];
842 #endif
843 
844  return ntStatus;
845 }
846 
848 {
849  PAGED_CODE();
850  ASSERT(PropertyRequest);
851  DBGPRINT(("[PropertyHandler_ChannelConfig]"));
852 
853 #ifdef WAVERT
854  CMiniportWaveCMI *that = (CMiniportWaveCMI *) ((PMINIPORTWAVERT)PropertyRequest->MajorTarget);
855 #else
856  CMiniportWaveCMI *that = (CMiniportWaveCMI *) ((PMINIPORTWAVECYCLIC)PropertyRequest->MajorTarget);
857 #endif
858 
859  if (PropertyRequest->Node == KSNODE_WAVE_DAC) {
860 
861  if (PropertyRequest->ValueSize == 0) {
862  PropertyRequest->ValueSize = sizeof(LONG);
863  return STATUS_BUFFER_OVERFLOW;
864  } else if (PropertyRequest->ValueSize < sizeof (LONG)) {
865  PropertyRequest->ValueSize = 0;
867  }
868 
869  if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
870  *(PLONG)PropertyRequest->Value = that->requestedChannelMask;
871  PropertyRequest->ValueSize = sizeof(ULONG);
872  return STATUS_SUCCESS;
873  } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
874  if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_7POINT1) {
875  that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
876  that->requestedChannelCount = 8;
877  return STATUS_SUCCESS;
878  }
879  if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_5POINT1) {
880  that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
881  that->requestedChannelCount = 6;
882  return STATUS_SUCCESS;
883  }
884  if ((*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_QUAD) || (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_SURROUND)) {
885  that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
886  that->requestedChannelCount = 4;
887  return STATUS_SUCCESS;
888  }
889  if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_STEREO) {
890  that->requestedChannelMask = *(PLONG)PropertyRequest->Value;
891  that->requestedChannelCount = 2;
892  return STATUS_SUCCESS;
893  }
894  } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
895  PULONG AccessFlags = PULONG(PropertyRequest->Value);
897  PropertyRequest->ValueSize = sizeof(ULONG);
898  return STATUS_SUCCESS;
899  }
900  }
902 }
903 
905 
907 {
908  PAGED_CODE();
909  DBGPRINT(("CreateMiniportWaveStreamCMI"));
910 
911 #ifdef WAVERT
912  *MiniportWaveStreamCMI = new (PoolType, 'gnaa') CMiniportWaveStreamCMI(NULL);
913 #else
914  *MiniportWaveStreamCMI = new (PoolType, 'gnaa') CMiniportWaveStreamCMI(pUnknownOuter);
915 #endif
916  if (*MiniportWaveStreamCMI) {
917  (*MiniportWaveStreamCMI)->AddRef();
918  return STATUS_SUCCESS;
919  }
920 
922 }
923 
925 {
926  PAGED_CODE();
927  DBGPRINT(("CMiniportWaveStreamCMI[%p]::prepareStream()", this));
928  DBGPRINT(("---streamIndex: %d, channelNumber: %d", streamIndex, channelNumber));
929 
930  NTSTATUS ntStatus;
931  UInt32 val;
932 
933  if (state == KSSTATE_RUN) {
935  }
936 
937  if (!(Miniport->cm)) {
938  DBGPRINT(("Miniport not set"));
940  }
941 
942  enableSPDIF = ((currentSampleRate == 44100 || currentSampleRate == 48000 || currentSampleRate == 88200 || currentSampleRate == 96000) &&
943  ((currentResolution == 16) || (currentResolution == 32)) && (currentChannelCount == 2)) &&
945 
946  if (!isCaptureStream) {
947  ntStatus = setupSPDIFPlayback(enableSPDIF);
948  if (!NT_SUCCESS(ntStatus)) {
949  return ntStatus;
950  }
951  ntStatus = setDACChannels();
952  if (!NT_SUCCESS(ntStatus)) {
953  return ntStatus;
954  }
955  }
956 
958 
960  if (isCaptureStream) {
961  Miniport->cm->regFUNCTRL0 |= val; // 1->Recording
962  } else {
963  Miniport->cm->regFUNCTRL0 &= ~val; // 0->Playback
964  }
966 
967  //set sampling frequency
968  val = Miniport->CMIAdapter->readUInt32(REG_FUNCTRL1);
969  if ((currentSampleRate == 88200) || (currentSampleRate == 44100)) {
970  if (channelNumber) {
971  val &= ~SFC_CH1_MASK;
972  val |= SFC_44K_CH1;
973  } else {
974  val &= ~SFC_CH0_MASK;
975  val |= SFC_44K_CH0;
976  }
977  } else if ((currentSampleRate == 96000) || (currentSampleRate == 48000)) {
978  if (channelNumber) {
979  val &= ~SFC_CH1_MASK;
980  val |= SFC_48K_CH1;
981  } else {
982  val &= ~SFC_CH0_MASK;
983  val |= SFC_48K_CH0;
984  }
985  } else {
988  }
989  Miniport->CMIAdapter->writeUInt32(REG_FUNCTRL1, val);
990 
991  //set resolution
992  val = Miniport->CMIAdapter->readUInt32(REG_CHFORMAT);
993  if (channelNumber) {
994  val |= FORMAT_CH1;
995  } else {
996  val |= FORMAT_CH0;
997  }
998  Miniport->CMIAdapter->writeUInt32(REG_CHFORMAT, val);
999 
1000  KeReleaseMutex(&Miniport->mutex, false);
1001 
1002  return STATUS_SUCCESS;
1003 }
1004 
1006 {
1007  PAGED_CODE();
1008  DBGPRINT(("CMiniportWaveStreamCMI[%p]::setDACChannels()", this));
1009  NTSTATUS ntStatus = STATUS_SUCCESS;
1010 
1011  if (currentChannelCount > 2) {
1014  }
1015  if ((currentResolution != 16) || (currentChannelCount < 2)) {
1017  }
1018 #if OUT_CHANNEL == 0
1020 #endif
1022  Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, DWORD_MAPPING);
1023  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, XCHG_DAC);
1024 
1025  switch (currentChannelCount) {
1026  case 4:
1027  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_4CH_CH1);
1028  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_5CH_CH1);
1029  Miniport->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_6CH_CH1);
1030  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_CENTER);
1031  break;
1032  case 6:
1033  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_4CH_CH1);
1034  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_5CH_CH1);
1035  Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_6CH_CH1);
1036  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_CENTER);
1037  break;
1038  case 8:
1039  if (Miniport->cm->chipVersion == 68) {
1040  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_4CH_CH1);
1041  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_5CH_CH1);
1042  Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_6CH_CH1);
1043  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_CENTER);
1044  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL2, EN_8CH_CH1);
1045  break;
1046  } else {
1047  ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1048  }
1049  default:
1050  ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1051  }
1053  } else {
1054  if (Miniport->cm->canMultiChannel) {
1056  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_5CH_CH1 | EN_4CH_CH1);
1057  Miniport->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_6CH_CH1 | DWORD_MAPPING);
1058  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_CENTER);
1059  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, XCHG_DAC);
1060  if (Miniport->cm->chipVersion == 68) {
1061  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL2, EN_8CH_CH1);
1062  }
1064  }
1065  }
1066  return ntStatus;
1067 }
1068 
1070 {
1071  PAGED_CODE();
1072  DBGPRINT(("CMiniportWaveStreamCMI[%p]::setupSPDIFPlayback(%d)", this, enableSPDIF));
1073 
1075 
1076  if (enableSPDIF) {
1077  Miniport->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_SPDIF_OUT);
1078  Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDO2DAC);
1079 #if OUT_CHANNEL == 0
1080  Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDF_0);
1081 #else
1082  Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDF_1);
1083 #endif
1084  setupAC3Passthru();
1085 
1086  if ( (currentSampleRate == 48000) || (currentSampleRate == 96000) ) {
1087  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDIF_48);
1088  } else {
1089  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDIF_48);
1090  }
1091 
1092  if (currentSampleRate == 96000) {
1093 #if OUT_CHANNEL == 0
1094  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH0);
1095 #else
1096  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH1);
1097 #endif
1098  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, DBLSPDS);
1099  } else if (currentSampleRate == 88200) {
1100 #if OUT_CHANNEL == 0
1101  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD88_CH0);
1102 #else
1103  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD88_CH1);
1104 #endif
1105  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, DBLSPDS);
1106  } else {
1107 #if OUT_CHANNEL == 0
1108  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH0 | SPD96_CH0);
1109 #else
1110  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH1 | SPD96_CH1);
1111 #endif
1112  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, DBLSPDS);
1113  }
1114 
1115  } else {
1116  Miniport->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_SPDIF_OUT);
1117  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDO2DAC);
1118 #if OUT_CHANNEL == 0
1119  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_0);
1120 #else
1121  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_1);
1122 #endif
1123 #if OUT_CHANNEL == 0
1124  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH0 | SPD96_CH0);
1125 #else
1126  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD88_CH1 | SPD96_CH1);
1127 #endif
1128  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, DBLSPDS);
1129  setupAC3Passthru();
1130  }
1131 
1132  KeReleaseMutex(&Miniport->mutex, false);
1133  return STATUS_SUCCESS;
1134 }
1135 
1137 {
1138  PAGED_CODE();
1139  DBGPRINT(("CMiniportWaveStreamCMI[%p]::setupAC3Passthru() [enableAC3Passthru: %d]", this, enableAC3Passthru));
1140 
1141  if (enableAC3Passthru) {
1142  Miniport->CMIAdapter->writeUInt8(REG_MIXER1, Miniport->CMIAdapter->readUInt8(REG_MIXER1) | MUTE_WAVE);
1143 
1144  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_1);
1145  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDO_AC3_2);
1146 
1147  if (Miniport->cm->canAC3HW) {
1148  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_3);
1149  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SPD32SEL);
1150  if (Miniport->cm->chipVersion >= 39) {
1151  Miniport->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
1152  }
1153  } else {
1154  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SPD32SEL);
1155  if (Miniport->cm->chipVersion == 33) {
1156  if (currentSampleRate >= 48000) {
1157 #if OUT_CHANNEL == 0
1158  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH0);
1159 #else
1160  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD96_CH1);
1161 #endif
1162  } else {
1163 #if OUT_CHANNEL == 0
1164  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH0);
1165 #else
1166  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH1);
1167 #endif
1168  }
1169  }
1170  }
1171  } else {
1173  Miniport->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
1174  }
1175 
1176  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_1);
1177  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDO_AC3_2);
1178 
1179  if (Miniport->cm->canAC3HW) {
1180  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, EN_SPDO_AC3_3);
1181  if (currentResolution > 16) {
1182  Miniport->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SPD32SEL);
1183  Miniport->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SPD24SEL);
1184  } else {
1185  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SPD32SEL);
1186  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD24SEL);
1187  }
1188  } else {
1189  Miniport->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SPD32SEL);
1190 #if OUT_CHANNEL == 0
1191  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH0);
1192 #else
1193  Miniport->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SPD96_CH1);
1194 #endif
1195  }
1196  }
1197  return STATUS_SUCCESS;
1198 }
1199 
1201 {
1202  PAGED_CODE();
1203 
1204  DBGPRINT(("CMiniportWaveStreamCMI[%p]::~CMiniportWaveStreamCMI [streamIndex: %d]", this, streamIndex));
1205 
1206  if (state != KSSTATE_STOP) {
1207  SetState(KSSTATE_STOP);
1208  }
1209 
1210 #ifdef WAVERT
1211  if (Port) {
1212  Port->Release();
1213  Port = NULL;
1214  }
1215 #else
1216  if (DMAChannel) {
1217  DMAChannel->Release();
1218  DMAChannel = NULL;
1219  }
1220 
1221  if (ServiceGroup) {
1222  ServiceGroup->Release();
1223  ServiceGroup = NULL;
1224  }
1225 #endif
1226 
1228 
1236  }
1237 
1238  if (Miniport) {
1239  Miniport->Release();
1240  Miniport = NULL;
1241  }
1242 }
1243 
1244 STDMETHODIMP CMiniportWaveStreamCMI::NonDelegatingQueryInterface(REFIID Interface, PVOID *Object)
1245 {
1246  PAGED_CODE();
1247  ASSERT(Object);
1248  DBGPRINT(("CMiniportWaveStreamCMI[%p]::NonDelegatingQueryInterface(%p, %p)", this, Interface, Object));
1249 
1252 #ifdef WAVERT
1253  } else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveRTStream)) {
1255 #else
1256  } else if (IsEqualGUIDAligned(Interface,IID_IMiniportWaveCyclicStream)) {
1258 #endif
1259  } else if (IsEqualGUIDAligned (Interface, IID_IDrmAudioStream)) {
1260  *Object = (PVOID)(PDRMAUDIOSTREAM(this));
1261  } else {
1262  *Object = NULL;
1263  }
1264 
1265  if (*Object) {
1266  PUNKNOWN(*Object)->AddRef();
1267  return STATUS_SUCCESS;
1268  }
1269 
1270  return STATUS_INVALID_PARAMETER;
1271 }
1272 
1273 #ifdef WAVERT
1274 NTSTATUS CMiniportWaveStreamCMI::Init(CMiniportWaveCMI* Miniport_, UInt32 streamIndex_, bool isCaptureStream_, PKSDATAFORMAT DataFormat, PPORTWAVERTSTREAM Port_)
1275 #else
1276 NTSTATUS CMiniportWaveStreamCMI::Init(CMiniportWaveCMI* Miniport_, UInt32 streamIndex_, bool isCaptureStream_, PKSDATAFORMAT DataFormat, PDMACHANNEL DMAChannel_, PSERVICEGROUP* OutServiceGroup)
1277 #endif
1278 {
1279  PAGED_CODE();
1280  ASSERT(Miniport_);
1281  ASSERT(DataFormat);
1282 
1283  NTSTATUS ntStatus;
1284 
1285 #ifdef WAVERT
1286  ASSERT(Port_);
1287  DBGPRINT(("CMiniportWaveStreamCMI[%p]::Init(%p, %d, %d, %p, %p)", this, Miniport_, streamIndex_, isCaptureStream_, DataFormat, Port_));
1288  Port = Port_;
1289  Port->AddRef();
1290 #else
1291  DBGPRINT(("CMiniportWaveStreamCMI[%p]::Init(%p, %d, %d, %p, %p, %p)", this, Miniport_, streamIndex_, isCaptureStream_, DataFormat, DMAChannel_, OutServiceGroup));
1292  DMAChannel = DMAChannel_;
1293  DMAChannel->AddRef();
1294 #endif
1295 
1296  Miniport = Miniport_;
1297  Miniport->AddRef();
1298 
1299  streamIndex = streamIndex_;
1300  isCaptureStream = isCaptureStream_;
1301  state = KSSTATE_STOP;
1302 
1303  if ( (streamIndex == PCM_OUT_STREAM) || (streamIndex == AC3_OUT_STREAM) ) {
1304  channelNumber = OUT_CHANNEL;
1305  } else {
1306  channelNumber = IN_CHANNEL;
1307  }
1308 
1309 #ifndef WAVERT
1310  ntStatus = PcNewServiceGroup(&ServiceGroup,NULL);
1311  if (!NT_SUCCESS(ntStatus)) {
1312  DBGPRINT(("PcNewServiceGroup() or NewMasterDmaChannel() failed"));
1313  return ntStatus;
1314  }
1315  *OutServiceGroup = ServiceGroup;
1316  ServiceGroup->AddRef();
1317 #endif
1318 
1319  ntStatus = SetFormat(DataFormat);
1320  if (!NT_SUCCESS(ntStatus)) {
1321  DBGPRINT(("SetFormat() failed"));
1322  return ntStatus;
1323  }
1324 
1325  Miniport->isStreamRunning[streamIndex] = true;
1326 
1327  return ntStatus;
1328 }
1329 
1330 NTSTATUS CMiniportWaveStreamCMI::SetFormat(PKSDATAFORMAT Format)
1331 {
1332  PAGED_CODE();
1333  DBGPRINT(("CMiniportWaveStreamCMI[%p]::SetFormat(%p)", this, Format));
1334  PWAVEFORMATEX waveFormat = PWAVEFORMATEX(Format + 1);
1336  if (!NT_SUCCESS(ntStatus)) {
1337  return ntStatus;
1338  }
1339  // the DAC and ADC can only run at the same sample rate simultaneously
1342  return STATUS_UNSUCCESSFUL;
1343  }
1344  }
1347  return STATUS_UNSUCCESSFUL;
1348  }
1349  }
1352  return STATUS_UNSUCCESSFUL;
1353  }
1354  }
1356  return STATUS_UNSUCCESSFUL;
1357  }
1358 
1360  currentSampleRate = waveFormat->nSamplesPerSec;
1361  currentChannelCount = waveFormat->nChannels;
1362  currentResolution = waveFormat->wBitsPerSample;
1364  KeReleaseMutex(&Miniport->mutex, false);
1365  ntStatus = prepareStream();
1366 
1367  return ntStatus;
1368 }
1369 
1370 // DRM crap - we're supposed to disable every digital interface here
1371 STDMETHODIMP_(NTSTATUS) CMiniportWaveStreamCMI::SetContentId(ULONG contentId, PCDRMRIGHTS drmRights)
1372 {
1373  PAGED_CODE();
1374  DBGPRINT(("CMiniportWaveStreamCMI[%p]::SetContentId(%d, %p)", this, contentId, drmRights));
1375 
1376  return STATUS_SUCCESS;
1377 }
1378 
1379 #ifdef WAVERT
1380 STDMETHODIMP_(NTSTATUS) CMiniportWaveStreamCMI::AllocateAudioBuffer(ULONG size, PMDL *userModeBuffer, ULONG *bufferSize, ULONG *bufferOffset, MEMORY_CACHING_TYPE *cacheType)
1381 {
1382  PAGED_CODE();
1383 
1384  PHYSICAL_ADDRESS low;
1385  PHYSICAL_ADDRESS high;
1386  DBGPRINT(("CMiniportWaveStreamCMI[%p]::AllocateAudioBuffer(0x%x, %p, %p, %p, %p)", this, size, userModeBuffer, bufferSize, bufferOffset, cacheType));
1387 
1388  if (size <= size % (currentChannelCount * 2)) {
1389  return STATUS_UNSUCCESSFUL;
1390  }
1391  size -= size % (currentChannelCount * 2);
1392 
1393  if (size == 0) {
1394  return STATUS_UNSUCCESSFUL;
1395  }
1396 
1397  low.HighPart = 0; low.LowPart = 0;
1398  high.HighPart = 0; high.LowPart = MAXULONG;
1399  if (size <= 4096) {
1400  audioBufferMDL = Port->AllocatePagesForMdl(high, size);
1401  } else {
1402  audioBufferMDL = Port->AllocateContiguousPagesForMdl(low, high, size);
1403  }
1404  if (!audioBufferMDL) {
1405  DBGPRINT(("AllocateContiguousPagesForMdl()/AllocatePagesForMdl() failed (size: 0x%x)", size));
1407  }
1408 
1409  dmaAddress = Port->GetPhysicalPageAddress(audioBufferMDL, 0).LowPart;
1410  dmaMemorySize = size;
1411 
1412  *userModeBuffer = audioBufferMDL;
1413  *bufferSize = size;
1414  *bufferOffset = 0;
1415  *cacheType = MmCached;
1416 
1417  return STATUS_SUCCESS;
1418 }
1419 
1420 
1421 STDMETHODIMP_(VOID) CMiniportWaveStreamCMI::FreeAudioBuffer(PMDL Mdl, ULONG Size)
1422 {
1423  PAGED_CODE();
1424  DBGPRINT(("CMiniportWaveStreamCMI[%p]::FreeAudioBuffer(%p, %x)", this, Mdl, Size));
1425 
1426  Port->FreePagesFromMdl(Mdl);
1427  audioBufferMDL = NULL;
1428  dmaAddress = 0;
1429  dmaMemorySize = 0;
1430 }
1431 
1432 STDMETHODIMP_(void) CMiniportWaveStreamCMI::GetHWLatency(PKSRTAUDIO_HWLATENCY hwLatency)
1433 {
1434  PAGED_CODE();
1435  DBGPRINT(("CMiniportWaveStreamCMI[%p]::GetHWLatency(%p)", this, hwLatency));
1436  hwLatency->FifoSize = 32;
1437  hwLatency->ChipsetDelay = 0;
1438  hwLatency->CodecDelay = 4;
1439 }
1440 
1441 STDMETHODIMP_(NTSTATUS) CMiniportWaveStreamCMI::GetPositionRegister(PKSRTAUDIO_HWREGISTER hwRegister)
1442 {
1443  PAGED_CODE();
1444  DBGPRINT(("CMiniportWaveStreamCMI[%p]::GetPositionRegister(%p)", this, hwRegister));
1445 
1446  return STATUS_UNSUCCESSFUL;
1447 }
1448 
1449 STDMETHODIMP_(NTSTATUS) CMiniportWaveStreamCMI::GetClockRegister(PKSRTAUDIO_HWREGISTER hwRegister)
1450 {
1451  PAGED_CODE();
1452  DBGPRINT(("CMiniportWaveStreamCMI[%p]::GetClockRegister(%p)", this, hwRegister));
1453 
1454  return STATUS_UNSUCCESSFUL;
1455 }
1456 
1457 #endif // WAVERT
1458 
1459 /*
1460 ** non-paged code below
1461 */
1462 #ifdef _MSC_VER
1463 #pragma code_seg()
1464 #endif
1465 
1466 STDMETHODIMP CMiniportWaveStreamCMI::SetState(KSSTATE NewState)
1467 {
1468  DBGPRINT(("CMiniportWaveStreamCMI[%p]::SetState(%d) [streamIndex: %d, channelNumber: %d]", this, NewState, streamIndex, channelNumber));
1469 
1470  UInt32 inthld, chen, reset, pause;
1471  UInt8 reg;
1472 
1473  inthld = EN_CH0_INT << channelNumber;
1474  chen = EN_CH0 << channelNumber;
1476  pause = PAUSE_CH0 << channelNumber;
1477 
1478  NTSTATUS ntStatus = STATUS_SUCCESS;
1479 
1481  return STATUS_INVALID_PARAMETER;
1482  }
1483 
1484  if (NewState == KSSTATE_RUN_AC3) {
1485  NewState = state;
1486  state = KSSTATE_STOP;
1487  }
1488 
1489  // STOP -> ACQUIRE -> PAUSE -> PLAY -> PAUSE -> ACQUIRE -> STOP
1490  if (state != NewState) {
1491  switch (NewState) {
1492  case KSSTATE_ACQUIRE:
1493  DBGPRINT(("---KSSTATE_ACQUIRE: previous state: %d", state));
1494  if (state == KSSTATE_PAUSE) {
1495  break;
1496  }
1497 
1498 #ifdef WAVERT
1499  if ((dmaMemorySize == 0) || (dmaAddress == 0)) {
1500  return STATUS_UNSUCCESSFUL;
1501  }
1502  dmaSize = (dmaMemorySize / (2 * (currentResolution >> 3)) );
1503  periodSize = dmaSize;
1504  DBGPRINT(("---dmaAddress: %x, dmaMemorySize: %x, dmaSize: %x", dmaAddress, dmaMemorySize, dmaSize));
1505 #else
1506  if (currentResolution == 32) {
1507  dmaSize = (DMAChannel->BufferSize() / (2 * (32 >> 3)) );
1508  } else {
1509  dmaSize = (DMAChannel->BufferSize() / (2 * (currentResolution >> 3)) );
1510  }
1511 #endif
1512  DBGPRINT(("---SampleRate: %d, Resolution: %d, Channels: %d", currentSampleRate, currentResolution, currentChannelCount));
1513 
1514  if (periodSize > dmaSize) {
1515  periodSize = dmaSize;
1516  }
1517 
1518  // set address of the DMA buffer
1521 #ifdef WAVERT
1522  Miniport->CMIAdapter->writeUInt32(reg, dmaAddress);
1523 #else
1524  Miniport->CMIAdapter->writeUInt32(reg, DMAChannel->PhysicalAddress().u.LowPart);
1525  DBGPRINT(("---DMA Address: HighPart: 0x%08X LowPart: 0x%08X", DMAChannel->PhysicalAddress().u.HighPart, DMAChannel->PhysicalAddress().u.LowPart));
1526 #endif
1527  // count of samples
1529  Miniport->CMIAdapter->writeUInt16(reg, dmaSize-1);
1530  Miniport->CMIAdapter->writeUInt16(reg + 2, periodSize-1);
1531  DBGPRINT(("---DMA Size: 0x%04X, Period Size: 0x%04X, enableSPDIFIn: %d", dmaSize, periodSize, Miniport->cm->enableSPDIFIn));
1532  if (isCaptureStream) {
1533  if (Miniport->cm->enableSPDIFIn) {
1534 #if OUT_CHANNEL==0
1535  Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDF_1);
1536 #else
1537  Miniport->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, SPDF_0);
1538 #endif
1539  } else {
1540 #if OUT_CHANNEL==0
1541  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_1);
1542 #else
1543  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_0);
1544 #endif
1545  }
1546  }
1547  KeReleaseMutex(&Miniport->mutex, false);
1548  break;
1549 
1550  case KSSTATE_PAUSE:
1551  DBGPRINT(("---KSSTATE_PAUSE: previous state: %d", state));
1552  if (state == KSSTATE_RUN) {
1554  Miniport->cm->regFUNCTRL0 |= pause;
1557  }
1558  if (state == KSSTATE_STOP) {
1560  Miniport->cm->regFUNCTRL0 &= ~pause;
1562  KeReleaseMutex(&Miniport->mutex, false);
1563  }
1564  break;
1565 
1566  case KSSTATE_RUN:
1567  DBGPRINT(("---KSSTATE_RUN: previous state: %d", state));
1568 
1570  // set interrupt
1571  Miniport->CMIAdapter->setUInt32Bit(REG_INTHLDCLR, inthld);
1572  Miniport->cm->regFUNCTRL0 &= ~pause;
1573  Miniport->cm->regFUNCTRL0 |= chen;
1574  // and enable the channel
1576 
1577  DBGPRINT(("---FUNCTRL0: 0x%08X", Miniport->cm->regFUNCTRL0));
1578  DBGPRINT(("---FUNCTRL1: 0x%08X", Miniport->CMIAdapter->readUInt32(REG_FUNCTRL1)));
1579  DBGPRINT(("---CHFORMAT: 0x%08X", Miniport->CMIAdapter->readUInt32(REG_CHFORMAT)));
1580  DBGPRINT(("---LEGACYCTRL: 0x%08X", Miniport->CMIAdapter->readUInt32(REG_LEGACY)));
1581  DBGPRINT(("---MISCCTRL: 0x%08X", Miniport->CMIAdapter->readUInt32(REG_MISCCTRL)));
1582  DBGPRINT(("---MIX1: 0x%02X", Miniport->CMIAdapter->readUInt8(REG_MIXER1)));
1583  DBGPRINT(("---MIX2: 0x%02X", Miniport->CMIAdapter->readUInt8(REG_MIXER2)));
1584  DBGPRINT(("---MIX3: 0x%02X", Miniport->CMIAdapter->readUInt8(REG_MIXER3)));
1585 
1586  KeReleaseMutex(&Miniport->mutex, false);
1587  break;
1588 
1589  case KSSTATE_STOP_AC3:
1590  case KSSTATE_STOP:
1591  DBGPRINT(("---KSSTATE_STOP: previous state: %d", state));
1593  // clear interrupt
1594  Miniport->CMIAdapter->clearUInt32Bit(REG_INTHLDCLR, inthld);
1595  Miniport->cm->regFUNCTRL0 &= ~chen;
1596  // reset
1600 #if OUT_CHANNEL==0
1601  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_1);
1602 #else
1603  Miniport->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, SPDF_0);
1604 #endif
1605  }
1607  break;
1608  }
1609  if (NewState != KSSTATE_STOP_AC3) {
1610  state = NewState;
1611  }
1612  }
1613  return ntStatus;
1614 }
1615 
1616 #ifdef WAVERT
1617 
1619 {
1620  ASSERT(Position);
1621 
1622  UInt32 reg;
1623 
1624  if ((state == KSSTATE_RUN) && (dmaAddress)) {
1626  Position->PlayOffset = Miniport->CMIAdapter->readUInt32(reg) - dmaAddress;
1627  Position->WriteOffset = Position->PlayOffset + currentChannelCount * 2 * 8;
1628  } else {
1629  Position->PlayOffset = 0;
1630  Position->WriteOffset = 0;
1631  }
1632 
1633  return STATUS_SUCCESS;
1634 }
1635 
1636 #else //WaveCyclic
1637 
1639 {
1640  ASSERT(Position);
1641 
1642  UInt32 reg;
1643 
1644  if ((DMAChannel) && (state == KSSTATE_RUN)) {
1645 #if 0
1646 // this implementation messes with SPDIF-in recording
1648  *Position = dmaSize - (Miniport->CMIAdapter->readUInt16(reg)-1);
1649  *Position *= 2 * (currentResolution >> 3);
1650 #else
1652  *Position = Miniport->CMIAdapter->readUInt32(reg);
1653  if (*Position > DMAChannel->PhysicalAddress().u.LowPart) {
1654  *Position -= DMAChannel->PhysicalAddress().u.LowPart;
1655  } else {
1656  *Position = 0;
1657  }
1658 #endif
1659  } else {
1660  *Position = 0;
1661  }
1662 
1663  return STATUS_SUCCESS;
1664 }
1665 
1666 STDMETHODIMP_(ULONG) CMiniportWaveStreamCMI::SetNotificationFreq(ULONG Interval, PULONG FramingSize)
1667 {
1669 
1670  if (state == KSSTATE_RUN) {
1671  return 0;
1672  }
1673  // periodSize [sample] = interval [ms] * sample rate [Hz] * 1e-3 [milli]
1675  // FramingSize [byte] = periodSize [sample] * #Channels * resolution [byte];
1676  *FramingSize = periodSize * currentChannelCount * (currentResolution >> 3);
1677 
1681 
1682  DBGPRINT(("periodSize: %x, FramingSize: %x", periodSize, *FramingSize));
1683  return Interval;
1684 }
1685 
1686 STDMETHODIMP CMiniportWaveStreamCMI::NormalizePhysicalPosition(PLONGLONG PhysicalPosition)
1687 {
1688  // time_pos [ns] = byte_pos [byte] / (1e-9 [nano] * #Channels * resolution [byte] * sample rate [Hz])
1689  *PhysicalPosition = (*PhysicalPosition * 10000000L) / (currentChannelCount * (currentResolution >> 3) * currentSampleRate);
1690  return STATUS_SUCCESS;
1691 }
1692 
1693 
1694 STDMETHODIMP_(void) CMiniportWaveStreamCMI::Silence(PVOID Buffer, ULONG ByteCount)
1695 {
1696  RtlFillMemory(Buffer, ByteCount, 0x00);
1697 }
1698 
1699 #endif //WAVERT
1700 
1701 STDMETHODIMP_(void) CMiniportWaveCMI::ServiceWaveISR(UInt32 streamIndex)
1702 {
1703 #ifndef WAVERT
1704  if ((streamIndex == PCM_OUT_STREAM) && isStreamRunning[AC3_OUT_STREAM]) {
1705  streamIndex = AC3_OUT_STREAM;
1706  }
1707  if (Port && stream[streamIndex]->ServiceGroup) {
1708  Port->Notify(stream[streamIndex]->ServiceGroup);
1709  }
1710 #endif
1711 }
#define FMT_882_DOLBY
Definition: property.h:52
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
IPortWaveRTStream * PPORTWAVERTSTREAM
Definition: portcls.h:1791
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
IServiceGroup * PSERVICEGROUP
Definition: portcls.h:614
#define REG_FUNCTRL1
Definition: cmireg.hpp:43
UInt32 requestedChannelCount
Definition: minwave.hpp:57
#define REG_CH1_FRAME2
Definition: cmireg.hpp:155
#define XCHG_DAC
Definition: cmireg.hpp:118
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
CPPORT Port[4]
Definition: headless.c:34
#define SPDF_1
Definition: cmireg.hpp:52
#define MAX_SAMPLE_RATE_AC3
Definition: interfaces.hpp:53
IPortWaveRT * PPORTWAVERT
Definition: interfaces.hpp:682
#define DBGPRINT(...)
Definition: pdo.c:21
Definition: drmk.h:18
IDmaChannel * PDMACHANNEL
Definition: portcls.h:772
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:921
union WAVEFORMATEXTENSIBLE::@2916 Samples
NTSTATUS NTAPI CreateMiniportWaveCMI(PUNKNOWN *Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType)
Definition: minwave.cpp:36
#define KSAUDIO_SPEAKER_STEREO
Definition: ksmedia.h:1354
struct _WAVEFORMATEX * PWAVEFORMATEX
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define MIN_SAMPLE_RATE_WMA
Definition: interfaces.hpp:59
NTSTATUS isFormatAllowed(UInt32 sampleRate, BOOLEAN multiChan, BOOLEAN AC3)
Definition: minwave.cpp:380
#define FMT_480_MULTI_PCM
Definition: property.h:47
NTSTATUS processResources(PRESOURCELIST resourceList)
Definition: minwave.cpp:47
#define EN_6CH_CH1
Definition: cmireg.hpp:101
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
#define AC3_OUT_STREAM
Definition: interfaces.hpp:64
DWORD UInt32
Definition: chm_lib.c:104
WAVEFORMATEXTENSIBLE WAVEFORMATPCMEX
Definition: mmreg.h:467
#define REFCLSID
Definition: guiddef.h:117
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
static COORD Position
Definition: mouse.c:34
#define MIN_BITS_PER_SAMPLE_WMA
Definition: interfaces.hpp:57
#define SFC_CH0_MASK
Definition: cmireg.hpp:53
WORD nChannels
Definition: mmreg.h:79
#define EN_SPDI2DAC
Definition: cmireg.hpp:130
NTSTATUS Init(CMiniportWaveCMI *Miniport_, UInt32 streamIndex_, bool isCaptureStream_, PKSDATAFORMAT DataFormat, PDMACHANNEL DMAChannel_, PSERVICEGROUP *OutServiceGroup)
NTSTATUS loadChannelConfigFromRegistry()
Definition: minwave.cpp:232
IMiniportWaveRTStream * PMINIPORTWAVERTSTREAM
Definition: portcls.h:1809
LONG NTSTATUS
Definition: precomp.h:26
#define DWORD_MAPPING
Definition: cmireg.hpp:109
NTSTATUS CreateMiniportWaveStreamCMI(CMiniportWaveStreamCMI **MiniportWaveStreamCMI, PUNKNOWN pUnknownOuter, POOL_TYPE PoolType)
IDrmAudioStream * PDRMAUDIOSTREAM
Definition: drmk.h:107
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
#define UInt8
Definition: interfaces.hpp:75
#define REG_CHFORMAT
Definition: cmireg.hpp:60
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
KSDATAFORMAT DataFormat
Definition: ksmedia.h:531
NTSTATUS validateFormat(PKSDATAFORMAT format, ULONG PinID, BOOLEAN capture)
Definition: minwave.cpp:413
enum _DMA_WIDTH DMA_WIDTH
PCMIADAPTER CMIAdapter
Definition: minwave.hpp:48
#define EN_CENTER
Definition: cmireg.hpp:112
#define RST_CH0
Definition: cmireg.hpp:40
#define FMT_480_PCM
Definition: property.h:43
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
#define SPD32SEL
Definition: cmireg.hpp:117
#define REG_MISCCTRL
Definition: cmireg.hpp:111
#define MIN_SAMPLE_RATE
Definition: interfaces.hpp:44
bool enableSPDIFOut
Definition: interfaces.hpp:145
NTSTATUS setupSPDIFPlayback(bool enableSPDIF)
BOOL Init(PUSERCONNECT UserCon)
Definition: dllmain.c:385
#define FORMAT_CH0
Definition: cmireg.hpp:61
#define KSAUDIO_SPEAKER_SURROUND
Definition: ksmedia.h:1357
#define SFC_44K_CH1
Definition: cmireg.hpp:57
#define KSAUDIO_SPEAKER_QUAD
Definition: ksmedia.h:1355
#define EN_8CH_CH1
Definition: cmireg.hpp:158
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
UInt32 regFUNCTRL0
Definition: interfaces.hpp:149
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define MIN_BITS_PER_SAMPLE_AC3
Definition: interfaces.hpp:50
KSDSOUND_BUFFERDESC BufferDesc
Definition: ksmedia.h:562
#define KSSTATE_RUN_AC3
Definition: interfaces.hpp:79
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define MAX_SAMPLE_RATE_MULTI
Definition: interfaces.hpp:46
IMiniportWaveRT * PMINIPORTWAVERT
Definition: portcls.h:1927
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define PAGED_CODE()
Definition: video.h:57
#define KSDATAFORMAT_SUBTYPE_WMA_SPDIF
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define REG_MIXER3
Definition: cmireg.hpp:146
PDMACHANNEL DMAChannel
Definition: minwave.hpp:110
#define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Definition: ksmedia.h:931
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
#define REG_LEGACY
Definition: cmireg.hpp:98
PDMACHANNEL DMAChannel[3]
Definition: minwave.hpp:53
PSERVICEGROUP ServiceGroup
Definition: minwave.hpp:111
#define WAVE_FORMAT_DOLBY_AC3_SPDIF
Definition: mmreg.h:129
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:389
#define EN_4CH_CH1
Definition: cmireg.hpp:76
WAVEFORMATEX WaveFormatEx
Definition: ksmedia.h:557
NTSTATUS NTAPI PropertyHandler_ChannelConfig(PPCPROPERTY_REQUEST PropertyRequest)
#define FMT_441_PCM
Definition: property.h:42
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SPD24SEL
Definition: cmireg.hpp:74
static PCFILTER_DESCRIPTOR WaveMiniportFilterDescriptor
#define WAVE_FORMAT_PCM
Definition: constants.h:425
UInt32 notificationInterval
Definition: minwave.hpp:54
#define MAX_BITS_PER_SAMPLE_AC3
Definition: interfaces.hpp:51
#define ADC_CH0
Definition: cmireg.hpp:34
#define REG_FUNCTRL0
Definition: cmireg.hpp:33
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IN_CHANNEL
Definition: interfaces.hpp:70
#define FORMAT_CH1
Definition: cmireg.hpp:62
#define MAX_CHANNELS_WMA
Definition: interfaces.hpp:56
NTSTATUS newDMAChannel(PDMACHANNEL *dmaChannel, UInt32 bufferLength)
Definition: minwave.cpp:61
#define SPD96_CH1
Definition: cmireg.hpp:70
long LONG
Definition: pedump.c:60
#define REG_CH0_FRAME1
Definition: cmireg.hpp:152
PCMITOPOLOGY TopoMiniport
Definition: interfaces.hpp:144
CMiniportWaveStreamCMI * stream[3]
Definition: minwave.hpp:61
bool isStreamRunning[3]
Definition: minwave.hpp:62
PPORTWAVECYCLIC Port
Definition: minwave.hpp:52
#define FMT_441_DOLBY
Definition: property.h:50
WORD wBitsPerSample
Definition: audioclient.idl:45
static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[]
#define STDMETHODIMP
Definition: basetyps.h:43
#define EN_SPDO_AC3_2
Definition: cmireg.hpp:115
KSDATARANGE DataRange
Definition: ksmedia.h:579
unsigned char BOOLEAN
#define KSAUDIO_SPEAKER_5POINT1
Definition: ksmedia.h:1359
smooth NULL
Definition: ftsmooth.c:416
#define PCM_IN_STREAM
Definition: interfaces.hpp:63
NTSTATUS setupAC3Passthru()
#define KSDATAFORMAT_SPECIFIER_WILDCARD
Definition: ks.h:1344
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
DWORD nSamplesPerSec
Definition: audioclient.idl:42
GLuint GLfloat * val
Definition: glext.h:7180
#define EXTRACT_WAVEFORMATEX_ID(Guid)
Definition: ksmedia.h:127
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2030
#define FMT_960_MULTI_PCM
Definition: property.h:49
DWORD Interval
Definition: netstat.c:33
#define PAUSE_CH0
Definition: cmireg.hpp:36
#define MAX_CHANNELS_AC3
Definition: interfaces.hpp:49
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KSPROPERTY_TYPE_BASICSUPPORT
Definition: dmksctrl.h:45
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
#define KSDATAFORMAT_TYPE_WILDCARD
Definition: ks.h:1338
#define EN_CH0
Definition: cmireg.hpp:38
CMI8738Info * cm
Definition: minwave.hpp:56
GLsizeiptr size
Definition: glext.h:5919
IRegistryKey * PREGISTRYKEY
Definition: portcls.h:999
#define PCM_OUT_STREAM
Definition: interfaces.hpp:62
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UInt32 requestedChannelMask
Definition: minwave.hpp:58
WAVEFORMATEX Format
Definition: ksmedia.h:538
#define DBLSPDS
Definition: cmireg.hpp:65
INT POOL_TYPE
Definition: typedefs.h:76
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define REG_CH1_FRAME1
Definition: cmireg.hpp:154
BOOLEAN ScatterGather
Definition: iotypes.h:2027
const GUID IID_IUnknown
UInt32 formatMask
Definition: interfaces.hpp:148
ULONG MinimumSampleFrequency
Definition: ksmedia.h:583
IMiniportWaveCyclicStream * PMINIPORTWAVECYCLICSTREAM
Definition: portcls.h:1468
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
CMiniportWaveCMI * Miniport
Definition: minwave.hpp:103
struct _MINIPORT * PMINIPORT
#define FMT_960_PCM
Definition: property.h:45
static IUnknown Object
Definition: main.c:512
ULONG AddRef()
struct KSDATARANGE_AUDIO * PKSDATARANGE_AUDIO
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define REG_INTHLDCLR
Definition: cmireg.hpp:79
#define SFC_44K_CH0
Definition: cmireg.hpp:54
WORD wFormatTag
Definition: mmreg.h:78
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI PcNewRegistryKey(OUT PREGISTRYKEY *OutRegistryKey, IN PUNKNOWN OuterUnknown OPTIONAL, IN ULONG RegistryKeyType, IN ACCESS_MASK DesiredAccess, IN PVOID DeviceObject OPTIONAL, IN PVOID SubDevice OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN ULONG CreateOptions OPTIONAL, OUT PULONG Disposition OPTIONAL)
Definition: registry.cpp:281
Definition: parse.h:22
#define SFC_CH1_MASK
Definition: cmireg.hpp:56
UInt32 maxChannels
Definition: interfaces.hpp:136
static int state
Definition: maze.c:121
#define REG_MIXER1
Definition: cmireg.hpp:129
ULONG LowPart
Definition: typedefs.h:104
#define EN_SPDIF_48
Definition: cmireg.hpp:124
PUNKNOWN MajorTarget
Definition: portcls.h:258
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define EN_SPDIF_OUT
Definition: cmireg.hpp:104
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:883
bool enableSPDIFIn
Definition: interfaces.hpp:146
#define EN_5CH_CH1
Definition: cmireg.hpp:77
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
enum _DMA_SPEED DMA_SPEED
IResourceList * PRESOURCELIST
Definition: portcls.h:442
#define MAXULONG
Definition: typedefs.h:250
WORD wValidBitsPerSample
Definition: ksmedia.h:541
struct KSDATAFORMAT_WAVEFORMATEX * PKSDATAFORMAT_WAVEFORMATEX
#define MAX_SAMPLE_RATE
Definition: interfaces.hpp:45
IMiniportWaveCyclic * PMINIPORTWAVECYCLIC
Definition: portcls.h:1524
#define EN_CH0_INT
Definition: cmireg.hpp:87
#define KSDATAFORMAT_SPECIFIER_DSOUND
Definition: ksmedia.h:888
GLboolean reset
Definition: glext.h:5666
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
KSSTATE
Definition: ks.h:1214
#define KSSTATE_STOP_AC3
Definition: interfaces.hpp:78
ULONG MaximumSampleFrequency
Definition: ksmedia.h:584
static calc_node_t temp
Definition: rpn_ieee.c:38
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
#define STATUS_NO_MATCH
Definition: ntstatus.h:737
WORD cbSize
Definition: mmreg.h:84
#define SPDF_0
Definition: cmireg.hpp:51
#define KSDATAFORMAT_SUBTYPE_WILDCARD
Definition: ks.h:1341
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
struct KSDATAFORMAT_DSOUND * PKSDATAFORMAT_DSOUND
#define KSAUDIO_SPEAKER_7POINT1
Definition: ksmedia.h:1362
#define MAX_BITS_PER_SAMPLE_WMA
Definition: interfaces.hpp:58
#define EN_SPDO_AC3_3
Definition: cmireg.hpp:72
static int reg
Definition: i386-dis.c:1275
#define MIN_SAMPLE_RATE_AC3
Definition: interfaces.hpp:52
#define FMT_480_DOLBY
Definition: property.h:51
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define MAX_SAMPLE_RATE_WMA
Definition: interfaces.hpp:60
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
#define SPD88_CH1
Definition: cmireg.hpp:68
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2036
#define FMT_882_MULTI_PCM
Definition: property.h:48
WORD wBitsPerSample
Definition: mmreg.h:83
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI PcNewServiceGroup(OUT PSERVICEGROUP *OutServiceGroup, IN PUNKNOWN OuterUnknown OPTIONAL)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
bool enableSPDIFInMonitor
Definition: interfaces.hpp:147
#define SPD88_CH0
Definition: cmireg.hpp:67
#define FMT_960_DOLBY
Definition: property.h:53
#define EN_SPDO_AC3_1
Definition: cmireg.hpp:73
#define FMT_882_PCM
Definition: property.h:44
#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF
KSDATAFORMAT DataFormat
Definition: ksmedia.h:561
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define SFC_48K_CH0
Definition: cmireg.hpp:55
WAVEFORMATPCMEX * PWAVEFORMATPCMEX
Definition: mmreg.h:468
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:605
#define OUT_CHANNEL
Definition: interfaces.hpp:71
Definition: module.h:446
#define REG_MIXER2
Definition: cmireg.hpp:139
#define REG_MISCCTRL2
Definition: cmireg.hpp:157
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define SPD96_CH0
Definition: cmireg.hpp:69
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
#define FMT_441_MULTI_PCM
Definition: property.h:46
#define REG_DWORD
Definition: sdbapi.c:596
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
signed int * PLONG
Definition: retypes.h:5
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define SFC_48K_CH1
Definition: cmireg.hpp:58
IPortWaveCyclic * PPORTWAVECYCLIC
Definition: portcls.h:1172
DWORD GetPosition(DWORD private_handle, PMMTIME time, DWORD time_size)
NTSTATUS storeChannelConfigToRegistry()
Definition: minwave.cpp:294
#define REG_CH0_FRAME2
Definition: cmireg.hpp:153
#define WAVE_FORMAT_EXTENSIBLE
Definition: ksmedia.h:551
#define MAXLEN_DMA_BUFFER
Definition: interfaces.hpp:34
#define SPDO2DAC
Definition: cmireg.hpp:49
#define WAVE_FORMAT_WMA_SPDIF
KSDATAFORMAT * PKSDATAFORMAT
#define ADC_CH1
Definition: cmireg.hpp:35
STDMETHODIMP_(void) CMiniportWaveCMI
Definition: minwave.cpp:342
#define INIT_WAVEFORMATEX_GUID(Guid, x)
Definition: ksmedia.h:867
BOOLEAN NTAPI IoIsWdmVersionAvailable(IN UCHAR MajorVersion, IN UCHAR MinorVersion)
Definition: util.c:126
bool canMultiChannel
Definition: interfaces.hpp:138
#define MUTE_WAVE
Definition: cmireg.hpp:136