Thanks for the example patch I am almost getting perhaps close to understanding :) However have a few queries about what is happening.
I have been trying to work out the wrapping a vline patch first as
this seems the most straightforward, as this is all really new to me.
So first off
[r x] object receives a bang from the x subpatch every 200 milliseconds.
This bang then outputs the message [0, 1 10] every 200 millisecond The message [0,1 10] means go from 0 to 1 in 10 milliseconds
this message then goes into the vline object which creates the ramp
(sawtooth)
i.e. the y=mx equation that you mentioned where the 10 milliseconds
could be the gradient of the sawtooth waveform or the gradient could
be later on.
The output of the vline object is then multiplied by 3 which in
effect multiplies the steepness of the slope by 3
This multiplication could be the m in the equation y=mx and seems
like a more logical place than in the ramp.
This is then wrapped to keep the output cycling to 1.
So in effect we get 3 sawtooth waveforms for each bang sent by x
which occurs every 200milliseconds.
and now I have an oscillator :)
Just a few things I need to clarify
The frequency of the phasor is determined by the slope of the line,
by the phase increment k.
If y=mx +k and wrapping this produces an oscillator, I understand
that adding k can be the phase increment i.e. what point the waveform
will start from,
Does this mean that in this example the [*~ 3] object represents m
and therefore the frequency of the oscillator and you would add a
[+~ ] to control the phase increment?
In practice, in code, we combine the integrator and wrap into a
single unit so that the line does not increase without bound. If it does then
the oscillator will work for a while, but then the line will exceed the
representation range of the CPU.
Am I understanding you correctly in thinking that the integrator and
wrap and combined so that rather than leave the integrator to keep
counting higher and higher (unitl the processor can't cope) the wrap
function is somehow combined with it so that the integrator keeps
reseting itself so that the number it counts up to never gets that big?
Once again thankyou for this example, I don't know if you are a
lecturer and this is an example you use. Its really helped me
visualize things.
cheers
Geoff
On 7 Feb 2009, at 19:07, Andy Farnell wrote:
Here's some notes and an example patch on exactly this subject hope it helps.
a.
----------------snip-------------------------- The first principles of generative DSP can be broken into three
concepts which follow easily from one another.The first and most fundamental is that of the accumulator. This
just means something likex = x + 1
Or more correctly x[t_n] = x[t_n-1] + k
It just makes a line. The line increases without bound. From high
school maths you will know the line equation y = mx + c, the slope m
determines how fast the line rises from an origin c on the y axis for a given
interval on the x axis. In DSP we make the x axis be time, t, and the
discrete time values n and n-1 represent contiguous samples along the time line.In a simple sense of programming the accumulator/incrementor/ integrator can be considered an endless loop, a do-while(1) or for(;;;) loop, in
which a variable is incremented by a small amount on each step. In a more advanced
interpretation the accumulator/incrementor can be thought of as a filter, an IIR
filter in which the current output depends on the last output plus input k, so it
integrates k over time. Thus by changing k we can change the slope (slew or phase increment) of the line.Shown in part one of the example patch is a couple of ways of doing
this. The first uses [vline~] to make a line that will rise steadily over a
long period of time. The second is more arcane, it uses a [biquad~] object as
an integrator.This isn't much use until we combine it with the second fundamental
concept, the idea of wrapping. Wrapping creates a discontinuous periodic
function by making any input value x greater than N become 0 < x < N, wrapping the
output back into the range between zero and N. If x is a float then it's the
fractional part of x, or x - floor(x), like the modulo operator is to integers. In
Pure Data it is defined for the range 0 to 1.0. What we get by combining an
accumulator with a wrap is called a phasor, a line that cycles up from 0.0 to 1.0
over and over. The frequency of the phasor is determined by the slope of the line,
by the phase increment k.In practice, in code, we combine the integrator and wrap into a
single unit so that the line does not increase without bound. If it does then
the oscillator will work for a while, but then the line will exceed the
representation range of the CPU.A wrapped line is shown in the second part of the patch along with
an example of how it is like the built-in [phasor~] object.The final part of the picture is a new periodic function that sets
the waveform of our oscillator. It is defined over the domain 0.0 to 1.0 so the
phasor drives the input nicely, but it normally has a bipolar range defined
between -1.0 and 1.0 to give a symmetrical waveform without a DC component. This can be
in the form of a lookup table, for which the domain is mapped to the table size,
or a trigonometric function like cos(x) for which the domain is mapped to 2 time PI.
In other words the periodic function takes a phasor that cycles up to 1.0 and maps it
onto a waveform that cycles backwards and forwards around zero.In the last part of the example patch we see a wrapped line and
periodic function behave as an oscillator alongside the built-in [osc~] object which
does more or less the same thing.------snip------------------
On Sat, 7 Feb 2009 17:31:48 +0000 Geoff geoffspuredata@googlemail.com wrote:
Hi I am very new to PD and DSP concepts. So this will be hopelessly, awfully, basic :)
I have just started chapter 3 of 'The theory and technique of electronic music' which is excellent
However it raises a million questions in my head...... one of which is how do I create an oscillator myself?
Its really bugging me everytime I create an example from the book. I feel I need to understand the fundamentals of how the basic objects are created too.
It seems too easy for me to just use the phasor object provided,
So I thought I would struggle through it and try to work it out.
This is how I am thinking about it. If I want to create a sawtooth oscillator then this is just a ramp function i.e. a number that increases by 1 each time. therefore if I use a simple float that, that adds 1 each time and a modulus % object to cap it, then I will have my repeating ramp
wave :)However I am triggering it by the metro object which is way too slow, how can I send a bang to the float object say every sample? or alot quicker than one millisecond?
My thinking is if I could speed up the bangs to a sample level I would then have more scope to then actually tune it, and create the shape I want. However I am sure to do this well would require working at a higher sample rate, but I am not really sure how to proceed.
Below is my appalling attempt :) I use the number box to change
pitch.Any guidance appreciated Cheers Geoff
#N canvas 325 62 681 388 10; #X obj 119 69 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 121 96 f; #X obj 181 116 + 1; #X obj 115 17 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 127 238 dac~; #X obj 118 46 metro 1; #X floatatom 187 163 5 0 0 0 - - -; #X obj 115 160 %; #X obj 114 199 /; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 1 0 7 0; #X connect 2 0 1 1; #X connect 3 0 5 0; #X connect 5 0 0 0; #X connect 6 0 7 1; #X connect 6 0 8 1; #X connect 7 0 8 0; #X connect 8 0 4 0;
-- Use the source<oscil- basics.pd>_______________________________________________ Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/ listinfo/pd-list