Appreciate the quick response! Thanks for clarifying.
On Tue, Jun 16, 2020 at 2:23 PM Matthew van Eerde <
Chatted with the devs and this is the response:
APOs are not in control of the cadence of the realtime pipeline they
operate in. So in your scenario, the APO cannot get away without
implementing a ring buffer.
The Calc*Frames methods are only relevant for APOs that perform sample
In particular, CalcInputFrames is used by APOs on the microphone path that
change the sample rate, e.g. the Windows resampler APO when the audio
client is initialized with the AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM flag.
CalcOutputFrames is used similarly by APOs on the speaker path that change
the sample rate.
*From: *Akshay Cadambi <akshay@xxxxxxxxxxxx>
*Sent: *Tuesday, June 16, 2020 1:50 PM
*Subject: *[EXTERNAL] [wdmaudiodev] Behavior of CalcInputFrames and
We are currently implementing some custom audio processing via an SFX APO
and an EFX APO. Some of our algorithms require a power-of-two or
multiple-of-two buffer size in order to meaningfully process audio. Our
current implementation currently gets around this by using a ring-buffer.
However, we noticed that the IAudioProcessingObjectRT interface provides
the following two methods via baseaudioprocessing object
the swap APO sample.
STDMETHOD_(UINT32, CalcInputFrames)(_In_ UINT32 u32OutputFrameCount);
STDMETHOD_(UINT32, CalcOutputFrames)(_In_ UINT32 u32InputFrameCount);
Playing around with the debugger we found that CalcInputFrames gets
called with 480 being the output frame count. Given the 10ms latency
requirement in the windows audio engine, this makes sense for a sample rate
If we override this function to return 480*2 then we notice that
APOProcess gets called with double the number of input frames (as
We also noticed that CalcOutputFrames never gets called.
We are considering using this mechanism as a way to obtain the appropriate
number of frames that our algorithm requires and removing the need to use
ring buffers in our implementation.
We have the following questions:
1. When does CalcOutputFrames get called?
2. Is there any documentation that you can point us to in order to
ensure that we are implementing these correctly?
3. What is the behavior when these functions are overridden?
4. What if we return a non-integer multiple of the input argument
in CalcInputFrames: for example, if we receive 480 --- and we return 512
(next power of two).
5. Other than the fact that it is called by the real-time thread,
are there any other gotchas that we should be aware of with using these
Apologies for the lack of specificity. We are merely trying to understand
the appropriate use cases for those two methods, and what the behavior of
the audio engine is, before moving forward with a solution.
Any help or documentation would be appreciated. Thanks in advance for your
time and energy!