I sent a post to this list about this a few days ago. I'll answer my own post.
The situation is that a simple synth built with AUInstrumentBase and friends fails to work properly under Ableton Live. (For example, the SinSynth example that comes in the CoreAudio SDK doesn't work under Live.)
The reason why is this:
Live calls ValidFormat with scope 0 (global) and element 0.
Most probably it should call in output scope, but it does not do this.
The SupportedNumChannels(NULL) call returns 0 since this property is not
supported in SinSynth. MusicDeviceBase::ValidFormat says that the format is fine
and then we get to the following bit of code in AUInstrumentBase.
AUIOElement *el = GetIOElement (inScope, inElement);
return (el->GetStreamFormat().NumberChannels() == inNewFormat.NumberChannels());
This is where the problem happens. With scope 0 (global), GetIOElement(0,0)
throws an exception since the global scope isn't an AUIOElement. This exception is not caught by the audio unit and is (I presume) caught by Live, which promptly (and probably correctly) disables the audio unit.
This (calling ValidFormat with global scope) is probably a fault of Live, but I don't know where definitive information on such matters resides. In any case, I am unable to make changes to Live for obvious reasons. To make an AUInstrumentBase based instrument work in Live one needs to override the ValidFormat method so that if the scope is 0, the ValidFormat method of MusicDeviceBase is queried.
Thus, change (in ValidFormat)
if (SupportedNumChannels (NULL))
return MusicDeviceBase::ValidFormat(inScope, inElement, inNewFormat);
to
if (SupportedNumChannels (NULL) || inScope == 0)
return MusicDeviceBase::ValidFormat(inScope, inElement, inNewFormat);
and we have at least a quick hack to keep Live happy.
John