[wdmaudiodev] Re: WaveCyclic Driver, sample rate changed by hardware

  • From: Ed Tottenham <Ed.Tottenham@xxxxxxxxx>
  • To: "wdmaudiodev@xxxxxxxxxxxxx" <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Tue, 28 Jan 2020 16:52:19 +0000

Hello again.

Sorry to keep banging on about this one, but I still seem to be missing 
something.

The driver detects that the hardware has changed sample rate.

It raises five KSEVENT_PINCAPS_FORMATCHANGE events, one for each WAVE Pin.

The Port Driver calls into my driver's PropertyHandler_WaveFilter proposing 
various sample rates and resolutions. I refuse all but the sample 
rate/resolution that the device has switched to and eventually get a "Set 
Format" call for each Pin and everything is working as it should be.

My problem is now that I can't distinguish the attempts at changing sample rate 
due to a user playing via WASAPI or Kernel Streaming. The change of sample rate 
seems to use the same mechanism as the handling of the 
KSEVENT_PINCAPS_FORMATCHANGE event.

Although the device can change the sample rate, we want it to change the format 
(if necessary) when a WASAPI/Kernel stream starts playing.

Is there any way to detect that a format change is due to a WASAPI/Kernel 
Stream being played? The only thing I can see at the moment is to refuse it if 
it comes "shortly" after a KSEVENT_PINCAPS_FORMATCHANGE event. But this seems 
to be very unsatisfactory, and "shortly" appears to be several seconds on our 
larger devices with 24 channels in each direction.

Best Wishes

Ed Tottenham

________________________________
From: wdmaudiodev-bounce@xxxxxxxxxxxxx [wdmaudiodev-bounce@xxxxxxxxxxxxx] on 
behalf of Matthew van Eerde [dmarc-noreply@xxxxxxxxxxxxx]
Sent: 21 January 2020 17:45
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Re: WaveCyclic Driver, sample rate changed by hardware


  *   Pin 0 (I believe that is used to change the format on all pins).

No, that is not correct. If you have five audio endpoints, you need to raise 
five separate KSEVENT_PINCAPS_FORMATCHANGE events – one for each pin factory 
whose format capabilities have changed. The filter and pin ID need to be 
correct for each of these events, there is no wildcarding.

From: Ed Tottenham<mailto:Ed.Tottenham@xxxxxxxxx>
Sent: Tuesday, January 21, 2020 8:27 AM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [EXTERNAL] [wdmaudiodev] Re: WaveCyclic Driver, sample rate changed by 
hardware

Hello,
After a long delay, I am still struggling with this problem. I've listed below 
what I see happening and how the driver reacts. Could someone please tell me 
where I am going wrong.

The device has 4 input channels and 6 output channels. These are configured to 
show up as stereo pairs, so 2 pairs of inputs and 3 pairs of outputs. Although 
there are pins specified for each pair, there is only one global sample format 
for the whole device.

The driver detects that the device has changed the sample rate from 44k1 to 
96k. It calls GenerateEventList() specifying KSEVENT_PINCAPS_FORMATCHANGE as 
the Event ID and KSEVENTSETID_PinCapsChange as the Event Set for Pin 0 (I 
believe that is used to change the format on all pins).

2.03 seconds later, the Port Driver calls into my driver's 
PropertyHandler_WaveFilter with a KSPROPERTY_PIN_PROPOSEDATAFORMAT(SET) to 
specify PCM WAV as the format. It then calls in with 
KSPROPERTY_PIN_PROPOSEDATAFORMAT(SET). The driver returns a structure 
specifying the preferred format as 2 Channel, 24 bit, 96k.

The Port Driver calls my driver to set the format as 2 Channel, 24 bit, 96k. 
This is the desired behaviour, BUT...

The Port Driver goes on to propose different PCM formats every 30 milliseconds. 
Initially these are all 1 channel with all permutations of 16, 24 and 32 bit 
resolutions with 44k1, 48k, 88k2, 96k, 176k4 and 192k sample rates. These are 
all refused because they are single channel.

The Port Driver then proposes 2 Channel, 16 bit, 44k1. From experience if the 
driver refuses this proposal, then that format will not be available to any 
applications using WASAPI, so the driver accepts the proposal as a valid 
format. The Port Driver then immediately calls my driver to set the format as 2 
Channel, 16 bit, 44k1.

The Port Driver continues, every 30mS to propose all combinations of 2 channels 
at 16, 24 and 32 bit resolution with 44k1, 48k, 88k2, 96k, 176k4 and 192k 
sample rates. The driver accepts all of these except the 32-bit variants.

This whole process repeats several times. The Port Driver makes the GET 
request. Now the driver returns that the preferred format is 2 Channel, 16 bit, 
44k1 (from the Driver's point of view, this could have been a WASAPI 
application which has switched to that format). The Port Driver proposes that 
format, the driver accepts it and SetFormat is called to set that format again. 
The Port Driver continues to propose all combinations of 1 and 2 channels with 
16, 24 and 32 bits with 44k1, 48k, 88k2, 96k, 176k4 and 192k sample rates. 
Sometimes it decides to set the format as 2 Channel, 16 bit, 44k1 and sometimes 
2 Channel, 24 bit, 44k1.

The switch to 96k has been totally lost in all this.

A thought occurs to me that the calls to me that it might be because the format 
change calls are being made on a "per Stream" basis rather than for the driver 
overall. But if this is the case, how do I link the calls with their intended 
pins.

Many thanks in advance
Ed Tottenham

From: wdmaudiodev-bounce@xxxxxxxxxxxxx <wdmaudiodev-bounce@xxxxxxxxxxxxx> On 
Behalf Of Matthew van Eerde
Sent: 30 October 2019 15:22
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Re: WaveCyclic Driver, sample rate changed by hardware

The way it works is, the driver advertises support for a set of formats (could 
be a single format), and (optionally) a “preferred” format. The Windows audio 
engine then chooses one of those to use to stream audio.

If the driver’s supported set of formats changes, or its format preference 
changes, it raises a KSEVENT_PINCAPS_FORMATCHANGE event, and the negotiation 
starts over from the beginning.

From: Ed Tottenham<mailto:Ed.Tottenham@xxxxxxxxx>
Sent: Wednesday, October 30, 2019 8:16 AM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [wdmaudiodev] WaveCyclic Driver, sample rate changed by hardware

Hi there,

Can someone tell me how sample rate changes should be "pushed" up to the Port 
Driver.

I need to modify a WaveCyclic Miniport Driver to be able to handle sample rate 
changes which come from the hardware.

My first attempt was to call GenerateEventList() specifying 
KSEVENT_PINCAPS_FORMATCHANGE as the Event ID and KSEVENTSETID_PinCapsChange as 
the Event Set.

But, doing this seems to cause the Port Driver to start rebuilding the 
endpoints, proposing just about every sample rate under the sun.

Effectively, I need to let the hardware set the sample rate if it feels it 
needs to, but I also want WASAPI to be able to change it too.

Can this be achieved?

Ed Tottenham



Other related posts: