Second Audio output device

Hii,

I am new with juce and I am building an app that can play sounds whenever I like to.

I would like to have that this can output its sound on more than one audio device.
At the moment I only know that there exists a AudioDeviceManager in my AudioAppComponent but this manager can only handle one Audio device.

To “generate” my audio I use the getNextAudioBlock method of my main AudioAppComponent wich looks as follows:

void GUI::getNextAudioBlock(const juce::AudioSourceChannelInfo& bufferToFill)
{
	bufferToFill.clearActiveBufferRegion();

	//Pitch
	float pitch = (2 * midiInput->pitch) / 127;

	resample->setResamplingRatio(pitch);

	MixerAudioSource* mix = new MixerAudioSource();
	mix->addInputSource(resample, true);

	if (!paused)
	{
		mix->getNextAudioBlock(bufferToFill);
	}

	for (auto channel = 0; channel < bufferToFill.buffer->getNumChannels(); channel++)
	{
		auto* buffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);

		//pan
		float panFactor = ((((1 - channel) * 127.0f) - (midiInput->pan)) * 2) / 127.0f;
		if (panFactor < 0)
		{
			panFactor = -panFactor;
		}

		for (auto sample = 0; sample < bufferToFill.numSamples; ++sample)
		{
			//Modify Sound
			buffer[sample] = buffer[sample] * midiInput->volume * panFactor;
		}
	}

	//Synthesiser output
	MidiBuffer incomingMidi;
	audioController->synthesiser.renderNextBlock(*bufferToFill.buffer, incomingMidi, 0, bufferToFill.numSamples);
}

How can I add another manager that plays the sound on a second audio device?

I somehow solved this problem.

I just added to my main AudioAppComponent “GUI” (is the component that is owned by MainWindow) 2 children who are also AudioAppComponent so that I have 2 individual AudioDeviceManager.

Now in these 2 children will be the code executed that you can see in GUI::getNextAudioBlock. And that works… a bit.

As long as only one of my 2 children plays back the audio everthing is fine. They even play on different audiodevices. But when both play the sound has a lot of cracks and it plays a lot faster.

In comparison to this: It sounds like I would call mix->getNextAudioBlock(bufferToFill); 2 times in a row.

I found out that when I add 2 children the programm creates 2 WASAPI threads. So I also have 2 individual AudioSourceChannelInfo and 2 individual buffer.

And yet I have this problem.

How can i solve this problem?

My personal advice would be to drop the AudioAppComponent. That is nothing but a Component with an AudioDeviceManager and an AudioSourcePlayer.

The AudioDeviceManager is not suitable to manage two AudioIODevices. But you can use it to open the devices.

If you still want to use the AudioAppComponents, you can at least feed the AudioDeviceManager of the first you are creating as reference to the next AudioAppComponent:

AudioAppComponent app1;
AudioAppComponent app2 { app1.deviceManager };

Ok I understand that I need a second AudioIODevice?!

The AudioDeviceManager is not suitable to manage two AudioIODevices. But you can use it to open the devices.

I don’t really know how to do that. I see that AudioIODevice and AudioIODeviceCallback only has virtual functions.

How can I open 2 AudioIODevices?