ReactOS 0.4.15-dev-7918-g2a2556c
miniport.cpp
Go to the documentation of this file.
1// Every debug output has "Modulname text"
2#define STR_MODULENAME "AC97 Miniport: "
3
4//#include "shared.h"
5//#include "miniport.h"
6#include "wavepciminiport.h"
7
8/*****************************************************************************
9 * PinDataRangesPCMStream
10 *****************************************************************************
11 * The next 3 arrays contain information about the data ranges of the pin for
12 * wave capture, wave render and mic capture.
13 * These arrays are filled dynamically by BuildDataRangeInformation().
14 */
15
19
21{
22 {
23 sizeof(KSDATARANGE),
24 0,
25 0,
26 0,
30 }
31};
32
33/*****************************************************************************
34 * PinDataRangesPointersPCMStream
35 *****************************************************************************
36 * The next 3 arrays contain the pointers to the data range information of
37 * the pin for wave capture, wave render and mic capture.
38 * These arrays are filled dynamically by BuildDataRangeInformation().
39 */
43
44/*****************************************************************************
45 * PinDataRangePointerAnalogStream
46 *****************************************************************************
47 * This structure pointers to the data range structures for the wave pins.
48 */
50{
52};
53
54
55/*****************************************************************************
56 * Wave Miniport Topology
57 *========================
58 *
59 * +-----------+
60 * | |
61 * Capture (PIN_WAVEIN) <---|2 --ADC-- 3|<=== (PIN_WAVEIN_BRIDGE)
62 * | |
63 * Render (PIN_WAVEOUT) --->|0 --DAC-- 1|===> (PIN_WAVEOUT_BRIDGE)
64 * | |
65 * Mic (PIN_MICIN) <---|4 --ADC-- 5|<=== (PIN_MICIN_BRIDGE)
66 * +-----------+
67 *
68 * Note that the exposed pins (left side) have to be a multiple of 2
69 * since there are some dependencies in the stream object.
70 */
71
72/*****************************************************************************
73 * MiniportPins
74 *****************************************************************************
75 * This structure describes pin (stream) types provided by this miniport.
76 * The field that sets the number of data range entries (SIZEOF_ARRAY) is
77 * overwritten by BuildDataRangeInformation().
78 */
80{
81 // PIN_WAVEOUT
82 {
83 1,1,0, // InstanceCount
84 NULL, // AutomationTable
85 { // KsPinDescriptor
86 0, // InterfacesCount
87 NULL, // Interfaces
88 0, // MediumsCount
89 NULL, // Mediums
92 KSPIN_DATAFLOW_IN, // DataFlow
93 KSPIN_COMMUNICATION_SINK, // Communication
94 (GUID *) &KSCATEGORY_AUDIO, // Category
95 NULL, // Name
96 0 // Reserved
97 }
98 },
99
100 // PIN_WAVEOUT_BRIDGE
101 {
102 0,0,0, // InstanceCount
103 NULL, // AutomationTable
104 { // KsPinDescriptor
105 0, // InterfacesCount
106 NULL, // Interfaces
107 0, // MediumsCount
108 NULL, // Mediums
111 KSPIN_DATAFLOW_OUT, // DataFlow
112 KSPIN_COMMUNICATION_NONE, // Communication
113 (GUID *) &KSCATEGORY_AUDIO, // Category
114 NULL, // Name
115 0 // Reserved
116 }
117 },
118
119 // PIN_WAVEIN
120 {
121 1,1,0, // InstanceCount
122 NULL, // AutomationTable
123 { // KsPinDescriptor
124 0, // InterfacesCount
125 NULL, // Interfaces
126 0, // MediumsCount
127 NULL, // Mediums
130 KSPIN_DATAFLOW_OUT, // DataFlow
131 KSPIN_COMMUNICATION_SINK, // Communication
132 (GUID *) &PINNAME_CAPTURE, // Category
134 0 // Reserved
135 }
136 },
137
138 // PIN_WAVEIN_BRIDGE
139 {
140 0,0,0, // InstanceCount
141 NULL, // AutomationTable
142 { // KsPinDescriptor
143 0, // InterfacesCount
144 NULL, // Interfaces
145 0, // MediumsCount
146 NULL, // Mediums
149 KSPIN_DATAFLOW_IN, // DataFlow
150 KSPIN_COMMUNICATION_NONE, // Communication
151 (GUID *) &KSCATEGORY_AUDIO, // Category
152 NULL, // Name
153 0 // Reserved
154 }
155 },
156
157 //
158 // The Microphone pins are not used if PINC_MICIN_PRESENT is not set.
159 // To remove them, Init() will reduce the "PinCount" in the
160 // MiniportFilterDescriptor.
161 //
162 // PIN_MICIN
163 {
164 1,1,0, // InstanceCount
165 NULL, // AutomationTable
166 { // KsPinDescriptor
167 0, // InterfacesCount
168 NULL, // Interfaces
169 0, // MediumsCount
170 NULL, // Mediums
172 PinDataRangePointersMicStream, // DataRanges
173 KSPIN_DATAFLOW_OUT, // DataFlow
174 KSPIN_COMMUNICATION_SINK, // Communication
175 (GUID *) &KSCATEGORY_AUDIO, // Category
176 NULL, // Name
177 0 // Reserved
178 }
179 },
180
181 // PIN_MICIN_BRIDGE
182 {
183 0,0,0, // InstanceCount
184 NULL, // AutomationTable
185 { // KsPinDescriptor
186 0, // InterfacesCount
187 NULL, // Interfaces
188 0, // MediumsCount
189 NULL, // Mediums
192 KSPIN_DATAFLOW_IN, // DataFlow
193 KSPIN_COMMUNICATION_NONE, // Communication
194 (GUID *) &KSCATEGORY_AUDIO, // Category
195 NULL, // Name
196 0 // Reserved
197 }
198 }
199};
200
201/*****************************************************************************
202 * PropertiesDAC
203 *****************************************************************************
204 * Properties for the DAC node.
205 */
207{
208 {
213 }
214};
215
216/*****************************************************************************
217 * AutomationVolume
218 *****************************************************************************
219 * Automation table for volume controls.
220 */
222
223/*****************************************************************************
224 * TopologyNodes
225 *****************************************************************************
226 * List of nodes.
227 */
229{
230 // NODE_WAVEOUT_DAC
231 {
232 0, // Flags
233 &AutomationDAC, // AutomationTable
234 &KSNODETYPE_DAC, // Type
235 NULL // Name
236 },
237 // NODE_WAVEIN_ADC
238 {
239 0, // Flags
240 NULL, // AutomationTable
241 &KSNODETYPE_ADC, // Type
242 NULL // Name
243 },
244 //
245 // The Microphone node is not used if PINC_MICIN_PRESENT is not set.
246 // To remove them, Init() will reduce the "NodeCount" in the
247 // MiniportFilterDescriptor.
248 //
249 // NODE_MICIN_ADC
250 {
251 0, // Flags
252 NULL, // AutomationTable
253 &KSNODETYPE_ADC, // Type
254 NULL // Name
255 }
256};
257
258/*****************************************************************************
259 * MiniportConnections
260 *****************************************************************************
261 * This structure identifies the connections between filter pins and
262 * node pins.
263 */
265{
266 //from_node from_pin to_node to_pin
271 //
272 // The Microphone connection is not used if PINC_MICIN_PRESENT is not set.
273 // To remove them, Init() will reduce the "ConnectionCount" in the
274 // MiniportFilterDescriptor.
275 //
278};
279
280/*****************************************************************************
281 * MiniportFilterDescriptor
282 *****************************************************************************
283 * Complete miniport description.
284 * Init() modifies the pin count, node count and connection count in absence
285 * of the MicIn recording line.
286 */
288{
289 0, // Version
290 NULL, // AutomationTable
291 sizeof(PCPIN_DESCRIPTOR), // PinSize
292 SIZEOF_ARRAY(MiniportPins), // PinCount
293 MiniportPins, // Pins
294 sizeof(PCNODE_DESCRIPTOR), // NodeSize
295 SIZEOF_ARRAY(MiniportNodes), // NodeCount
296 MiniportNodes, // Nodes
297 SIZEOF_ARRAY(MiniportConnections), // ConnectionCount
298 MiniportConnections, // Connections
299 0, // CategoryCount
300 NULL // Categories: NULL->use defaults (audio, render, capture)
301};
302
303#ifdef _MSC_VER
304#pragma code_seg("PAGE")
305#endif
306/*****************************************************************************
307 * CMiniport::PropertyChannelConfig
308 *****************************************************************************
309 * This is the property handler for KSPROPERTY_AUDIO_CHANNEL_CONFIG of the
310 * DAC node. It sets the channel configuration (how many channels, how user
311 * was setting up the speakers).
312 */
314(
315 IN PPCPROPERTY_REQUEST PropertyRequest
316)
317{
318 PAGED_CODE ();
319
320 ASSERT (PropertyRequest);
321
322 DOUT (DBG_PRINT, ("[CMiniport::PropertyChannelConfig]"));
323
325
326 // The major target is the object pointer to the wave miniport.
327 // HACK ALERT - unsafe pointer cast - HACK ALERT
329 (PMINIPORTWAVEPCI)PropertyRequest->MajorTarget;
330
331 ASSERT (that);
332
333 // We only have a set defined.
334 if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
335 {
336 // validate buffer size.
337 if (PropertyRequest->ValueSize < sizeof(LONG))
338 return ntStatus;
339
340 // The "Value" is the input buffer with the channel config.
341 if (PropertyRequest->Value)
342 {
343 // We can accept different channel configurations, depending
344 // on the number of channels we can play.
345 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
346 {
347 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
348 {
349 // we accept 5.1
350 if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_5POINT1)
351 {
352 that->m_dwChannelMask = *(PLONG)PropertyRequest->Value;
353 that->m_wChannels = 6;
354 that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask);
355 ntStatus = STATUS_SUCCESS;
356 }
357 }
358
359 // accept also surround or quad.
360 if ((*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_QUAD) ||
361 (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_SURROUND))
362 {
363 that->m_dwChannelMask = *(PLONG)PropertyRequest->Value;
364 that->m_wChannels = 4;
365 that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask);
366 ntStatus = STATUS_SUCCESS;
367 }
368 }
369
370 // accept also stereo speakers.
371 if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_STEREO)
372 {
373 that->m_dwChannelMask = *(PLONG)PropertyRequest->Value;
374 that->m_wChannels = 2;
375 that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask);
376 ntStatus = STATUS_SUCCESS;
377 }
378 }
379 }
380
381 return ntStatus;
382}
383
384
385/*****************************************************************************
386 * CMiniport::BuildDataRangeInformation
387 *****************************************************************************
388 * This function dynamically build the data range information for the pins.
389 * It also connects the static arrays with the data range information
390 * structure.
391 * If this function returns with an error the miniport should be destroyed.
392 *
393 * To build the data range information, we test the most popular sample rates,
394 * the functions calls ProgramSampleRate in AdapterCommon object to actually
395 * program the sample rate. After probing that way for multiple sample rates,
396 * the original value, which is 48KHz is, gets restored.
397 * We have to test the sample rates for playback, capture and microphone
398 * separately. Every time we succeed, we update the data range information and
399 * the pointers that point to it.
400 */
402{
403 PAGED_CODE ();
404
405 NTSTATUS ntStatus;
406 int nWavePlaybackEntries = 0;
407 int nWaveRecordingEntries = 0;
408 int nMicEntries = 0;
409 int nChannels;
410 int nLoop;
411
412 DOUT (DBG_PRINT, ("[CMiniport::BuildDataRangeInformation]"));
413
414 //
415 // Calculate the number of max. channels available in the codec.
416 //
417 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
418 {
419 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
420 {
421 nChannels = 6;
422 }
423 else
424 {
425 nChannels = 4;
426 }
427 }
428 else
429 {
430 nChannels = 2;
431 }
432
433 // Check for the render sample rates.
434 for (nLoop = 0; nLoop < WAVE_SAMPLERATES_TESTED; nLoop++)
435 {
436 ntStatus = AdapterCommon->ProgramSampleRate (AC97REG_FRONT_SAMPLERATE,
437 dwWaveSampleRates[nLoop]);
438
439 // We support the sample rate?
440 if (NT_SUCCESS (ntStatus))
441 {
442 // Add it to the PinDataRange
444 PinDataRangesPCMStreamRender[nWavePlaybackEntries].DataRange.Flags = 0;
446 PinDataRangesPCMStreamRender[nWavePlaybackEntries].DataRange.Reserved = 0;
451 PinDataRangesPCMStreamRender[nWavePlaybackEntries].MinimumBitsPerSample = 16;
452 PinDataRangesPCMStreamRender[nWavePlaybackEntries].MaximumBitsPerSample = 16;
455
456 // Add it to the PinDataRangePointer
457 PinDataRangePointersPCMStreamRender[nWavePlaybackEntries] = (PKSDATARANGE)&PinDataRangesPCMStreamRender[nWavePlaybackEntries];
458
459 // Increase count
460 nWavePlaybackEntries++;
461 }
462 }
463
464 // Check for the capture sample rates.
465 for (nLoop = 0; nLoop < WAVE_SAMPLERATES_TESTED; nLoop++)
466 {
467 ntStatus = AdapterCommon->ProgramSampleRate (AC97REG_RECORD_SAMPLERATE, dwWaveSampleRates[nLoop]);
468
469 // We support the sample rate?
470 if (NT_SUCCESS (ntStatus))
471 {
472 // Add it to the PinDataRange
474 PinDataRangesPCMStreamCapture[nWaveRecordingEntries].DataRange.Flags = 0;
475 PinDataRangesPCMStreamCapture[nWaveRecordingEntries].DataRange.SampleSize = 4;
476 PinDataRangesPCMStreamCapture[nWaveRecordingEntries].DataRange.Reserved = 0;
480 PinDataRangesPCMStreamCapture[nWaveRecordingEntries].MaximumChannels = 2;
481 PinDataRangesPCMStreamCapture[nWaveRecordingEntries].MinimumBitsPerSample = 16;
482 PinDataRangesPCMStreamCapture[nWaveRecordingEntries].MaximumBitsPerSample = 16;
485
486 // Add it to the PinDataRangePointer
487 PinDataRangePointersPCMStreamCapture[nWaveRecordingEntries] = (PKSDATARANGE)&PinDataRangesPCMStreamCapture[nWaveRecordingEntries];
488
489 // Increase count
490 nWaveRecordingEntries++;
491 }
492 }
493
494 // Check for the MIC sample rates.
495 for (nLoop = 0; nLoop < int(MIC_SAMPLERATES_TESTED); nLoop++)
496 {
497 ntStatus = AdapterCommon->ProgramSampleRate (AC97REG_MIC_SAMPLERATE, dwMicSampleRates[nLoop]);
498
499 // We support the sample rate?
500 if (NT_SUCCESS (ntStatus))
501 {
502 // Add it to the PinDataRange
504 PinDataRangesMicStream[nMicEntries].DataRange.Flags = 0;
515
516 // Add it to the PinDataRangePointer
518
519 // Increase count
520 nMicEntries++;
521 }
522 }
523
524 // Now go through the pin descriptor list and change the data range entries to the actual number.
525 for (nLoop = 0; nLoop < int(SIZEOF_ARRAY(MiniportPins)); nLoop++)
526 {
527 if (MiniportPins[nLoop].KsPinDescriptor.DataRanges == PinDataRangePointersPCMStreamRender)
528 MiniportPins[nLoop].KsPinDescriptor.DataRangesCount = nWavePlaybackEntries;
529 if (MiniportPins[nLoop].KsPinDescriptor.DataRanges == PinDataRangePointersPCMStreamCapture)
530 MiniportPins[nLoop].KsPinDescriptor.DataRangesCount = nWaveRecordingEntries;
531 if (MiniportPins[nLoop].KsPinDescriptor.DataRanges == PinDataRangePointersMicStream)
532 MiniportPins[nLoop].KsPinDescriptor.DataRangesCount = nMicEntries;
533 }
534
535 return STATUS_SUCCESS;
536}
537
538
539/*****************************************************************************
540 * CMiniport::GetDescription
541 *****************************************************************************
542 * Gets the topology.
543 */
544STDMETHODIMP_(NTSTATUS) CMiniport::GetDescription
545(
546 _Out_ PPCFILTER_DESCRIPTOR *OutFilterDescriptor
547)
548{
549 PAGED_CODE ();
550
551 ASSERT (OutFilterDescriptor);
552
553 DOUT (DBG_PRINT, ("[CMiniport::GetDescription]"));
554
555 *OutFilterDescriptor = &MiniportFilterDescriptor;
556
557
558 return STATUS_SUCCESS;
559}
560
561
562/*****************************************************************************
563
564
565 * CMiniport::DataRangeIntersection
566 *****************************************************************************
567 * Tests a data range intersection.
568 * Cause the AC97 controller does not support mono render or capture, we have
569 * to check the max. channel field (unfortunately, there is no MinimumChannel
570 * and MaximumChannel field, just a MaximumChannel field).
571 * If the MaximumChannel is 2, then we can pass this to the default handler of
572 * portcls which always chooses the most (SampleFrequency, Channel, Bits etc.)
573 *
574 * This DataRangeIntersection function is strictly only for the exposed formats
575 * in this sample driver. If you intend to add other formats like AC3 then
576 * you have to be make sure that you check the GUIDs and the data range, since
577 * portcls only checks the data range for waveformatex.
578 */
580STDMETHODIMP_(NTSTATUS) CMiniport::DataRangeIntersection
581(
582 ULONG PinId,
583 PKSDATARANGE ClientsDataRange,
584 PKSDATARANGE MyDataRange,
585
587 PVOID ResultantFormat,
588 PULONG ResultantFormatLength
589)
590{
591 PAGED_CODE ();
592
593 DOUT (DBG_PRINT, ("[CMiniport::DataRangeIntersection]"));
594
595 //
596 // This function gets only called if the GUIDS in the KSDATARANGE_AUDIO
597 // structure that we attached to the pin are equal with the requested
598 // format (see "BuildDataRangeInformation).
599 // Additionally, for waveformatex portcls checks that the requested sample
600 // frequency range fits into our exposed sample frequency range. Since we
601 // only have discrete sample frequencies in the pin's data range, we don't
602 // have to check that either.
603 // There is one exception to this rule: portcls clones all WAVEFORMATEX
604 // data ranges to DSOUND dataranges, so we might get a data range
605 // intersection that has a DSOUND specifier. We don't support that
606 // since this is only used for HW acceleration
607 //
609 {
610 DOUT (DBG_PRINT, ("[DataRangeIntersection] We don't support DSOUND specifier"));
612 }
613
614 //
615 // Start with checking the size of the output buffer and validating that it is not NULL.
616 //
617 if (!OutputBufferLength || NULL == ResultantFormat)
618 {
619 *ResultantFormatLength = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX);
621 }
622
623 if (OutputBufferLength < (sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX)))
624 {
625 DOUT (DBG_WARNING, ("[DataRangeIntersection] Buffer too small"));
627 }
628
629 //
630 // We can only play or record multichannel (>=2 channels) except for the MIC
631 // recording channel where we can only record mono. Portcls checked the channels
632 // already, however, since we have no minimum channels field, the KSDATARANGE_AUDIO
633 // could have MaximumChannels = 1.
634 //
635 if (PinId != PIN_MICIN)
636 {
637 // reject mono format for normal wave playback or capture.
638 if (((PKSDATARANGE_AUDIO)ClientsDataRange)->MaximumChannels < 2)
639 {
640 DOUT (DBG_WARNING, ("[DataRangeIntersection] Mono requested for WaveIn or WaveOut"));
641 return STATUS_NO_MATCH;
642 }
643 }
644
645 //
646 // Fill in the structure the datarange structure.
647 // KSDATARANGE and KSDATAFORMAT are the same.
648 //
649 *(PKSDATAFORMAT)ResultantFormat = *MyDataRange;
650
651 //
652 // Modify the size of the data format structure to fit the WAVEFORMATPCMEX
653 // structure.
654 //
655 ((PKSDATAFORMAT)ResultantFormat)->FormatSize =
656 sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX);
657
658 //
659 // Append the WAVEFORMATPCMEX structur.
660 //
661 PWAVEFORMATPCMEX WaveFormat = (PWAVEFORMATPCMEX)((PKSDATAFORMAT)ResultantFormat + 1);
662
663 // We want a WAFEFORMATEXTENSIBLE which is equal to WAVEFORMATPCMEX.
665 // Set the number of channels
666 if (PinId == PIN_WAVEOUT)
667 {
668 // Get the max. possible channels for playback.
669 ULONG nMaxChannels = min (((PKSDATARANGE_AUDIO)ClientsDataRange)->MaximumChannels, m_wChannels);
670
671 // We cannot play uneven number of channels
672 if (nMaxChannels & 0x01)
673 nMaxChannels--;
674 // ... and also 0 channels wouldn't be a good request.
675 if (!nMaxChannels)
676 return STATUS_NO_MATCH;
677
678 WaveFormat->Format.nChannels = (WORD)nMaxChannels;
679 }
680 else
681 // This will be 2 for normal record and 1 for MIC record.
682 WaveFormat->Format.nChannels = (WORD)((PKSDATARANGE_AUDIO)MyDataRange)->MaximumChannels;
683
684 //
685 // Hack for codecs that have only one sample rate converter that has both
686 // playback and recording data.
687 //
690 {
691 //
692 // We have to return this sample rate that is used in the open stream.
693 //
694 ULONG ulFrequency;
695
698 else
700
701 //
702 // Check if this sample rate is in the requested data range of the client.
703 //
704 if ((((PKSDATARANGE_AUDIO)ClientsDataRange)->MaximumSampleFrequency < ulFrequency) ||
705 (((PKSDATARANGE_AUDIO)ClientsDataRange)->MinimumSampleFrequency > ulFrequency))
706 {
707 return STATUS_NO_MATCH;
708 }
709
710 WaveFormat->Format.nSamplesPerSec = ulFrequency;
711 }
712 else
713 {
714 // Since we have discrete frequencies in the data range, min = max.
715 WaveFormat->Format.nSamplesPerSec = ((PKSDATARANGE_AUDIO)MyDataRange)->MaximumSampleFrequency;
716 }
717
718 // Will be 16.
719 WaveFormat->Format.wBitsPerSample = (WORD)((PKSDATARANGE_AUDIO)MyDataRange)->MaximumBitsPerSample;
720 // Will be 2 * channels.
721 WaveFormat->Format.nBlockAlign = (WaveFormat->Format.wBitsPerSample * WaveFormat->Format.nChannels) / 8;
722 // That is played in a sec.
723 WaveFormat->Format.nAvgBytesPerSec = WaveFormat->Format.nSamplesPerSec * WaveFormat->Format.nBlockAlign;
724 // WAVEFORMATPCMEX
725 WaveFormat->Format.cbSize = 22;
726 // We have as many valid bits as the bit depth is (16).
727 WaveFormat->Samples.wValidBitsPerSample = WaveFormat->Format.wBitsPerSample;
728 // Set the channel mask
729 if (PinId == PIN_WAVEOUT)
730 {
731 // If we can play in our configuration, then set the channel mask
732 if (WaveFormat->Format.nChannels == m_wChannels)
733 // Set the playback channel mask to the current speaker config.
734 WaveFormat->dwChannelMask = m_dwChannelMask;
735 else
736 {
737 //
738 // We have to set a channel mask.
739 // nChannles can only be 4 if we are in 6 channel mode. In that
740 // case it must be a QUAD configurations. The only other value
741 // allowed is 2 channels, which defaults to stereo.
742 //
743 if (WaveFormat->Format.nChannels == 4)
745 else
747 }
748 }
749 else
750 {
751 // This will be KSAUDIO_SPEAKER_STEREO for normal record and KSAUDIO_SPEAKER_MONO
752 // for MIC record.
753 if (PinId == PIN_MICIN)
754 // MicIn -> 1 channel
756 else
757 // normal record -> 2 channels
759 }
760 // Here we specify the subtype of the WAVEFORMATEXTENSIBLE.
762
763 // Now overwrite also the sample size in the ksdataformat structure.
764 ((PKSDATAFORMAT)ResultantFormat)->SampleSize = WaveFormat->Format.nBlockAlign;
765
766 //
767 // That we will return.
768 //
769 *ResultantFormatLength = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX);
770
771 DOUT (DBG_STREAM, ("[DataRangeIntersection] Frequency: %d, Channels: %d, bps: %d, ChannelMask: %X",
772 WaveFormat->Format.nSamplesPerSec, WaveFormat->Format.nChannels,
773 WaveFormat->Format.wBitsPerSample, WaveFormat->dwChannelMask));
774
775 // Let portcls do some work ...
776 return STATUS_SUCCESS;
777}
778
779
781(
784)
785{
786 //
787 // Validate the channel (pin id).
788 //
789 if ((Pin != PIN_WAVEOUT) && (Pin != PIN_WAVEIN) &&
790 (Pin != PIN_MICIN))
791 {
792 DOUT (DBG_ERROR, ("[NewStream] Invalid channel passed!"));
794 }
795
796 //
797 // Check if the pin is already in use
798 //
799 if (Streams[Pin/2])
800 {
801 DOUT (DBG_ERROR, ("[NewStream] Pin is already in use!"));
802 return STATUS_UNSUCCESSFUL;
803 }
804
805 //
806 // Check parameters.
807 //
809 if (!NT_SUCCESS (ntStatus))
810 {
811 DOUT (DBG_VSR, ("[NewStream] TestDataFormat failed!"));
812 return ntStatus;
813 }
814
815 return ntStatus;
816}
817
818
819/*****************************************************************************
820 * CMiniport::TestDataFormat
821 *****************************************************************************
822 * Checks if the passed data format is known to the driver and verifies that
823 * the number of channels, the width of one sample match to the AC97
824 * specification.
825 */
827(
830)
831{
832 PAGED_CODE ();
833
834 ASSERT (Format);
835
836 DOUT (DBG_PRINT, ("[CMiniport::TestDataFormat]"));
837
838 //
839 // KSDATAFORMAT contains three GUIDs to support extensible format. The
840 // first two GUIDs identify the type of data. The third indicates the
841 // type of specifier used to indicate format specifics. We are only
842 // supporting PCM audio formats that use WAVEFORMATEX.
843 //
847 {
848 DOUT (DBG_ERROR, ("[TestDataFormat] Invalid format type!"));
850 }
851
852 PWAVEFORMATPCMEX waveFormat = (PWAVEFORMATPCMEX)(Format + 1);
853
854 //
855 // If the size doesn't match, then something is messed up.
856 //
857 if (Format->FormatSize < (sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX)))
858 {
859 DOUT (DBG_WARNING, ("[TestDataFormat] Invalid FormatSize!"));
861 }
862
863 //
864 // We only support PCM, 16-bit.
865 //
866 if (waveFormat->Format.wBitsPerSample != 16)
867 {
868 DOUT (DBG_WARNING, ("[TestDataFormat] Bits Per Sample must be 16!"));
870 }
871
872 //
873 // We support WaveFormatPCMEX (=WAVEFORMATEXTENSIBLE) or WaveFormatPCM.
874 //
875 if ((waveFormat->Format.wFormatTag != WAVE_FORMAT_EXTENSIBLE) &&
876 (waveFormat->Format.wFormatTag != WAVE_FORMAT_PCM))
877 {
878 DOUT (DBG_WARNING, ("[TestDataFormat] Invalid Format Tag!"));
880 }
881
882 //
883 // Make additional checks for the WAVEFORMATEXTENSIBLE
884 //
885 if (waveFormat->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
886 {
887 //
888 // If the size doesn't match, then something is messed up.
889 //
890 if (Format->FormatSize < (sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATPCMEX)))
891 {
892 DOUT (DBG_WARNING, ("[TestDataFormat] Invalid FormatSize!"));
894 }
895
896 //
897 // Check also the subtype (PCM) and the size of the extended data.
898 //
900 (waveFormat->Format.cbSize < (sizeof(WAVEFORMATPCMEX) - sizeof(WAVEFORMATEX))))
901 {
902 DOUT (DBG_WARNING, ("[TestDataFormat] Unsupported WAVEFORMATEXTENSIBLE!"));
904 }
905
906 //
907 // Check the channel mask. We support 1, 2 channels or whatever was set
908 // with the Speaker config dialog.
909 //
910 if (((waveFormat->Format.nChannels == 1) &&
911 (waveFormat->dwChannelMask != KSAUDIO_SPEAKER_MONO)) ||
912 ((waveFormat->Format.nChannels == 2) &&
913 (waveFormat->dwChannelMask != KSAUDIO_SPEAKER_STEREO)) ||
914 ((waveFormat->Format.nChannels == m_wChannels) &&
915 (waveFormat->dwChannelMask != m_dwChannelMask)))
916 {
917 DOUT (DBG_WARNING, ("[TestDataFormat] Channel Mask!"));
919 }
920 }
921
922 //
923 // Check the number of channels.
924 //
925 switch (Pin)
926 {
927 case PIN_MICIN: // 1 channel
928 if (waveFormat->Format.nChannels != 1)
929 {
930 DOUT (DBG_WARNING, ("[TestDataFormat] Invalid Number of Channels for PIN_MICIN!"));
932 }
933 break;
934 case PIN_WAVEIN: // 2 channels
935 if (waveFormat->Format.nChannels != 2)
936 {
937 DOUT (DBG_WARNING, ("[TestDataFormat] Invalid Number of Channels for PIN_WAVEIN!"));
939 }
940 break;
941 case PIN_WAVEOUT: // channel and mask from PropertyChannelConfig or standard.
942 if (waveFormat->Format.nChannels != m_wChannels)
943 {
944 DOUT (DBG_WARNING, ("[TestDataFormat] Invalid Number of Channels for PIN_WAVEOUT!"));
946 }
947 break;
948 }
949
950 //
951 // Print the information.
952 //
953 if (waveFormat->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
954 {
955 DOUT (DBG_STREAM, ("[TestDataFormat] PCMEX - Frequency: %d, Channels: %d, bps: %d, ChannelMask: %X",
956 waveFormat->Format.nSamplesPerSec, waveFormat->Format.nChannels,
957 waveFormat->Format.wBitsPerSample, waveFormat->dwChannelMask));
958 }
959 else
960 {
961 DOUT (DBG_STREAM, ("[TestDataFormat] PCM - Frequency: %d, Channels: %d, bps: %d",
962 waveFormat->Format.nSamplesPerSec, waveFormat->Format.nChannels,
963 waveFormat->Format.wBitsPerSample));
964 }
965
966 return STATUS_SUCCESS;
967}
968
969/*****************************************************************************
970 * CMiniport::PowerChangeNotify
971 *****************************************************************************
972 * This routine gets called as a result of hooking up the IPowerNotify
973 * interface. This interface indicates the driver's desire to receive explicit
974 * notification of power state changes. The interface provides a single method
975 * (or callback) that is called by the miniport's corresponding port driver in
976 * response to a power state change. Using wave audio as an example, when the
977 * device is requested to go to a sleep state the port driver pauses any
978 * active streams and then calls the power notify callback to inform the
979 * miniport of the impending power down. The miniport then has an opportunity
980 * to save any necessary context before the adapter's PowerChangeState method
981 * is called. The process is reversed when the device is powering up. PortCls
982 * first calls the adapter's PowerChangeState method to power up the adapter.
983 * The port driver then calls the miniport's callback to allow the miniport to
984 * restore its context. Finally, the port driver unpauses any previously paused
985 * active audio streams.
986 */
987STDMETHODIMP_(void) CMiniport::PowerChangeNotify
988(
989 _In_ POWER_STATE NewState
990)
991{
992 PAGED_CODE ();
993 NTSTATUS ntStatus = STATUS_SUCCESS;
994
995 DOUT (DBG_PRINT, ("[CMiniport::PowerChangeNotify]"));
996
997 //
998 // Check to see if this is the current power state.
999 //
1000 if (NewState.DeviceState == m_PowerState)
1001 {
1002 DOUT (DBG_POWER, ("New device state equals old state."));
1003 return;
1004 }
1005
1006 //
1007 // Check the new device state.
1008 //
1009 if ((NewState.DeviceState < PowerDeviceD0) ||
1010 (NewState.DeviceState > PowerDeviceD3))
1011 {
1012 DOUT (DBG_ERROR, ("Unknown device state: D%d.",
1013 (ULONG)NewState.DeviceState - (ULONG)PowerDeviceD0));
1014 return;
1015 }
1016
1017 DOUT (DBG_POWER, ("Changing state to D%d.", (ULONG)NewState.DeviceState -
1019
1020 //
1021 // In case we return to D0 power state from a D3 state, restore the
1022 // interrupt connection.
1023 //
1024 if (NewState.DeviceState == PowerDeviceD0)
1025 {
1026 ntStatus = InterruptSync->Connect ();
1027 if (!NT_SUCCESS (ntStatus))
1028 {
1029 DOUT (DBG_ERROR, ("Failed to connect the ISR with InterruptSync!"));
1030 // We can do nothing else than just continue ...
1031 }
1032 }
1033
1034 //
1035 // Call the stream routine which takes care of the DMA engine.
1036 // That's all we have to do.
1037 //
1038 for (int loop = PIN_WAVEOUT_OFFSET; loop < PIN_MICIN_OFFSET; loop++)
1039 {
1040 if (Streams[loop])
1041 {
1042 Streams[loop]->PowerChangeNotify (NewState);
1043 }
1044 }
1045
1046 //
1047 // In case we go to any sleep state we disconnect the interrupt service
1048 // reoutine from the interrupt.
1049 // Normally this is not required to do, but for some reason this fixes
1050 // a problem where we won't have any interrupts on specific motherboards
1051 // after resume.
1052 //
1053 if (NewState.DeviceState != PowerDeviceD0)
1054 {
1055 InterruptSync->Disconnect ();
1056 }
1057
1058 //
1059 // Save the new state. This local value is used to determine when to
1060 // cache property accesses and when to permit the driver from accessing
1061 // the hardware.
1062 //
1063 m_PowerState = NewState.DeviceState;
1064 DOUT (DBG_POWER, ("Entering D%d",
1066}
1067
1068/*****************************************************************************
1069 * CMiniport::ProcessResources
1070 *****************************************************************************
1071 * Processes the resource list, setting up helper objects accordingly.
1072 * Sets up the Interrupt + Service routine and DMA.
1073 */
1075(
1077)
1078{
1079 PAGED_CODE ();
1080
1082
1083
1084 DOUT (DBG_PRINT, ("[CMiniport::ProcessResources]"));
1085
1086
1087 ULONG countIRQ = ResourceList->NumberOfInterrupts ();
1088 if (countIRQ < 1)
1089 {
1090 DOUT (DBG_ERROR, ("Unknown configuration for wave miniport!"));
1092 }
1093
1094 //
1095 // Create an interrupt sync object
1096 //
1097 NTSTATUS ntStatus = STATUS_SUCCESS;
1098 ntStatus = PcNewInterruptSync (&InterruptSync,
1099 NULL,
1101 0,
1103
1104 if (!NT_SUCCESS (ntStatus) || !InterruptSync)
1105 {
1106 DOUT (DBG_ERROR, ("Failed to create an interrupt sync!"));
1108 }
1109
1110 //
1111 // Register our ISR.
1112 //
1113 ntStatus = InterruptSync->RegisterServiceRoutine (InterruptServiceRoutine,
1114 (PVOID)this, FALSE);
1115 if (!NT_SUCCESS (ntStatus))
1116 {
1117 DOUT (DBG_ERROR, ("Failed to register ISR!"));
1118 return ntStatus;
1119 }
1120
1121 //
1122 // Connect the interrupt.
1123 //
1124 ntStatus = InterruptSync->Connect ();
1125 if (!NT_SUCCESS (ntStatus))
1126 {
1127 DOUT (DBG_ERROR, ("Failed to connect the ISR with InterruptSync!"));
1128 return ntStatus;
1129 }
1130
1131 //
1132 // On failure object is destroyed which cleans up.
1133 //
1134 return STATUS_SUCCESS;
1135}
1136
1137/*****************************************************************************
1138 * CMiniport::NonDelegatingQueryInterface
1139 *****************************************************************************
1140 * Obtains an interface. This function works just like a COM QueryInterface
1141 * call and is used if the object is not being aggregated.
1142 */
1144(
1147 _In_ REFIID iMiniPort,
1148 _In_ PMINIPORT miniPort
1149)
1150{
1151 PAGED_CODE ();
1152
1153 ASSERT (Object);
1154
1155 DOUT (DBG_PRINT, ("[CMiniport::NonDelegatingQueryInterface]"));
1156
1157 // Is it IID_IUnknown?
1159 {
1160 *Object = (PVOID)miniPort;
1161 }
1162 // or IID_IMiniport ...
1163 else if (IsEqualGUIDAligned (Interface, IID_IMiniport))
1164 {
1165 *Object = (PVOID)miniPort;
1166 }
1167 // or IID_IMiniportWavePci ...
1168 else if (IsEqualGUIDAligned (Interface, iMiniPort))
1169 {
1170 *Object = (PVOID)miniPort;
1171 }
1172 // or IID_IPowerNotify ...
1173 else if (IsEqualGUIDAligned (Interface, IID_IPowerNotify))
1174 {
1175 *Object = (PVOID)(PPOWERNOTIFY)this;
1176 }
1177 else
1178 {
1179 // nothing found, must be an unknown interface.
1180 *Object = NULL;
1182 }
1183
1184 //
1185 // We reference the interface for the caller.
1186 //
1187 ((PUNKNOWN)(*Object))->AddRef();
1188 return STATUS_SUCCESS;
1189}
1190
1191/*****************************************************************************
1192 * CAC97MiniportWaveRT::Init
1193 *****************************************************************************
1194 * Initializes the miniport.
1195 * Initializes variables and modifies the wave topology if needed.
1196 */
1197STDMETHODIMP_(NTSTATUS) CMiniport::Init
1198(
1199 _In_ PUNKNOWN UnknownAdapter,
1201 _In_ PPORT Port_
1202)
1203{
1204 PAGED_CODE ();
1205
1206 ASSERT (UnknownAdapter);
1208 ASSERT (Port_);
1209
1210 DOUT (DBG_PRINT, ("[CMiniport::Init]"));
1211
1212 //
1213 // AddRef() is required because we are keeping this pointer.
1214 //
1215 obj_AddRef(Port_, (PVOID *)&Port);
1216
1217 //
1218 // Set initial device power state
1219 //
1221
1222 NTSTATUS ntStatus = UnknownAdapter->
1223 QueryInterface (IID_IAC97AdapterCommon, (PVOID *)&AdapterCommon);
1224 if (NT_SUCCESS (ntStatus))
1225 {
1226 //
1227 // Alter the topology for the wave miniport.
1228 //
1229 if (!(AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT) &&
1230 AdapterCommon->GetPinConfig (PINC_MIC_PRESENT)))
1231 {
1232 //
1233 // Remove the pins, nodes and connections for the MICIN.
1234 //
1238 }
1239
1240 //
1241 // Process the resources.
1242 //
1243 ntStatus = ProcessResources (ResourceList);
1244
1245 //
1246 // Get the default channel config
1247 //
1248 AdapterCommon->ReadChannelConfigDefault (&m_dwChannelMask, &m_wChannels);
1249
1250 //
1251 // If we came till that point, check the CoDec for supported standard
1252 // sample rates. This function will then fill the data range information
1253 //
1254 if (NT_SUCCESS (ntStatus))
1255 ntStatus = BuildDataRangeInformation ();
1256 }
1257
1258 //
1259 // If we fail we get destroyed anyway (that's where we clean up).
1260 //
1261 return ntStatus;
1262}
1263
1265{
1266 if(ppvObject) {
1267 *ppvObject = obj;
1268 if(obj) obj->AddRef();
1269 }
1270}
1271
1272
1274{
1275 if(ppvObject) {
1277 *ppvObject = NULL;
1278 if(obj) obj->Release();
1279 }
1280}
1281
1282/*****************************************************************************
1283 * CAC97MiniportWaveRT::~CAC97MiniportWaveRT
1284 *****************************************************************************
1285 * Destructor.
1286 */
1288{
1289 PAGED_CODE ();
1290
1291 DOUT (DBG_PRINT, ("[CMiniport::~CMiniport]"));
1292
1296 obj_Release((PVOID *)&Port);
1297}
1298
1299/*****************************************************************************
1300 * Non paged code begins here
1301 *****************************************************************************
1302 */
1303
1304#ifdef _MSC_VER
1305#pragma code_seg()
1306#endif
1307/*****************************************************************************
1308 * InterruptServiceRoutine
1309 *****************************************************************************
1310 * The task of the ISR is to clear an interrupt from this device so we don't
1311 * get an interrupt storm and schedule a DPC which actually does the
1312 * real work.
1313 */
1315(
1316 IN PINTERRUPTSYNC InterruptSync,
1317 IN PVOID DynamicContext
1318)
1319{
1321
1323 ASSERT (DynamicContext);
1324
1325 ULONG GlobalStatus;
1326 USHORT DMAStatusRegister;
1327
1328 //
1329 // Get our context which is a pointer to class CAC97MiniportWaveRT.
1330 //
1331 CMiniport *that = (CMiniport *)DynamicContext;
1332
1333 //
1334 // Check for a valid AdapterCommon pointer.
1335 //
1336 if (!that->AdapterCommon)
1337 {
1338 //
1339 // In case we didn't handle the interrupt, unsuccessful tells the system
1340 // to call the next interrupt handler in the chain.
1341 //
1342 return STATUS_UNSUCCESSFUL;
1343 }
1344
1345 //
1346 // From this point down, basically in the complete ISR, we cannot use
1347 // relative addresses (stream class base address + X_CR for example)
1348 // cause we might get called when the stream class is destroyed or
1349 // not existent. This doesn't make too much sense (that there is an
1350 // interrupt for a non-existing stream) but could happen and we have
1351 // to deal with the interrupt.
1352 //
1353
1354 //
1355 // Read the global register to check the interrupt bits
1356 //
1357 GlobalStatus = that->AdapterCommon->ReadBMControlRegister32 (GLOB_STA);
1358
1359 //
1360 // Check for weird return values. Could happen if the PCI device is already
1361 // disabled and another device that shares this interrupt generated an
1362 // interrupt.
1363 // The register should never have all bits cleared or set.
1364 //
1365 if (!GlobalStatus || (GlobalStatus == 0xFFFFFFFF))
1366 {
1367 return STATUS_UNSUCCESSFUL;
1368 }
1369
1370 //
1371 // Check for PCM out interrupt.
1372 //
1373 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
1374 if (GlobalStatus & GLOB_STA_POINT)
1375 {
1376 //
1377 // Read PCM out DMA status registers.
1378 //
1379 DMAStatusRegister = (USHORT)that->AdapterCommon->
1380 ReadBMControlRegister16 (PO_SR);
1381
1382
1383 //
1384 // We could now check for every possible error condition
1385 // (like FIFO error) and monitor the different errors, but currently
1386 // we have the same action for every INT and therefore we simplify
1387 // this routine enormous with just clearing the bits.
1388 //
1389 if (that->Streams[PIN_WAVEOUT_OFFSET])
1390 {
1391 //
1392 // ACK the interrupt.
1393 //
1394 that->AdapterCommon->WriteBMControlRegister (PO_SR, DMAStatusRegister);
1395 ntStatus = STATUS_SUCCESS;
1396
1397 //
1398
1400 }
1401 }
1402
1403 //
1404 // Check for PCM in interrupt.
1405 //
1406 if (GlobalStatus & GLOB_STA_PIINT)
1407 {
1408 //
1409 // Read PCM in DMA status registers.
1410 //
1411 DMAStatusRegister = (USHORT)that->AdapterCommon->
1412 ReadBMControlRegister16 (PI_SR);
1413
1414 //
1415 // We could now check for every possible error condition
1416 // (like FIFO error) and monitor the different errors, but currently
1417 // we have the same action for every INT and therefore we simplify
1418 // this routine enormous with just clearing the bits.
1419 //
1420 if (that->Streams[PIN_WAVEIN_OFFSET])
1421 {
1422 //
1423 // ACK the interrupt.
1424 //
1425 that->AdapterCommon->WriteBMControlRegister (PI_SR, DMAStatusRegister);
1426 ntStatus = STATUS_SUCCESS;
1427
1429 }
1430 }
1431
1432 //
1433 // Check for MIC in interrupt.
1434 //
1435 if (GlobalStatus & GLOB_STA_MINT)
1436 {
1437 //
1438 // Read MIC in DMA status registers.
1439 //
1440 DMAStatusRegister = (USHORT)that->AdapterCommon->
1441 ReadBMControlRegister16 (MC_SR);
1442
1443 //
1444 // We could now check for every possible error condition
1445 // (like FIFO error) and monitor the different errors, but currently
1446 // we have the same action for every INT and therefore we simplify
1447 // this routine enormous with just clearing the bits.
1448 //
1449 if (that->Streams[PIN_MICIN_OFFSET])
1450 {
1451 //
1452 // ACK the interrupt.
1453 //
1454 that->AdapterCommon->WriteBMControlRegister (MC_SR, DMAStatusRegister);
1455 ntStatus = STATUS_SUCCESS;
1456
1458 }
1459 }
1460
1461 return ntStatus;
1462}
#define PAGED_CODE()
@ AC97REG_MIC_SAMPLERATE
Definition: ac97reg.h:46
@ AC97REG_RECORD_SAMPLERATE
Definition: ac97reg.h:45
@ AC97REG_FRONT_SAMPLERATE
Definition: ac97reg.h:42
LONG NTSTATUS
Definition: precomp.h:26
#define WAVE_FORMAT_PCM
Definition: constants.h:425
const GUID IID_IUnknown
#define SIZEOF_ARRAY(ar)
Definition: cdrom.h:1482
virtual void InterruptServiceRoutine() PURE
void PowerChangeNotify(IN POWER_STATE NewState)
Definition: stream.cpp:289
ULONG GetCurrentSampleRate(void)
Definition: stream.h:130
DWORD m_dwChannelMask
Definition: miniport.h:35
NTSTATUS ProcessResources(IN PRESOURCELIST ResourceList)
Definition: miniport.cpp:1075
PINTERRUPTSYNC InterruptSync
Definition: miniport.h:32
NTSTATUS BuildDataRangeInformation(void)
Definition: miniport.cpp:401
CMiniportStream * Streams[PIN_MICIN_OFFSET+1]
Definition: miniport.h:29
DEVICE_POWER_STATE m_PowerState
Definition: miniport.h:34
NTSTATUS ValidateFormat(IN PKSDATAFORMAT DataFormat, IN WavePins Pin)
Definition: miniport.cpp:781
PADAPTERCOMMON AdapterCommon
Definition: miniport.h:31
WORD m_wChannels
Definition: miniport.h:36
NTSTATUS TestDataFormat(IN PKSDATAFORMAT Format, IN WavePins Pin)
Definition: miniport.cpp:827
PDMACHANNEL DmaChannel
Definition: miniport.h:33
static NTSTATUS NTAPI PropertyChannelConfig(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: miniport.cpp:314
static NTSTATUS NTAPI InterruptServiceRoutine(IN PINTERRUPTSYNC InterruptSync, IN PVOID StaticContext)
Definition: miniport.cpp:1315
NTSTATUS NonDelegatingQueryInterface(_In_ REFIID Interface, _COM_Outptr_ PVOID *Object, _In_ REFIID iMiniPort, _In_ PMINIPORT miniPort)
Definition: miniport.cpp:1144
_In_ PRESOURCELIST _In_ PPORT Port_
Definition: miniport.h:98
PPORT_ Port
Definition: miniport.h:30
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
KSDATAFORMAT * PKSDATAFORMAT
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static KSDATARANGE_AUDIO PinDataRangesMicStream[MIC_SAMPLERATES_TESTED]
Definition: miniport.cpp:18
static KSDATARANGE_AUDIO PinDataRangesPCMStreamRender[WAVE_SAMPLERATES_TESTED]
Definition: miniport.cpp:16
void __fastcall obj_AddRef(PUNKNOWN obj, void **ppvObject)
Definition: miniport.cpp:1264
static PCPROPERTY_ITEM PropertiesDAC[]
Definition: miniport.cpp:206
static PKSDATARANGE PinDataRangePointersAnalogBridge[]
Definition: miniport.cpp:49
static PCPIN_DESCRIPTOR MiniportPins[]
Definition: miniport.cpp:79
static KSDATARANGE PinDataRangesAnalogBridge[]
Definition: miniport.cpp:20
static PKSDATARANGE PinDataRangePointersPCMStreamRender[WAVE_SAMPLERATES_TESTED]
Definition: miniport.cpp:40
void __fastcall obj_Release(void **ppvObject)
Definition: miniport.cpp:1273
static PKSDATARANGE PinDataRangePointersPCMStreamCapture[WAVE_SAMPLERATES_TESTED]
Definition: miniport.cpp:41
static PKSDATARANGE PinDataRangePointersMicStream[MIC_SAMPLERATES_TESTED]
Definition: miniport.cpp:42
static KSDATARANGE_AUDIO PinDataRangesPCMStreamCapture[WAVE_SAMPLERATES_TESTED]
Definition: miniport.cpp:17
static PCNODE_DESCRIPTOR MiniportNodes[]
Definition: miniport.cpp:228
static PCCONNECTION_DESCRIPTOR MiniportConnections[]
Definition: miniport.cpp:264
static PCFILTER_DESCRIPTOR MiniportFilterDescriptor
Definition: miniport.cpp:287
STDMETHODIMP_(void) CMiniport
Definition: miniport.cpp:987
const int DBG_STREAM
Definition: debug.h:22
const int DBG_POWER
Definition: debug.h:23
#define DOUT(lvl, strings)
Definition: debug.h:82
const int DBG_VSR
Definition: debug.h:28
const int DBG_WARNING
Definition: debug.h:18
void __fastcall obj_AddRef(PUNKNOWN obj, void **ppvObject)
Definition: miniport.cpp:1264
const DWORD dwMicSampleRates[MIC_SAMPLERATES_TESTED]
Definition: miniport.h:18
const int PIN_WAVEIN_OFFSET
Definition: miniport.h:22
const int MIC_SAMPLERATES_TESTED
Definition: miniport.h:14
void __fastcall obj_Release(void **ppvObject)
Definition: miniport.cpp:1273
const DWORD dwWaveSampleRates[WAVE_SAMPLERATES_TESTED]
Definition: miniport.h:16
const int WAVE_SAMPLERATES_TESTED
Definition: miniport.h:13
const int PIN_MICIN_OFFSET
Definition: miniport.h:23
const int PIN_WAVEOUT_OFFSET
Definition: miniport.h:21
WavePins
Definition: shared.h:317
@ PIN_MICIN
Definition: shared.h:322
@ PIN_WAVEOUT
Definition: shared.h:318
@ PIN_WAVEOUT_BRIDGE
Definition: shared.h:319
@ PIN_WAVEIN_BRIDGE
Definition: shared.h:321
@ PIN_WAVEIN
Definition: shared.h:320
@ PIN_MICIN_BRIDGE
Definition: shared.h:323
@ PINC_SURROUND_PRESENT
Definition: shared.h:74
@ PINC_CENTER_LFE_PRESENT
Definition: shared.h:75
@ PINC_MICIN_PRESENT
Definition: shared.h:70
@ PINC_MIC_PRESENT
Definition: shared.h:71
@ NODEC_PCM_VSR_INDEPENDENT_RATES
Definition: shared.h:97
@ NODE_WAVEOUT_DAC
Definition: shared.h:331
@ NODE_MICIN_ADC
Definition: shared.h:333
@ NODE_WAVEIN_ADC
Definition: shared.h:332
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define STATICGUIDOF(guid)
Definition: dmksctrl.h:25
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
unsigned short WORD
Definition: ntddk_ex.h:93
const ULONG MC_SR
Definition: ichreg.h:38
const ULONG PI_SR
Definition: ichreg.h:24
const ULONG PO_SR
Definition: ichreg.h:31
const ULONG GLOB_STA_PIINT
Definition: ichreg.h:89
const ULONG GLOB_STA_POINT
Definition: ichreg.h:88
const ULONG GLOB_STA
Definition: ichreg.h:43
const ULONG GLOB_STA_MINT
Definition: ichreg.h:87
NTSTATUS NTAPI PcNewInterruptSync(OUT PINTERRUPTSYNC *OutInterruptSync, IN PUNKNOWN OuterUnknown OPTIONAL, IN PRESOURCELIST ResourceList, IN ULONG ResourceIndex, IN INTERRUPTSYNCMODE Mode)
Definition: interrupt.cpp:295
#define KSDATAFORMAT_SPECIFIER_NONE
Definition: ks.h:1157
union KSDATAFORMAT KSDATARANGE
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
@ KSPIN_COMMUNICATION_NONE
Definition: ks.h:1254
@ KSPIN_COMMUNICATION_SINK
Definition: ks.h:1255
union KSDATAFORMAT * PKSDATARANGE
@ KSPROPERTY_AUDIO_CHANNEL_CONFIG
Definition: ksmedia.h:1056
#define KSAUDIO_SPEAKER_SURROUND
Definition: ksmedia.h:1457
#define KSAUDIO_SPEAKER_MONO
Definition: ksmedia.h:1453
#define KSAUDIO_SPEAKER_5POINT1
Definition: ksmedia.h:1459
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:1021
struct KSDATARANGE_AUDIO * PKSDATARANGE_AUDIO
#define KSAUDIO_SPEAKER_QUAD
Definition: ksmedia.h:1455
#define KSNODETYPE_ADC
Definition: ksmedia.h:262
#define KSDATAFORMAT_SUBTYPE_ANALOG
Definition: ksmedia.h:993
#define WAVE_FORMAT_EXTENSIBLE
Definition: ksmedia.h:651
#define KSAUDFNAME_RECORDING_CONTROL
Definition: ksmedia.h:333
#define PINNAME_CAPTURE
Definition: ksmedia.h:147
#define KSNODETYPE_DAC
Definition: ksmedia.h:287
#define KSDATAFORMAT_SPECIFIER_DSOUND
Definition: ksmedia.h:988
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:983
#define KSAUDIO_SPEAKER_STEREO
Definition: ksmedia.h:1454
#define KSCATEGORY_AUDIO
Definition: ksmedia.h:172
#define KSPROPSETID_Audio
Definition: ksmedia.h:1051
#define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Definition: ksmedia.h:1031
static PCPIN_DESCRIPTOR MiniportPins[]
static PCNODE_DESCRIPTOR MiniportNodes[]
static PCCONNECTION_DESCRIPTOR MiniportConnections[]
static PCFILTER_DESCRIPTOR MiniportFilterDescriptor
WAVEFORMATPCMEX * PWAVEFORMATPCMEX
Definition: mmreg.h:468
#define ASSERT(a)
Definition: mode.c:44
#define __fastcall
Definition: sync.c:38
static HRESULT QueryInterface(REFIID, void **)
Definition: events.c:2587
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
#define min(a, b)
Definition: monoChain.cc:55
#define _Use_decl_annotations_
Definition: ms_sal.h:275
#define _Out_
Definition: ms_sal.h:345
#define _COM_Outptr_
Definition: ms_sal.h:449
#define _In_
Definition: ms_sal.h:308
#define DBG_ERROR
Definition: nfs41_debug.h:78
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ PowerDeviceD0
Definition: ntpoapi.h:49
@ PowerDeviceD3
Definition: ntpoapi.h:52
#define STATUS_NO_MATCH
Definition: ntstatus.h:751
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
int nChannels
Definition: pcmconverter.c:95
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
IInterruptSync * PINTERRUPTSYNC
Definition: portcls.h:888
IResourceList * PRESOURCELIST
Definition: portcls.h:442
#define PCFILTER_NODE
Definition: portcls.h:154
#define DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTable, PropertyTable)
Definition: portcls.h:368
IMiniportWavePci * PMINIPORTWAVEPCI
Definition: portcls.h:1697
@ InterruptSyncModeNormal
Definition: portcls.h:840
IPowerNotify * PPOWERNOTIFY
Definition: portcls.h:2059
IPort * PPORT
Definition: portcls.h:1105
#define REFIID
Definition: guiddef.h:118
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
ULONG MaximumChannels
Definition: ksmedia.h:680
ULONG MinimumBitsPerSample
Definition: ksmedia.h:681
ULONG MaximumBitsPerSample
Definition: ksmedia.h:682
ULONG MaximumSampleFrequency
Definition: ksmedia.h:684
KSDATARANGE DataRange
Definition: ksmedia.h:679
ULONG MinimumSampleFrequency
Definition: ksmedia.h:683
ULONG ConnectionCount
Definition: portcls.h:362
KSPIN_DESCRIPTOR KsPinDescriptor
Definition: portcls.h:343
WAVEFORMATEX Format
Definition: ksmedia.h:638
WORD wValidBitsPerSample
Definition: ksmedia.h:641
union WAVEFORMATEXTENSIBLE::@3029 Samples
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
uint32_t * PULONG
Definition: typedefs.h:59
void * PVOID
Definition: typedefs.h:50
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:168
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082