Re: AudioUnit - notify on hosts beat and bar changes
Re: AudioUnit - notify on hosts beat and bar changes
- Subject: Re: AudioUnit - notify on hosts beat and bar changes
- From: Christian Rober <email@hidden>
- Date: Thu, 15 Jan 2015 14:11:21 -0500
Reply Inline:
On Thu, Jan 15, 2015 at 1:15 PM, Nick <email@hidden> 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@hidden>:
>>
>> 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@hidden> 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@hidden)
>> > Help/Unsubscribe/Update your Subscription:
>> >
>> >
>> > This email sent to email@hidden
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden