Intercepting and postprocessing all audio streams on Windows - c++

I would like to know is there any way I create an application which can intercept all the audio that is being played back on the computer, so I can process the audio (apply some effect) and then pass it further to the Windows audio subsystem?
I just had a glimpse in Vista/7 WASAPI, there is this sAPO:
http://www.microsoft.com/whdc/device/audio/sysfx.mspx
but it seems that I cannot create my sAPO and install it anywhere I like - I need a WHQL drivers for this.
Is there any universal way to do that?
I have an experience with DirectSound but I haven't seen any useful info about intercepting the audio streams.

If you're loading a custom sAPO, you're globally affecting the sound for a system. This is going to require signing. From this article:
The audio engine does not load
unsigned sAPOs into the audio
processing graph. So while you are
testing your sAPO, you must disable
the protected process for Audiodg.exe.
To disable the protected process, set
the value of the
DisableProtectedAudioDG registry key
to '1'.

Related

Windows Audio Driver vs. WASAPI

I'm right now reading the microsoft documentation about drivers and core audio apis. At the moment I'm still confuse which way to go to achieve what I need.
I have an audio application which is Standalone and coded with framework JUCE in C++. And I need to build a Windows solution that would capture the audio stream that is going to an audio endpoint device to use it as an input of my audio application.
This stream must have an unaltered volume: always 1.0 (no matter if the hardware volume is changed or muted).
I must be able to choose between the different endpoint devices, for exemple if I have an external soundcard that is plugged, my audio application should be able to intercept and copy the stream that is going to that external soundcard, or do the same for the stream that is going to the built-in speakers.
The idea is to capture the output streams before they are modified by hardware volume modifications, and make a copy of them routed to my application without changing the output routing and behaviour.
The microsoft documentation is very furnished, but even if the WASAPI provides a lot of ways to capture and stream from audio endpoint devices, I'm not sure it is possible to get an unaltered volume, as it will always capture what's exactly coming out of the speakers.
This is why I don't know If I can implement a feature directly in my audio application that will get the streams I want with WASAPIs or if I have to code a proper Audio Driver that would make a copy of the streams I want for my application to be able to use these streams.
The documentations I refer to:
Audio Drivers design guide
Core Audio APIs / WASAPI
Thanks for the help,
Best,
Maxime
Sometimes the volume control is implemented in software, and sometimes it is implemented in hardware. You can call IAudioEndpointVolume::QueryHardwareSupport to see if the volume control for the audio endpoint you're working with is implemented in hardware or software.
Sometimes the audio loopback is implemented in software, and sometimes it is implemented in hardware. There is no API to tell which.
If the audio loopback is implemented in software, and the volume control is implemented in hardware, then you will get back the data you want.
If the audio loopback is implemented in hardware, or the volume control is implemented in software, the the audio data you get back has already had the volume adjustment applied.
What does your application do with the audio data it receives? The primary use case for audio loopback data is echo cancelation, where you usually WANT the volume to be applied.

Can I directly interact with audio endpoints on windows?

I am trying to write a pro music/audio processing application, and I would like to be able to interact with the audio inputs/outputs at a very low level - ideally something allowing me to apply effects to the audio inputs and output this in real-time, similar to programs like Logic, Ableton etc.
I have written a pretty basic program that detects audio endpoint devices and can change their volumes using the MMDevice interface, but this is nowhere near the functionality I would like.
I have learned from the Microsoft docs that the four core-audio APIs are:
MMDevice
WASAPI
DeviceTopology
EndpointVolume
but it doesn't seem like any of these have the capabilities that I need. I'm thinking that I will need to be able to interact with the speakers at the level of setting the position of the membrane at a given time.
Is this even possible? If so, what can I use to do this?
The Windows Audio Session API (WASAPI) is the best bet for this purpose. It allows interaction with audio endpoints and setting up audio streams (which are streams of data that you can send or receive in real time). A good example is here.

Create audio buffer from application's audio interface

Using PortAudio, how can I access running applications' audio interface so that I can capture the audio they produce in real time? The goal would be then to send this audio as UDP packet to a server.
I've had a look at PortAudio's code samples but can't find anything similar.
Maybe PortAudio is not the right library for me?
I'm working mainly on Mac OS.
Core Audio does not have the sort of functionality you're looking for. Processes are sandboxed/isolated from one another.
You could probably achieve this using library injection, but there are a number of complications. OSX has added System Integrity Protection which disables injections. If you're willing to disable SIP (which is dangerous! Proceed at your own risk!) then you could try something like mach_inject and intercepting the target processes' calls to Core Audio. But you'd never be able to ship something like this, since asking users to disable SIP is not reasonable.

Capturing Audio signals in Qt

I was wondering if it is possible to capture a copy of the audio output in Qt so I can process it. Here they said it's possible to monitor the playback, but I think it's only possible if you use a self made music player, which I don't want. I want to capture the signal from no matter where it is player (youtube, spotify, facebook, etc.). Is there a way to analyze this data with Qt? Is it possible to set my output of my soundcard as a QMediaSource?
Thank you in advance.
In general, no, that isn't possible, simply because your process (and therefore the Qt library that is loaded into your process) does not have access to that information. (I believe this lack of access is deliberate; since if it did have access like that, there might be security and/or privacy implications, i.e. app A could use it to spy on the audio output of app B, etc)
There may be an OS-specific mechanism that you can use; for example, if you are running your program under MacOS/X, you can install the SoundFlower audio driver that can function as a loopback device, allowing programs to read audio from its "audio input" that was previously routed to its "audio output". But without that kind of external support, it's not currently possible to record the computer's audio output via Qt.

MIDI sniffing + OpenGL in Windows

I'm currently specing out projects for my graphics class and I am thinking of writing an application that displays a visualizer for midi data. What I would like to do is sniff midi data as it passes through the system. I do not want to hijack a driver, only watch the data go by (that is, I want the MIDI data to later be accessible by a DAW). I am not familiar with programatically accessing midi in windows. The closest I could find to what I want seems to be midi spy. However I would prefer to write the app in c/c++.
I was looking at MIDI Stream API, but I can't tell if I'll be able to sniff devices that weren't opened by the library. I was also looking at SDL Mixer and QT Midi. I'm just trying to get some personal pros and cons to the options that I've presented or ones that I haven't found.
Unfortunately, there is no way to actually sniff MIDI streams under Windows. All you can do is place your application between the two MIDI devices.
Unless you are putting software between physical in/out ports, you will need to set up a virtual MIDI loopback driver that directs the MIDI stream data from an input to an output. Fortunately, there are a few off-the-shelf solutions already. The easiest method is to require your users to set up a virtual MIDI port and configure it on their own. LoopBe1 and MIDI Yoke are free.
Another method is to use a virtual MIDI driver that goes directly to your application. Tobias Erichsen has created a very easy-to-use driver for this very purpose. I don't believe he has released it yet, but if you shoot him an e-mail, he might get back to you. See this question: DDK "Hello World"