locked
Creating an audio mixer using win .dll calls RRS feed

  • Question

  • I'm writing a Python program for running under Win10, that needs to play two different sounds simultaneously and allow the user to change their volumes separately while playing. I can not use any 3rd party library but I can make calls to native Win dll.

    I was looking into winmm.dll but it seems that it doesn't allow you to change volumes of two sounds separately.

    Are there any other dlls I could use to make a controllable sound mixer?

    Monday, June 10, 2019 7:41 AM

All replies

  • Hi,

    Thank you for posting here.

    >>Are there any other dlls I could use to make a controllable sound mixer?

    I suggest you could try to use Windows Audio Mixer API Wrapper Library. For more details you could refer to the link:
    https://www.codeproject.com/Articles/30296/Windows-Audio-Mixer-API-Wrapper-Library

    Best Regards,

    Jeanine Zhang

    Monday, June 10, 2019 9:13 AM
  • > I can not use any 3rd party library

    That is a ridiculous restriction.  The primary reason one uses Python is because there is an active community producing a rich collection of good quality components, so that you don't waste your time and your company's money by reinventing the same wheel over and over.  You will be learning lessons other people have already learned, and making silly mistakes that other people have already made and fixed.

    The low-level Windows Audio APIs do not have the concept of "separate sounds".  You feed pre-mixed audio buffers into the render endpoint.  Since you are doing the mixing, you can adjust the individual volume levels.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Monday, June 10, 2019 6:43 PM
  • I don't see how that helps me at all, this library just displays system sound devices and controls.
    Monday, June 10, 2019 9:36 PM
  • Unfortunately, I can only work with Python modules that are supplied with the program people buy, I can't write a plug-in that downloads and install extra packages. I can import from ctypes that gives me some freedom.

    As to the pre-mixed buffers, when you change separate volumes on the fly, should I re-pre-mix them on the fly as well, that's how it works?

    Can you please point me to an example?

    On the other hand, if I open two copies of music players in Win, they will play independently with separate volumes, so what mixes them?


    • Edited by alikim Monday, June 10, 2019 9:47 PM
    Monday, June 10, 2019 9:43 PM
  • Hi,

    >> if I open two copies of music players in Win, they will play independently with separate volumes, so what mixes them?

    I suggestyou could try to use XAudio2. It provides a signal processing and mixing foundation. Submixing combines several sounds into a single audio stream—for example, an engine sound made up of composite parts, all of which are playing simultaneously. XAudio2 allows for arbitrary levels of submixing, enabling the creation of complex sounds.

    For more details you could refer to the link:
    https://docs.microsoft.com/zh-cn/windows/desktop/xaudio2/xaudio2-voices

    >>As to the pre-mixed buffers, when you change separate volumes on the fly, should I re-pre-mix them on the fly as well, that's how it works?

    I suggest you could refer to the link:
    https://docs.microsoft.com/zh-cn/windows/desktop/xaudio2/how-to--change-voice-volume

    Best Regards,

    Jeanine Zhang

    Wednesday, June 12, 2019 5:07 AM
  • > ... that are supplied with the program people buy.

    No one buys Python.  It is free.

    > if I open two copies of music players in Win, they will play independently with
    > separate volumes, so what mixes them?

    The Audio Engine mixes them, but it's the music players providing the volume control.  There's a master volume for the speaker endpoint, but not separate volumes by application.

    In your case, your application represents one stream into the Audio Engine.  It doesn't know there are multiple sources.  So, it's up to you to mix them.  As long as both sources have the same data rate, that's not too hard.  You will need a component that takes one buffer at a time from each source, then blends them together in a loop kind of like:

        for i in range(buffersize):
            outbuf[i] = inbuf1[i] * volume1 + inbuf2[i] * volume2

    You might need to limit or clip the result, but that's the concept.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Wednesday, June 12, 2019 8:56 PM