Problems with setAudioDeviceSetup of AudioDeviceManager

Hi,
I have problems using setAudioDeviceSetup (const AudioDeviceSetup &newSetup, bool treatAsChosenDevice)
It always return error. The returned strings are “Can’t open the audio device! This may be because another application is currently using the same device - if so, you should close any other applications and try again!” or “Couldn’t open the input device!

I am writing a simple audioserver, so I want to remotely control the behaviour of the soundcard.
My server creates the AudioDeviceManager and initialise it, playTestSound() produces sound (I call it remotely using a JSON message) so I think the audio system is working properly.
Now the client says “Server change buffer_size 512”, the server calls getAudioDeviceSetup (AudioDeviceSetup &setup) to obtain the actual config, then tweaks the bufferSize param and calls setAudioDeviceSetup (const AudioDeviceSetup &newSetup, bool treatAsChosenDevice)

Looking at the code of AudioDeviceSelectorComponent it seems to me to do the same thing but probably not as my app doesn’t work… :slight_smile:
instead AudioDemo works perfectly!

Hope someone could help me,
bye

Andrea

You should debug the process of opening the device, and see how far it gets.

Debugging I noticed where things go wrong but I cannot find a solution:

I have initialised with

Then I ask the audioDeviceManager to change to 2nd output device (as an example)

audioDeviceManager->getAudioDeviceSetup(actualSetup); actualSetup.outputDeviceName = "mySecondOutputDevice"; actualSetup.useDefaultOutputChannels = true; audioDeviceManager->setAudioDeviceSetup(actualSetup, false);
Now in juce_AudioDeviceManager.cpp (line 386)

returns nullptr

In particular device.initialise() in juce_win32_WASAPI.cpp (line 1035) fails.
initialise() calls createDevice(), the 1st condition is verified

so it return false…

After that… I continue not to understand why when the audioEngine starts I can listen sound but I cannot change anything…

Well, if the OS can’t even create an instance of the device enumerator, then something is pretty screwed-up! I’ve no idea what you’d have to do to make that fail!

You’re calling it from the main message thread, right?

mmm, maybe not:
audioDeviceManager is a member variable of MyClass_ServiceHandler.

MyClass_ServiceHandler has a method called “handleMessage” that is called by MyClass_Connection::messageReceived(const MemoryBlock &message)
so the operation on audioDeviceManager is executed by the thread of MyClass_Connection.

The interaction is something like:
MyClass_Connection (inherits from InterprocessConnection) when receives a message calls MyClass_ServiceHandler::handleMessage that based on the message could calls audioDeviceManager to tweak the soundcard.

Well WASAPI uses COM objects, so it’ll fail if you try to call it on a thread that hasn’t had CoInitialize called.

My knowledge stops here… :frowning:
How to call CoInitialize(0) in the thread of connection? I have tried to add that in the constructor of MyClass_Connection but obviously it is not accepted as it is not a method of MyClass_Connection, InterprocessConnection, Thread

If you’re using an InterprocessConnection, why not just set it to use the message thread? It’s an option in the constructor.

You are my idol !!!
It is great when only changing a param from “false” to “true” makes everything to work!

Thank you!

Andrea