Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting... Please check out the Community Guidelines in the
Announcements and Administration Category, below.

SysVAD driver issue: Output audio being interrupted

Bruce_LuBruce_Lu Posts: 4
Hi Guys,

I created a virtual microphone driver based on MSVAD (it works with win7) and another based on SysVAD (it works with Win10).

I send 48KHZ stereo PCM samples from my application to virtual driver with IKsControl::KsProperty method. The PCM samples are reading from mp3 or wave file, then send to driver 4608 bytes continuously.

In the driver side, I create a circular buffer to cache pcm samples from application. When the 'CMiniportWaveCyclicStreamMSVAD::CopyFrom' is calling after 'CMiniportWaveCyclicStreamMSVAD::GetPosition', I copy the cached samples from circular buffer to DMA. If the cached sample is not enough, I fill 0.

The issue is: the output audio of virtual microphone sounds being interrupted sometimes and have noise. It seems because GetPostion and CopyFrom are called every 10 milliseconds, and the CopyFrom request 1920 bytes each time, but application send data to driver with 4608 bytes frequency.

I tried to allocate bigger buffer size for circular buffer, but it doesn't work.

How to fix this issue? Could anyone help me?
Thanks

Comments

  • Tim_RobertsTim_Roberts Posts: 12,567
    On Jul 7, 2018, at 3:48 AM, xxxxx@hotmail.com <xxxxx@lists.osr.com> wrote:
    >
    > The issue is: the output audio of virtual microphone sounds being interrupted sometimes and have noise. It seems because GetPostion and CopyFrom are called every 10 milliseconds, and the CopyFrom request 1920 bytes each time, but application send data to driver with 4608 bytes frequency.
    >
    > I tried to allocate bigger buffer size for circular buffer, but it doesn't work.

    Your driver is required to supply what the Audio Engine asks for. You will have to have a circular buffer inside your driver to hold the larger buffers from your application, and deliver them 1920 bytes at a time to the Audio Engine.

    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Bruce_LuBruce_Lu Posts: 4
    Yes, I have a circular buffer to hold the data from application. And copy the required 1920 bytes from the circular buffer to the destination pointer of CopyFrom.

    Does the GetPostion of msvad or sysvad return accurate values? These two samples use relative timestamp to calculate position.
  • Tim_RobertsTim_Roberts Posts: 12,567
    xxxxx@hotmail.com wrote:
    > Yes, I have a circular buffer to hold the data from application. And copy the required 1920 bytes from the circular buffer to the destination pointer of CopyFrom.
    >
    > Does the GetPostion of msvad or sysvad return accurate values? These two samples use relative timestamp to calculate position.

    I think you need to prove that to yourself.  Have you added trace
    outputs so you can follow the computations and verify they're doing what
    you expect?  I just completed a virtual audio driver project based on
    MSVAD that works very much as you described (application feeds fake mic
    data into circular buffer which is then sent out through CopyFrom, as
    well as in the other direction), and it's working reliably.  I maintain
    statistics so we can monitor the circular buffer levels over time, and
    the graph is quite consistent.

    Also, are you putting a red flag in the debug log if the circular buffer
    either fills or goes dry?  That's an indication of a problem.

    Where does your app get its timing?

    --
    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Bruce_LuBruce_Lu Posts: 4
    Thanks for your suggestion. I will add trace in the circular buffer.

    > Where does your app get its timing?
    My application doesn't send timestamp to Driver. I use DirectShow to play an audio file and I use DirectShow's Sample Grabber to get playing PCM samples then pass them to Driver.
    In the driver side, I haven't modified the MSVAD's GetPosition function, so the time is calculated from KeQueryInterruptTime.
  • Tim_RobertsTim_Roberts Posts: 12,567
    xxxxx@hotmail.com wrote:
    > Thanks for your suggestion. I will add trace in the circular buffer.
    >
    >> Where does your app get its timing?
    > My application doesn't send timestamp to Driver. I use DirectShow to play an audio file and I use DirectShow's Sample Grabber to get playing PCM samples then pass them to Driver.

    It's not about timestamping, it's about pacing the data flow so you
    don't flood the circular buffer.  The answer to my question is
    "DirectShow".  It gets its timing from timestamps in the audio file.

    --
    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Bruce_LuBruce_Lu Posts: 4
    After some tests and checking dump data of capturing stream, I found it's not an issue of circular buffer, GetPosition or CopyFrom. It seems that is a bug of MS...

    Each time a new application render the virtual microphone, in first 1.5 minutes the audio sounds being interrupted, after 1.5 minutes it will be smooth. Keep the first application running, then launch another application to render the virtual microphone, the second application gets audio noise in first 1.5 minutes.

    It seems the WASAPI layer doesn't get data from microphone driver correctly in the first 1.5 minutes. I think if it's a hardware microphone the audio quality is lower, the noise is not obviously. When I send high quality song data to microphone driver, it's every easy to hear noise at beginning.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!