looper overdubbing not lining up.....
Hey @whale-av and anyone else interested in this issue.
I'm still trying to wrap my head around this.
So this looper works if you loop one pass and play it. It works with overdubbing at speed = 1 or -1.. The problem is if you overdub at any speed other than 1 or -1.
I am going to explain the issue as I see it, although I may be mistaken. It is set up so the buffer length will not change after the first recording, so when overdubbing the buffer size doesn't change. If you doing playback at a speed other than 1 or -1 the speed of the phasor~ reading the array with the loop will change to that new speed. When you are done overdubbing, it would seem that the phasor~ should be at the same speed it was during the overdub, but if this is the case things get out of whack. At least that was my observation in the "simple3.pd" patch a few posts up.
I added an [expr] object to try and accomodate for what I was hearing. But now what is happening is it seems that the loop is getting shorter if it is less than 1 and it's too long if it's greater than 1.
I must be missing something obvious here.
I haven't tried this yet, but maybe I should add another phasor~ that is lined up to start with the first phasor~ playing the array, but when I alter playback speed this 2nd phasor will change as well and i can use that to start and stop the overdub process. What I am hearing is the overdub, when playing at speed = 2, will double in speed , then double in speed again during a recording. and the opposite is true for half speed. I think maybe a 2nd phasor can modulate to the new speed when an overdub is activated then take over reading the array when an overdub is finished. It's just an idea I had.
Anyway, any suggestions into this would be much appreciated.
Here is what I have now. simple6.pd
Thank you.
get phase of [osc~]
[phasor~]
|
[cos~]
should be the same as
[osc~]
but this time I need to measure the phase of [osc~]
and do the same as

with [osc~] instead of [phasor~].
I have a running patch, but sometimes it flips the phase by 180 degrees.
Do you know why or how to avoid that?
Here is the patch:
phase_of_normalized_cosine~.pd

The patch calculates the phase of a normalized cosine y(x) by
asin(y(x)) / (pi/2)
this is a triangle wave, following cosine's shape linearized.
Then a tri-to-saw waveshper:
invert the falling part of the triangle
and divide it's frequency by 2.
late EDIT: also read this: https://forum.pdpatchrepo.info/topic/15128/snapshotting-and-restoring-the-state-of-a-phasor-exactly
Signal logic - Clocks, Division and sequences
clock division and clock multiplication for a phaseaccumulator?
division is easy.
[*~ 4.]
[%~ 1.]
but multiplication is more or less impossible, as it would require something to count the current subcycle.
there are a workarounds though. if you want to use a phasor~ and a phasor~ which is 4 times slower, you could
a ) use multiple phasors~ from the beginning on and then select one of them
or, if you need them to be in sync with a "master phasor",
b ) use a phasor which is 8 times slower than the rated rate and derive the base speed phasor from it already using multiplication.
Audio click occur when change start point and end point using |phasor~| and |tabread4~|
Hi Junzhe 
I often like to think through something like this with a concrete example.
Let's start with 10 seconds of audio: phasor = 0 --> time 0, phasor = 1 --> time 10000 (ms).
Then, at 5000 ms, you change the end time to 7000 ms.
So, now, phasor = 0.5, time = 5000. And you need phasor = 1 now to map onto 7000 ms.
So two things need to happen:
- The phasor, running at its current speed, would reach its end 5000 ms later -- but you actually need it to reach the end in 2000 ms. So the phasor's speed has to increase by a factor of 5/2 = current_time_to_end / new_time_to_end.
- The linear mapping currently locates phasor = 1 at time = 10000, but now you need phasor = 1 --> time 7000. So the slope of the linear mapping will have to adjust by a factor of 2/5 = new_time_to_end / current_time_to_end (and the linear function's intercept would have to change too).
The changes in phasor frequency and linear slope should cancel out.
Then, at the start of the next cycle (which can be detected by [samphold~]), you would have to recalculate the slope for the entire start <--> end segment.
I might be overthinking it, but e.g. jameslo admits that in a simpler solution "the pitch is not steady as you adjust the start and end" so I think there aren't many shortcuts to be taken.
BTW there is another way to integrate a rate: rpole~. With an integrator, you don't have to worry about rejiggering slopes -- it just continues on its way, and reaches the end value in its own time. But, you would be responsible for triggering the reset at that point. This version uses control messages for triggering, so it would be quantized to block boundaries. To do it sample-accurately involves feedback and I never worked that out.

And a quick test patch (array "a" is 44100 samples, vertical range -10 to +50):

hjh
PS Hm, now I guess the [route float bang] isn't needed after all.
s~/r~ throw~/catch~ latency and object creation order
For a topic on matrix mixers by @lacuna I created a patch with audio paths that included a s~/r~ hop as well as a throw~/catch~ hop, fully expecting each hop to contribute a 1 block delay. To my surprise, there was no delay. It reminded me of another topic where @seb-harmonik.ar had investigated how object creation order affects the tilde object sort order, which in turn determines whether there is a 1 block delay or not. Object creation order even appears to affect the minimum delay you can get with a delay line. So I decided to do a deep dive into a small example to try to understand it.
Here's my test patch: s~r~NoLatency.pd
The s~/r~ hop produces either a 64 sample delay, or none at all, depending on the order that the objects are created. Here's an example that combines both: s~r~DifferingLatencies.pd
That's pretty kooky! On the one hand, it's probably good practice to avoid invisible properties like object creation order to get a particular delay, just as one should avoid using control connection creation order to get a particular execution order and use triggers instead. On the other hand, if you're not considering object creation order, you can't know what delay you will get without measuring it because there's no explicit sort order control. Well...technically there is one and it's described in G05.execution.order, but it defeats the purpose of having a non-local signal connection because it requires a local signal connection. Freeze dried water: just add water.
To reduce the number of cases I had to test, I grouped the objects into 4 subsets and permuted their creation orders:
The order labeled in the diagram has no latency and is one that I just stumbled on, but I wanted to know what part of it is significant, so I tested all 24 permuations. (Methodology note: you can see the object creation order if you open the .pd file in a text editor. The lines that begin with "#X obj" list the objects in the order they were created.)

It appears that any time the phasor group is created before the r~, there is latency. Nothing else matters. Why would that be? To test if it's the whole audio chain feeding s~ that has to be created before, or only certain objects in that group, I took the first permutation with latency and cut/pasted [phasor~ 1] and [*~ 44100] in turn to push the object's creation order to the end. Only pushing [phasor~ 1] creation to the end made the delay go away, so maybe it's because that object is the head of the audio chain?
I also tested a few of these permutations using throw~/catch~ and got the same results. And I looked to see if connection creation order mattered but I couldn't find one that did and gave up after a while because there were too many cases to test.
So here's what I think is going on. Both [r~ next] and [phasor~ 1] are the heads of their respective locally connected audio chains which join at [-~]. Pd has to decide which chain to process first, and I assume that it has to choose the [phasor~ 1] chain in order for the data buffered by [s~ next] to be immediately available to [r~ next]. But why it should choose the [phasor~ 1] chain to go first if it's head is created later seems arbitrary to me. Can anyone confirm these observations and conjectures? Is this behavior documented anywhere? Can I count on this behavior moving forward? If so, what does good coding practice look like, when we want the delay and also when we don't?
looking for velvet noise generator
@porres oh yeah I always forget about [expr~] for some reason.. maybe bc of the license it used to have.
There's no real reason to have the phase reset inlet, just more control.
From what I can tell, velvet noise is outputting a 1-sample impulse of value that's either 1 or -1, chosen randomly, at a random point in a regular period.
So I have a [phasor~] to keep track of the period, and the [samphold~] samples a random value from 0-1 when the [phasor~] resets. This will be the point in the phase of that period that the impulse will occur. When the [phasor~] gets to above or equal to this value, the [<~ ] will go from 1 to 0. That goes into [rzero~ 1], which will put out a -1 on the sample that occurs. That goes into the [==~ -1], which acts (together with [*~ ]) as a gate for the noise value that has been manipulated to either be 1 or -1, depending on if the output of [noise~] is positive or not.
The issue with this original implementation was that when the [phasor~] wraps around to start a new phase, it can wrap to a value greater than the new [samphold~] value from the noise. That means that if the noise value is very small, there will be no impulse for that period since the [phasor~] value will never be less than the sampled noise value for that period (and therefore the [<~ ] won't go from 1 to 0, which means the [rzero~ 1] below it won't output a -1, and so on). So, the [rzero~] and [<~ 0] put out a 1-sample value of 1 when the [phasor~] wraps around, which is combined with the other signal in [min~ 1] to take care of this. That way the [rzero~ 1] below the [min~ 1] will get a 1 even if the wrapped-around [phasor~] value is less than the new sampled noise value, and there will be an impulse for that period.
(that is what "make sure there is at least 1 1 on wraparound" means)
edit: after writing all of this it occurred to me that the sampled noise value could also be greater than the value that the [phasor~] will get to before it wraps around.. perhaps the solution is to constrain the sampled noise value depending on the frequency and phase of the [phasor~]...
Windowed-sync oscillator: Style questions
@jameslo "Since many programmers seem to want to avoid [fexpr~] at all costs, maybe you could rewrite your [fexpr~] with [expr~ $v1 > $v2] and [rzero_rev~ 0]"
Hmm, yeah. I had thought that both [expr~] and [fexpr~] were said to be bad for performance.
I suppose this might be another way to do a signal-rate comparison:

There's a very small chance of the [-~] result being between 0 and 1e-30, where the clip~ value would be between zero and one but not exactly either. With typical signal magnitudes, that's unlikely, so this wouldn't work in cases where only 0 and 1 are acceptable.
+1 RE the mystifying omissions and irregularities in vanilla. Since I started thinking of it as a scripting language (and stopped comparing it to c, c++, c#, Java...) everything became happy and easy-going.
Yes and no... Pd is an important and valuable tool and it's good to make friends with it as it is. At the same time, lack of some core operators can be seen as a usability issue.
I definitely wouldn't compare it to C and such. Miller Puckette himself acknowledges[1] that many algorithms are straightforward to write in procedural languages (and maybe even more straightforward in functional languages), but rip-your-hair-out painful in dataflow patchers. E.g., quicksort, which in Haskell goes:
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
and in C is... somewhat longer but still a fairly straightforward recursive implementation.
I can literally not even imagine how to implement a quicksort in Pd.
In SuperCollider, I'm doing most of my performances using a sequence-scripting language of my own design, where SC code is parsing the expressions and translating them into SC patterns. That's been a long project but within reach of an object-oriented language with a full suite of data structures. Pd... again, I can't imagine where to begin.
Puckette points out in that interview that Max and Pd are designed to react to input events, and they are very elegant for this. In Pd, you can connect a slider to a number box. In SC, the same is:
(
var number, slider;
w = Window("slider", Rect(800, 200, 500, 400)).front;
w.layout = VLayout(
nil,
HLayout(
number = NumberBox().fixedWidth_(80),
slider = Slider().orientation_(\horizontal)
),
nil
);
slider.action = { |view|
number.value = view.value;
};
)
In that case, definitely, Pd's expression of the idea of a value flowing from an interface object toward the display object is as concise as you can imagine, and SC's version is verbose and puzzling until you get used to it. Use the tool that's right for the job.
lacuna:
There are [vphasor~], [vphasor2~] and [vsamphold~] from @Maelstorm .
Oh that's good.
It's hard to find extensions like this, if you don't know where it is.
In your patch [rpole~ 1] is working with a signal-inlet, isn't it?
Yes. The idea is, while the (signal) coefficient is 1, then the left-hand signal gets integrated. If, for a single sample, both the signal and coefficient are 0, then the output is 0, and it will start integrating again as soon as the coefficient flips back to 1.
Which is that other forum you mentioned?
TBH I think SC wins in terms of clear expression of this synthesis algorithm:
(
{
var sync = LFTri.ar(SinOsc.kr(0.2).exprange(100, 400));
var phase = Sweep.ar(sync, SinOsc.kr(0.12743).exprange(700/3, 2100));
var synced = SinOsc.ar(0, (phase % 1) * 2pi);
dup(LeakDC.ar(synced * sync) * 0.1)
}.play;
)
This is part of what I mean by "usability issues" -- Pd: 7 objects for the triangle wave vs SC: LFTri.ar(freq), or the automatic exponential scaling exprange, and Sweep has a signal-rate retrigger built-in (there's also a range-rewrapping Phasor, and it has an audio-rate trigger too)... SC's initial learning curve is steeper but once you know it well, it took a couple of minutes to write that, vs 30-40 minutes (including head-scratching time) in Pd. (Admittedly I'm less fluent in Pd.)
hjh
[1] https://omny.fm/shows/future-of-coding/47-maxmsp-pure-data-miller-puckette
Windowed-sync oscillator: Style questions
Hi,
The topic of windowed sync oscillators came up on another forum. For fun, and also to improve my Pd chops -- this is what I came up with. (One reason for sharing is that I feel like this is a new level of Pd-idiomatic patching for me.)
I have a couple of questions, below the patch.

-
Is [fexpr~] the best way to check for the phasor reset? With cyclone I could do [rzero~ 1] --> [>~ 0] I think. The goal is a signal that is 1 while the phasor is incrementing, and 0 for exactly one sample when it wraps around. It must be 0 for exactly one sample, because this is used to reset the [rpole~] accumulator (syncing the sine oscillator).
(I've struggled with the lack of signal-rate comparators before. Yes, they're in cyclone, but... aren't these fundamental operators? Why not in vanilla? From past conversations, I gather that often, when a "basic" feature isn't present in vanilla, it's because you can build it from objects that do exist in vanilla. But I never figured out a good way, apart from [expr~] / [fexpr~], to do that for signal comparisons -- which feels like cheating in a way.)
-
The [rpole~ 1] is essentially a phasor with a signal-rate reset (as opposed to [phasor~], which can be reset, but only with control messages). Is there a better way? (Tbh I'm a little bit proud of this one
)
Thanks,
hjh
how can i make a [phasor~] myself?
my goal from doing this is to make a [phasor~], which only does one oscillation when it recieves a message, i can't simply use a line~ (at least AFAIK) to do this because i want to do FM on that [phasor~]. is there a way tho see what an object is made of, like opening a patch inside a patch, or is it just C code? i'm not good at C, BTW. could someone make a patch that does the same as [phasor~], or what i intend to do? both would be nice, because, if i just know haw the [phasor~] is made, i can probably transform it into what i need it for.
If none of the options above are possible, i have tried to use expr~/fexpr~ to time to turn off the [phasor~]/(output of [phasor~]), one attempt was with [fexpr~ if($x1[-1]==1,0,$x2[0])] where $x1 is the output of [phasor~], and $x2 is the frequency for [phasor~], and connect the output to [phasor~], but that didn't work. can somebody make a patch that reacts to [phasor~] reaching its peak: 1, and excactly between 1 and 0, when 1 is over and 0 has not started, and so turns the [phasor~] off?
help is greatly appreciated here:D
samphold-ing a previous signal value
I would like to create a Pd equivalent of SuperCollider's LFDNoise1 LFO (random line segments).
It's basically like this. In Pd, I can see how to do almost all of it, except for sample/holding the previous random value.
(
a = {
// pd: phasor~
var phasor = LFSaw.ar(1) * 0.5 + 0.5, // 0-1
// pd: [rzero~ 1] --> [<~ 0]
trig = HPZ1.ar(phasor) < 0, // 1 when phasor drops
// pd: [samphold~]
nextEndpoint = Latch.ar(WhiteNoise.ar, trig),
// pd: I don't know how to do this
prevEndpoint = Latch.ar(Delay1.ar(nextEndpoint), trig),
// pd: easy math
line = (nextEndpoint - prevEndpoint) * phasor + prevEndpoint;
// simple test signal: map bipolar LFO exponentially to freq
SinOsc.ar(400 * (2 ** line), 0, 0.1).dup
}.play;
)
a.free;
I made one failed attempt using [phasor~] --> [rzero~ 1] --> [*~ -1] --> [threshold~] --> [random], but if the phasor jumps to zero in the middle of a control block, then the random calculation is out of sync and the output glitches slightly. So I need to keep all of it in the signal domain (no control objects).
Thanks,
hjh



