Send and receive global and local far down the rabbit hole + questions
Now I have some questions.
number 1
how do you get your last operation not to be calculated first?
I had made this intricate tuning calculation for a Karplus - Strong 12 string.
It's microtuneable to non octave tunings so in order to detune the second strings it has to be done on the fly. So every now and then the thing plays way out of tune.
I put prints in enough places so I could see what was going on.
Well final operation on calculating the frequency was getting calculated first. Or at least it was getting printed first. So I started tracing trigger bangs and floats all the way back to the first bang that started the calculation. That was crazy While making the thing I had followed the path very carefully down but since some operations depended on other operations to get done first the bangs split in multiple directions. Instead of trying to get more confused in the tangled mess I started replacing
- , [+ ], etc.. with [expr] which made it a lot easier to comprehend still sometimes the thing plays out of tune.
This leads to my next question. The Karplus-Strong patch I started with sets a [block~ 1] is it possible this small block size is causing some of the calculation to get interrupted.
If the things that need to be calculated are not done within one block does that screw things up?
I thought the control operations were only sent once per block anyways.
and is that so if you change the block size to anything other than 64?
And another question is it more processor intensive to use [expr] instead of
- , [+], etc..?
Can a moog like filter be done without writing c code? Where can I learn about designing ladder filters in pure data? I like all the ext moog filters I've heard I'm just wanting to keep my patches vanilla unless I write the external. Propellorhead's Thor Ladder filter does not sound like any of the moog filters I've heard in pure data. Maybe it has something to do with the frequency snapped to the harmonic series or something but I've done that with the pure data moog filters and don't get the same results. Maybe the Propellorheads are upsampling to do the filters.
Another weird thing is I made a bypass for my filters. So I had 6 voices, 6 oscillators per voice, 2 filters per voice so that is 36 oscillators and 12 filters running. I added a 3rd filter per voice and when they were bypassed my machine went up to 90% cpu usage and more. So I removed the 3rd filter. Still CPU usage would go up when the filters were bypassed so I added a switch to turn them off whenever they were bypassed that fixed the problem with that. I probably ought to switch the oscilators off when they are not in use as well so I can add more. Some of them are feedback oscilators and generate chaotic signals so I guess there need to be an option to leave them on.
Now the next question and that will do it for today.
how do you print your entire patch to a ghost script printer?
I tried scaling the page so I could see the patch on the screen and still only get part of the patch in the ps file.
How do I do modulation routing with a matrix and do it polyphonically?
I want anything that has an input to be able to be routed to anything with an output and be scaled along the way. My voices are allready huge and so I would like it all to be done from within the main patch. At what point does your patches get too big? oops.
Oscillator & array - discrepancy between frequency & graph
Hi!
I'm quite new to PD and simply played around a little bit when the following question crossed my mind:
I have an oscillator running at 100Hz and and array which is updated every 100ms. 100Hz means 100 oscillations per second, so one full oscillator swing (from 1 to 1) should last a hundreth of a second = 10ms.
So, if I'm not already wrong at his point, I am supposed to see ten full oscillator circles on the array, no?
What happens with me is that I see one full oscillation at 400Hz. I attached a screenshot of this situation.
What am I getting wrong?
Thanks for your help!
Bandlimited oscillators
This is a collection of abstractions that generate bandlimited oscillators. They include:
[bl-saw.mmb~] - bandlimited sawtooth waveform
[bl-pulse.mmb~] - bandlimited pulse wave with PWM
[bl-tri.mmb~] - bandlimited triangle wave
[bl-asymtri.mmb~] - bandlimited asymmetrical triangle wave (sort of...see below)
There is also an object called [bl-init.mmb]. This is the object that initializes all the waveforms and at least one instance MUST be included in order for the others to work.
There are also help patches included.
IMPORTANT!
Before you can use these, you must do the following steps.
1. Open [bl-init.mmb]
2. There is a message box that says [44100(. This is the maximum sampling rate that these will work at (running at lower sampling rates will be fine). If you plan on using higher sampling rates, change this message box and click it. Technically, it will still work at a higher sampling rate, but it won't generate harmonics above the sampling rate in this box.
3. Click the [bang( to fill the wave tables. This patch actually creates a wavetable for EVERY harmonic between 30Hz and the Nyquist frequency. So it will take a few minutes. Be patient! You will get a message in the Pd window when it is done.
4. Save the patch.
Once you do this, [bl-init.mmb] will simply load with the tables already generated, so you don't have to wait every time you instantiate it. I didn't have this already done for you in order to keep the upload small, and so you can see how to adjust it if you need to.
So, I guess I'll go ahead and try to explain how these work. As stated above, every harmonic is generated in [bl-init.mmb] for the oscillators. It doesn't create a table for each set of harmonics however (e.g., there isn't a saw table with two harmonics, a saw table with three harmonics, etc.). Instead, each of these individual tables are tacked on to the end of each other to create one long wave table. So, for each set of 1027 samples in the sawtooth wavetable, there is one cycle with a set amount of harmonics.
When the oscillators read the frequency input, it is divided into the Nyquist frequency to determine how many harmonics are needed. It then uses this (* 1027) as the offset for the table. This is how I got around the problem of table switching at block boundaries. By doing this way, the "switching" is done at audio rate.
There are actually two [tabread4~]s. One has one less harmonic than the other. As the frequency changes it crossfades between these tables. When one table goes completely silent, that's when it "switches." Below 30Hz, they switch to geometrically perfect waveforms.
[bl-saw.mmb~] and [bl-tri.mmb~] just read through the tables. Nothing really interesting about them.
[bl-pulse.mmb~] is actually the difference between to sawtooths. In other words, there are two bandlimited sawtooth oscillators inside of it. Adjusting the pulse width cause the phase of one of the sawtooths to shift. When you subtract this phase-shifted sawtooth from the other, it creates a bandlimited pulse wave...without oversampling! This is the same Phase Offset Modulation method used in Reason's SubTractor.
[bl-asymtri.mmb~] uses the same technique as [bl-pulse.mmb~], except it uses bandlimited parabola waves instead of sawtooths. Adjust the phase offset sets where the top vertex is. This doesn't really generate true triangle or saw waves, though. They still have the parabolic curve in them, so the harmonics seem to come out a little more. It's more of a "reasonable approximation." But, it is bandlimited, and it does sound pretty cool to modulate the shape. I don't have the scaling quite right yet, but I'll get to it later...maybe.
I should also mention that these use my [vphasor.mmb~] abstraction, so the phase reset is sample accurate.
I'll eventually set these up to allow frequency and pulse-width arguments, but I'm currently in the process of moving to another country, so it may be a little bit before I get around to it.
Didn't any of that make any sense?
Lfo rate and depth
It depends.
osc~ oscillates between -1 and 1 so using it the way you did will not only oscillate the amplitude but also invert the signal.
What you could do is after multiplying it by a factor between 0 and 1 as arif suggests is to add 1 to it. That way it will oscillate between 0 and 2 at the maximum depth and stay centered at 1. That way if your depth is 0 it will stay at it's original amplitude.
It's probably also a good idea to divide the total output by 2 since it might clip at the maximum oscillation.
Hard-syncing phasors
Hello,
I'm trying to make something that sounds like C64 SID chip. One particular property of that chip is that, it is possible to hard-sync two oscillators, so that the slave oscillators phase is reset to zero every time master oscillators phase returns to zero. I couldn't find a a way to implement this in pd.
Trying to capture the zero crossings on the master oscillator seems to be a dead end, because i'll have to turn it into a control signal somewhere to connect it to the phase input on slave phasor. And control signals are much too slow to catch every zero crossing.
Any ideas?
\[zerox~\]
If you plan on using [xerox~] to phase sync two oscillators, it probably won't cut it. Generally, you want those things to be sample accurate. [xerox~] will give you a click corresponding to zero crossings out its right outlet, but, as far as I know at least, Pd's oscillators can't really use that for phase syncing ([xerox~] is actually based on a Max object, yet strangely Max's oscillators can't use it either). It would require a conversion to message rate to reset the phase, which kills sample accuracy, not to mention the fact that the phase input of [phasor~] quantizes to block boundaries (default 64 samples in Pd), which also kills sample accuracy.
However, if you know the ratio between your two oscillators, phase syncing can be achieved using a master [phasor~] to run both oscillators. Use the master sync frequency to drive the [phasor~], then multiply the output of the [phasor~] by the ratio between the synced (slave) oscillator and the master one. In other words, it should be multiplied by:
slave frequency / master frequency
Then, you just [wrap~] the signal and viola, you have a new synced phasor signal to drive the slave oscillator. The attached patch should hopefully clarify.
Noise-\>osc
ha ha, it's not very scientific. but anyway...
[noise~] outputs a random value between -1 and 1 every sample.
we then multiply the output of [noise~] by a number between 2000 and 20000
this means that going into the frequency control of the [osc~] object will be a signal between -2000 and 2000 at the lowest setting, and -20000 and 20000 at the highest setting.
sending negative frequencies into [osc~] is just the same as positive ones, but the oscillator wave flows in the opposite direction.
so, every sample, we are changing the frequency of the [osc~] oscillator. if we only oscillate at frequencies between -2000 and 2000, then the maximum frequency output will be 2000hz. however if we ramp it right up to 20000, then the oscillator will oscillate at higher frequencies.
it still sounds like noise though, because the frequency of [osc~] is changing so rapidly that there is barely any periodic content in the output waveform.
What causes this message error: inlet: expected ' ' but got 'float' ?
that is a symptom of an earlier error - you are sending messages to an object that couldn't be created - usually because it could not be found.
objects can be defined by abstractions (like foo.pd -> [foo]) or by "externals" which are usually written in C and have to be compiled (like bar.dll or bar.pd_linux -> [bar]).
to complicate things further, compiled externals can define more than one object class - these are "libraries" - you might have quux.pd_linux or quux.dll that defines [baz] but to actually get [baz] you have to load the [quux] library with -lib quux or something.
Patches for windows?
my guess is that patches aren't working for you because you don't have pd-extended...get it here:
http://sourceforge.net/project/showfiles.php?group_id=55736&package_id=76013
for a little mono-synth here is my juno emulator:
http://puredata.hurleur.com/sujet-861-hey-graduated-casio-emulators-got-myself-juno
a dodgy casio sorta sounding one:
http://puredata.hurleur.com/sujet-622-casiotone
and an 'emulation' i did of the casio cz1000, that not surprisingly doesn't sound anything like an actual cz1000, but might be interesting anyway:
http://puredata.hurleur.com/sujet-648-casio-sounds-gets-emulated
How do you timestretch?
Even easier. Forgive me, I'm new to Pd so this will be in Reaktor speak.
You can do this with basic granular synthesis. Do to it Homebrew style you need three things. You need two ramp oscillators (phasors?) and a clock generator. The main ramp sets the play position in samples, but ONLY when the clock generator bangs. The other ramp oscillator (phasor?) determins the pitch, so this is basically what you have now, just a basic table read. When the clock gen bangs this pitch osc is reset.
The speed of the clock generator is in milliseconds, this is the grain time.
BOTH the oscilators are added together, this sum is your new play position in your table!
It works pretty well, I've implemented it in reaktor. Hope this helps. Any questions, email me.