Question about Pure Data and decoding a Dx7 sysex patch file....
Hey Seb!
I appreciate the feedback 
The routing I am not so concerned about, I already made a nice table based preset system, following pretty strict rules for send/recives for parameter values. So in theory I "just" need to get the data into a table. That side of it I am not so concerned about, I am sure I will find a way.
For me it's more the decoding of the sysex string that I need to research and think a lot about. It's a bit more complicated than the sysex I used for Blofeld.
The 32 voice dump confuses me a bit. I mean most single part(not multitimbral) synths has the same parameter settings for all voices, so I think I can probably do with just decoding 1 voice and send that data to all 16 voices of the synth? The only reason I see one would need to send different data to each voice is if the synth is multitimbral and you can use for example voice 1-8 for part 1, 9-16 for part 2, 17-24 for part 3, 24-32 for part 4. As an example....... Then you would need to set different values for the different voices. I have no plan to make it multitimbral, as it's already pretty heavy on the cpu. Or am I misunderstanding what they mean with voices here?
Blofeld:
What I did for Blofeld was to make an editor, so I can control the synth from Pure Data. Blofeld only has 4 knobs, and 100's of parameters for each part.... And there are 16 parts... So thousand + parameters and only 4 knobs....... You get the idea 
It's bit of a nightmare of menu diving, so just wanted to make something a bit more easy editable .
First I simply recorded every single sysex parameter of Blofeld(100's) into Pure data, replaced the parameter value in the parameter value and the channel in the sysex string message with a variable($1+$2), so I can send the data back to Blofeld. I got all parameters working via sysex, but one issue is, that when I change sound/preset in the Pure Data, it sends ALL parameters individually to Blofeld.... Again 100's of parameters sends at once and it does sometimes make Blofeld crash. Still needs a bit of work to be solid and I think learning how to do this decoding/coding of a sysex string can help me get the Blofeld editor working properly too.
I tried several editors for Blofeld, even paid ones and none of them actually works fully they all have different bugs in the parameter assignments or some of them only let's you edit Blofeld in single mode not in multitimbral mode. But good thingis that I actually got ALL parameters working, which is a good start. I just need to find out how to manage the data properly and send it to Blofeld in a manner that does not crash Blofeld, maybe using some smarter approach to sysex.
But anyway, here are some snapshots for the Blofeld editor:
Image of the editor as it is now. Blofeld has is 16 part multitimbral, you chose which part to edit with the top selector:

Here is how I send a single sysex parameter to Blofeld:

If I want to request a sysex dump of the current selected sound of Blofeld(sound dump) I can do this:

I can then send the sound dump to Blofeld at any times to recall the stored preset. For the sound dump, there are the rules I follow:

For the parameters it was pretty easy, I could just record one into PD and then replace the parameter and channel values with $1 & $2.
For sound dumps I had to learn a bit more, cause I couldn't just record the dump and replace values, I actually had to understand what I was doing. When you do a sysex sound dump from the Blofeld, it does not actually send back the sysex string to request the sound dump, it only sends the actual sound dump.
I am not really a programmer, so it took a while understanding it. Not saying i fully understand everything but parameters are working, hehe 
So making something in Lua would be a big task, as I don't know Lua at all. I know some C++, from coding Axoloti objects and VCV rack modules, but yeah. It's a hobby/fun thing
I think i would prefer to keep it all in Pure Data, as I know Pure Data decently.
So I do see this as a long term project, I need to do it in small steps at a time, learn things step by step.
I do appreciate the feedback a lot and it made me think a bit about some things I can try out. So thanks 
12 bit sampler sound emulation?
this thread is 7 years old but still fascinating, especially acreills rundown of the vintage synths synthesis as im working on an old school wavetable synth with variable sample rate for a while. i still havent found a way to simulate variable sample rate with correct mirror frequencies in PD. the best way to do this now in hardware would be FPGA and an A-Law Dac that is being driven by the fpga with variable speed - i think.
synths like the PPG wave or the microwave sound exactly so cool because the mirror frequencies move with the tuning harmonically - or disharmonically
there is a video of an interview with one of the engineers of the prophet vs where he explains that a strange sounding sine from a PPG wave was one of the main inspirations for the prophet vs.
so tuning, sample rate and resolution are essential for the sound of an instrument.
does anybody have any clue as to how to simulate the mirror frequencies and variable sample rate in PD?
Few questions about oversampling
Hi,
About a year ago I started to learn a bit pure data in order to create a patch that would act as a groovebox and that should perform on limited cpu resources since I want it to run on a raspberry pi. First I tried to make somekind of fork of the Martin Brinkmann groovebox patch, even if it allowed me to learn a lot about data flow I didn't went to the core of the patch tweaking with sound generation. This led me to end this attempt at forking MNB groovebox patch because even if I could seperate GUI stuff from sound generation and run it on different thread ect... I couldn't go further in optimization in order to reduce the cpu use.
Then a few weeks ago I decided to start again from scratch my project and this time I wanted to be more patient and learn anything needed in order to be capable of optimizing my patch as much as possible. After making a functional drum machine which runs at 2/3% of cpu with 8 different tracks, 126 steps sequencer, a bit of fx ect... I tried to find synths that would opperate well aside the drum machine. And I basicly didn't find any patch that wouldn't use massive amount of cpu time. So I created my own synths, nothing incredible but I'm happy with what I got, though I noticed some aliasing. I read a bit the floss manual about anti aliasing and apply the method used in the manual(http://write.flossmanuals.net/pure-data/antialiasing/), it work well but my synths almost trippled their cpu use, even if I put all my oscilators in the same subpatch in order to use only one instance of oversampling.
I didn't tried to oversample it less than 16 time but since oversampling is so cpu intensive I'm wondering if there's no other option in order to get a good sound definition at a lower cpu cost. I'm already using banlimited waveform so I don't know what I could do in order to limit the aliasing, especialy for my fm patch where bandlimited waveform isn't very useful in order to reduce aliasing.
Since I want to have at least 4 synth track with some at least one synth having 5 voice polyphony I want to know what the best thing to do. Letting FM aside for this project and use switch~ for oversampling 2 or 4 time my synths that use bandlimited waveform ? Or should I try to run different instances of pd for each synth and controling it from a gui/control patch with netsend(though it wouldn't bring down the cpu use at least it would provide somekind of multithreading for my patch) ? Or is there another way to get some antiliasing ? Or should I review lower my expectation because there is no solution that could provide a decent antialiasing for 4 or more synth running at the same time with a low cpu use in pure data in 2021.
Thanks to everyone that would read my topic and try to give some advice in order to get the best antialising/low cpu use solution.
help with sixteen_harmonics.pd
@trumpetfish1 Hello and welcome to the forum.
Indeed, the $1 is the problem.
[sixteen_harmonics] is what we call an abstraction...... a patch that can be used many times inside another patch.
So that it can be used many times without conflicts between each copy it has been given a variable for the name of the array....... $1
It was designed to be used by the patch (in the same folder) building_waveforms_with_sines.pd
If you open that patch you will see that [sixteen_harmonics] has been given what we call an "argument".
In this case the argument is "wavetable" and as the patch is opened the $1 within [sixteen_harmonics wavetable] has been replaced with wavetable.
You don't see that change but if you open [sixteen_harmonics wavetable] you will see the patch you had trouble with working...... and if you put a [print] after [symbol $1] it will print "wavetable" to the terminal as you move a fader. The $1 in the following message will then also be replaced by "wavetable".
BEWARE $1 in an object and $1 in a message have different purposes...... see the link below...!!
It is a very powerful feature that you should know about and will let you build much faster and more easily once you understand it...... https://forum.pdpatchrepo.info/topic/9774/pure-data-noob/4
David.
Wav table - sampling -single wavshape
use an additional [tabread4~] to crossfade between the sounds too. I'd also recommend keeping the wavetable index a signal (then the fractional part is how much of the current vs. next wavetable).
you might have resolution issues with just using [+~ ] for the wavetable offset due to 32-bit resolution, but I don't think you'll have much difficulty for normal wavetable sizes.
there was a library iem_dp that had a tabread~ that allowed a signal to be used for the offset, but I don't see it in deken now
my library also has [tabread4hs~] which also has a signal inlet for offset (but uses different 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
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
[writesf~] problem
@EMR66 "I have only got a real precision, using soundfiler (although this limits me since the table only accepts whole samples as we have already spoken ..)"
This, of course, is not a limitation of soundfiler... It's a limitation of all sampled audio files.
There is no way to create an audio file, in any software, containing a fractional number of samples. Period, end of discussion.
In theory, if the frequency is a rational number, you could find the least common multiple of the wavelength and 1.0 and then have all the required sample values precalculated. But this would disallow irrational wavelengths because the LCM would be infinite. So if the desire is to support every possible real number frequency, without interpolation, it's mathematically impossible because of irrational numbers.
To handle every possible real number frequency requires interpolation. There is no way out of that.
"So, until I get that [writesf ~] record correctly, it is useless for me to use [tabread4 ~] or [tabplay ~] ..."
A fractionally sized wavetable is impossible. Literally, impossible.
Meanwhile, it's very easy to play a wavetable at an arbitrary frequency, with interpolation.
The practical solution here is to create the wavetable with a whole number of samples and interpolate in the wavetable oscillator.
hjh
[writesf~] problem
@EMR66 "But if I want to record an 8Hz wave (5512.5 samples) (125ms), the table will only accept 5512 samples, (124.988..ms) This time difference may seem insignificant, but for my work it is becoming a horror."
It's also, as David said, a wrong conception.
There is no such thing as a fractionally-sized wavetable. Period, full stop. (That's the main reason why you haven't been able to write exactly the duration you want: because it's impossible.)
The only way to use a wavetable to generate a frequency that is not an integer number of samples is to play back the wavetable with interpolation. (EDIT: David's solution (make the wavetable twice as long, and read every other sample) is also valid -- a different way around to the same result. I overstated a bit to say "the only way.")
You'll simply have to make the wavetable with an integer size (plus an extra 3 samples, per tabread4~'s requirement) and play it back at the desired rate, and allow tabread4~ to do its job and interpolate the samples for you.
hjh
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




