Reply Inline: On Thu, Jan 15, 2015 at 1:15 PM, Nick <[email protected]> wrote: > Hi Christian, > Thanks for the reply. > > Yes, I had found the functions > > AUBase::CallHostMusicalTimeLocation > > AUBase::CallHostBeatAndTempo > > AUBase::CallHostTransportState > > What I meant in my question however - is there a way to get > callbacks/notifications invoked in my Audio Unit every time when beat/bar > changes, or when the host playback starts/stops (for instance, when the user > clicks the Play button in MainStage). Or do I have to implement tracking of > these events manually in my render function by checking if and how the beat > value changed?
Yes, I believe you have to track the events yourself. This is what I have done in my work. > > Manual tracking sounds like a tedious work though. For instance, I would > like to have a function called every time a metronome ticks (i.e., a beat > changes). That would be handy. Though I think the API is designed around performing these calculations on the real-time audio thread only, and in a very predictable order. I think the moment before you render, on the audio thread, is the only place you could get an accurate reading of the current host position for your processing. If you did have an API for other function callbacks, it isn't clear to me on what other thread, and in what order, those functions would be called. If the calls are on any thread other than the audio thread processing your samples (ex: UI, background, etc.) then I think there are no guarantees as to when the host calls this function to alert you, with respect to the audio thread. In other words, if such an API existed, the musical data you are asking for would probably be stale by the time it reached you. Worse, it wouldn't even be stale by the same amount each time. > > CallHostBeatAndTempo returns fractional value, so what I can do - is in the > AU's Render() function trunc the Float64 beat value and compare it with a > trunced previous value, if it changed, then beat happened and I ought to > invoke my Beat() function. However host's (int)beat value can change not > only when the metronome ticks, but when the user presses the play button (it > was 0 before Play was pressed, then it jumps to 21.768750 (why?), then jumps > again to 0 and starts increasing normally every metronome tick by 1). So > when the user presses play, the Beat() function is invoked twice, even > though the metronome ticked only once. Weird. I too have seen lots of strange behavior from hosts using this API. I have learned to use as many of the parameters to these different callbacks as I need to determine "the truth" about the current host state. For example, the current global sample position (I forget the output parameter name) is really useful because it is integral/discrete, unlike beat output parameters which can be fractional. I use it in combination with tempo and sample rate to determine the current beat, in some applications. In your case, I would look to see how and when that value jumps around when the play state is toggled (via UI button I assume). I would definitely also keep an eye on the isCycling parameters, transportChanged params, and, as implied above, try to use samples instead of musical time when you can. One last observation: I have often forgot that the events or beats I am looking for may be in the middle of the current buffer, not at the beginning (sample 0). That is why it doesn't surprise me so see a beat value of 21.768759. It is supposed to be the host's best approximation of what is the "beat" of sample 0 for the current buffer. As such, he host may be giving momentarily stale information on a state transition that occurs/occurred in the middle of a rendering cycle. Also the UI might not, in that moment, accurately represent what is happening in the audio chain (i.e. threading races, as implied above). Sorry for the lengthy response, but I hope it helps! > > > 2015-01-15 19:44 GMT+02:00 Christian Rober <[email protected]>: >> >> On OS X, your host may set a property on your Audio Unit enumerated as >> kAudioUnitProperty_HostCallbacks. The payload of the property is the >> struct HostCallbackInfo, which in turn has a set of C function >> callbacks. If that property is set by the host, you can extrapolate >> the playback state and current beat position by calling those >> functions. AUBase has a handy wrapper around all of this, of course. >> >> Note: it is not guaranteed that a host who provides the struct will >> return all the information from the output parameters to the >> functions. >> >> I have been able to call this at the beginning of each render cycle on >> most hosts, and I believe this to be the standard way it is >> implemented. So you should only really need to call it before you >> render/process the samples per cycle. >> >> For the record, this struct also exists on iOS, but via the Inter-App >> Audio layer of the Audio Unit API. >> >> Hope that helps. >> >> --Christian >> >> On Thu, Jan 15, 2015 at 12:11 PM, Nick <[email protected]> wrote: >> > Hi >> > Is there a way to get a notification in audio unit that a host started >> > playback, and get a function called every metronome beat/or bar change? >> > Thank you >> > >> > _______________________________________________ >> > Do not post admin requests to the list. They will be ignored. >> > Coreaudio-api mailing list ([email protected]) >> > Help/Unsubscribe/Update your Subscription: >> > >> > https://lists.apple.com/mailman/options/coreaudio-api/recapitch%40gmail.com >> > >> > This email sent to [email protected] > > _______________________________________________ Do not post admin requests to the list. They will be ignored. Coreaudio-api mailing list ([email protected]) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com This email sent to [email protected]
