snapshotting and restoring the state of a [phasor~] exactly
@lacuna said:
Don't know about phasor's right inlet, but I guess for more precision on the outside of objects we'd have to use 'Pd double precision'.
Yes, I confirmed that my test patch runs without issue under Pd64. Unfortunately, my real patch doesn't
Also remember @ddw_music different approach than [phasor~]:
I think that "different approach" is a different issue--I'm not multipying its output to index into a large table. I'm just using it as an oscillator/LFO. Are you suggesting that there's a way to build an oscillator with [rpole~] that is as frequency-accurate as [phasor~] but without the single vs double precision issue?
On one sample late: It is [snapshot~] who is early, not [phasor~]:
...
I would call this a bug of [snapshot~] !%§$*(
I don't understand your conclusion about the timing of [snapshot~]. Here's how I would analyze your demonstration patch: the top bang is processed in-between audio blocks. Therefore, [tabplay~] and [fexpr~] run in the following audio block. [snapshot~] is different though, because it's a bridge between control rate and audio rate--like bang, it also runs between audio blocks. Therefore, the best it can do (without having to predict the future) is to return the last sample of the previous audio block. So it's not surprising for [fexpr~] to have to reach back into the previous audio block to get the same value as [snapshot~]. If [snapshot~] were to return the first sample of the following audio block, it couldn't pass that value to control rate code until that audio block's processing is complete. Do you see my point?
Also, I'm not saying [phasor~] is early, I'm just saying its right inlet isn't a mechanism for restoring its state. It's just for what the documentation says it's for: to reset its phase to a given value.
snapshotting and restoring the state of a [phasor~] exactly
Suppose you want to capture the state of a [phasor~] in order to return to it later, i.e. you want it to output the exact same sequence of samples as it did from the moment you captured its state. As a first attempt, you might [snapshot~] the [phasor~]'s output and then send that value to the [phasor~]'s right inlet sometime later to restore it. Of course you also want to capture the state of its frequency inlet (and record it if it's changing). But there are two subtleties to consider. Firstly, the value you write to the right inlet is the next value that the [phasor~] will output, but when you [snapshot~]ed it, the next value it output was a little greater, greater by the amount of the last frequency divided by the current sample rate. So really, this greater value (call it "snap++") is the one you should be writing to the right inlet.
The second subtlety has to do with the limits of Pd's single precision floats. Internally, [phasor~] is accumulating into a double precision float, so in a way, the right inlet overwrites the state of the phasor with something that can only approximate its state. The only solution I could find is to immediately write snap++ to the right inlet of the running [phasor~], so that the current and all future runs output the exact same sequence of samples. This might not be acceptable in your application if you are reliant on [phasor~]'s double precision accumulation because you'd be disrupting it in exchange for repeatability.
Here's a test patch that demonstrates the issue:
phasor snapshot restore test.pd
Looking for advice on using phasor~ to randomize tabread4~ playback
@nicnut said:
There is a number box labeled "transpose." The first step is to put a value in there, 1 being the original pitch, .5 is an octave down, 2 is an octave up, etc.
Here, you'd need to calculate the phasor frequency corresponding to normal playback speed, which is 1 / dur, where dur is the soundfile duration in seconds. Soundfile duration = soundfile size in samples / soundfile sample rate, so the phasor~ frequency can be expressed as soundfile sample rate / soundfile size in samples. Then you multiply this by a transpose factor, ok.
But I don't see you accounting for the soundfile's size or sample rate, so you have no guarantee of actually hitting normal playback speed.
After that you can change the frequency of the phasor in the other number box labled "change phasor frequency without changing pitch."
If you change the phasor frequency here, you will also change the transposition.
This way, I can make the phasor frequency, say .5 and the transposition 2,
Making the eventual playback speed 1 (assuming it was 1 to begin with), undoing the transposition.
which I don't think I can do using line~ with tabread4~.
The bad news is, you can't do this with phasor either.
hjh
Looking for advice on using phasor~ to randomize tabread4~ playback
@nicnut said:
Yes line~ would be better, but one thing I am doing is also playing the file for longer periods of time, by lowering the phaser~ frequency, and doing some math the transpose the pitch of the playback that I would like to keep. With line~ I don't know how to separate the pitch and the playback speed.
If I understand you right, separating pitch and playback speed would require pitch shifting...?
With phasor~, you can play the audio faster or slower, and the pitch will be higher or lower accordingly.
With line~, you can play the audio faster or slower, with the same result.
To take a concrete example -- if you want to play 0-10 seconds in the audio file, you'd use a phasor~ frequency of 0.1 and map the phasor's 0-1 range onto 0 .. (samplerate*10) samples. If instead, the phasor~ frequency were 0.05, then it would play 10 seconds of audio within 20 seconds = half speed, one octave down.
With line~, if you send it messages "0, $1 10000" where $1 = samplerate*10, then it would play the same 10 seconds' worth of audio, in 10 seconds.
To change the rate, you'd only need to change the amount of time: 10000 / 0.5 (half speed) = 20000. 10 seconds of audio, over 20 seconds -- exactly the same as the phasor~ 0.05 result.
frequency = 1 / time, time = 1 / frequency. Whatever you multiply phasor~ frequency by, just divide line~ time by the same amount.
(line~ doesn't support changing rate in the middle though. There's another possible trick for that but perhaps not simpler than phasor~.)
hjh
Sync Audio with OSC messages
@earlyjp There might well be a better way than the two options that I can think of straight away.
You could play the audio file from disk, and send a bang into [delay] objects as you start playback, with the delays set to trigger the messages at the correct time.
I am not sure how long a [delay] you can create though because of the precision limit of a number size that can be saved in Pd. You might need to use [timer] banged by a [metro]
Or as you say you could load the file into RAM using [soundfiler] and play the track in the array using [phasor~] and trigger the messages as the output of [phasor~] reaches certain values.
Using [phasor~] the sample will loop though.
To play just once you could use [line~] or [vline~]
You would need to catch the values from [phasor~] [line~] or [vline~] using [snapshot~].
[<=] followed by [once] would be a good idea for catching, as catching the exact value would likely be unreliable...... once.pd
The same will be true if you use [timer] as the [metro] will not make [timer] output every value.
Again, number precision for catching the value could be a problem with long audio files.
Help for the second method....... https://forum.pdpatchrepo.info/topic/9151/for-phasor-and-vline-based-samplers-how-can-we-be-sure-all-samples-are-being-played
The [soundfiler] method will use much more cpu if that is a problem.
If there is a playback object that outputs it's index then use that, but I have not seen one.
David.
simple polyphonic synth - clone the central phasor or not?
@manuels That's clever, thanks! I especially like how you get the slope of the input phasor (compensating for that downward jump every cycle) and how you construct the output phasor. But I think there are two issues with it. Firstly, a sync will reset the phase of the output phasor at an arbitrary point unless the output phasor frequency is an exact multiple of the input frequency. Secondly, without sync, I think the output phasor may drift WRT the input phasor due to floating point roundoff error. Agree?
Backing out to look at the big picture again, i.e. Brendan's question, this means that it couldn't be used to make either a "hardsync" synthesizer (disclaimer: I don't really know what that is) or a "phasor~-synchronized system", assuming that both require a precise phase relationship between the input and output phasors and that the output phasor doesn't contain discontinuities. What do you think?
using 0..10hz osc~ as amplitude modulation, when i get to 0, there's an audible click
@esaruoho when it gets to 0 frequency, use a [line~] going into the same inlet as the osc~ and ramp from
0 to the difference between the output value at the phase you want to set and the current output value (get w/ [snapshot~]). (so if current output of the osc~ is -0.25 and will be 1 when the phase gets set, ramp from 0 to 1,25).
then after the ramp is done, set the osc~ phase and reset the line~ to 0 at the same time.
this technique is called 'switch and ramp' and is explained by miller in his book http://msp.ucsd.edu/techniques/v0.11/book-html/node63.html
(here I did it in reverse by ramping first and then switching, but you could also simply add the discontinuity when you change the phase and ramp to 0. that would work to eliminate the discontinuity as well, but in that case the artifact might be more prominent bc the frequency is higher)
using 0..10hz osc~ as amplitude modulation, when i get to 0, there's an audible click
@whale-av said:
@esaruoho The image is not useful as you say.
The only [osc~] that I see seems to be set to 0Hz and have its phase reset 5ms after receiving data..... so maybe the phase reset causes the click as the [osc~] wave could be at any value when the phase is reset and a sudden jump in value is a click.
David.
yep, that's what's happening. if i don't have the delay5 0( then the amplitude might be set to anything, so then i have to keep resetting it to zero multiple times until it's at the original volume. so hence the phase needs to be reset to 0.
here, maybe this'll help.
clicks when goes to 0.pd
i tried both hooking the 0..10hz osc to the first inlet of [*~]
or the second inlet. both "goes to 0" result in an audible click.
how does one reset the phase so that the volume is at the original volume, please?
here's the attached script as a screenshot
Controlling ramp time
Hi all, beginner here.
I'm trying to find a way to simultaneously modulate my METRO time and the ramp time of my LINE. I tried to crudely illustrate that concept in the red line drawing on my patch.
What I have here is
- METRO sends regular pulses to RANDOM
- with each pulse RANDOM chooses a random value
- values ramp from one to the next via LINE
- LINE passes values to NUMBER
- NUMBER passes values to PHASOR~ as frequency values
I want to be able to use one control that overrides the METRO time with a value that simultaneously becomes my LINE's ramp time. So when METRO is 1000ms, LINE ramp time is also 1000ms; when METRO is 750ms, LINE ramp time is also 750ms, etc.
Any insights on how to patch this up? Thank you!
maths regarding conversion from metro speed to pitch
Another approach is to design the implementation around the requirement.
You want to be able to produce a specific frequency. So... make frequency the input parameter, rather than metro time interval.
You want to step through array values, with an equal amount of time for each. That suggests a linear ramp, with a given frequency... i.e., phasor~.
phasor~ always goes 0.0 - 1.0. With 12 points, the array indices go 0.0 - 11 -- but here, note that if you say 0.0 - 11.0, then index 0 covers a span of 1, but index 11 covers a span of 0! That doesn't sound right. Instead, define the span for each index as i <= x < (i+1) -- inclusive at the bottom, exclusive at the top. Now the entire range is 0 <= x < 12... leading to the idea of multiplying the phasor by 12 (number of points).
The array indexing should truncate away any fractional part: if (phasor * 12) = 3.546, it should just read 3. Fortunately, this is the normal behavior of tabread~ (not tabread4~).
So we can get a sample-and-hold waveform this way. (The third array is just showing the floor-ed indices, to demonstrate that tabread~ really is truncating rather than rounding.)
All that's left is to add linear interpolation. A standard way to do linear interpolation is:
x = crossfade factor (0.0 - 1.0)
a = value when x = 0
b = value when x = 1
xfade = (b-a) * x + a (this is a reduction of (a * (1-x)) + (b * x)
).
If i is the index, then a = array "at" i, and b = array "at" i+1 -- but here, b needs to be modulo-wrapped back around, because i+1 could be 12-point-something. Pd vanilla doesn't have [%~] at signal rate, but [expr~] has fmod().
So we can index the two values, subtract, multiply by the crossfade factor (which is phasor * 12 --> wrap~), then add the "array[i]" value back in.
Now you can do whatever frequency you want, without the awkward conversion. Doesn't matter what that online tutorial said, IMO this fits the stated requirement better.
hjh