Looking for an object like cyclone/togedge but for signals
@jenkutler
The helpfile of [cyclone/togegde~] doesn't work here, but I replicated it's behavior in signalrate like this:
If you want strictly ints, you can add a signalrate [int] like this:
@bocanegra said:
The logical output is signal rate (which can be very useful). If you want bangs look into [threshold~]. You should be able to set that up as a zero crossing detector.
I don't know about [threshold~] never used it, but my example above is not suitable as zerocrossing detector, as the chance of a sample being actually 0 at zero-crossing is very small!
Detecting zero-'crossing' would be a transition from postive to negative or vice versa, or to zero. There is also [zerox~].
The DSP block size will affect the accuracy of the timing though so if you need a bang exactly when your signal crosses zero, you will need to do [block~ 1]
Much later edit: the following is actually wrong, - it is even more complicated (((Message-handling happens in 64-sample periods, only. You can't change that. Even if [threshold~] would go down to 1 sample (still one sample late), the following message-chain won't.))))
EDIT: edited
Best way to avoid clicks (tabread4~)
@lacuna said:
Who hears clicks when switching at zero-crossings?
It's always been absolute nonsense that it's safe to edit at zero crossings -- as you demonstrated
I think: to avoid clicks, not only the signal itself should avoid discontinuities, but also the derivative (the slope) of the signal should avoid discontinuities. A sharp cutoff at a zero crossing will feature a break in the slope even if there isn't a large jump in the signal itself.
This is also why a sinusoidal envelope is smoother -- because the slope of the envelope is itself a sinusoid (derivative of sin = cos and vice versa).
hjh
how to get dynamically updated values into Pd from Python
First off thank you all for your help and suggestions!
I managed to find a solution with a little help from my friends.
So, my main problem turned out to be that I needed to create my socket BEFORE defining my function. Then only after both of these are done I could set up the string to send to Pd (because Python does this sort of weird recursivey thing).
Also as some of you suggested my string was named badly, first I was using a the wrong variable data type ("b") then I tried to make a string using "str" as a name which confuses Python as "str" is the string data type. So for anyone else dealing with this be sure to call your string something like "data" or "lsdfdjkhgs" but not "str"!
Anyway, it works now and I can send data over to [netrecieve]
incidentally @whale-av 's suggestion to use Pd's built in messaging scripts located in the application folder (pdsend & pdreceive) brought up a lot of interesting possibilities that I will be exploring later and for anybody wanting to send messages between Pd and other programs this looks like a cool way to do it.
anyway, I will share the code here in hopes it will help someone else:
import socket
from obspy.clients.seedlink.easyseedlink import create_client
# first get all the socket declaration out of the way
s = socket.socket()
host = 'localhost'
port = #put (your) open port here, this is also part of Pd's [netreceive] argument
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
# then we define our callback which happens when we receive data
# out socket is already set up so we can reference it here in the callback
def handle_data(trace):
# trace is an obspy.trace class so we must convert to string
# I have to mess around with this "trace" because it is part of the class my client code is using
data = str(trace)
# we can then neatly append a ; with a "f-string" to make it work with Pd's FUDI protocol (Pd messages end in ";")
data = f'{data};'
# or
# data = str(trace) + ';'
# if you like
# and send it over our socket
s.sendall(data.encode('utf-8'))
#then AFTER all this my code connecting to the server (that returns the data as a string "trace" above, but the entire part for communicating with Pd is up there, and surprisingly simple despite the 'strange loops'!
Mono / stereo detection
@Obineg I don't know Max.
There is [inlet]....... a control rate port..... and [inlet~]..... an audio rate port,, in Pd.
They are used to create inlets for sub-patches or abstractions so that a patch can be used within another patch and connected by "cords".
Of course [outlet] and [outlet~] too.
And of course [send] [send~]....... etc. for connection without cords but they then need names (arguments) to define the routing.
avid.
Paths and organizing .pd files for use.
@raynovich I use the [declare]
object instead of paths, keeps the paths list shorter and more manageable and also gives you a nice list of dependencies right in the patch so you never have to wade through the patch trying to figure out what it needs if you want to share the patch or copy it to a different machine. If you need a sub-folder you just declare the sub-folder. Use absolute paths when you declare, this way you can move the patch and it will still find what it needs. I generally have a sub-patch in each patch for declares and I avoid declaring folders, just declare the abstraction directly so I never have to try and figure out which abstractions a given patch uses, just open the declare sub-patch and it is all there. In my pd folder I have all my current patches, an abstractions folder, a folder for patches I am not currently working on and a folder for reference patches. I do my best to avoid making abstractions which only have use in a single patch, I will figure out how to generalize it to make it more useful for other patches so it can live in my abstraction folder without cluttering it up and helps avoid needing folders for patches. When a patch must have a folder it goes in the pd directory with the patch and I declare it instead of keeping the patch in it's own directory, this is mainly to minimize having to navigate folders as much.
Using [declare]
to explicitly declare individual abstractions also makes it easier to clean your abstraction folder, a simple shell script can check for abstractions which are not used by any patch or ones that just get used by a single patch so you can check them out to see if they are worth keeping or should be moved too the folder of that one patch which uses them.
Using Pd to remote control OBS
@Harlekin If you want TouchOSC to control OBS you don't need Pd....... just connect TouchOSC directly to the ports of osc4obs and make your remote.touchosc layout file.
If you want to do some other processing in Pd then connect TouchOSC to Pd directly (in and out)...... and then connect your processed control from PD to osc4obs directly (in and out).
osc4obs facilitates that by creating separate OSC in and out ports.
You will have to do that also if you want to use TouchOSC and Pd in an either/or situation as osc4obs only has one set of osc ports and is making a tcp connection with OBS.
OBS websocket is a tcp connection and so it is possible that osc4obs is requiring tcp for the OSC connections...... in which case remove the -u flag from [netsend] and [netreceive] in my examples below.
It could also be expecting ascii instead of binary in which case remove the -b flag (but I doubt that)....
Externals for Pd are written in C so if you are adept there is some help in Pd/doc/6.externs .....
Basically you need to make a websocket client that replicates osc4obs with outlets and inlets instead of the osc ports.
BUT... you could try the iemnet [tcpclient] first (NOT the [udpclient]...!).... and that should work.
Just replace both [netsend] and [netreceive] with the one [tcpclient]...... connect it to OBS and look at the output using a [print] object.
If OBS is on the same computer the connect message will be [connect 127.0.0.1 4444(
Remove the password from the OBS websocket unless you find that a password can be added to the [connect( message for [tcpclient]...... before or after the port number? preceded by "password" or "passwd"?...... guesswork...... and [tcpclient] might well not accept a password as it is not mentioned in the help file.
Once you are looking at a print of the received messages the problem will be to decode the proprietary message format (it will not be OSC)....... it might be easy.... or not.
If lucky there will probably be the ascii strings you are looking for or a decimal representation of them somewhere in the message.
If you go the osc4obs route then it is quite easy to use [oscformat] and [oscparse] in vanilla instead of creating an external.......
...... vanilla osc.zip
P.S. try to avoid integers within the OSC address (header) as they arrive in Pd as symbols at the output of [oscparse] ....... and are then difficult to route. So what/ever/6 data is best avoided if possible and what/ever/six data is easier to deal with in Pd...... but I have included a solution in the zip file above.
Be careful in TouchOSC to avoid message feedback (much like midi feedback)......... and the same applies in Pd. In Pd you can include "set" at the start of a message (without the quote marks)...... which will set a message in the next object or message box but not send it onward until that object or message is banged.
David.
Too many bangs or wrong note on onset for granular synth
@morpheu5 Your clones are identical. There are two incoming messages that change their operation.
[next $1( and [r $1-grainSpeed].
But [s $0-grainSpeed] sends to all of them so they all have their speed settings changed at the same time as a note is played (except that they do not without the "cursed" bang..)
With the cursed bang they are all updated for an incoming note...... but all the [vline~] are restarted causing an overload.
Without the cursed bang none are updated until the metro bangs again....... but there will be an indeterminate delay until the metro bangs........ during which time the tail of the previous grain will still be playing the previous note..... and then none of the others will be updated......
Assuming you want all the grain tails to be updated by the note but not be restarted..... (that is how it looks at the moment....... Monophonic.... if not then everything below is untrue).......
........ you will need to bang [vline~] only from the [next $1] message and modify the output of [vline~] before [tabread4~ $1-grainData] with a [x~] for all the other clones..... the value for the [x~] being the relationship between the current and the previous note.
..... And the new note needs to bang the [next $1( message...... not the [metro]
BUT you will not want the multiplier for the newly banged [vline~]....... and your clones are identical...... aargh.
SO in fact you need to get the grainSpeed into the clone as a modifier of the output of [vline~] and not as part of it's received message (so that they all change)....... and only bang one clone to restart one [vline~] at the same time through the [next $1] message..
Doing that you will only need to set the modifier as a value for the note and you will not need to mess around with relative values between notes.......
I think that is it in summary.....
David.
Just got my MIDI Violin! Here are some notes on it and how to use it with PD
@whale-av Hey, sorry I never replied- I just saw your reply now after I bought the instrument. I ended up getting the BOSS GP-10 as a MIDI interface for the instrument. I knew the GR-55, SY-300 and SY-1000 would work as well, but didn't know about the GI-20. Maybe it would've been more affordable...
Here are my notes. Happy to hear anyone else's experiences or ideas about how I can get the most out of this device:
1)The instrument has screws on the back that you can turn to increase/decrease the sensitivity of each string. I've adjusted these a bit with dealing with the problems mentioned below in observation 9)
2)The GP-10 also has some settings for more or less dynamic contrast. I've experimented with setting these differently, though setting "Dynamics" to 1 and "Play Feel" to FEEL 1 seems to be the best. Changing these doesn't seem to do anything for the problem in 9).
3)I have the GP-10 set to MONO mode, rather than poly mode so that each string outputs to a separate MIDI channel.
-
The output to separate channels works well if you do clear attacks with the bow (or use pizzicato of course). The attacks need to be clear whenever you switch to a different string. Raising the sensitivity (cf. 5)) allows you to have clear attacks that are still somewhat quiet.
-
As long as a note is sustained, you get continuously updated bend values, which can be combined with the original noteOn value to get exact pitches and perform glissandi. I combine the two values in Pure Data with math objects. noteplusbend.pd
-
The MIDI velocity value does not update continuously, but in PD I can use the velocity's value as a switch to allow the Audio-in (which also comes in through the GP-10's USB) to control the volume of the MIDI-activated note via [spigot].
-
Because attacks with the bow need to be clear, if you fade in a note very gradually with the bow, it won't be detected as MIDI.
-
By combining 6) and 7) I can construct patches in Pure Data so that a certain sound will play and be controlled purely by the Audio-input and that others will be activated by MIDI+Audio-Input. Eg. I can fade in a sound, crescendo with an up-bow and then attack crisply on the down-bow to activate other sounds.
-
There are some issues with stable pitch detection when playing double-stops (diads) on two neighboring strings. It seems when doing so that there's some interference. However, for some reason, playing smaller intervals (major 3rds or lower) seems to work better than larger intervals. And avoiding open strings helps as well.
-
The pitch detection of 9) could be ameliorated by removing the bend value from the equation, but of course glissandi/microtonality would be lost as a result.
-
The E string (the highest one) gives the quietest, least consistent output. Pitch detection suddenly falls off after the first octave.
[nfader~ ], an n-way pairwise linear interpolator
I needed a cross fader that could accept an arbitrary number of signals and interpolate between them linearly two at a time, based on a 0-1 parameter.
I made [nfader~ ]. The creation argument (defaults to 2) sets the number of signal inlets from 2 to n+1, and the first (signal) inlet takes in the cross-fading parameter, a number from 0 to 1 that sweeps all the 2-n+1 inlets two by two.
Let me know if you find it useful and feel free to suggest improvements!
Purr Data GSoC and Dictionaries in Pd
@ddw_music "A concrete benefit is: If I write some compositional algorithm and I want to decide later whether to play it within SC or using an external instrument, I don't have to change the composition logic at all. That part simply stuffs data into Event objects, and the event determines what finally happens."
That is exactly the purpose for which I built [slist-master]
Because it was built for lists the data "get" has to look for the place in the list so with a single value for the key........ key/value dog 12 is looked up by [value dog1]
It can be modded easily to avoid that if only single values are ever to be assigned..... see below.
I have changed the setting of data to use the more conventional "set" in place of "add".
When the data set is loaded (by set or loading a file) all [value] objects are loaded with their data, so retrieval should be fast.
Even a dynamically created [value] will already store the data for the key.
cat_n_dog.zip
And here for just key/value (lists truncated)...... key-value.zip so the receive objects are simply [value key]
Of course [value] is already [receive] with a store........ so be careful with key names...
And values can be overwritten but not cleared... that's in the nature of the [value] object....
David.
PS It is possible to access much of Pd media settings and change them from within a patch.
Some work was done recently to cope with reordering midi connections when their order has changed in the os. That could be applied to audio devices as well...... https://forum.pdpatchrepo.info/topic/13217/save-and-recall-midi-settings-in-a-project/2
I didn't follow up to see how complete the project was.....
A little more complex than some other programs of course.