Re: kAudioDevicePropertyHogMode and NSSpeechSynthesizer...
Re: kAudioDevicePropertyHogMode and NSSpeechSynthesizer...
- Subject: Re: kAudioDevicePropertyHogMode and NSSpeechSynthesizer...
- From: Jeff Moore <email@hidden>
- Date: Thu, 03 Jun 2010 21:48:32 -0700
On Jun 3, 2010, at 9:30 PM, charlie wrote:
>
>> Your app would need to hog all the devices on the system to do this.
>
> The code is written to loop thru all of the output devices and hold each of them exclusively until the app quits. For testing purposes, I've temporarily set it to only grab the "Built-in Output" device. But, once I've got all this figured out and working, I'll put the loop back the way it was before.
>
>
> Let me step back a bit. The purpose of exclusive access to an output device logically has to be to not only disallow other apps from using the device **but also allow our own process to use it**. It's obviously not designed to completely shut off access to the device. This begs the question: how is one expected to route audio thru the device when operating in this mode?
Typically, the clients that use hog mode are already using the lower level APIs in the stack that allow you to specify which audio device to use as opposed to just using the default device.
>
> WORKAROUNDS:
>
> For the last hour, I've been playing with NSSpeechSynthesizer's startSpeakingString:toURL: and then picking the file up again and playing it thru NSSound. startSpeakingString:toURL: works whether in exclusive mode or not. NSSound will only play the sound when **not** in exclusive mode.
NSSound has the method, -setPlaybackDeviceIdentifier: which allows you to tell it what device to use. The argument is the value of kAudioDevicePropertyDeviceUID for the device you want to use.
> But, if I could replace the NSSound code with something lower-level that **can** be routed thru my exclusive device, then I'd have something usable.
The AudioQueue API in the AudioToolbox framework would be a good place to start. An AudioQueue provides a straight forward way to play audio data to the device of your choice.
> (The vast majority of the students using this software will **not** have access to this text-to-speech feature, so exclusive mode will work exactly as expected on those instances. Only a very, very small fraction will even have this feature available for them to use in the interface. And for those few, performance is not going to be an issue. So, whereas normally I would hate the idea of dumping to a file and then reading it back in to play agin thru another audio framework, in this case it'll be ok if that's how it has to be.)
>
>
> Here's the other workaround I've been thinking about: I'm not sure how mixing works in a cross-app context, but if it's possible, maybe I could turn everybody else down and myself up. Then I wouldn't need exclusive access. Is that possible?
No. There is no facility for doing something like that.
> Also, is it possible to create a duplicate device in code? And, if so, would that be useful here?
I'm not sure I'm following you here.
>
> Thanks.
>
> Chuck
>
>
>
>
>
>
>
> On June 3, 2010 11:40:03 P.M. EDT, Jeff Moore <email@hidden> wrote:
>
>> On Jun 3, 2010, at 6:22 PM, charlie wrote:
>>> Thanks for the quick response, Jeff.
>>> This is for a kiosk test-taking app. One of the many lock down responsibilities of the app is to ensure that the test taker cannot have a pre-recorded audio cheat sheet playing in QuickTime Player or iTunes while he's taking the test. But at the same time, some students will need audio assistance from within the app to read questions aloud using text-to-speech.
>> Your app would need to hog all the devices on the system to do this. As you've seen, the default device will switch to another device when the current one becomes hogged.
>>> I just noticed something interesting...
>>> NSSpeechSynthesizer's documentation states that it outputs thru the "default output device", which I'm assuming means the selected output device in the Sound pref pane in System Preferences.
>>> If I open the Sound preferences and watch what happens when my app enters and exits exclusive output mode, I see that the selected output device (in the Sound pref pane) changes away from "Built-in Output" to something else when I enter exclusive mode, then switches back to "Built-in Output" after I exit exclusive mode.
>>> Logically, this makes sense I guess, since my app now owns that hardware, no one else should be able to route thru it.
>> Indeed. One of the requirements of being the default device is to not be hogged.
>>> But... If NSSpeechSynthesizer is trying to output thru the "default output device", then that might mean that it's picking up whatever happens to be selected in the Sound pref pane at that moment, which, in my case, would be "MacVide Audio Connector" and would result in silence.
>> Yes. This sounds like what I would expect to happen. If the current default device becomes hogged, a new default device is chosen.
>>> What I was hoping though, is that NSSpeechSynthesizer would define "default output device" from the app's perspective, not the System Preferences' perspective.
>> Unfortunately for your case, the default device is a system-wide property.
>>> Is there another list that would be better for asking questions about NSSpeechSynthesizer?
>> I don't know if the Speech group has a public API list but you might find some help on one Cocoa-oriented lists.
>>> On June 3, 2010 09:02:51 P.M. EDT, Jeff Moore <email@hidden> wrote:
>>>> I don't know a whole lot about NSSpeechSynthesizer. If it has a facility to tell it what audio device to use, then you might be able to work around the issue that way.
>>>> But to turn things on their heads, why do you need hog mode for your app? Hog mode is a really unfriendly thing to assert on the system. As such, it should only be used in circumstances where it is essential like sending non-mixable data (such as AC-3) to the hardware. The vast majority of apps are best off pretending like hog mode doesn't exist.
>>>> --
>>>> Jeff Moore
>>>> Core Audio
>>>> Apple
>>>> On Jun 3, 2010, at 5:56 PM, charlie wrote:
>>>>> To be clear, when I say it's "working perfectly", I mean that other apps stop emitting sound after I gain exclusive control of the output device and then resume emitting sound again after I relinquish exclusive control.
>>>>> The only sound my app will be generating is NSSpeechSynthesizer text-to-speech.
>>>>> Do I need to tell NSSpeechSynthesizer that we're in exclusive output mode somehow? Do I need to "select" the output device somehow after entering exclusive mode for that device?
>>>>> Thanks.
>>>>> Chuck
>>>>> On June 3, 2010 08:45:51 P.M. EDT, charlie <email@hidden> wrote:
>>>>>> I can obtain and relinquish exclusive control of the built-in output device using kAudioDevicePropertyHogMode. This works perfectly.
>>>>>> But, after obtaining exclusive control of the built-in output device, NSSpeechSynthesizer does not work (from within the same app/pid).
>>>>>> Anyone know how I can get NSSpeechSynthesizer to work while in exclusive output mode?
>>>>>> Thanks.
>>>>>> Chuck
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden