Multiple transportSources in AudioAppComponent?


#1

Hi, I’m currently trying to create a simple audio player using the AudioAppComponent. I was trying to be able to play multiple audio files concurrently so I made multiple transportSources. In the following code:

void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
{
if ((tReaderSource.get() == nullptr) || (yReaderSource.get() == nullptr))
{
bufferToFill.clearActiveBufferRegion();
return;
}
tTransportSource.getNextAudioBlock (bufferToFill);
yTransportSource.getNextAudioBlock (bufferToFill);
}

I noticed that only the very last transportSource can play any audio. Is there any way for me to play multiple audio files at once in this way, and if so could you please explain how or point me towards another way to play multiple audio files. Thanks in advance.


#2

Each getNextAudioBlock() call will overwrite the samples, that the previous one filled in.
You can connect your AudioTransportSources to a MixerAudioSource, and call the mixers’s getNextAudioBlock() instead (which will then call the individual ones of the transportSources and mix the signal automatically).

Please note, if you are planning to write an audio engine like that, you should use a different approach, because the timing of play/stop events on AudioTransportSources is very coarse, and musically not usable, because:

  • start/stop happens on the message thread. There can be any kind of delay, when your GUI is busy with other things
  • start/stop can only happen at full buffers, so you get discrete events with a deviation of up to 20ms (with typical 512 samples @ 48kHz) from the actual trigger

Usually you write an audio mixer yourself, that can take any sample position into account inside individual buffers, and that can update the play/stop and position parameters in the audio thread, to stay synchronised with the rest of the audio.


#3

Thanks for the advice Daniel! Apart from the page on the MixerAudioSource, are there any other resources you can point me to to get started with the MixerAudioSource? I’ve been trying to figure it out using just the documentation over the past couple of days and haven’t had much success.


#4

I was just about to write: simply plug them together.
But I think I know where you are struggling: A MixerAudioSource is not a PositionableAudioSource. I stumbled there a couple years back as well.

Unfortunately it means, you have to write your own PositionableMixerAudioSource yourself.
You can copy the whole MixerAudioSource, but instead:

  • inherit from PositionableAudioSource instead of AudioSource
  • change the input sources to accept only PositionableAudioSources instead of AudioSource
  • Implement the additional four abstract methods of PositionalAudioSource
    – getNextReadPosition : probably use the information from the first for a start
    – getTotalLength : probably use the information from the first for a start
    – isLooping : probably use the information from the first for a start
    – setNextReadPosition : call this for all sources

Hope that helps