Yesterday, I talked about volume in general, today I want to drill into volume more detail.
In Vista, for any given audio stream, there are actually 4 different volume controls.
Each of these is a gain stage, so each of them is applied linearly to the input audio samples to create the final output audio stream.
I'm going to steal my "big picture" from my "Audio in Vista, the Big Picture" post from last year:
Each of the WASAPI instances in this picture represents an audio stream, the streams are combined together in a mixer and streamed to the audio driver. The Stream, Simple, and Channel volumes are implemented with a single volume APO inserted on the individual audio streams, the endpoint volume is implemented either with a volume APO inserted post mix or with a hardware volume control depending on the capabilities of the users audio solution.
So how do these various volumes interrelate?
First off, the stream volume. The stream volume is a multi-channel volume control that is applied to each audio stream. It's intended for use by applications that want to do really simple 3d effects (using the multichannel per-stream volume to simulate position information when bouncing an animated ball across the screen, for example). It also can be used if your application wants to let the system handle managing volume control for individual audio streams, but the scenarios for this are relatively rare.
Next, the channel volume. The channel volume is a per-session volume and is applied to all the streams in a session (if you remember from the "big picture" post, a session is a container for audio streams). The channel volume exists for one reason only: the waveOutSetVolume API - since the wave volume is a multichannel (ok, it's only stereo) volume, we needed to have an analog in WASAPI. Again, the scenarios for using this volume are relatively rare - changing the channel volume is typically done as a system setup task (room correction) from the control panel (so it affects all applications, not just one application).
Then there's the "simple" volume. The simple volue is a per-session volume and is applied to all the streams in a session. The simple volume is a uniform volume control - it applies to all channels equally. This is the volume control that we expect most applications to use - it provides a very simple mechanism to control an applications volume and mute state, which should be sufficient for the vast majority of applications out there. It's also the volume that is shown in the per-application volume slider in the Vista sound mixer.
Logically you can consider these three volumes as being applied in series (it's not really true, they're all applied at the same time) to create the final volume for each audio stream.
Finally, there's the endpoint volume. As I've mentioned before, the endpoint volume represents the "master volume" for outputs. It is applied to the post-mix audio stream, and functions as the master volume for the particular endpoint.
Next: Some subtleties in Vista's volume control.
I just came across this, so sorry for coming to class late. ;-)
Having been away from Windows audio for some time, is Vista audio a superset of DirectShow and DirectAudio but with a managed API?
Where does exclusive mode fit in? Does the endpoint volume apply?
Richard, it is essentially impossible to write a managed application that has to deal with isochronous data (without insane (1-2 seconds) worth of buffering).
Vista's new audio engine sits below DShow/DSound and is 100% UNMANAGED.
Larry, thanks for the answer. Cool: so my decade and a half of C/C++/Win32 experience still has some relevance. ;-)
Time to get a Vista machine, methinks; thanks!
Larry, just wanted to say Kudos for the new audio engine. It sounds great; certainly much better than the old one. It's just a shame that you can no longer get hardware acceleration of DSound, especially after I spent so much on an X-Fi. It's also a shame that the new driver architecture for display drivers has resulted in such poor performance from existing hardware that I had to switch back to XP.
I don't really understand the difference between simple volume and channel volume. Let me see if I can get it straight:
Simple volume: Sets volume for every piece of audio playing in a program. (After their relative volumes have already been set by the stream volimes).
Channel volumes: Sets the relative volumes of all audio going to a particular speaker from a given program, regardless of source stream.
Is this correct?
nks: That's close enough to being right.
As I said, you can logically think of it as a two part process (since each volume is an amplitude scalar between 0 and 1, multiplying the sample by the amplitude scalar performs the desired volume scaling).
So setting the volume looks like:
foreach channel in stream
samples[channel] *= streamVolume[channel]
foreach stream in session
foreach channel in stream
samples[stream][channel] *= channelVolume[channel]
samples[stream][channel] *= simpleVolume
It doesn't work can you show all the codes public thx!
if I understand correctly:
a session contains streams which contain channels
the channel volume controls the individual channels in a stream
the stream volume controls the individual streams in a session
the simple volume is the master volume for a session
and the endpoint volume is the master volume for a device/endpoint
what I'd like to ask (I don't have Vista yet) is:
Is there a mechanism for moving sessions between endpoints (without the apps/sessions noticing)? If not, would it be feasible? (as a powertoy for example)
Hey, thanks for explaining how Vista audio works; it's an area that we normally don't give much thought to, but that is actually quite subtle!
Surge: No there's no mechanis for moving a session between endpoints. Among the issues is that an endpoint has a particular format - the stream format may not be compatible with the format of the new endpoint.
One error in your understanding. The channel volume controls the individual channels for all the streams in the session. Otherwise you're just about spot on.
Daniel: It gets even more complicated when you consider capture.
Our friend in the multimedia group and prolific blogger Larry Osterman is writing a series of articles
As anyone who's read this blog with any regularity knows, my son Daniel is a budding actor. As such,
I am building an ActiveX control that hosts a browser COM control. I would like to be able to programmatically (from my ActiveX code) control the sound volume of the embedded IE control.
I thought if I could get an IAudioClient interface from the web browser control, I could get its ISimpleAudioVolume, and that would allow me to control the sound volume. I have tried several ways to get the IAudioClient interface from the web browser control to no avail. I have even tried to get it from the IHTMLDocument. At this point, I am not sure what else to try…
Do you have any suggestions? I am on the right track for the approach? How could I obtain the IAudionClient interface from the Web Browser COM control?