looking for good drum synths
@bocanegra, addperc works nicely (and sounds great) in Pd-l2ork but not in vanilla. In the latter I get the following errors:
0-sqt: no such object
0-range: no such object
0-vcof: no such object
0-vcor: no such object
0-vcoa: no such object
0-mixg: no such object
0-mixr: no such object
0-mixa: no such object
0-shape: no such object
0-bpf: no such object
0-bpq: no such object
0-hpf: no such object
0-lpf: no such object
0-ega: no such object
0-egr: no such object
Audio click occur when change start point and end point using |phasor~| and |tabread4~|
@Junzhe-hou said:
@ddw_music Hi professor!?!? good to see you here!
Yes, it's me -- I almost didn't notice your username
I read your email last week but im so confused with your
patch--varispeed-segment:|noise~|
|
|lop~ 3|
|
|*~ 30|
|
|+~ 1|
This is just a way to generate a modulator for the playback rate. It could be any other modulator (LFO, envelope, anything).
After that, this is multiplied by a sample rate scaling factor.
As you asked jameslo: "if sample rate (in audio setting) changed the result sound different":
-
If the file sample rate is 96 kHz and the soundcard sample rate is 96 kHz, then normal-speed playback is to move forward exactly 1 sample in the file for every output sample.
-
If the file sample rate is 96 kHz and the soundcard sample rate is 48 KHz, then normal-speed playback is to move forward exactly 2 samples in the file for every output sample. (If you playback at 1:1, then the file will sound slower at the lower soundcard sample rate.)
This was one of the big reasons for me to make [soundfiler2] in my abstraction set. It calculates file_sr / system_sr
and saves this in a value object named after the ID+"scale". If you multiply the playback rate by this scaling factor, then the file should sound correct at any system sample rate.
(BTW you would have the same issue in SuperCollider: PlayBuf.ar(1, bufnum, rate: 1)
will sound different depending on the hardware sample rate, but PlayBuf.ar(1, bufnum, rate: BufRateScale.kr(bufnum))
would sound the same, except maybe for aliasing when downsampling.)
You method "L inlet = rate * scale for sample increment",so is the rate always changing?
Yes -- variable-speed playback.
@jameslo "I'm sorry if I just did your student's homework" -- actually this isn't for my class -- independent project. There are still some students who do hard things just because it's fun to overcome challenges
hjh
Granular sampler "Granular21"
hello!
the video is amazing and I can't wait to try the patch, but for some reason it is not opening up in my computer... I'm using Windows 10 on a Dell Inspiron 15, the processor is Intel i5. Couldn't open it on Pd vanilla, Pd-extended or Purr-Data.
I get several lines of an error message saying it can't open objects in funny characters, like this:
error: ¸¯": no such object
error: \%: no such object
error: P
": no such object
error: ]%: no such object
error: È\%: no such object
error: Ð]%: no such object
error: ": no such object
error: ° ": no such object
error: 0 ": no such object
error: ^%: no such object
error: ": no such object
error: èX&: no such object
error: ": no such object
error: Y&: no such object
error: ": no such object
error: Àa%: no such object
error: ": no such object
(it goes on forever)
I'd appreciate it if somebody knew what could be the problem... anyways, congrats for the work and thanks for sharing!
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?
List Comparison
@buzzelljason Yes. Well. Everything sent by a control rate object is a message.
The messages can be floats or symbols or lists.
Lists are a list comprising floats or symbols or a mixture of the two.
Items (atoms) in a list are separated by spaces.
It gets complicated.
If the first atom in the list is a float then the "list" tag is automatically applied, and then is silently ignored and dropped as it passes through the next object (except for [route list symbol float].......)
If the first atom in the list is a symbol then that symbol becomes the tag.... the list header..... and the list can be routed by that tag. But if the list passes through a [list] object then "list" is added (prepended) as the header. That is why [list trim] is used almost everywhere after a [list] object...... to remove the header and then be able to [route] by the original tag (if it was a symbol).
HINT.. If you install the Zexy library then [rawprint] shows you whether an atom is a "tag", 'symbol' or float....
Trying to work with vanilla OSC objects can be just guesswork without [rawprint].
mmm.pd
The messages arrive from [audiosettings] as a list which is a mixture of floats and symbols........ but the first atom is a symbol and there is no "list" tag.
[listdevices( returns a series of messages..... they are lists...... with the first atom "device"
That is why "device"....... a symbol.... and "0" or "1" can be routed. "1" could not be routed by [route 0 1] unless it is a float and "device" could not be routed by [route device] unless it is a symbol.
The device name is a symbol........ it can only be sent on in one hit because it is a symbol...... if it were a list then each part would be sent separately as a space normally "means" "next item".
But once it has passed through [route 0 1] it has lost its "symbol" tag. That can be put back by passing it through [symbol].
So the problem for [list-compare] is to create a symbol that is identical. Not easy as a message with component symbols will be treated as a list. Fortunately @ingox gave us a vanilla solution.... [concat].
And then of course to turn them both into lists for the comparison.
This will work........ this.zip
It can probably be simplified (and certainly @ingox will shortly post a more elegant solution.... ).
David.
Shared references to stateful objects?
This is how i see it:
┏━ | ━━━━━━━━━━━━━━━━━━ | ┳━ | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ┓ |
---|---|---|---|---|
┃ | Functional programming | ┃ | Pure Data | ┃ |
┡━ | ━━━━━━━━━━━━━━━━━━ | ╇━ | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ┩ |
├ | Function | ┼ | Abstraction | ┤ |
├─ | ────────────────── | ┼─ | ──────────────────────────────── | ┤ |
├ | Define function in code | ┼ | Create abstraction as separate file | ┤ |
├─ | ────────────────── | ┼─ | ──────────────────────────────── | ┤ |
├ | Call function | ┼ | Send a message to left inlet of the abstraction | ┤ |
├─ | ────────────────── | ┼─ | ──────────────────────────────── | ┤ |
├ | Arguments | ┼ | Input into the inlets and creation arguments | ┤ |
├─ | ────────────────── | ┼─ | ──────────────────────────────── | ┤ |
├ | Return values | ┼ | Output of the outlets | ┤ |
├─ | ────────────────── | ┼─ | ──────────────────────────────── | ┤ |
├ | Local variables | ┼ | $0 in object names | ┤ |
├─ | ────────────────── | ┼─ | ──────────────────────────────── | ┤ |
├ | Recursive function | ┼ | Manual recursion by using [until] outside of the abstraction | ┤ |
└─ | ────────────────── | ┴─ | ──────────────────────────────── | ┘ |
abstractions-as-creation-arguments...Things I wish I knew before
@svanya I would not do it that way personally, as like @ingox says when someone wants to open your patch to see how it works they will have to mentally substitute "$1", "$2" etc. for the objects, and have to remember what each one is as they look at your patch if they want to understand it.
what this IS useful for imo is if you have a bunch of objects with exactly the same interface and want to use arguments to choose which ones your abstraction will use. for instance, all relational objects have the same interface. Therefore I made an abstraction to pass numbers to the left outlet if they met a certain condition and the right outlet if not by using "$1" inside to be able to choose what relational object to use for the test:
then when you use the object you can use e.g. [passif == 5]
to pass the numbers out of the left outlet if they are equal to 5/the right inlet, and out the right outlet if not equal, or [passif < 5]
to pass out the left outlet if the numbers are less than 5/the right inlet, and out the right outlet if not less.
this could also be useful in a sorting algorithm in order to choose how to sort elements
another example might be if you had multiple objects that interpolate values, all with the same interface but with different interpolation methods. then you could do something like [myabs~ linear]
to select linear interpolation, and [myabs~ cubic]
to select cubic interpolation.
JASS, Just Another Synth...Sort-of, codename: Gemini (UPDATED: esp with midi fixes)
JASS, Just Another Synth...Sort-of, codename: Gemini (UPDATED TO V-1.0.1)
jass-v1.0.1( esp with midi fixes).zip
1.0.1-CHANGES:
- Fixed issues with midi routing, re the mode selector (mentioned below)
- Upgraded the midi mode "fetch" abstraction to be less granular
- Fix (for midi) so changing cc["14","15","16"] to "rnd" outputs a random wave (It has always done this for non-midi.)
- Added a midi-mode-tester.pd (connect PD's midi out to PD's midi in to use it)
- Upgrade: cc-56 and cc-58 can now change pbend-cc and mod-cc in all modes
- Update: the (this) readme
INFO: Values setting to 0 on initial cc changes is (given midi) to be expected.
JASS is a clone-based, three wavetable, 16 voice polyphonic, Dual-channel synth.
With...
- The initial, two wavetables combined in 1 of 5 possible ways per channel and then adding those two channels. Example: additive+frequency modulation, phase+pulse-modulation, pulse-modulation+amplitude modulation, fm+fm, etc
- The third wavetable is a ring modulator, embedded inside each mod type
- 8 wave types, including a random with a settable number of partials and a square with a settable dutycycle
- A vcf~ filter embedded inside each modulation type
- The attack-decay-release, cutoff, and resonance ranges settable so they immediately and globally recalculate all relevant values
- Four parameters /mod type: p1,p2, cutoff, and resonance
- State-saving, at both the global level (wavetables, env, etc.), as well as, multiple "substates" of for-each-mod-type settings.
- Distortion, reverb
- Midiin, paying special attention to the use of 8-knob, usb, midi controllers (see below for details)
- zexy-limiters, for each channel, after the distortion, and just before dac~
Instructions
Requires: zexy
for-entire-state
- O: Open preset. "default.txt" is loaded by...default
- S: Save preset (all values incl. the multiple substates) (Note: I have Not included any presets, besides the default with 5 substates.)
- SA: Save as
- TEST: A sample player
- symbol: The filename of the currently loaded preset
- CL: Clear, sets all but a few values to 0
- U: Undo CL
- distortion,reverb,MASTER: operate on the total out, just before the limiter.
- MIDI (Each selection corresponds to a pgmin, 123,124,125,126,127, respectively, see below for more information)
- X: Default midi config, cc[1,7,8-64] available
- M: Modulators;cc[10-17] routed to ch1&ch2: p1,p2,cutoff,q controls
- E: Envelopes; cc[10-17] routed to filter- and amp-env controls
- R: Ranges; cc[10-17] routed to adr-min/max,cut-off min/max, resonance min/max, distortion, and reverb
- O: Other; cc[10-17] routed to rngmod controls, 3 wavetypes, and crossfade
- symbol: you may enter 8 cc#'s here to replace the default [10-17] from above to suit your midi-controller's knob configuration; these settings are saved to file upon entry
- vu: for total out to dac~
for-all-mod-types
- /wavetable
- graph: of the chosen wavetype
- part: partials, # of partials to use for the "rn" wavetype; the resulting, random sinesum is saved with the preset
- duty: dutycycle for the "du" wavetype
- type: sin | square | triangle | saw | random | duty | pink (pink-noise: a random sinesum with 128 partials, it is not saved with the preset) | noise (a random sinesum with 2051 partials, also not saved)
- filter-env: (self-explanatory)
- amp-env: (self-explanatory)
- rngmod: self-explanatory, except "sign" is to the modulated signal just before going into the vcf~
- adr-range: min,max[0-10000]; changing these values immediately recalculates all values for the filter- and amp-env's scaled to the new range
- R: randomizes all for-all-mod-types values, but excludes wavetype "noise"; rem: you must S or SA the preset to save the results
- U: Undoes R
for-each-mod-type
- mod-type-1: (In all cases, wavetable1 is the carrier and wavetable2 is the modulator); additive | frequency | phase | pulse | amplitude modulation
- mod-type-2: Same as above; mod-type-2 May be the same type as mod-type-1
- crossfade: Between ch1 and ch2
- detune: Applied to the midi pitch going into ch2
- for-each-clone-type controls:
- p1,p2: (self-explanatory)
- cutoff, resonance: (self-explanatory)
- navigation: Cycles through the saved substates of for-each-mod-type settings (note: they are lines on the end of a [text])
- CP: Copy the current settings, ie. add a line to the end of the [text] identical to the current substate
- -: Delete the current substate
- R: Randomize all (but only a few) substate settings
- U: Undo R
- cut-rng: min,max[0-20000] As adr-range above, this immediately recalculates all cutoff values
- res-rng: min,max[0-100], same as previously but for q
- pbend: cc,rng: the pitchwheel may be assigned to a control by setting this to a value >7 (see midi table below for possibilities); rng is in midi pitches (+/- the value you enter)
- mod-cc: the mod-wheel may be assigned to a control [7..64] by setting this value
midi-implementation
name | --- | Description |
---|---|---|
sysex | not supported | |
pgmin | 123,124,125,126,127; They set midi mode | |
notein | 0-127 | |
bendin | pbend-cc=7>pitchbend; otherwise to the cc# from below | |
touch | not supported | |
polytouch | not supported |
cc - basic (for all midi-configs)
# | name | --- | desciption |
---|---|---|---|
1 | mod-wheel | (assignable) | |
7 | volume | Master |
cc - "X" mode/pgmin=123
cc | --- | parameter |
---|---|---|
8 | wavetype1 | |
9 | partials 1 | |
10 | duty 1 | |
11 | wavetype2 | |
12 | partials 2 | |
13 | duty 2 | |
14 | wavetype3 | |
15 | partials 3 | |
16 | duty 3 | |
17 | filter-att | |
18 | filter-dec | |
19 | filter-sus | |
20 | filter-rel | |
21 | amp-att | |
22 | amp-dec | |
23 | amp-sus | |
24 | amp-rel | |
25 | rngmod-freq | |
26 | rngmod-sig | |
27 | rngmod-filt | |
28 | rngmod-amp | |
29 | distortion | |
30 | reverb | |
31 | master | |
32 | mod-type 1 | |
33 | mod-type 2 | |
34 | crossfade | |
35 | detune | |
36 | p1-1 | |
37 | p2-1 | |
38 | cutoff-1 | |
39 | q-1 | |
40 | p1-2 | |
41 | p2-2 | |
42 | cutoff-2 | |
43 | q-2 | |
44 | p1-3 | |
45 | p2-3 | |
46 | cutoff-3 | |
47 | q-3 | |
48 | p1-4 | |
49 | p2-4 | |
50 | cutoff-4 | |
51 | q-4 | |
52 | p1-5 | |
53 | p2-5 | |
54 | cutoff-5 | |
55 | q-5 | |
56 | pbend-cc | |
57 | pbend-rng | |
58 | mod-cc | |
59 | adr-rng-min | |
60 | adr-rng-max | |
61 | cut-rng-min | |
62 | cut-rng-max | |
63 | res-rng-min | |
64 | res-rng-max |
cc - Modes M, E, R, O
Jass is designed so that single knobs may be used for multiple purposes without reentering the previous value when you turn the knob, esp. as it pertains to, 8-knob controllers.
Thus, for instance, when in Mode M(pgm=124) your cc send the signals as listed below. When you switch modes, that knob will then change the values for That mode.
In order to do this, you must turn the knob until it hits the previously stored value for that mode-knob.
After hitting that previous value, it will begin to change the current value.
cc - Modes M, E, R, O assignments
Where [10..17] may be the midi cc #'s you enter in the MIDI symbol field (as mentioned above) aligned to your particular midi controller.
cc# | --- | M/pgm=124 | --- | E/pgm=125 | --- | R/pgm=126 | --- | O/pgm=127 |
---|---|---|---|---|---|---|---|---|
10 | ch1:p1 | filter-env:att | adr-rng-min | rngmod:freq | ||||
11 | ch1:p2 | filter-env:dec | adr-rng-max | rngmod:sig | ||||
12 | ch1:cutoff | filter-env:sus | cut-rng-min | rngmod:filter | ||||
13 | ch1:q | filter-env:re | cut-rng-max | rngmod:amp | ||||
14 | ch2:p1 | amp-env:att | res-rng-min | wavetype1 | ||||
15 | ch2:p2 | amp-env:dec | res-rng-max | wavetype2 | ||||
16 | ch2:cutoff | amp-env:sus | distortion | wavetype3 | ||||
17 | ch2:q | amp-env:rel | reverb | crossfade |
In closing
If you have anywhere close to as much fun (using, experimenting with, trying out, etc.) this patch, as I had making it, I will consider it a success.
For while an arduous learning curve (the first synth I ever built), it has been an Enormous pleasure to listen to as I worked on it. Getting better and better sounding at each pass.
Rather, than say to much, I will say this:
Enjoy. May it bring a smile to your face.
Peace through love of creating and sharing.
Sincerely,
Scott
On the off chance this might save you some trouble
How to connect multiple outlets to multiple inlets, etc.
(I saw someone do this on a video so looked it up.
The info was originally posted on the newsgroup at:
[link Intelligent Patching](link https://lists.puredata.info/pipermail/pd-list/2018-06/122789.html) by IOhannes m zmoelnig .)
These do work. Just sort of tricky to get the steps right.
quote:
Intelligent Patching
new connection features:
-
select any two objects, and press <Ctrl>+<k> (or <Cmd>+<k> if you insist), to connect them (trivially, so just the first inlet)
-
to connect a (signal) outlet to multiple arbitrary inlets, you can now press <Shift> while hovering the yet-unconnected cord over an inlet
-
to add more connections between two already connected object, select the connection and pressl <Ctrl>+<d> to extend the connections to the right ("duplicate")
-
to fully connect two objects, select both objects before connecting them.
-
to connect multiple objects to a single inlet, select all the source objects (but not the sink object) before connecting them.
-
(the other way round works as well, but will give you fan-outs!!!)
-
to connect multiple objects to a multi-inlet object, select all the source objects and the sink object before connecting the leftmost source to the leftmost inlet.
-
to connect a multi-outlet object to multiple objects, select all the source object and all the sink objects before connecting the leftmost outlet to the leftmost sink.
:end quote
May the info/techniques help to expedite yr work flow.
Peace through sharing.
-S
scramble the outputs of a route object...
Hi,
I have a route object has 12 outputs. It takes a list and sends each element to the corresponding outlet.
So it looks like this: [route 0 1 2 3 4 5 6 7 8 9 10 11 ]
what I want to do is scramble up these outlets randomly. So that element 5 might go to output 7, element 7 might go to outlet 2, etc. And I can reset it back to normal, so element 1 goes to outlet 1, element 2 goes to outlet 2, etc.
How would I do this?
In Max there is a router object where I can have 12 inputs and 12 outputs. I can use a matrix control object to route the inputs and outputs.
In the Else library there is a [router] object and a [mtx.ctl] object. But the router doesn’t work the same. You can choose which outlet you want, but not actually re-route things ( it seems).
I was thinking I could take a list [ 0 1 2 3 4 5 6 7 8 9 10 11 ( and send it to zl scramble, then send it to the route object, but that didn’t work either.
let me know if anyone has any ideas I can try for this.
thanks. Nick