I notice that in the Microsoft SDK audio samples, both of the Render/Exclusive examples will, for example, stop iTunes playing through my headphones (wholly expected), but when the example program has completed, iTunes is left in a kind of zombie state that requires it to be closed and restarted in order to play anything.
Is this normal, or a fault of iTunes (my version: 11.1.3.8)... or is there something an application should do to announce to other applications that its exclusive use of the endpoint has finished?
Related
I'm using WebRTC (Native Mac & Native Windows -- not JS) and am trying to change the default playout and recording devices and am having a lot of trouble. This is starting to drive me nuts since it should be very simple.
Question: What's the recommended way to change audio playout and recording devices while a call is ongoing on Mac & Windows, natively?
Here's what I've tried:
Method 1
Mac
I noticed the audio device module listens to Core Audio API notifications and adjusts playout and recording devices properly. This works, but I'm not sure if this is the recommended way to change devices.
Windows
I was not able to find a system-wide way of setting the default audio playout/recording device. The only way I could tell MIGHT work is by getting a reference to the audio device module and calling SetPlayoutDevice / SetRecordingDevice on it manually...which leads to Method 2 below:
Method 2
Mac
If possible, I'd rather use SetPlayoutDevice (link) / SetRecordingDevice (link) to change the audio input/output (so Mac & Windows work the same way).
The unit tests to test real audio IO devices shows we should be able to call StartPlayout and StopPlayout after a call to SetPlayoutDevice -- but this makes my app freeze. I've tried it without the call to StopPlayout and StartPlayout however it doesn't seem to do anything. This makes sense since it looks like only internal state is modified but nothing is modified.
Q: How can I change the default audio playout device and recording device on Mac?
Windows
I haven't had a chance to try this out on Windows yet, but Mac not working makes me think there's something I'm missing here.
Answering this myself.
VoEHardwareImpl (https://chromium.googlesource.com/external/webrtc/stable/webrtc/+/refs/heads/master/voice_engine/voe_hardware_impl.cc) seems to have some relevant code.
For playout:
StopPlayout
...set device index...
StereoPlayoutIsAvailable
SetStereoPlayout
InitPlayout
StartPlayout
For recording:
StopRecording
...set device index...
StereoRecordingIsAvailable
SetStereoRecording
InitRecording
StartRecording
Depending on the commit you're on, you might need to ensure you won't get into a deadlock situation. Some of these methods acquire locks so make sure the lock isn't acquired yet if you're calling a method that requires locks. Better yet -- do this a level above or wrap the adm if possible.
I need help debugging an issue, where an application that uses CoreAudio to mix several input sources into an output screen, experiences crackling in the output stream, but only after the Mac has woken from sleep.
The app was running fine before the Mac went to sleep, and restarting the app fixes the problem.
The application uses a couple of threads to do it's thing, which makes me assume that resource limits are altered by the system for the app, or some buffers used by CoreAudio have changed in size.
Any ideas how to debug that issue?
I developed an application in C that can display 4 videos, and 1 sound file in the background.
The video uses the WMP object in the C++ class provided by Microsoft in the WMP SDK. The audio uses Windows' MCI (Media Control Interface) which is sent command strings.
To be able to play lots of different formats, I installed windows.7.codec.pack.
I experience a problem that when playing more than 3 media files (video or audio), the media stall. A video to be started constantly cycles from state 3 (Playing) to state 9 (Preparing new media) to state 10 (Ready to begin playing - without anything happening), and so on and so on. This is seen as a flicker of the video (state 3) followed by a few seconds of nothing (black, or desktop background, state 9). Once a video has started, it plays fine until the end.
Decreasing the number of media files to play to 2 videos and 1 audio lets it play fine; increasing to 3 video or more and 1 audio and this happens. Task Manager shows a CPU load of less than 25%, so CPU cannot be the problem.
It seems that MCI and WMP share stuff in the background because not only do videos stall, also audio stops without reporting errors (querying MCI returns that it is playing, but there is no sound).
I upgraded to windows.7.codec.pack.v4.2.6. This had a terrible performance
I reverted to windows.7.codec.pack.v4.1.6. This has a much better performance but still not perfect.
My question(s):
Is there any way I can configure Windows or the codec package to seamlessly handle 5 streams?
How can I report this problem to the developer?
Are there other codec packages that do not have this problem?
Any other suggestion?
System info: Intel i7-3520M X64 dual core at 2.9Ghz with 8GB physical memory and NVIDIA Quatro K1000M display adapter.
I think I found the solution.
After playing a video, I called the Player's Close() method. The documentation says:
The close method releases Windows Media Player resources.
Remarks
This method closes the current digital media file, not the Player itself.
Indeed I wanted to release the media file so it would no longer be busy in the file system. However, it seems that more resources were released than just the media file. As a consequence, for a next media file to be played, the player had to allocate resources again. It seems that turned out to be a bottle neck.
No longer calling Close() but just giving it the URL (filename) of the next media file to play now solved the problem. (I still have to give some retries sometimes but the general performance is now very well acceptable.)
The media file is released when the next media file starts playing.
I want to create a virtual audio device that gets audio data from the default output (which is an output IOAudioStream) and converts it to an input IOAudioStream.
I went through most of the examples I could find, however they only implement a feature to copy the output IOAudioStream to the input one at most. That means it only converts the audio to an input stream if the audio device is selected as output.
This should be possible, since ScreenFlow allows recording of computer audio by installing a kext that creates a virtual driver.
How can I access the audio data from the default output and send it to my virtual driver?
Take a look at the open-source WavTap, which is a simplified fork of the open-source SoundFlower virtual sound card driver. It is a .kext that I believe does substantially what you want.
For reference, here is how some popular commercial closed-source options work:
Rogue Amoeba's Audio Hijack Pro
-Captures system audio via code based off of the open-source SoundFlower .kext
-Captures an application's audio by substituting a "patch" framework for the normal CoreAudio.framework when launching the application
-Captures an already-running application's audio with the help of the haxie "Application Enhancer" (APE) from Unsanity
These features are branded as their "Instant On" feature (InstantOn.kext).
Ambrosia Software's WireTap Studio
-Captures system audio and application audio via an in-house developed .kext
Telestream's ScreenFlow
-Captures system audio via an in-house developed .kext. (Version 2.x uses varaudio.kext; Version 3.x uses TelestreamAudio.kext)
Macsome's Audio Recorder
-Unknown method
Araelium Group's Screenflick
-Captures system audio using the SoundFlower .kext
UPDATE #1
After reading the author's comments, it appears the underlying goal is to be able to capture the system sound without publishing the virtual audio driver as a device (that would appear in the System Preference's list) and without changing the current default output device (or at least the appearance that the device has changed).
SoundFlower: Adds a sound device to the list upon installation
WavTap: Adds a sound device to the list upon installation; auto-selects the device when the WavTap application is started; auto-deselects the device when the application is shutdown and reselects the previous device
Audio Hijack Pro: Adds a sound device only when audio capture of the default system sound is selected; removes the sound device when audio capture is no longer selected and reselects the previous device
WireTap Studio: Unknown
ScreenFlow: Captures the system sound without changing the current default output device and without publishing the virtual audio driver as a device
UPDATE #2
A quote from Jeff Moore, a CoreAudio Apple engineer, in reference to applications such as WireTap and Audio Hijack Pro:
"There are no APIs on the system that will give you the output of any specific app or the whole mix going to the hardware...[Capturing System Sound] isn't supported by the System and those folks had to be clever. There's nothing stopping you from doing the same thing except how willing you are to get your hands dirty.
The fact is, Mac OS X's audio system was designed first and foremost for performance. This lead us to a design where it is not easy to support the functionality you want without imposing performance penalties. So, we have opted for better performance at the cost of not being able to provide this feature."
If you want to read more on the subject, check out these threads on the CoreAudio API mailing list:
"WireTap, CoreAudio's API, and system capture, and kexts..."
"Another question on capturing audio played back by a software"
"Capturing currently played audio using CoreAudio on Mac"
"'audio hijack'"
"monitoring system audio output like wire tap"
"Capturing audio output to a file"
"Mirroring Audio Output"
"Recording system audio"
Relevant SO Questions:
Hide Audio device using codeless kext
So long story short, you're not likely to find examples from Apple that accomplish this, and you're not likely to find open source code that accomplishes this either, unless someone is feeling very generous. It appears to be too valuable of information.
After additional research, here are some theoretical techniques I came up with that might allow you to accomplish your goal:
Similar to Prosoft Engineering's Hear product, you could create a HAL plugin (user-mode virtual driver) rather than a .kext (kernel-mode virtual driver). Apple has a sample HAL plugin called "SampleHardwarePlugIn" and PulseAudio has one as well. However, with his method I don't think you get access to a pre-mixed system sound stream. You would have to gather up all streams from the various applications (which must use CoreAudio to play sound) and mix them together for pseudo system sound capture.
Create a virtual audio device that is hidden [1][2] from user interaction. When the user wishes to capture the default sound, programmatically create an aggregate device that includes your hidden virtual device and the current default sound device. Temporarily set this aggregate device as the default output. In this manner, you are able to both capture the default sound and hear it.
Side Note: If Mac OS X allows for a hidden device to also be set as the default output device, what would System Preferences show as the selected device? If it instead shows the secondary output device as selected, then you have the added allusion that nothing has changed.
A newer open-source virtual audio device that works with the latest versions of MacOS is BlackHole - it supports multiple audio channels and sampling rates.
It can be used as an audio sink and/or source. It's also handy as part of an aggregate audio device so audio can be heard and re-routed - e.g. using the MacOS Audio MIDI Setup app
I need to know the application status i.e app is in resume state,active or any..programatically in windows mobile 5,6,7 OS phones.
Please help me for that...
Like Chris pointed out, you are not going to be able to check a devices state and have it tell you what it was in. If the device is dormant or not running, your code is not going to run.
However, if you are using Windows Mobile 6, you can elect to receive notifications through the State and Notifications Broker whenever your device goes from one state to another by using the RegistryNotifyApp.
There is a Using the State and Notifications Broker in Native Code example that goes into details.
This tool was not available prior to version 6 of Windows Mobile.
The newer Windows 7 Phone OS is drastically different, and I have no experience with what it is capable of.