Feature request
So, I'm still at a loss to figure out why the transport and timepoint system don't have a mode for just working in straight elapsed time. Yes, I know about [translate], but is there some reason we can't just have a mode where the transport reports elapsed time and we set the timepoints in elapsed time? Unless I'm missing something here? It makes no sense to me that we have a system for handling time that doesn't handle time natively, but forces us to translate between bars/beats at a given tempo and time signature on the one hand and just straight time on the other. I'd be happy to be shown a way to just work in time, not bars & beats, with the transport & timepoint objects.
Anyone?
Thanks
Can you say what it is, specifically, that you want to do that you currently can't do? Maybe an example showing what you dislike?
I think the whole point of the transport system (when it was introduced a few years back) was to provide a bars.beats.ticks system for those who wanted to keep track/report time in a traditional musically notated type of way, as opposed to milliseconds. It provides a traditional musical way to report/work with time in beats and measures instead of milliseconds, which objects like [metro], [timer] and [clocker] use.
Is there a specific reason you wish to use transport instead of those other objects? [metro] and [counter] for example are a good combination.
But, of course, it all depends on what you're doing with it.
FWIW, here is a method I have been using for a time-based transport. I haven't done it yet but I'm sure the [clocker] object can be linked to the master transport so you can have parallel timing in bars:beats and in h:m:s:ms.
@Christopher - the pretty basic usage is simply to trigger actions at a known time while using an easy and flexible controller for the time, and have it be available system-wide. This seems to me to be exactly the transport system - easy, well-integrated system-wide, and deals with time, except that it forces one to deal with time as bars/beats/units rather than providing the option to choose. It seems a real no-brainer to me to have this sort of flexibility, especially given that the internal timing mechanism is undoubtedly itself dealing with elapsed time in ms (or some other common unit); why not expose this underlying layer with a 'mode' attribute? In other words, I want all the power and ease of use of the transport/timepoint system without having to calculate the timepoints in bars/beats/units when I really want to structure my piece in time.
@Michael - Yes, I fully understand the intended usage, and have no problem with that. I simply see no reason it can't do both, given that it, fundamentally, is used to structure events in time - so why not have the option to deal with standard time units as well as metrical musical time units? It retains all the power and adds flexibility.
@stringtapper - thanks, I've used such home-brew systems in the past, as well. There are certainly work-arounds to accomplish what I'm doing. It just seems a bit odd (not to mention counter-productive) to provide the ability to structure events in time (i.e., transport/timepoint) and then not allow the system to deal directly with time (elapsed time in raw ms, or hh.mm.ss, or whatever). Why have to build a duplicate and less well-integrated parallel system when the in-built system already exists to do something identical and extends to all the time-related objects?
In short, thanks all of you for the feedback so far. I'm still wondering what the 'benefit' is of NOT having the transport/timeline/etc. system include a mode to deal with standard time units.
@Steven,
While I understand your point of view, try thinking of it this way. There are two ways (or "modes", as you say) to measure time in Max: one is what you call "straight" time (I usually call it "clock" time, meaning that it refers to an agreed-upon, reliable clock) and what you call the "musical way" (I call it tempo-relative timing, because a given time in bars.beats.units will equal a particular clock time that depends on the stated beat tempo in bpm). The purpose of the transport object is to facilitate the musical way, so transport is always thinking of time in terms of bpm, timesig, and bars:beats:units. The purpose of the translate object is to provide that "mode" translation that you desire. Now, you might wish that instead of the translation taking place in a separate object, it could take place inside the transport object, but a) it's actually more practical for that whole issue to by handled by a generalized translator object 'cause there are many situations in which translation is needed, b) transport's job is to manage the tempo-relative timing, so it really doesn't need to report clock time to you since you can translate any tempo-relative time into clock time and vice versa, and c) one could just as well argue that you'd have to work even harder to program around a transport object that reports time in different ways depending on some "mode" attribute (imagine an outlet that's sending ticks and then suddenly starts sending milliseconds; you'd have to have a bunch of math objects to re-translate for you in that case anyway).
Most importantly, it's one thing for a DAW like ProTools or Logic to provide a simple switch between different ways of expressing time, but compare that to the complexity of keeping track of tempo-relative time in a programming environment where people can write a program that changes timesig, tempo, or timepoints at any instant, can leap backward in time, etc., and does it all in real time and needs to stay as accurate as possible, and then you start to see why translation between the modes needs to be done constantly and is best done separately. The translate object does that for you by doing its translation every time the transport's tempo changes.
Oh, and you make the assumption that, "It seems a real no-brainer to me to have this sort of flexibility, especially given that the internal timing mechanism is undoubtedly itself dealing with elapsed time in ms (or some other common unit)," but in fact that's just the point: transport is not dealing with elapsed time in clock time, it's dealing with it in tempo-relative time ("ticks"), and has to recalculate all timepoints, metro intervals, etc. every time something significant changes (such as tempo, most notably). The Max scheduler is the invariant clock that keeps track of scheduled events. The transport system (tempo-relative timepoints, etc.) are all managed separately from the Max scheduler. The Max scheduler, just holds a single scheduled event telling it, in effect, "Here's the next time you'll need to check back in to see what's going on in the tempo-relative world."
So, I hope that long-winded rationale makes you feel a little better about the way DZ and company decided to implement it. If not, I guess I'd just reiterate my question above. Is your objection just on principle, or have you actually encountered something you want to do that you can't do?
If I want to schedule timepoints in straight clock time, it's easy enough to do, and if I want transport to report the current time to me in straight clock time, that's easy enough to do, too. In the following example, when you start the transport with the toggle, it rewinds to time 0 and schedules a timepoint to occur at time 5.5 seconds. By default the transport's tempo is 120 bpm, so we would expect that timepoint to happen 11 beats later, i.e., after 5280 ticks, i.e. on beat 4 of bar 3 (in the default timesig of 4/4). Now try changing the tempo and restart the transport. The timepoint object will do whatever it needs to do to translate the 5.5 second request into the correct number of ticks based on the new tempo, and it will still trigger at the correct time. Of course, transport will report different tempo-relative times for that instant, but the translate object will reliably translate the ticks back into clock time for printing.
Hi Christopher, thanks for the in-depth reply.
My response will be rather simple, because your elegant solution both illustrates your point, and makes the case for mine, as well. If we can send the message "0:0:5.500 hh:mm:ss" to timepoint, and it responds at the appropriate time, then it's already doing the translation in-house. Surely sending the realtime clock time out an outlet directly isn't too much overhead, when clearly it's already using it internally, as your example shows.
And I'm sorry, I don't understand your point that transport is not dealing with clock time, but with tempo-relative time. In order to calculate it on the basis of tempo, it still needs to count time as it elapses, in order to report it and keep track of it, no? My point is that it's already doing what I'm asking: it's just obfuscating the 'time' behind tempo/bar/beat/etc. when it can do both simultaneously, because it already does; it simply isn't reporting time directly. In an ideal world, it would report both.
Thanks!
Yep, I understand your point. But in the meantime, just put a [translate @in ticks @out ms] object after the ticks outlet of transport, and voilà, non?
Yes, indeed. And the hh:mm:ss command was also part of the missing link for me, though I'd read through the 'time syntax' reference pages a number of times, that bit for some reason eluded me. Thanks again.