Bug in AudioDeviceSelectorComponent?

I haven’t been able to track down why this asserts an invalid changeListener:[code]#include <juce.h>

class AudioSettingsDialog : public DialogWindow
{
public:
AudioSettingsDialog (AudioDeviceManager& audioDeviceManager) : DialogWindow (T(“Audio Settings”), Colours::lightgrey, true)
{
AudioDeviceSelectorComponent* audioControlComp = new AudioDeviceSelectorComponent (audioDeviceManager, 0, 0, 0, 2, false);
setContentComponent (audioControlComp);
centreWithSize (500, 300);
addAndMakeVisible(audioControlComp);
}
~AudioSettingsDialog()
{
deleteAllChildren();
}
void closeButtonPressed()
{
JUCEApplication::quit();
}
};

class MyApp : public JUCEApplication
{
AudioDeviceManager dm;
AudioSettingsDialog* d;

public:
MyApp()
{
}
~MyApp()
{
}
void initialise (const String& commandLine)
{
dm.initialise(0,2,0);
d = new AudioSettingsDialog(dm);
d->setVisible (true);
d->toFront (true);
}
void shutdown()
{
delete d;
}
const String getApplicationName()
{
return T(“MyApp”);
}
const String getApplicationVersion()
{
return T(“1.0”);
}
};

START_JUCE_APPLICATION(MyApp)[/code]It’s annoying the heck out of me.

Also, an exception occurs if no items are selected in the component (it’s on the default Direct Sound device) when it is deleted. Seems to be a timing issue since it doesn’t occur if I trace through the deletion. It also doesn’t occur if I select another device, then reselect the default device.

  • kbj

You shouldn’t call deleteAllChildren() on a DialogWindow - it manages its components itself, so if you delete them first, it’ll be left with dangling pointers.

I think that’s explained in the comments, but I should probably add some code to throw an assertion if you do it.

Tried that already. It asserts regardless. Doesn’t affect the exception either.

  • kbj

Must be the audiodevicemanager member variable, which will get created before juce has actually had a chance to initialise the message manager, so can’t register itself as a changebroadcaster…

You should only ever have pointers inside your app object, and must always create the objects in its initialise() method, never let them get created automatically. I think that’s explained somewhere in the app class… if not, I’ll add some extra comments about it.

(You also don’t need to add the component that you’ve already set as the content component).

[quote]You should only ever have pointers inside your app object, and must always create the objects in its initialise() method, never let them get created automatically.[/quote]Ahhh, that 'twas it. Makes sense too.

[quote]I think that’s explained somewhere in the app class… if not, I’ll add some extra comments about it.[/quote]It wasn’t. That’s why I was confused.

[quote](You also don’t need to add the component that you’ve already set as the content component).[/quote]Yah, I know this. But dumping out several hundred lines of proper code into a message seems less preferable than making up a small (if somewhat erroneous) example case.

Thanks for clearing up the JUCEApplication instantiation issues!

  • kbj

I’ve added some assertions to pick up that kind of thing in the future now, and some more strenuous comments about what not to do in the app class!