vstplugin~ with Purr Data?
Purr-Data and PlugData are very appealing graphically and are able to handle my high resolution display properly (in contrast to Pure Data). Here my comparison of Purr-Data and PlugData from my point of view. I should add that I did not really use PlugData, I only tested it shortly.
Purr-Data
- A little bit more graphically appealing although not as customizable as PlugData.
- I can operate sliders, buttons and switches with my fingers on my touchscreen (very important for me live).
- Reduced to what is really necessary.
- GUI gets slow with big patches (really annoying).
PlugData
- Can be used as VST plugin (not relevant for me).
- GUI can be customized much better with themes etc.
- I cannot operate sliders, buttons and switches properly with my fingers on my touchscreen (I don't know why, but no precise response).
- Seems to be more actively developed.
- Offers built-in effects and instruments etc (I prefer to create such abstractions on my own).
- I can only set 1 input and 1 output (no-go for me, I'm using 8 ins and 8 outs).
[text] object help file could be a lot more helpful
Hi, I'm just trying to figure out how to work with this object and the help file is really confusing to me
Firstly- can any kind soul point me toward a better resource for understanding how to use this object?
Secondly, I'm going to point out a few of my confusions with the help file, specifically in [text define]:
- "text define" maintains a text object and can name it so that other objects can find it (and later should have some, alternative, anonymous way to be found)."
-
- What does that second half mean? An "anonymous way to be found" sounds like an oxymoron to me.
- When i click the message box [write text-object-help.txt] that is connected to [text define -k text-help-1], I get an error in the console that reads "text-object-help.txt: write failed"
-
- Why should something in a help file fail like this? There's nothing apparent in the help file to explain the error. I'm running realtime Purr-Data on Manjaro's latest realtime kernel, everything is updated.
- Next to the message box [sort], there's just a comment that reads "comment"
-
- lol what?
- It seems like [text define] creates the text file with its third argument (e.g., [text define -k file-name-here]" However, the help patch is reading from a file called "text-object-help.txt" and when the file is opened, "text-help-1" is on the top of the window.
-
- Dear god, what is going on?
If anyone feels like helping me out here, I would gladly help put together a better help patch. Or maybe I'm just reading this totally incorrectly.
Thanks continually for all of your support, everyone!
Uranus- a polyphonic synth for Automatonism
I build a polyphonic synth for Automatonism with the following features:
It features:
- 3 - bandlimited oscillators with different kind of waveforms + a noise source
- 8-voice
- hardsync-matrix
- 2 or 4 Pole LP/ HP/ BP filters
- pre/post distorsion (before or after filtering stage)
- curved envelopes
- stereofield control
- preset saving
- sophiscated randomizing and reseting system
- mono-mode
- glide
- CPU optimized
Help with audio patch on off based on some condition
What I am trying to add is if the audio is playing more then 60 seconds the audio will stop and will back to the beginning of the file (so when pressed again it will start from beginning).
Do you mean like this?
- Pause >= 5 sec:
- Next play should always start from the beginning
- Pause < 5 sec:
- Last audio play time >= 60 sec: play from beginning
- Last audio play time < 60 sec: resume
(It's really helpful to make a tree, or a table, describing the cases. If you just write sentences, it's very easy to overlook patterns.)
One pattern you can see from this is that the "pause >= 5" branch is easy: always from the beginning. So the "all" is fine.
But the "resume" message needs to be either "resume" or "all," depending on the last play duration. The last play duration is measured at the time of the "off" trigger.
This is a common pattern in patching, which has a standard solution: You need a changing message to be sent later, where the contents of the message are determined earlier based on some condition. (When the user lets go of the sensor, you determine at that moment how the next "on" will behave.)
For this, you need:
- A storage object. One of the messages is a list, so, use [list store].
- The "off" trigger sets the value of this storage object using its cold inlet.
- The (later) "on" trigger bangs the hot inlet.
Should be something like this:
1676400706585-talk.pd -- EDIT: but I just realized there's a mistake in here, the [r nextr] should be [r $0-nextr] and then the message-sends to that name should change to a real [s $0-nextr] instead of the message-box shortcut. I can update the patch later but I don't have time right this second.
This usage of a storage object is a pattern that's useful in thousands of contexts -- took me forever to figure it out (which reflects a pedagogy problem).
hjh
How to loop/reset an audio file to the beginning
@KMETE Requoting myself: "To crossfade properly, it needs to subtract 100 ms from the file's total duration."
Let's say you have 10 seconds of audio.
You want to loop it, with a 100 ms crossfade.
If you just use "all" then it will do this:
- Start at 0 and play to 10 sec.
- Loop back to 0.
- At this point, for a cross fade, the step 2 audio fades in, and the step 1 audio fades out. But step 1 has already run out of audio.
So at that point, you don't get a cross fade. You get an immediate jump to silence (maybe with a click), and then a fade in.
It "seems to work" in that there is no error, nothing crashes, no major audio glitches. But it isn't crossfade looping.
The solution here changes it to:
- Start at 0 and play to 9.9 sec.
- Loop back to 0.
- At this point, the step 2 audio fades in, and the step 1 audio fades out over the range 9.9 - 10 sec = clean crossfade.
But if you're happy without a proper crossfade, then by all means, do what you feel is best.
At this point, with apologies, I need to withdraw from the thread. I've already spent much more time on it than I expected, and the follow-up questions are becoming a bit like... not the best use of time. Like, I'm getting ready to shoot a YouTube tutorial on Pd external sync, and instead of working on those materials, I was explaining crossfading here. I think I need to strike a better balance.
hjh
Properly usable soundfile playback without silly gotchas
I think I finally got sound file playback abstracted to the point where it's actually usable.
-
[monofile id path startframe numframes] or [stereofile ...]:
- Automatically creates 1 or 2 arrays.
- Loads the file.
- Sets up 5 [value] variables:
- idframes
- iddur (in ms -- automatically compensates if the disk file sample rate doesn't match the hardware sample rate)
- idsr -- disk file sample rate
- idsr001 -- sample rate * 0.001 = samples / ms (useful in many places in Pd)
- idscale -- file SR / system SR
-
[sf-play~] / [sf-play2~] uses the table(s) defined in [monofile] / [stereofile] and uses the [value] objects to drive a [cyclone/play~] in a sensible way. (E.g., play~ help says that times are given in milliseconds, but that's true only if the file sample rate matches the audio system -- my abstraction automatically multiplies by the sample rate scale variable, so you really can just specify time in milliseconds and not worry about it.)
I guess I might catch some heat for depending on cyclone, but 1/ cyclone is really indispensable and 2/ I've spent enough time on this and I don't want to rebuild a buffer player that's capable of crossfade looping when a fine one already exists.
https://github.com/jamshark70/hjh-abs with a few other miscellaneous little toys.
2021-09-19: Updated to fix a bug with looping.
hjh
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.
Purr Data GSoC and Dictionaries in Pd
If you need to store a bunch of key/value(s) pairs as a group (like an associative array does), a [text] object will allow you to do that with semi-colon separated messages.
Performance is abysmal, though -- I had guessed this would perform linearly = O(n), and a benchmark proves it.
-
The array y range is 0 to 3000 (= 3 seconds). 10000 lookups per 'pd benchmark'.
-
I had to abandon the test because, long before 100,000 elements, each iteration of the test was already taking 4-5 seconds.
-
[* 1.2]
-- in a search, failure is the worst-case. This is an arbitrary choice to generate 1/6 or about 16% failure cases.
I translated this from a quick benchmark in SuperCollider, using its associative collection IdentityDictionary.
(
f = { |n|
var d = IdentityDictionary.new;
n.do { |i| d[i] = i };
d
};
t = Array.fill(200, { |i|
var n = (i+1) * 1000;
var d = f.value(n);
var top = (n * 1.2).asInteger; // 16% failure
bench { 100000.do { d[top.rand] } };
});
t.plot;
)
-
SC's implementation is a hash table, which should give logarithmic performance. The graph more or less follows that.
-
SC is doing 10 times as many lookups per iteration, but:
- In this graph, SC's worst performance between 46000 and 56000 elements is 17.4 ms.
- If I look up in the Pd 'bench' array at 50 (51000 elements), I get 3082.
- Extrapolating for SC's number of iterations, that's 30820 / 17 = 1771 times slower on average per lookup.
- Since Pd is linear and SC is logarithmic, this ratio will get worse as n increases.
"This isn't fair, you're comparing apples to oranges" -- true, but that isn't my point at all. The point is that Pd doesn't have a properly optimized associative table implementation in vanilla. It has [text], but... wow, is it ever slow. Wow. Really not-OK slow.
So than people think, "Well, I've been using Pd for years and didn't need it"... but once it's there, then you start to use it and it expands the range of problems that become practical to approach in Pd... as jancsika said:
It's hard to know because I've gotten so used to the limitations of Pd's data types.
That shouldn't be considered acceptable, not really.
TL;DR I would love to see more robust and well-performing data structures in Pd.
hjh
fx3000~: 30 effect abstraction for use with guitar stompboxes effects racks, etc.
fx3000~
fx3000~ is a 30-effect abstraction (see effects list below) designed to expedite the creation, spec. of guitar, effect "racks".
It takes one creation argument, an identifying float, ex. 0, 1, etc.
Has
- two inlets
- left:~: the audio signal
- right: a list of the parameter values: [0-1] for the first 4, [0..29] for the 5th, and [0|1] for the 6th.
- 1-4: depth and parameters' 1-3 values
- 5: the index of the effect
- 6: the bypass for the effect
- a [r~ fx3000-in-$1] and [s~ fx3000-$1-OUT] to better expedite routing multiple instances
- a [r fx3000-rndsetter-$1] to set random values via a send
- 20 preset slots per abstraction creation argument, i.e. index, via "O" and "S" bangs, so abs #0 writes to preset file=pres-0.txt (NOTE: if you have yet to save a preset to a slot nothing will happen, i.e. you must add additional presets sequentially: 0 then 1, then 2, etc.)
- a [r PREIN-$1] to send values in from a global preset-ter
- the names of the parameters/effect are written to labels upon selecting (so I will not list them here)
- and a zexy~ booster-limiter to prevent runaway output~
The help file includes three such abstractions, a sample player, and example s~/r~'s to experiment with configurations.
Note: the origin of each effect is denoted by a suffix to the name according to the following, ex. ""chorus(s)"
- s:Stamp Album
- d:DIY2
- g:Guitar Extended
- v:scott vanya
The available effects are:
- 0 0-raw
- 1 audioflow(v)
- 2 beatlooper(v)
- 3 chorus(s)
- 4 delay(3tap)(d)
- 5 delay(fb)(d)
- 6 delay(pitch)(v)
- 7 delay(push)(v)
- 8 delay(revtape)(g)
- 9 delay(spect)(g)
- 10 delay(tbr)(v)
- 11 delay(wavey)(v)
- 12 detuning(g)
- 13 distortion(d)
- 14 flanger(s)
- 15 hexxciter(g)
- 16 looper(fw-bw)(v)
- 17 octave_harmonizer(p)
- 18 phaser(s)
- 19 pitchshifter(d)
- 20 reverb(pure)(d)
- 21 ringmod(g)
- 22 shaper(d)
- 23 filter(s)
- 24 tremolo(d)
- 25 vcf(d)
- 26 vibrato(d)
- 27 vibrato(step)(g)
- 28 wah-wah(g)
- 29 wavedistort(d)
I sincerely believe this will make it easier for the user,...:-) you, to make stompboxes, effects racks, etc.
I hope I am correct.
Peace. Love through Music.
-S
p.s. of course, let me know if you notice anything awry or need clarification on something.
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