On Thu, 2014-03-06 at 19:22 -0500, Brian Fay wrote:
On Tue, Mar 4, 2014 at 8:53 PM, Chris McCormick chris@mccormick.cx wrote:
Not sure if this is relevant or already common knowledge but newer versions of Pd allow you to specify metro and delay tempo & units, including in samples. e.g. [metro 500 1 samp].
Does anybody know if sample-accurate [metros] are available in libpd?
Assuming, that libpd uses the same code for [metro], I'd say yes.
I'm making an application that allows for fairly arbitrary divisions of a tempo. Originally I was going to make clocks out of metros, but I wasn't aware that you could set a [metro] faster than one bang per ms.
[metro] used to have an artificial lower limit of 1ms. I assume this was implemented in order to save Pd from freezing if a [metro] accidentally received a '0' as interval. It seems that is not the case anymore in 0.45. The current behavior is that it allows any non-zero input, but falls back to one unit as defined in the 'tempo' method when set to 0.
If I wanted a bunch of different rhythms, not just eigths and sixteenths, but triplets and divisions of fives or sevens or whatever, I would need to make a bunch of [metro] objects (or maybe one running at the least common multiple of the various divisions).
In the end, I settled on handling this logic in the Java side of my application by counting samples and doing some math.
This is still only sample precise, while you could make it sub-sample precise in Pd.
This isn't addressed to you specifically, but it is a common misconception to think of the audio domain as being precise and the message domain as being rounded to vectors. This might apply to many softwares, especially those that have two configured rates, one audio sampling rate and one fixed control rate. However, there is no such thing as a control rate in Pd. It is true, though, that many classes with message inlets and signal outlets only evaluate the incoming message only at block boundaries ([tabplay~], [line~] and more). However, [vline~] is the __one__ class that connects the two worlds (message and signal) without losing precision. But I'm getting off-topic now, as your topic is about precision in the message domain only. Anyway, the precision of [metro], [delay], [timer] and co is only limited by the float type used in Pd.
I can schedule bangs at arbitrary divisions of a base amount of time (so I can make seven-tuplets or fiftythree-uplets or whatever strange rhythm I want to). In theory my solution should be sample-accurate, and it sounds like it's working fine.
But is there a straightforward way to do this in pd that I completely overlooked?
It depends on what you consider straight-forward. It is certainly possible to have many [metro]s with arbitrary divisions running in sync. I still think the whole topic is very complex. I implemented something like that in some of the netpd instruments. However, I figured the tick rate of the master metro would be way too high, if I'd make it dividable by all the possible divisions I can think of. I went for a different strategy. The master metro ticks at 16th of the given BPM. I made an [metro] replacement abstraction that takes divisor and dividend as arguments. [polymetro 7 5] plays 7 ticks within the period of 5 ticks of the master metro. [polymetro] is designed so that it runs on its own and plays 7 ticks and then waits for every 5th master tick to start again. The difficult part was to allow tempo changes without losing sync. Pd's [metro] applies the new tempo only at the next tick. In order to be able to run many [polymetro]s concurrently without them losing sync on tempo changes, I had to create a [metro] replacement that allows for in-interval tempo changes. By using that [metro] replacement in the master metro and the [polymetro]s, it is possible to change tempo at any time without losing sync. One issue, that I haven't solved yet is a clean start at an arbitrary tick. [polymetro] doesn't immediately start when master metro is started at a non-zero tick, but it waits for the next sync tick of the master (any 5th master metro tick in the case of [polymetro 7 5]).
Roman