WaveRT miniport: dynamic channel number change

Dear Community,

could you, pls, advise w/ the following topic

I’m implementing Win audio driver which exposes virtual micarray and speaker (see simpleaudiosample for ex.). It has WaveRT and Topology miniports for both speaker and mic. What I need is to change number of supported channels dynamically at runtime.

Basically, driver is based on simpleaudiosample example from ms. What I’m doing to change is:

  1. Get custom IOCTL w/ new channel number;
  2. Handover this channel number to mic and speaker WaveRTs;
  3. In each WaveRT I do the following:
    3.1. Update EndpointMinipair->DeviceMaxChannels to a new channel value;
    3.2. Update streaming pin’s audio format data range (have only one entry) w/ new max channel number;
    3.3. Update streaming pin’s array with supported device formats and modes (basically formats in this structure) w/ new max channel number;
    3.4. Emit KSEVENT_PINCAPS_FORMATCHANGE event for streaming pin (event is present in automation table for streaming pin and properly registered in port driver w/ AddEventToEventList() upon PCEVENT_VERB_ADD);

My expectation is that upon KSEVENT_PINCAPS_FORMATCHANGE , port driver will call KSPROPERTY_PIN_PROPOSEDATAFORMAT (implemented only set) / KSPROPERTY_PIN_PROPOSEDATAFORMA2 (implemented only get) and IMiniportWaveRT::DataRangeIntersection(), and will adjust streaming pin’s format to new number of channels. My expectation to vary number of channels to any value in the range [0;32].

Problem is that:

  • OK: If I initialize miniport (upon subdevice creation) and all supported formats (step 3.3) contain 32 channels only, I can vary number of channels dynamically to any value in the range [0;32].
  • NOT OK: But if I initialize miniport (upon subdevice creation) and all supported formats (step 3.3) contain 2 channels and then try to change number of channels to 32, speaker device cannot be initialized through WASAPI AudioClient. I also can’t play test tone through mmsys.cpl speaker’s properties. However mic is initialized normally

I’ve tried to debug different things, but could not solve ‘NOT OK’ case. I also don’t understand why there is difference between speaker and mic when KSEVENT_PINCAPS_FORMATCHANGE is emitted (mic: initialized, speaker: not). Could you, pls, share your expertise and help me to clarify how to find the root cause of ‘NOT OK’ case? Thank you for your time

@Tim_Roberts may be you may advice here? Previously, I’ve found your input extremely helpful in other osr topics. My apologies for bothering

In the video world (AVStream), the static data formats report everything you can ever possibly do, and the DataIntersection handler trims that down to the list of things you can do right now. I have not always had the same experience with audio drivers. There do seem to be some hidden assumptions about 2-channel devices, but I was never able to come up with a mental model to describe it.

As always, I would suggest you ask your question on the [wdmaudiodev] list at https://www.freelists.org/list/wdmaudiodev . That’s where the cool audio kids hang out, including two members of the Microsoft audio team who have proven to be an incredible resource over the years.

1 Like

@Tim_Roberts said:
In the video world (AVStream), the static data formats report everything you can ever possibly do, and the DataIntersection handler trims that down to the list of things you can do right now. I have not always had the same experience with audio drivers. There do seem to be some hidden assumptions about 2-channel devices, but I was never able to come up with a mental model to describe it.

As always, I would suggest you ask your question on the [wdmaudiodev] list at https://www.freelists.org/list/wdmaudiodev . That’s where the cool audio kids hang out, including two members of the Microsoft audio team who have proven to be an incredible resource over the years.

@Tim_Roberts Thx a lot for feedback. I was already not expecting to get recommendation, so almost lost your comment.

Anyway, I could move forward w/ the investigation of this topic. I think you are right, there is some hidden assumption. But I’m not sure it is related to 2 channels. The same story w/, for ex., 6 channels. I think this is rather related to endpoint categories. One of such non-hidden assumptions we know as the one - speaker’s friendly name is always hardcoded to ‘Speakers’. Here I think may be the same story.

I was experimenting w/ multiple endpoints support for the same device and had to change topo bridge pin category to DIGITAL_INTERFACE and got unexpected bonus. Looks like this limitation disappeared. I can initialize subdevice w/ 2 channels and then change number of channels as I need. This is something I expected initially. At the moment I don’t know why the same behavior does not work w/ mic/speaker catgories. But, as I mentioned, you may be right and there are hidden assumptions. If I understand, I’ll update the topic w/ this info.

Also, want to thank you for recommendation related [wdmaudiodev] list. I appreciate and already there. I have one more topic which is unclear to me for this group. Till now I could not find an answer by my own and probably will ask for recommendations if will not find an answer in the near future. In particualr it’s interesting if there is an API to set input/output audio endpoints to a different process which has an audio client. Basically, it’s iteresting to do programmatically the same that may be done manually for the process through Settings>Sound>Mixer settings panel in Win 11.

Anyway, thx a lot for your input and time

In particualr it’s interesting if there is an API to set input/output audio endpoints to a different process which has an audio client

Are you asking if you can move an audio endpoint to another process? No, and there’s really no point in doing so. If you “stole” an endpoint from a process that wasn’t expecting it, or forced an endpoint into a process not expecting one, disaster would ensue. And if both processes are cooperating, then just have process A close the endpoint and process B open it.

1 Like

@Tim_Roberts I think the reason you mentioned is fair. At the end this is just pin instance which has limited number of streams. So, I think in the best case there could be a replacement. In the worst case - replacement w/ endpoint which does not have available streams. Indeed this may look as “stealing” and lead to a mess. I thought this replacement could require appropriate privileges. Also, I think something similar is done through mixer sound settings manually. But as, I mentioned, you are right. Looks like this door is closed. From my side I also could not find API for this purpose