Pure Data [bang~] equivalent

Fora's icon

Hi guys,

I was hoping somebody could point me in the right direction. I am trying to translate a PD patch into Max and I can't figure out how to mimic PD's [bang~]
'output a "bang" message after each DSP cycle'

Has anybody got any ideas?

Many thanks in advance

Fora's icon

Great, I was doing some more research into PD vector size and yes, like you said it's fixed at 64 vs.

Many thanks, I'll give this a go, I think this will do the trick nicely!

Fora's icon

Appreciate the update, I ended up stripped away most of it and kept the gen -> edge.

Raja you're a total legend, many thanks yet again!

Fora's icon

Oh just in case you're curious, I am trying to port martin brinkmann's small Paul patch

Fora's icon

yeah that's the one but my patching skills have subsided after a long hiatus away from Max so it may take slightly longer than expected!

Cool, I'll post it here if I manage to complete it!

Fora's icon

Hey Raja!

Wondering if I could pick your inter-dimensional brain for a moment?

I am facing a issue trying to replace two PD objects, hoping you might know a good replacement for these two..

[tabreceive~] and [block~]

I have a feeling I could replace [block~] with poly~

[tabreceive~] --> index perhaps?

Roman Thilenius's icon

sending a signal into snapshot~ should also do it?

Fora's icon

edited*

Many thanks for chiming in Roman and please correct me if I am wrong but I don't think snapshot~ is correct in this instance, as part of the original PD patch the object tabreceive~ is driving a Hann function.

tabread~ has been replaced with [play~]
tabwrite~ has been replaced with [poke~] and Andrew Benson's gen [cshot~] btw

I have attached a screenshot section of the PD patch..

I have included another screenshot of the whole patch in case anybody wants to see it for better context.

Also this was taken from PD's help guide..

tabrecieve~ '- read a block of a signal from an array continuously'

Fora's icon

Thanks for clearing that up for me Raja and my apologies to Roman, in regards to [bang~] yes, snapshot~ @interval 64, will explore the new features of snapshot~, same here, I haven’t explored it in awhile!

Right, ok I'll will delve into your suggested links and see what kind of solution I can come up with!

Raja and Roman, many thanks yet again, two long term legends chiming in, I feel blessed!

Roman Thilenius's icon

i was only guessing around, fine that i hit it.

but are you sure about 64 samples?

i was more thinking that it only spits out data with the first sample of every vector (which would mean that it stopped working when someone has a vectorsize bigger than the sheduler time(?)) (or when i am wrong about this)

Roman Thilenius's icon

btw: count~ and zerox~ could be an alternative.

count will start counting when you turn audio on, so a certain number from it is always in sync with the beginning or any other position of the signal frame.

Fora's icon

I didn't think about that, I am planning to run the patch inside poly~ because of pd's [block~]
so I am wondering if snapshot~ is still a good option?

Raja posted a nice gen solution above which I may use instead just to make sure.

Roman Thilenius's icon

i think it stands for patcher (it is not very polyphonic)

regarding pd´s bang~, i wonder how it is used? where would you need to know when an audio vector begins (or ends) but with the inaccuracy of control messages?

Roman Thilenius's icon

I didn't think about that, I am planning to run the patch inside poly~

it should make no difference. poly also only starts processing with the next vector. (including when it has a vector size and/or samplingrate different from the enviroment.)

Fora's icon

thanks for the responses guys, unfortunately I am walking deeper into murky depths as fft is way outside my comfort zone! I should take some time to look at some of the basic tutorials that you linked above @raja.

I was hoping I would find some 'like for like' ports of some of the pd objects and move along with the port rather swiftly but alas, it's a bigger undertaking than I originally planned!

Although I found a couple of pd substitutes on this forum, specifically [tabwrite] (which essentially two objects [cshot] and [poke]) but I can't get it to work as intended.

I am also having a hard time getting a replacement for [tabreceive], I am still figuring out how it works.

block~ 'block, overlap, and resampling control for DSP' I read somewhere poly would be the choice solution, but before I can experiment, I still need to get the audio engine working.. sigh

I came across Volker Böhm's vb.stretch which is similar to Paulstretch, it sounds great but it's osx only, I would rather have a solution I can use without the need for relying on externals.

TL;DR fft seems like the way to go but I need to brush up on the tutorials before progressing!

anyway, thanks for the help guys. I may put this idea to rest for now.

but if anybody else is reading with experience using PD, I would love to know of any decent ports of the tab (series) of audio objects!

Fora's icon

Another idea would be to port Paul Nasca's paulstretch code into gen~

https://github.com/paulnasca/paulstretch_cpp

but that's C++ and another level for me completely!

Roman Thilenius's icon

no, that would be FFT. :D

Roman Thilenius's icon

I was hoping I would find some 'like for like' ports of some of the pd objects and move along with the port rather swiftly but alas

this is why i replied to this thread. i also wish a had an 1:1 translation library (except for very similar objects, that wouldnt make sense) but i am too lazy to do it on my own and without reason.

somebody once gave me that as pd[samphold~], which is one of the more complicated ones:

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 139 181 53 196617 >~ -1;
#P newex 217 199 53 196617 gate~;
#P outlet 343 217 15 0;
#P inlet 61 148 15 0;
#P inlet 139 73 15 0;
#P newex 260 164 53 196617 sah~;
#P newex 343 164 53 196617 gate~;
#P newex 428 146 53 196617 ==~ -1;
#P newex 139 128 53 196617 change~;
#P connect 0 0 8 0;
#P connect 0 0 1 0;
#P connect 5 0 3 0;
#P connect 5 0 2 1;
#P connect 7 0 6 0;
#P connect 2 0 6 0;
#P connect 1 0 2 0;
#P connect 1 0 3 1;
#P connect 3 0 7 1;
#P connect 8 0 7 0;
#P connect 4 0 0 0;
#P window clipboard copycount 9;

Fora's icon

Cool, samplehold is also something I found here, its featured in the patch I was trying to port.

I have a collection of PD ports from Stefan Tiedje called st.tools, there's a folder called Pd abhaXions, really nice collection.

https://github.com/TjShredder/St.ools

Fora's icon

@Roman, I was researching a PD post entitled "Don't understand tabreceive" which Raja linked and found two bits of info in regards to the behaviour of the tabreceive and block objects which I have quoted below..

Regarding tabreceive;

"Basically, what it does is cycle through a block's worth of array elements aligned with each block. So if your block size is 128, then [tabreceive~] will spit out the first 128 elements of the array on each block, one element for each sample. It's kind of like having a [phasor~] with the frequency quantized to the block frequency (sample rate/block size) and phase quantized to block boundaries, and then having that [phasor~] read the array."

Possible to recreate this using index / phasor etc?

Block; - Am I correct in saying this sounds a lot like Poly~?

"From what I understand, blocks are essentially buffers meant to make audio computation more efficient. If every sample had to be calculated individually, that means computation must happen at the sample rate (for example, 44100 times per second). Blocks (also referred to as vectors in other programs) allow calculations to be performed on groups of samples. By default, Pd uses blocks of 64 samples, but this can be adjusted per patch/subpatch using [block~]. This can help streamline the code so that some variables that don't need to be updated at every sample can be initialized at the beginning of the block, and then loops can be run on the 64 samples using only the necessary code. It also gives the cpu a little bit of leeway; in case computation falls behind (as a result of other processes interfering, for example) it has some headroom to catch back up."

Roman Thilenius's icon

recreating pd:tabreceive sounds superflous, in my opinion you would normally use cycle (pd:osc) and a send/receive. or no send/receive at all.

some people would design that thing above completely different, even in pd. :)

poly can change the vectorsize only _inside the subpatcher, so a max recreation of the block~ object itself will not work. (i think the runtime would have to allow different vectorsizes in one patch, too, and it currently doesnt. you can only control it globally.)

multirate would be way cooler to have anyway. :)

Fora's icon

true, it seems poly wouldn't behave like how I would want block to behave.

Oh well!

I just thought it would be nice to try and port this PD patch but man, I have been exploring options for the last couple of days and I guess I will lay it to rest but it's driven me to explore FTT in more depth which is a good thing.

I am going to continue my exploration of PD as well, it's still a good environment for porting patches into different O/S' and hardware setups (Raspberry PI)

Anyway, let's call it a day on this chapter Roman. Cheers for your input as always! :)

Fora's icon

Raja, wow! Thanks for your input and contribution. Ok this patch may not be what I originally wanted but it's a bloody great start and your explanation is great imo, even for a FFT n00b like myself, I was able to get my head around some of the technicals.

I will pick apart this patch, try out some ideas acquired through some of the tutorials you linked in your previous posts and see what kind of weird sound toy I may come up with, I'm sure it will take me along a different direction I wasn't expecting myself to take, like all experiments!

Thanks again Raja, you're an absolute diamond geeza!

Roman Thilenius's icon


raja
the font scrambler ?



Fora's icon

italic-disco!

vichug's icon

yo, i'm wondering if something could be done with the fftin~ nofft to replicate tabreceive~ ; and if maybe vectral~ could be of help here

vichug's icon

Also when i downloaded the pd patch from Martin's website, there is no samphold~ anymore in the abs_small_paul abstraction. Where did you get your version, Fora ?

Fora's icon

@vichug

I found a few useful conversions in this post linked below

Max Patch
Copy patch and select New From Clipboard in Max.


Roman Thilenius's icon

does pd:wrap~ work for negative numbers, and if yes, what does it it do? i might have a replacement.

Fora's icon

I believe it works for negative numbers. wrap~ can be replaced with [%~ 1.]

I came across wrap~ in the post I linked just above.

from PD, wrap~ is explained as follows; Remainder modulo 1

'[wrap~] gives the difference between the input and the largest integer not exceeding it (for positive numbers this is the fractional part)'

Roman Thilenius's icon

I believe it works for negative numbers. wrap~ can be replaced with [%~ 1.]

that is somehow contradictory, because % does not not work for negative numbers. :)

i was always using this

expr ((($f1-int($f1/$f2)*$f2) + ($f2)*(($f1-int($f1/$f2)*$f2)==0))*($f1>=0)) + ((((($f1-int($f1/$f2)*$f2)+$f2) + (-$f2)*((($f1-int($f1/$f2)*$f2)+$f2)==0))*($f1<0)))

but somehow i am afraid there is a simpler way (like some "wrap" external?)

Roman Thilenius's icon

negative numbers on modulo result in negaitive results, which is the correct result, but not what you would exspect from wrapping a range.

vichug's icon

(the fonts of Raja's patch appear normal on my machine)
(@Fora i meant, where did you get your PD patch version ? ;) )
re:vectral~, after looking into it slightly further, there is the problem that in pd the pitch change is done in time domain - via reading more or less of the original sound during one frame, so changing playback speed - not spectral domain, so one frame of signal will be repitched *before* there is an fft on it. BUT it is also windowed when it is pitched in this time domain, and not yet fft'ed. So vectral~ couldn't have an use for this problem, only something like "manual" windowing and fft'ing could help, as Raja already suggested... vectral~ could maybe potentially have a use though, if there is a way to change the pitch in fft domain, by "switching" bin's amplitudes - or there is the gizmo~ external, maybe that's how it works, i don't know ; but that wouldn't sound the same surely ?
Then, there is that PD can change windowing block size very conveniently, which you can't do in Max (one needs to recreate the object and give a new arg to change fft/windowing size whereas in PD, you can pass a message to block~). Soooo, er, as Raja said, that's, complicated :p and borderline impossible to obtain exactly the same result as in PureData in as much elegant way (copying abstraction with fft~ and manual windowing for each possible vector size to choose from, or script recreating the fft objects with new frame size each time it's changed are possible options....)

Fora's icon

@vichug..

Oh, the patch is a slight reworking by derek xkwan and the abbstraction is found here..

vichug's icon

thanks man ! :)

Fora's icon

No problem, let me know how you get on, I have put this idea on hold for the time being but I will defo keep tags on this thread