[route aSymbol] doesn't match tagged symbols?
@ddw_music The old extended route-help explained the 3 modes for [route]...... route-help.pd in the "inlets" section.
And there was a bit more info in all_about_route.pd especially that the list header is stripped and so [route list] followed by [route list] will fail for the second.
But mixing data types in a single [route]..... i.e. [route 5 woof] will not work as expected..... so unsupported.
David.
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.
Control MIDI sampler rate from -2x to 2x with CC messages
Hello.
I need help implementing logic.
Let me explain :
I have a MIDI sampler and I would like to take control of the rate (speed/pitch) via MIDI CC messages.
The rate goes from -2x (reverse) to 2x (forward. It takes CC values from 0-127.
With a value of 64, the rate is at 0, so the sampler on pause, kind of
With a value of 127, the sampler plays forward 2x the original rate
With a value of 0, it plays reverse 2x the original rate
And with a value of 95, it plays forward at the original rate (1x)
Here’s what I’m trying to achieve :
I would like to be able to play with the rate and at some point, momentarily, thru a CC message, jump to the opposite side with the same rate ; for example, from 1x to -1x or from 0.5x to -0.5. I know that from 1x to -1x need the CC value 95 (1x) and 31 (-1x). I found that by subtracting 64 to the CC values received and I get the value that correspond to the reverse rate value of the sampler. But I get confused when I send values below 64, then I get negative values. It would be great if when I get under 64, then the logic would be reversed and I would get values over 64. I don’t know if my explanations are clear.
Thank a lot for you help.
Regards.
Routing different signals to clone instances
@whale-av Thank you very much for your reply! In my case I need to route signal outputs of each cloned object inside one module to another cloned objects inside another module. What I mean is that the first module receives signals from outside of it. I don’t need to route signals between instances of cloned objects inside the module, what i need is to direct multiple signals coming from different instances of cloned objects inside one module and send them outside and then send them to cloned instances inside another module. Hope I managed to explain well enough. Thanks a lot!
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
Android processing and Purr data communication
Hi!
I have a new problem,
Everthing is working but not when I want to use the accelerometer of the phone, that's really weird.
Processing is receiving but not PD
Processing code:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import oscP5.;
import netP5.;
import controlP5.*;
ControlP5 controlP5;
OscP5 oscP5;
NetAddress myRemoteLocation;
Context context;
SensorManager manager;
Sensor sensor;
AccelerometerListener listener;
float ax, ay, az;
void setup() {
fullScreen();
frameRate(25);
// create a new instance of oscP5.
// 12000 is the port number you are listening for incoming osc messages.
oscP5 = new OscP5(this, 12000);
myRemoteLocation = new NetAddress("192.168.137.1", 12011);
controlP5 = new ControlP5(this);
context = getActivity();
manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
listener = new AccelerometerListener();
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME);
textFont(createFont("SansSerif", 30 * displayDensity));
}
void draw() {
background(0);
text("X: " + ax + "\nY: " + ay + "\nZ: " + az, 0, 0, width, height);
}
class AccelerometerListener implements SensorEventListener {
public void onSensorChanged(SensorEvent event) {
ax = event.values[0];
ay = event.values[1];
az = event.values[2];
print(ax);
print(ay);
print(az);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
void mousePressed() {
/* in the following different ways of creating osc messages are shown by example */
//OscMessage myMessage = new OscMessage(int(knobValue));
//myMessage.add();
OscMessage myMessage = new OscMessage("/test");
myMessage.add(ax);
myMessage.add(ay);
myMessage.add(az);
/* send the message */
oscP5.send(myMessage, myRemoteLocation);
}
PD code:
[import mr peach] -----> [udpreceive 127.0.0.1 12000]--------->[unpackOSC]------->[routeOSC /test]---->[number]
I've already try like that too :
[import mr peach] -----> [udpreceive 127.0.0.1 12000]--------->[unpackOSC]------->[routeOSC /test]----> [unpack f f f]-------->[number]
Thanks in advance
external objects will only load after opening help file
The fact seems to be, when you look for an external, library, abstraction, no matter how much directorys you have into your startup path list, PD will check what's inside those directorys, but not what's inside the directorys contained inside those directorys.
Plus, PD will check the folders containing your current patchs, but not what's inside the sub folders.
Maybe this could make too much ?
So you have to write the name (or path if it is necessary, because the library/external folder is inside a sub directory of one of those directory) of this particuliar folder that contained the file you want.
You also have to write a flag.
Depending on wich flag you use, it will checkt into the startup path directorys+ the patch's directory (path / lib flags) or into the PD's "extra" directory (stdpath / stdlib flags), if there is a folder of that name.
I needed to think through that.
Pduino, what firmata for both in and outs
@cfry https://forum.pdpatchrepo.info/topic/12118/pduino-simultaneous-analog-input-and-digital-output-problems
I have just found the Floss manual version in English.
For me it is a bit harder to read but....... http://write.flossmanuals.net/pure-data/starting-pduino/
has a more detailed instructible.
......and both require https://at.or.at/hans/pd/objects.html#pduino
[arduino-test] allows you to set all the pins as desired.
David.