Can't make window functions for the life of me.
Populating a window table depends on a couple of patching design patterns that come up everywhere, but which nobody talks about:
- Initialize - process - finalize (where finalizing is sometimes optional).
- Counting.
That is, the "fill operation" consists of counting an index from the beginning of the array to the end. Each index value gets mapped mathematically onto the window value at that moment, and [tabwrit(e)]-ten into the array.
Since you're saying that nothing is happening in your loop, I'd have to guess that some of this logic is not quite right in your patch.
Step by step:
"Initialize/process" is because, every time you bang the operation, you want to start at the beginning of the array. So the counter needs to be initialized. Use [t] at the top -- we need at least 2 bangs here.
The loop is done by [until]. The [array size] is to tell it how many times to run.
Then, for tabread4~, you need:
- i = 1, phase = 0
- i = size-3, phase = pi
phase = (i - 1) / (size-4) * pi (I might be off-by-one here?)
Then take sin^2 of this for a Hann window.
I added another "f" into the counter's [t], because one branch here needs to set the [tabwrite] index (and this must happen before doing the math). Also the (size-4) needs a [t] to split the array-size output message.
hjh
Question about muliple arrays in one graph
I decided to redesign the thing, taking a different approach. Rather than try to display two arrays in the same graph, I defined one array (named "$1-array"), the only one which actually gets displayed, using the Put menu. Then I defined two other arrays (named "$1-velocity" and "$1-duration") using [array define], and a horizontal radio button to allow the user to select which of the two arrays to display. When the user clicks on one of the radio button selections, it saves the current contents of $1-array and then copies the contents of the selected array into $1-array.
It works the first time I open the patch, but when I go to close it, PD asks me if I want to save my changes (even though I didn't make any changes, except to the data in the arrays. I don't have "Save contents" checked either. If I say "No", I can open the patch again and it still works. But if I say "Yes", it replaces the original name of the displayed array ("$1-array") with the actual number (for example, "1150-array", as in the screen print below) inside the patch. I'm not sure why it's doing this, or if it's expected behaviour. It doesn't over-write the names of the other two arrays ($1-velocity and $1-duration) inside the patch, though. Any ideas?
The whole thing is getting a little complicated, so I've uploaded the parent patch ("test-array-abs.pd") and the abstraction containing the arrays ("array-abs.pd"). This is the line in "array-abs.pd" that gets changed if I say "Yes". Of course, I could try to remember never to say "Yes", but that's a bit much to ask of the user, I think. And it's kind of annoying to have to answer in the first place.
Before:
#X array \$1-array 32 float 2;
After:
#X array 1161-array 32 float 2;
How to make a slider have a limit and change direction?
Obineg says: "and while GUI objects might be able to understand a message to set new min and max values, it is not good practice to use this feature to perform math operations"
I'd absolutely agree with this. Program logic should be program logic. GUIs should be for input or display. GUIs should not be performing program logic!
For that matter, sliders' min/max limits don't apply to values coming in:
The slider has set a limit max = 127. I sent in the number 150, and the slider sent out the number... 150. Not clipped to 127.
So you cannot use the GUI to enforce numeric limits at all. That is, the title of this thread is already leading in the wrong direction. A slider having a limit is irrelevant to what you're trying to do.
It seems like you're looking for an increment/decrement behavior that stops once it reaches a certain value (and then maybe triggers a different increment/decrement -- though this is unclear in your description because you say both "and change direction" and "once it hits the limit stays at that value until I press stop").
So, first, increment and decrement. You have the right idea with the float box. You don't need both a [+] and a [-] box because you can set the second operand: you can [+ 0.01] or [+ -0.01] using the same object.
Then, you need something that will decide whether the number is in range or out of range, i.e., you need numeric comparisons. I like [moses] for this but you could also use [>], [<] if you wanted.
So the way I would design "increment or decrement, and stop when the value goes out of range" might be like this.
Both buttons set the same initial value and start the metronome. The third outlet of the [t b b b] objects sets the up or down direction. Remember [t] outputs right to left, so the order is: 1/ set direction, 2/ set counter initial value, 3/ run the [metro].
At the top right is the "stop" signal (triggered by a too-low or too-high value). If you wanted to trigger some other action, you could put that here.
hjh
PS (edit) Actually the initializer could have slightly fewer crossing wires by splitting the [t] objects:
[lincurve] based on SuperCollider's lincurve mapping
Here's a Pd-vanilla version of a linear-to-curved range mapping formula from SuperCollider. Published at https://github.com/jamshark70/hjh-abs . There's a message-rate and signal-rate version.
(Helpfile typo has been fixed but I won't bother to upload a new screenshot.)
This is, of course, close to cyclone's [scale]. It's close -- the symmetry is different (help file says "better" but actually that's a matter of taste, or situational need). For reciprocal values of [scale]'s "exponential" factor, the respective curves seem to be a reflection around the diagonal (x <--> y); for negated values of [lincurve]'s curve factor, one curve is a 180-degree rotation of the other (x --> -x and y --> -y). Compare -7 vs +7 lincurve against 0.2 vs 5.0 scale:
-7 curve, ~0.2 exp:
+7 curve, ~5.0 exp (lincurve and scale are very very close here!):
hjh
Raspberry Pi Audio Output Crackling when Mic enabled
Hello,
I have a USB audio interface (3D Sound Audio Interface see below) plugged into a raspberry pi. When I have it selected for audio input (port audio seems to be the only one that works) along with audio output via the speaker on the GPIO pins I get crackling as if PD can't handle the processing of audio input while outputting on raspberry pi. NOTE: if I turn off audio input the output sounds perfect.
Anyone else encounter this issue?
FYI, I hooked up a nice little speaker to make the Raspberry Pi more portable via the I2S Amp on connected and powered by the GPIO pins (see this link for details
[bob~]
Here are all available Pure Data Filters collected as automatonism modules in action:
In your Boca Ladder abstraction i mixed the normal tanh with the analog clipper,which in my opinion gives the best results. If in exp~ the quotient is ==5 , only analog clipping is used via switch. if both mixed are together the sounds gets some superb irregular resonances. the bite parameter in the module amplifies the resonance:
i also spent a oversampling switcher for 2/4 *oversampling, where with 4 OS the snapping of modulation sources sounds greater
imho.
Here is the test-file
Battle of the filters Vol.zip
s~/r~ throw~/catch~ latency and object creation order
@whale-av I opened the s~r~NoLatency patch I posted above and swapped the [-~] inputs. The latency (or lack thereof) didn't change.
Then I recreated the patch where every object is created in top to bottom order, the permutation in row 18 of the spreadsheet, and swapped the [-~] inputs. Again no change in latency.
If I've understood your theory, I think this disproves it, no? I wouldn't have guessed that audio sends and receives are simply replaced by audio connections by the interpreter because it would suggest that Pd's dsp loop detection is more sophisticated than what I've observed it to be.
If my conjecture in the original post is correct, then for any patch with non local signal connections (and that does not contain feedback), you should be able to make it latency-free with the following procedure:
{1] trace backwards from the end of the audio chain to the first set of [r~] or [catch~] you encounter. Cut and re-paste them.
[2] continue tracing from their corresponding [s~] and [throw~] until you reach the next set of [r~] or [catch~], if any. Cut and re-paste those.
[3] repeat [2] until you have nothing but audio chain heads. Cut and re-paste them.
This worked on a patch I made when I started investigating this, one that I decided was too complicated to be able to see what was going on.
Edit: This procedure also worked on a patch with delwrite~/delread~ to overcome the minimum 1 block delay: delwrite~read~.pd
You can watch the minimum delays go away by starting DSP, cut/pasting [delread~ delay2 0], then [delread~ delay1 0], and finally [phasor ~1].
Contribute to better Pd Documentation
As a Puredata teacher in a fine art school since 10years (and many workshops in China) the only solution for me to make pd "usable" by my students, was to distributed my own puredata version modified with translated help files from an "computer-scientist" to an "artist" point of view, and with many extra things.
@whale-av said:
Maybe adding a "Documentation" link to the console help menu would be a good first move....?
I agree, if only clickable link could be added to console.
The doc subfolder names are not enticing..... "3.audio.examples" really could be "3.digital.audio.tutorial" for example.
I don't think there is even a link to it in the "HTML Manual" which becomes "PD Documentation" when it is opened.
All very confusing though as the Pd.doc folder is mostly a patching tutorial that complements the Floss manual.
I agree, the documentation could a bit more explicit and well organised. I simply don't use it and added mine.
Finally, Here is an example of my pd version that I throw to students now to have a chance to keep them in the game:
-
I am using ceammc a lot, and added some objets and a simple theme:
-
I added a template for every new patches and some personnal icons to ceammc bar:
-
Here is my Intro-help.pd (accessible from any right clic in a patch)
-
I added my own fast prototyping ofelia abstractions:
-
The right click show all the objects (also have auto-completion of course)
I think right-click on objects should propose "Online Reference" that lead to an online up-to-date documentation... or wiki.
Having lots of switches into Pd
@alexandros said:
@cfry the thing is that the last bit of code you posted seems just fine, excluding the calling to pinMode where you're enabling the integrated pull-up resistors. Can you try that code removing these lines in setup(), and instead of heat sensitive sensors or whatever you're currently using, use simple potentiometers and verify whether that works or not? In case it doesn't work, please post a diagram of your circuit in some way (even hand-drawn is ok), as well as the full Arduino sketch and a screenshot of the Pd patch.
int outPins[3] = {2, 4, 7};
int pwmPins[6] = {3, 5, 6, 9, 10, 11};
int channel = 0;
int inPins[2] = {8, 12};
int analogPins[8] = {0, 1, 2, 3, 4, 5, 6, 7};
// int debug_skip = 0;
void setup() {
for (int i = 0; i < 3; i++) {
pinMode(outPins[i], OUTPUT);
}
for (int i = 0; i < 6; i++) {
pinMode(pwmPins[i], OUTPUT);
}
for(int i = 0; i < 2; i++) {
pinMode(inPins[i], INPUT_PULLUP);
}
Serial.begin(115200);
}
void loop() {
//DO OUTPUTS
if (Serial.available()) {
static int temp;
byte in = Serial.read();
if (isDigit(in)) temp = temp * 10 + in - '0';
//quote out this section to avoid crash
else if (in == 'c') {
channel = temp;
temp = 0;
}
else if (in == 'd') {
digitalWrite(outPins[channel], temp);
temp = 0;
}
else if (in == 'p') {
analogWrite(pwmPins[channel], temp);
temp = 0;
}
//end quote out here
}
// DO INPUTS
Serial.print("analog");
for(int i = 0; i < 8; i++){
unsigned int analogVal = analogRead (analogPins[i]);
Serial.print(" ");
Serial.print(analogVal);
}
Serial.println();
Serial.print("digital");
for(int i = 0; i < 2; i++) {
unsigned int digitalVal = digitalRead(inPins[i]);
Serial.print(" ");
Serial.print(digitalVal);
}
Serial.println();
}
If I do the following PureData will always freeze and requires force quit. Occasionally the whole OS becomes sluggish/freeze and need a reboot.
- Have this code snippet in the Arduino sketch
//quote out this section to avoid crash
else if (in == 'c') {
channel = temp;
temp = 0;
}
else if (in == 'd') {
digitalWrite(outPins[channel], temp);
temp = 0;
}
else if (in == 'p') {
analogWrite(pwmPins[channel], temp);
temp = 0;
}
//end quote out here
- Connect [print $1c$2p] -> [comport]
(I have also noted different behavior using [comport] from the tutorial by copy and paste compared to creating a comport object (cmd+1 and then typing). At times the latter did not work at all, but after reboot of the system both seems to work.)
Thanks for helping
Here is the patch from screenshot above:
tmp_arduino_pd_testing.pd
Adding Ring Modulation to a Sampler
Thanks so much @whale.av David that makes sense and helps a lot. Would you mind if I asked a few further questions, as My aim is to save the fully completed patch as an external, so I have been building up the elements (within a graph on parent with Gui objects) using subpatches. I'm just wondering can I run each subpatch through one dac~ ? And if this is the case would I just change the dac~ within each subpatch to outlet~ ? Would I then need to reconnect them to dac~ each time I open the (completed) external patch ? Lastly I decided to use my ring mod code as a standalone preset reading from an open object...is there a way to open different files through one open object?
I have added some screenshots to help explain what I mean.
Thanks so much in advance David,
Naomi