How to use the bezier option in an array?
Arrays have an option to generate a bezier curve. In the attached patch, seven points are put into an array and displayed as a bezier curve. It looks nice, but does it have any function? When you read the array, you just get the points you put into it, not the points on the bezier curve. Is there a way to use the bezier curve as a wavetable or envelope, instead of the original seven points?
bezier.pd
Buffer delay loop
@DesignDefault Welcome to the Forum...!
Sorry, this will be a lot for a newbie.
You will see in the video @ricky has linked to that the [phasor~] object controls the speed at which the array is being read.
So you will need to increase the number that it receives at its left inlet in order to increase the speed.
It is an audio rate inlet, so you will need [sig~] to convert a control rate 1 to a signal rate 1.
1 will play at normal speed, 2 at double that speed etc.
Unfortunately you will need to "catch" a moment in the [phasor~] loop using [edge~] and then increment that value to [sig~] by whatever increase you want each time that [edge~] outputs a bang.
Catching the exact moment that it loops can be awkward and you might well need to add or subtract a value from the output of [phasor~] before sending it into [edge~]
A more reliable method would be to use a [metro] to increase the [sig~] with the metro rate set by the value from [timer].
Also, before playback (it only needs to be done once for the array after it has been filled) extra data points should be added.
That will stop clicks as [phasor~] wraps back to the beginning of the array.
https://forum.pdpatchrepo.info/topic/14301/add-delete-guard-points-of-an-array-for-4-point-interpolation-of-tabread4-ect
That will add 3 data points to the array, allowing [tabread4~] to correctly interpolate the samples at wrap around.
For that to work properly you should then add 3.... [+ 3] to the total number of samples after the [* 44.1]
Also, if you are running Pd at 48000Hz the [* 44.1] should be changed to [* 48] for the initial playback speed to be correct.
David.
Get the range of an array
Hello, I want to send an array (1) from my main patch, to another array (2) that is within an abstraction, replacing the contents of array 2 in the process.
I want the size and the range of array 1 to also overwrite those properties of array 2, so that I can drop an array of any size and range into the master patch.
I have so far managed to overwrite the size of array 2 using [array size array-1], which allows you to get and change the size of an array, but I cannot find the equivalent for the range property. The [array] object has a couple of arguments, 'min' and 'max' that I thought might help, but they get the min and max values from the data in the array, not the actual min and max range from the array properties.
Does anyone know if there is a way to get min and max range properties from an array, and then set those properties to another?
looking for velvet noise generator
@porres said:
to never miss a period, but I also think this is a job for a C code.
To atone for my earlier SC jibe, here's a delay-based approach. (Also, indeed you're right -- I hadn't read the thread carefully enough. Dust / Dust2 don't implement exactly "one pulse per regular time interval, randomly placed within each interval.")
Uses else's del~ because delread~ requires a message-based delay time, which can't update fast enough, and delread4~ interpolates, which smears the impulses. With del~, I could at least round the delay time to an integer number of samples, and AFAICS it then doesn't interpolate.
It looks to me in the graphs like there is exactly one nonzero sample per phasor~ cycle.
hjh
PS FWIW -- one nice convenience in SC is that non-interpolating DelayN doesn't require the delay time to be rounded
(
a = { |density = 2500|
// var pulse = Impulse.ar(density);
// for similarity to Pd graphs, I'll phasor it
// but the Impulse is sufficient for the subsequent logic
var phasor = LFSaw.ar(density);
var pulse = HPZ1.ar(phasor) < 0;
var delayTime = TRand.ar(0, density.reciprocal - SampleDur.ir, pulse);
var rand = TRand.ar(-1, 1, pulse).sign;
[DelayN.ar(rand * pulse, 0.2, delayTime), phasor]
}.plot;
)
Plot points by importing coordinates from an external text file
Impressive examples for struct patches:
https://forum.pdpatchrepo.info/topic/10756/vanilla-struct-multislider-with-jump-on-click-and-drag
@Balwyn
https://forum.pdpatchrepo.info/topic/14009/hide-array-name/14
https://forum.pdpatchrepo.info/topic/14037/plot-graph-a-way-to-display-waveforms
Here is a workshop on data structures from some years ago (things might have changed in the meantime, but I don't know). Unfortunately the workshop-patches are not online, but you might ask João in the Pd-mailinglist.
https://media.ccc.de/v/lac2018-26-understanding_and_being_creative_with_pure_data_s_data_structures#t=1633
I am interested in how to pipe data from Pd to a fully equipped plotting-software?
https://stackoverflow.com/questions/17543386/pipe-plot-data-to-gnuplot-script
https://stackoverflow.com/questions/33457750/gnuplot-plotting-using-piped-input
@katjav https://www.katjaas.nl/plot/plot.html
(all of this is on my undone-list)
Sample rate issues while using [Soundfiler]
@ChicoVaca The problem as you say is the number of samples per second for your sample. Pd will be playing them at 44100 or 48000 samples per second (which you have set for your sound card in the Pd media settings).
So 4000 samples will be played in about 1/10th of a second.
The solution is about a third of the way down the page that you linked to, and a little bit of maths can calculate the value (automatically in your patch using the sample rate from [soundfiler] and the setting for Pd) that you will need for [line~] to play the sample correctly using [tabread4~]
For correct interpolation guard points should be added to the array, and fortunately @lacuna made a patch that makes adding guard points very easy........ https://forum.pdpatchrepo.info/topic/14301/add-delete-guard-points-of-an-array-for-4-point-interpolation-of-tabread4-ect
David.
Partial array read with soundfiler?
I was hoping to build a variable-speed sound file streamer abstraction -- like readsf~ but with a rate inlet (particularly for correcting a mismatch between the file's sample rate and the DSP sample rate).
I was hoping to do it like this:
- Allocate an array with x frames.
- Upon "cue," load x/2 frames at the beginning of the array.
- When playback takes off from frame 0, load the next x/2 frames into the second half of the array.
- When playback crosses the halfway point, load the 3rd x/2 chunk into the beginning of the array.
- At this point, then, a phasor can just read forward through the array, and loop back to the beginning. At every half-transition, load data into the half of the array that isn't being played.
I quickly run into gaps in soundfiler's interface.
- "-maxsize" resizes the target array -- there appears to be no way to load partially into an array.
- There also doesn't seem to be any way to read starting at index 'a' in an array. "-skip" will skip frames from the file, but there isn't a flag for where to start putting data into the array. (Compare SC, with parameters
fileStartFrame
,numFrames
andbufStartFrame
for the buffer read message.)
This was to distribute a multichannel fixed-media work. I was thinking Pd because the download size is small. But I think I'm going to have to take this back to SuperCollider because there's a VDiskIn built-in -- can just use it, not spend time hacking it.
In any case... are there any workarounds for those two limitations? (I guess I would need two arrays -- I was hoping to avoid that because switching the table name sample-synchronously also sounds a little bit tricky.)
hjh
how do YOU make a "light" waveform display?
@Load074 Over the past few years I've also been trying out various approaches along the lines of what you're looking for, and actually tried something rather similar to your idea: pulling only one sample per x samples of the source array and sending to a smaller display array. And indeed, it doesn't work because those values are just scattered snapshots of the signal & will be discontinuous with the neighboring display samples. I realized that some kind of averaging would be needed, started to work on it, then got sidetracked & never followed through...
But, I ended up finding two pre-baked solutions:
rh_wavedisplay from netpd
pp.waveform from AudioLab
I can't quite wrap my head around how rh_wavedisplay works from looking inside the abstraction, but the result looks nice. From the help patch:
This abstraction finds the minima and maxima for each section of the source table that covers one pixel of the display array. The result is a good looking waveform that does not suffer from aliasing.
I also like that it allows for only a section of the source array to be used for display (which is important for how my performance patch uses arrays). In practice it still causes audio dropouts when updating large source arrays, unfortunately.
pp.waveform uses data structures, which is why the result looks so different visually. I don't understand data structures enough to play around with this or try to adapt it for my uses, but I would be definitely curious about whether it's any more efficient than those other graphical array manipulation methods.
I also wonder if there's simply no method that will prevent audio dropouts without some kind of array manipulation that can run on a different thread. I've been looking into the shmem library to see if it's possible to outsource the array processing to another Pd instance (similar to the Pd~ approach that @alexandros suggested), haven't gotten very far so I still don't know if there will be a bottleneck when dumping a huge array to memory.
Performance of [text] objects
@ddw_music said:
By contrast, if, in SuperCollider, I made 4 arrays of strings with 10 items, 100, 1000 and 10000 respectively, I'd expect it to go at least an order of magnitude faster, maybe two orders, because array indexing in SC is O(1) (so the entire fill would be O(n) provided that you allocate all the array slots in advance -- since the number is known, that's easy).
That turned out to be wrong:
(
var letterA = $a.ascii;
f = { |n| Array.fill(n, { String.fill(50, { (26.rand + letterA).asAscii }) }) };
bench {
a = [f.(10), f.(100), f.(1000), f.(10000)];
};
)
time to run: 0.06757064 seconds. ~= 0.07
About half. So a lot of the time is spent just generating the strings, I guess, in both environments.
Repeating the array-read benchmark in SC, though... this is what O(1) array lookup looks like:
(
a.do { |array|
var n = array.size;
(n.asString ++ " elements: ").post;
bench {
1000000.do { array[n.rand] }
}
}
)
10 elements: time to run: 0.038383661000012 seconds.
100 elements: time to run: 0.035132123000039 seconds.
1000 elements: time to run: 0.033579056999997 seconds.
10000 elements: time to run: 0.034433505999914 seconds.
... no performance degradation for higher sizes.
hjh
can an array object be moved with a metronome, like shift left & then right?
@esaruoho So you don't really want to move it....... you are still looking for a way to have a constant update (while it is actually updating).
Some messages will update the [array] as @oid says..... and there are many......... https://forum.pdpatchrepo.info/topic/10720/change-appearance-of-an-array-by-sending-a-message
But there is only one message that will do so without changing the data or the appearance.....
[;
arrayname rename arrayname(
....... renaming the array with the same name will cause a redraw.
I am a bit loathe to point you in these directions as it will create more fun.....
When an array is updated Pd will send a ping message..... that could be used to update again, but maybe a small delay would be advisable (feedback overflow)..... https://forum.pdpatchrepo.info/topic/11501/get-array-values-when-they-are-updated
For [array define] a copy can be created for display...... could also be done with a [metro]...... https://forum.pdpatchrepo.info/topic/12072/display-an-array-define-array-constantly
But too fast updating will cause dropouts.
David.