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
Building a game sound engine for a mobile app : flexible sampler
Hi, I'm building an audio sound engine for a mobile game using libpd and the rjlib library. I want it to be CPU efficient so as to run on lower end android phones too without glitches
My first assumption is that playing back audio is less costly than using synths : is this a fact or am I wrong from the start ?
The idea is to build a flexible sampler with distinct attack, sustain and release parts. I can then load any synth sound I exported from my DAW and play it almost as if it were the original synth (without all the modulations of course). Kind of like the ableton sampler: I could choose the start, the sustain loop portion, and the release part of the sound. That would allow me to add portamento, amplitude, pitch and filter enveloppes, hold notes forever, instantly change the pitch, with no glitches between parts ... It would have to sound like I was playing the original synth preset from my DAW, inside PD !
However this looks a bit trickier than I thought and seems to require a bit of patching. In the end I'm wondering if it's not going to end up costing more resource from the CPU than using a PD synth ?
So before I start building this thing I'm wondering : is it a good idea, or I am missing something here ? And also, does it not already exist ?
I hope I've managed to be somewhat clear, i'd love to hear your feedback !
Cheers
Simon
String Machine - Granular
And for those who are interested, an alternative version, with iemguts library. It works differently, using "live" dynamic patching. I might not work on all platforms, depending on the library's versions available.
And here is the patch that I used to automatically generate all the granule~ in the string machine V 1.6
How to send a message to all clones whitout s/r
If you are trying to make some polyphony using clone object and you need to find a free voice you can use : [your midi pitch]-[next $1] - [clone synth.cl nr_of_voices]. [next $1] is a message object that will find a free voice for your clone object. "nr_of_voices" is your number of voices for the clone object. "synth.cl" is your abstraction for one voice.
waveforms and filters in standard synths
Honestly never really used regular computer synths much, but started doing some daily eartraining with Syntorial and got to trying to remake some of the synth sounds in PD. Two questions:
How are low-pass filters constructed in a standard computer synth? They have a 0-1 value in Syntorial (and presumably other synths). To reproduce that in PD I'm multiplying 0-1 by 30 (arbitrary value so that the sound stays pretty bright when the lop value is at 1) by the frequency of the pitch being filtered and putting it into a chain of [lop~]...
Syntorial's sawtooth and pulse(square) sound pretty clean, but in PD they have a lot of frequencies below the ground tone that make the sound very noisy. Are these filtered out with [hip~]s?
Also, anyone know any nice PD patches that regulate a standard synth setup? Might be interesting to analyze them.
edit: just noticed the thread two lines below this one, so I'll check that out...
Sending different envelope's out of the same polypatch
Hello,
I'm new with PD. Currently I'm working on an audiovisual project. For that I use a polyphonic synth I found on the patch-repository called SYNTH-0. I uploaded my modified version (for use in purr or l2ork) here.SYNTH-0.5.zip . With it I'm trying to send values to VVVV, which does all the visual part.
Now from this patch I would like to send out 4 numbers of the 4 voice signals as they go through the filter & adsr-envelope. I've gotten pretty far. The problem is the following: the patch uses the "poly"-object, which routes the midi-input 4 times to a subpatch called voice, which then again contains the envelopes and produces an output.
Within "voice" I attached a number-box and an object to send to my sending subpatch, which transfer data to VVVV via FUDI. The thing is: with that I get numbers for one out of the 4 voice patches, I'd like to receive all 4 of them in a pack however. If I attach a numberbox in a subpatch that is 4 times called the same name but is factually 4 different instances, how does pd make the decision which of the 4 to send out with a send object? Might be that I'm missing out on something fundamental about subpatches. Glad for any help!
Polyphonic Granular patch, looking for some feedback/tips
Hey folks.
Here's a polyphonic granular playback (and sampling) patch, I've been working on it for a while, I've used some different versions of it for a few different projects like the EN-1 video I posted last week. Full patches here: https://github.com/yannseznec/Granular-Polyphonic
It's currently 8 voice polyphonic, and uses 8 grains. These could both be raised significantly on any standard computer, I've kept them low for running on low-spec boards. It currently uses MIDI note input to play, with the note values controlling pitch. All other settings are controlled via UI sliders.
It's getting to a pretty decent point now, where it's relatively flexible...my long-term goal has been to make it somewhat drag-and-droppable.
It still needs work, of course! A few things I'd like to get some feedback on, if anyone has the energy to download all of the patches and have a play:
- At certain pitch values (particularly low ones) there is a fair amount of high frequency noise. I guess this is aliasing? I've tried to use the lop~ object to filter this out but it hasn't proven to be a satisfying solution. Any tips? I can just about understand why it's happening, with all of the fast phasors going on and the repitching of a sound file and so on, but it's still somewhat frustrating.
- Does the patch generally make sense? Any glaring mistakes?
- Any ideas for how you would use a patch like this, which could lead to different features, UI elements, or approaches to a hardware build?
In any case, enjoy! Hope you like it.
Fm Synth Mod Matrix Help
@LarsXI In the 3-op synth patch you mentioned there is an option the synch the phasors when you hit a new note, I don't know if that helps with what you are saying.
It's good to know that it's a little cheaper, anything helps as by the time you add polyphony things add up pretty quickly. I think that making a full-blown polyphonic 6-op synth with this method is pretty unrealistic, I think it's interesting to experiment with less operators and different waveforms. I did modify that 3-op synth with added waveforms like the TX81z, but then got carried away and added CZ-style oscillators too and that messed up the patch and I never had time to fix it.
I look forward to your 2-op patch, those camomile plugins you posted sound pretty sweet.
best practices, sample-accurate polyphonic envelope, note stealing
Hi everyone. I have frequently revised designs for polyphonic envelopes. i've often misunderstood things about vline~ and scheduling voices in such a way to avoid unwanted clicks while also keeping things on time and snappy.
i'd be really happy to know what your methods are for envelopes.
i submit this patch, a reflection on envelope practices and how i address certain challenges. envwork.pd
this patch makes these assertions:
1- because vline~ maintains sample accuracy by scheduling events for the next block, you can switch dsp on in a subpatch with block~ while sending a message to vline~ and the dsp will be active by the start of the vline~ output. This also works if you need to configure a non-signal inlet before triggering a voice. send a message to such an inlet concurrently with a vline~ message and the parameters will update on the block boundary before the vline~ plays.
2- accounting for note stealing can cause issues in a polyphonic patch. if the stealing note has a slow attack and the envelope of the stolen note is not closed, there will be a click as the pitch of the new note jumps. the voices in my patch apply slight portamento to smooth out this click. if, however, the attack time of the stealing note is faster than this slight portamento it is counterproductive and will soften the attack of stolen notes. Stolen notes need every bit of snap they can get because the envelopes may be starting at a non-zero value. so i limit the time of the portamento to the attack time.
3- to make sure a note that is still in its release phase is treated as a stolen note, it is necessary to monitor the state of the envelopes like so:
switching the dsp off too close to the end of the release causes clicks. after testing, my system liked a full 50ms of extra delay after the end of a release before it was safe to switch off dsp. I don't think this is attributable just to the scheduling delay of vline~ but it's a small mystery to me. possibly there's a problem with my voices.
This all gets a little more complex when there are multiple envelopes per voice. The release time that affects the final output of the voice must reset all envelopes to when it is finished and before dsp is switched off. Otherwise an envelope with a long release affecting something like filter frequency can be held at a non-zero value when dsp is switched off and spoil the starting state of the vline~ on a new note.
finally, on vline~ and sample accuracy and timing, let me type out what i believe is the case. i could be wrong about this. if you programmed a synth using line~ for the envelopes, it would be faster than vline~ but not all notes equally faster. all notes would sound at the block boundary. Notes arriving shortly after the last block boundary might take 90% of the block period to sound. notes arriving just before the block boundary might take 10% of the period to sound.
vline~ will always be delayed by 100% of the block boundary. but the events will be scheduled sample-accurately, so the vline~ will trigger at exactly the real time intervals of the input. a synth with line~ envelopes will trigger any two events within a single block at the same time.
this should mean that vline~ envelopes can be accurately delay compensated and stay absolutely true to input timing, in the case of something like a Camomile plugin.
however, if one was to build a synth for something like a raspberry pi that will act as hardware, would it be better to use line~ envelopes and gain a little bit of speed? is the restriction of locking envelopes to block boundaries perceptible under normal playing conditions?! i could test some midi input and see if the notes in a chord ever achieve a timing spread greater than the block period anyway...
[Solved] Several MidiNotes to several osc's
@Balwyn said:
If you were thinking of using [poly] to create a polyphonic [osc~] synth, you can do it this way
Balwijn Thanks you also much for your help! This is a clear picture and understandable to me how to continue my experiment with PureData!
Greeting Crojav