Quality granular processing in pd
OK, here's a basic live input granulator, no really fancy features, just pitch shifting.
The handling of grain playback rate in the one-grain abstraction is a neat trick I had worked out some time ago. For example, if you want to play the grain an octave higher (2x speed), then you need to span 2 * dur ms of audio in dur ms of time. You can do that by modulating the delay time as a straight line, from dur ms to 0 ms -- adding dur to the delay time at the beginning adds that many ms to the amount of audio being used: dur * (rate-1). Or, to play slower, start with a shorter delay and go toward a longer delay, and the boundary is again dur * (rate-1). If rate = 1, then the delay time goes from 0 to 0 = no change = normal speed. That might look a bit funky in the patch you can try it with different transposition intervals, which will show that it's correct.
For sound file processing, replace the delay line with a soundfiler-filled array, and use tabread4~ for the audio source (and the line~ driving it will have to be different too).
IMO granular processing is 99% refinement and more advanced modulation of these basic parameters, which you should be able to tailor to your needs. I think the pitch shifting is more-or-less smooth here, though I'm not sure it matches your comparison plugins -- this is 66.6667 grains per second, with 4x overlap.
one-delay-grain.pd
live-granular.pd
hjh
Waveguide/Karplus strong delay time problem
Hello, to put you into context I'm working on a waveguide-style physical modeling synth in PlugData (basically the same as Pure Data), and I'm running into an issue where my delay line won't produce high-pitched notes correctly. I'm using a [delwrite~] and [vd~] or [delread4~] combo, with the delay time calculated from frequency using [expr~ 1000 / $v1], where $v1 is the pitch in Hz (converted from MIDI with [mtof]). The delay time is in milliseconds.
The patch works fine for low and mid frequencies, but when I try to play higher notes (especially MIDI note 100 and up), the pitch output seems stuck. it just keeps playing the same note, i doesn't happen with low notes though.
I've already tried the usual fixes. I made sure the [delwrite~] buffer is small (100 and even around 5–10 ms), verified that the delay time input is a smooth signal ([sig~]), and tried both [vd~] and [delread4~] for interpolation, nothing works.
Out of curiosity, I tested the patch at a global sample rate of 96,000 Hz. That actually allowed the waveguide to reach the correct higher notes, but the patch became very laggy and glitchy, and the CPU usage was noticeably worse (as expected)
At this point, I'm wondering if there's a clean way to make a delay line in Pure Data (or PlugData) that supports very short delay times for high pitches (e.g. MIDI 120+), without needing to oversample the entire patch or push the sample rate to 96kHz. Is there a known solution for sub-millisecond delay accuracy that works well in Pd? Would a local oversampling strategy using [block~] be effective here? Any guidance or best practices would be really appreciated 

ofxOfeliaExtended
These are the contents of the .zip file you mention:
abs/ CHANGES.txt examples/ LICENSE.txt ofelia-object-help.lua ofelia_textwindow.tcl opencv_core4100.dll opencv_features2d4100.dll opencv_imgproc4100.dll README.md
assimp-vc142-mt.dll classesAndGlobalFunctions.txt libxml2.dll ofelia.dll ofelia-object-help.pd opencv_calib3d4100.dll opencv_dnn4100.dll opencv_flann4100.dll opencv_objdetect4100.dll stable-diffusion.dll
Are these supposed to be located in the ofeliaExtendedLib directory? Because, all there is in there, is already in the directory of the ofelia.pd_linux Pd external directory too.
[vline~] may not start at block boundaries
@lacuna said:
click bang [o] (GUI always on block-boundary) > [spigot] opens > [bang~] bangs > [spigot] closes > [vline~] starts (still on same block-boundary).
Yes, this is how I was hoping it would work, but it's not always the case that [bang~] bangs after the spigot is open within the same control block. It appears to bang afterward if there is a direct bang from a GUI element, but bangs before if the bang came from a delay. (Edit: I'm going to start a new topic on this, I don't see why this should be true)
bang~ runs last.pd
bang~ runs first.pd
If it runs before, then we are really waiting until it bangs at the end of the next audio block. (BTW, you can modify the number of blocks of delay and see the numbers change as you'd expect)
You use [rpole~ 1] as sample-counter, right? But [snapshot~] only snapshots on block-boundaries.
Yes, but all I'm concluding from that is that the message is available in the control block before the audio block that contains its actual time. The fact that so many Pd objects ignore the fractional block of time remaining suggests to me that it could be possible to truncate that fractional block of time in the message in order to make objects like vline~ start at the beginning of the audio block, like sig~.
So is it correct that you want to move the start of vline~ 'backward' ? To the start of the block?
Your diagram annotation is correct, but "want" is a strong word
. Let's just say I'm curious if it's possible. Right now, I'm delaying things like [sig~] to match [vline~] by inserting [vline~] just before them. I could have used any of our 3 quantizers to align the first [vline~] ramp with the block following the block that contains the fractional block timed message, but then I would have had to also delay my [sig~] processing a block as @seb-harmonik-ar confirmed.
The last two slides in that PP deck you linked to shows what I mean. Objects like [vline~] implement the ideal, but I'm wondering how to make it behave more like the last slide. See how the message's timing is labeled "t0+16"? Wouldn't it be possible just to zero out the "16" part?
Avoid clicks controlling Time Delay with MIDI Knob
@Zooquest You will hear clicks because there will be jumps between samples.... if the playback was at a sample level of 0 and you change the delay time to a point where the level is 1 then the click will be loud.
You will hear "steps" as the playback point is probably being changed repeatedly by the ctrl messages.
You could experiment with a [lop~] filter in the delayed sound output, with a high value e.g... [lop~ 5000] but you will lose some high frequencies in the echo.
That might sound natural though, like an old tape echo, but you will probably still hear the clicks a little.
Or you could "duck" the echoes by not changing the delay time immediately, reducing the echo volume to zero in say 3msecs using using [vline~] and not bringing the echo volume back up to 1 (in, say, 3msecs again) until you have NOT received a ctrl message to change the delay time...... for again 3msecs.
The last part of that would need a [delay 3] using the property that any new bang arriving at its inlet will cancel the previously scheduled bang.
You would need to duck the FB signal as well though, and all that that might sound worse than the [lop~].
I cannot remember well...... but this "sampler_1.pd" might contain elements useful to demonstrate "ducking" https://forum.pdpatchrepo.info/topic/13641/best-way-to-avoid-clicks-tabread4/12
Or do a crossfade between separate delays once the incoming control messages have stopped..... https://forum.pdpatchrepo.info/topic/12357/smooth-delay-line-change-without-artifacts ..... as you can then avoid the "duck"ing effect.
David.
Karplus strong and strange issues with fexpr~
@reubenm I never care about computational expense until it's a problem, and even then it sometimes generates some cool stuttering that I would never have thought of. But if that fexpr~ way of doing things speaks to you, then maybe you should look into supercollider
And I'm not trying to be a jerk because as a former java/c# programmer I'd probably prefer it!
Edit: Ouch! I think I'm confused about the delay line and forced order of execution. In KS you're feeding back the output of the delay line into the input, so either you have to have the delay line read upstream of the write (and so you have a min 1 block delay) or you have to send the delay line read signal back up to the delay line write (which also incurs a 1 block delay). So either way I think you have to reduce the block size to get frequencies above 689hz.
count~ pause option?
@KMETE said:
edit: and my reason is that if I want to do comparison of two numbers - lets say if the timer that s running is larger then constant number - if the timer will not output the numbers constantly I might miss this logic...
What you're talking about is a timeout situation -- checking whether something did or didn't happen within x amount of time.
In the normal case, in Pd, you can do a timeout like this (no [metro], no constant polling):

Here, I'm using the word "start" and "stop," but they can be any messages being generated for any reason.
-
If the user hits only "start," then the [delay] time expires, [delay] generates a bang, and you know that the elapsed time >= threshold.
-
If the user hits "start" and then "stop" within the time limit, then 1/ you have the trigger from the user and 2/ the [delay] gets canceled (no erroneous timeout message).
When you're talking about a timer that can pause, that complicates it a bit (because [delay] wouldn't know about the pause).
But, to be honest, based on your requirement from the other thread -- when audio playback pauses (because of user action or the 30-second(?) timeout), you're always resetting the timer. When the timer goes back to 0, then pause is irrelevant. So I kinda wonder if the original question in this post stems from an unclear requirement rather than an actual need (though it is a kinda cool abstraction, and I'll add it to my library later).
After all, if you only want to stop checking for the timeout based on user pause, you can just stop banging the [timer] at that point... then, no check, no false timeout, and no need to over-engineer. Or using the [delay] approach, just "stop" the delay.

So there's a polling timeout that is aware of paused status, without using a special pausable timer. So this idea that you have to keep banging the timing object and the timing object should be responsible for not advancing when paused is perhaps overcomplicated.
edit2: I could bang the poll message every 10ms using metro but then we again have an issue on cpu?
[timer] shouldn't use much CPU... it's probably fine, and if it's more comfortable for you, feel free to go that way. I'm just pointing out that brute force is not the only way here.
hjh
PlugData / Camomile "position" messages: What are these numbers?
@whale-av said:
@ddw_music Yes.... buffer.
Maybe some DAWs have implemented a tempo message since then?
Tempo must be available, since plug-ins have been doing e.g. tempo-synced delays for at least a decade already.
(In fact, it is available via Camomile: [route tempo position].)
Anyway... I've been considering solutions, and I think I can do this.
- Set some threshold close to the beat, but before the beat, say x.9 beats.
- For the first tick past the threshold, get "time to next beat" = roundUp(pos) - pos = int(pos + 0.99999999) - pos.
- [delay] by this many beats ([delay] and the tick-scheduler will have been fed "tempo x permin" messages all along).
- Then issue the tick message to the scheduler, in terms of whole beats (where the time-slice duration is always 1.0).
At constant tempo, I'd expect this to be sub-ms accurate.
If the tempo is changing, especially a large, sudden change, then there might be some overlaps or gaps. But [delay] correctly handles mid-delay tempo changes, so I'd expect these to be extremely small, probably undetectable to the ear.

Half a beat at 60 bpm + half a beat at 120 bpm does indeed = 750 ms -- so the delay object is definitively updating tempo in the middle of a wait period.
I'll have to build it out and I don't have time right now, but I don't see an obvious downside.
hjh
phase index of an oscillator and 1 sample delay in pd?
delread~ is not a sample delay it is a tapping buffer.
a tapping delay does not delay "the samples", it delays their content.
plus its minimum delay time is the vectorsize.
i think in pd you would replace [delay~ 1] with [fexpr~]... something like x = x1, no idea about the correct synthax.
How to best read/debug a button sending too many 1s and 0s at once
How about this
[comport] <- I guess you're reading values from a serial bus
|
| [r spigot]
| /
[spigot 1]
|
[t f b b]
| | |
[0\ [0( [del 100]
| |
| [1(
| /
[s spigot]
This will receive the first value, close [spigot], and re-open it after 100ms. You can experiment with the argument to [del] to get an optimal result.


