Adding Sound to Animated Application

I created an “Animated Application” via Projucer to test moving graphics elements around. This worked so well that it turned into a game. Now I just need to add some sound effects.

But it suddenly seems I started the wrong type of project, and instead of having chosen “Animated Application”, which seemed what was I needed for fast frame updates at the time, I should have chosen “Audio Application”.

So is there an easy way to add audio to my existing project, or would it be best to start all over with a new “Audio Application”?

You can add AudioDeviceManager and SoundPlayer as member variables of your MainComponent class to get some simple audio playback capabilities. You may need to add some additional Juce modules like juce_audio_utils into your project to be able to use those.

If you want to control the audio completely yourself, you can inherit from AudioIODeviceCallback and add an instance of that class into the AudioDeviceManager. (SoundPlayer wouldn’t be needed in that case, you would generate the audio yourself in your AudioIODeviceCallback subclass.)

You could also start a new Audio Application project and do the GUI animations yourself. AnimatedAppComponent doesn’t do anything special you couldn’t implement yourself in a few lines of code. (Just make the AudioAppComponent subclass also inherit from Timer, and do your animation stuff in the timer callback method.)

1 Like

Ok thank you very much, I’ll look into your suggestions.

One more thing. In what order and how exactly does the timer or update work with paint.

It seems when I start my application, paint is processed before the first timer/update.

Then on every timer/update paint is called again, but is it called at the beginning or end of the timer/update code block.

Also what happens if the drawing inside paint is not finished before the next timer/update, is the paint code allowed to finish, or is it aborted?

paint() is called whenever it is needed, like when the Component is shown or resized. When you call repaint() from a timer callback (like the AnimatedAppComponent does internally), a repaint is scheduled to happen at some point in the future. The painting and the timer callbacks happen from the same (GUI) thread, so there is not going to generally speaking be anything weird like the paint() function being interrupted in the middle of its execution.

It could be a bit platform specific what happens when the paint() function takes a long time, but what could be expected to happen is that timer callbacks that can’t be executed in time, are going to be dropped. But to see how it actually behaves on your particular system, you will need to test it.

Ok thanks. As there are no specific repaint() at the end of my AnimatedAppComponent update() code, do you know when the automatic repaint() is done, first or last?

void MainComponent::update()
{	
  // Automatic repaint() is done here?

  // Various animate values
  xx++;
  yy--;
  // And so on

  // Or is automatic repaint() is done here
}

From the AnimatedAppComponent code :

void AnimatedAppComponent::timerCallback()
{
    ++totalUpdates;
    update();
    repaint();
    lastUpdateTime = Time::getCurrentTime();
}

So, the repaint request happens after the call to update() in your subclass of AnimatedAppComponent.

Thanks for making that clear!

This is definitely helpful. Are there any tutorials about how to do this? I have a JUCE OpenGL application that runs fine and now I’m trying to add audio playback. Since I cannot have my main window inherit from both OpenGLAppComponent and AudioAppComponent, I’m left to do something like what you are describing. I’m fine with this, but I cannot find any good examples of something that should be simple and obvious. Any thoughts? And I would encourage y’all to add something like this to the tutorials (e.g. “Add Simple Audio Playback to Your (non-JUCE) Program”).