changing phasor~ frequency in sync with itself

Mattijs's icon

Hi, is there a way to do the following in signal domain only?

Max Patch
Copy patch and select New From Clipboard in Max.

Mattijs

justin's icon

this is one solution, although there is probably scope for improvement! oh, and i hope you like FM noises. ;)

peter mcculloch provided a very good patch for doing this with wave~ and drum loops. if you cant find it on the forum, i think i have it somewhere on my HD.

ez. j

Max Patch
Copy patch and select New From Clipboard in Max.

Mattijs's icon

Thanks justin.

The problem of your solution is that there is always a vectorsize delay before the frequency is set. I would like it to be sampleaccurate, which means the new frequency should be updated on exactly the same sample that the phasor jumps back to 0.

In fact I suspect this to be fundamentally impossible in MSP.

Am I right?

Mattijs

Quote: justin wrote on Wed, 27 June 2007 19:25
----------------------------------------------------
> this is one solution, although there is probably scope for improvement! oh, and i hope you like FM noises. ;)
>
> peter mcculloch provided a very good patch for doing this with wave~ and drum loops. if you cant find it on the forum, i think i have it somewhere on my HD.
>
> ez. j
>
> #P window setfont "Sans Serif" 9.;
> #P window linecount 2;
> #P comment 17 92 167 196617 some randomly generated fm tones...;
> #P window linecount 1;
> #P newex 126 421 46 196617 *~ 0.5;
> #P newex 128 176 43 196617 sah~;
> #P newex 128 220 46 196617 +~ 5;
> #P newex 128 196 46 196617 *~ 100;
> #P newex 128 261 66 196617 *~ 200;
> #P newex 17 319 46 196617 *~;
> #P newex 128 241 55 196617 cycle~ 40;
> #P comment 447 43 211 196617 2. change frequency , and press bang to start;
> #P newex 17 223 46 196617 +~ 36;
> #P newex 162 377 94 196617 trapezoid~ 0.1 0.9;
> #P newex 161 134 53 196617 r sah_trig;
> #P newex 530 229 53 196617 s sah_trig;
> #P newex 17 177 43 196617 sah~;
> #P newex 17 289 46 196617 mtof~;
> #P newex 17 145 46 196617 abs~;
> #P newex 17 264 46 196617 trunc~;
> #P newex 17 199 46 196617 *~ 36;
> #P newex 17 124 46 196617 noise~;
> #P newex 126 466 46 196617 dac~;
> #P newex 17 340 46 196617 cycle~;
> #P newex 126 399 46 196617 *~;
> #P user number~ 495 272 534 287 9 3 3 2 0. 0. 0 0. 250 0. 0 0 0 221 221 221 222 222 222 0 0 0;
> #P newex 530 183 53 196617 tapout~ 0;
> #P newex 484 341 46 196617 tapin~ 1;
> #P newex 501 142 21 196617 0.;
> #P newex 480 102 31 196617 t 1. b;
> #P newex 501 122 38 196617 del 50;
> #P newex 480 161 29 196617 sig~;
> #P user scope~ 315 412 445 542 256 3 128 -1. 1. 0 0. 0 0. 102 255 51 135 135 135 0;
> #P button 487 57 15 0;
> #P user number~ 447 57 486 72 9 3 3 1 0. 0. 0 0.2 250 0. 0 0 0 221 221 221 222 222 222 0 0 0;
> #P newex 447 312 46 196617 >~ 0.99;
> #P user ezdac~ 341 58 385 91 0;
> #P user scope~ 447 412 577 542 256 3 128 -1. 1. 0 0. 0 0. 102 255 51 135 135 135 0;
> #P newex 447 209 43 196617 sah~;
> #P newex 447 272 46 196617 phasor~;
> #P comment 341 43 100 196617 1. enable audio;
> #P connect 19 0 22 0;
> #P connect 22 0 24 0;
> #P connect 24 0 20 0;
> #P connect 20 0 28 0;
> #P connect 28 0 21 0;
> #P connect 21 0 23 0;
> #P connect 23 0 31 0;
> #P connect 31 0 17 0;
> #P fasten 26 0 24 1 166 164 55 164;
> #P connect 32 0 31 1;
> #P fasten 17 0 16 0 22 378 131 378;
> #P connect 16 0 36 0;
> #P connect 36 0 18 0;
> #P fasten 22 0 35 0 22 169 133 169;
> #P connect 35 0 33 0;
> #P connect 33 0 34 0;
> #P connect 34 0 30 0;
> #P connect 30 0 32 0;
> #P connect 26 0 35 1;
> #P fasten 1 0 27 0 452 299 167 299;
> #P connect 27 0 16 1;
> #P connect 36 0 18 1;
> #P fasten 1 0 8 0 452 304 320 304;
> #P connect 6 0 2 0;
> #P connect 2 0 1 0;
> #P connect 1 0 5 0;
> #P connect 5 0 3 0;
> #P fasten 7 0 11 0 492 87 485 87;
> #P connect 12 0 9 0;
> #P connect 11 0 9 0;
> #P fasten 14 0 2 1 535 204 485 204;
> #P connect 9 0 2 1;
> #P fasten 5 0 13 0 452 335 489 335;
> #P fasten 2 0 15 0 452 231 500 231;
> #P connect 11 1 10 0;
> #P connect 10 0 12 0;
> #P fasten 13 0 14 0 489 370 603 370 603 170 535 170;
> #P connect 14 0 25 0;
> #P connect 9 0 25 0;
> #P window clipboard copycount 38;
>
----------------------------------------------------

justin's icon

Quote: Mattijs wrote on Fri, 29 June 2007 13:07
----------------------------------------------------
> Thanks justin.
>
> The problem of your solution is that there is always a vectorsize delay before the frequency is set. I would like it to be sampleaccurate, which means the new frequency should be updated on exactly the same sample that the phasor jumps back to 0.

even peter mcculloch's patch uses tapin / tapout to get round the feedback issue - and incur the vector size delay. although his is somewhat more complex (and probably better) than my attempt!

> In fact I suspect this to be fundamentally impossible in MSP.
>
> Am I right?

i suspect that you are right. although you might be able to find a solution with eric lyon's sample accurate timing objects. but that's 3rd party...

j

Mattijs's icon

>
> > In fact I suspect this to be fundamentally impossible in MSP.
> >
> > Am I right?
>
> i suspect that you are right.

Funny, it seems such a basic operation.. maybe it's a conceptual problem. I'll go back and see where the info that results in the new frequency value is originally translated to the signal domain. Maybe I'll find the solution there.

> although you might be able to find a solution with eric lyon's sample accurate timing objects. but that's 3rd party...

But when it is fundamentally impossible I don't think eric lyon will have made a workaround.

Thanks,
Mattijs

Peter McCulloch's icon

It's not possible without third-party externals, but for 95% of
applications, the existing vanilla-max solution will sound fine. Out of
curiosity, what is the particular need for 1 sample accuracy? (also
note that you can get the existing vanilla-max solution to within 2
sample accuracy using poly~)

The reason I ask is that this thread keeps coming up, and it seems like
we should either have a dedicated object for this in the Max distro if
there is a need for it.

Peter McCulloch

On Jun 30, 2007, at 8:22 AM, Mattijs Kneppers wrote:

>
>>
>>> In fact I suspect this to be fundamentally impossible in MSP.
>>>
>>> Am I right?
>>
>> i suspect that you are right.
>
> Funny, it seems such a basic operation.. maybe it's a conceptual
> problem. I'll go back and see where the info that results in the new
> frequency value is originally translated to the signal domain. Maybe
> I'll find the solution there.
>
>> although you might be able to find a solution with eric lyon's sample
>> accurate timing objects. but that's 3rd party...
>
> But when it is fundamentally impossible I don't think eric lyon will
> have made a workaround.
>
> Thanks,
> Mattijs
> --
> SmadSteck - http://www.smadsteck.nl
> Hard- and software for interactive audiovisual sampling
>
>
www.petermcculloch.com

Mattijs's icon

Hi Peter,

I'm working on a granular time stretcher/pitch shifter and I need the grains to update their play speed and length only when they've finished playing. The sound will distort if the updates are done mid-grain.

I am quite sure that 3rd party externals will not solve the problem, there is just no way to make a feedback loop within one sample. When the dsp chain is rebuilt and an object is encountered that was already seen in the current branch, the branch is disabled. The only way would be to make a custom phasor~ with this behaviour built in.

Mattijs

Quote: peter.mcculloch@gmail.com wrote on Sat, 30 June 2007 19:30
----------------------------------------------------
> It's not possible without third-party externals, but for 95% of
> applications, the existing vanilla-max solution will sound fine. Out of
> curiosity, what is the particular need for 1 sample accuracy? (also
> note that you can get the existing vanilla-max solution to within 2
> sample accuracy using poly~)
>
> The reason I ask is that this thread keeps coming up, and it seems like
> we should either have a dedicated object for this in the Max distro if
> there is a need for it.
>
> Peter McCulloch
>
>
>
> On Jun 30, 2007, at 8:22 AM, Mattijs Kneppers wrote:
>
> >
> >>
> >>> In fact I suspect this to be fundamentally impossible in MSP.
> >>>
> >>> Am I right?
> >>
> >> i suspect that you are right.
> >
> > Funny, it seems such a basic operation.. maybe it's a conceptual
> > problem. I'll go back and see where the info that results in the new
> > frequency value is originally translated to the signal domain. Maybe
> > I'll find the solution there.
> >
> >> although you might be able to find a solution with eric lyon's sample
> >> accurate timing objects. but that's 3rd party...
> >
> > But when it is fundamentally impossible I don't think eric lyon will
> > have made a workaround.
> >
> > Thanks,
> > Mattijs
> > --
> > SmadSteck - http://www.smadsteck.nl
> > Hard- and software for interactive audiovisual sampling
> >
> >
> www.petermcculloch.com
>
>
----------------------------------------------------

Peter McCulloch's icon

Hi Mattijs,

Since you're presumably doing windowing, I don't think this is going to
be a sonic issue. Try the solution that I posted awhile ago that uses
sah~ and delta~, and it should be effective. I use it all the time for
granular processes and have no problems whatsoever. 64 samples is
nothing when you're fading a sample out over 20 ms... Though it's not
theoretically accurate, it won't matter sonically; if you're to the
point of doing 64 sample long grains, then pitch isn't really much of
an issue and noise is almost a guarantee anyways.

A third party external most definitely could solve this bigger problem
by doing the changeover internally, so that no feedback loop is
required.
It would be very nice, however, if Cycling'74 could add an argument to
phasor~ to switch frequency from free-roaming to synchronous.

Peter McCulloch

On Jun 30, 2007, at 2:15 PM, Mattijs Kneppers wrote:

>
> Hi Peter,
>
> I'm working on a granular time stretcher/pitch shifter and I need the
> grains to update their play speed and length only when they've
> finished playing. The sound will distort if the updates are done
> mid-grain.
>
> I am quite sure that 3rd party externals will not solve the problem,
> there is just no way to make a feedback loop within one sample. When
> the dsp chain is rebuilt and an object is encountered that was already
> seen in the current branch, the branch is disabled. The only way would
> be to make a custom phasor~ with this behaviour built in.
>
> Mattijs
>
> Quote: peter.mcculloch@gmail.com wrote on Sat, 30 June 2007 19:30
> ----------------------------------------------------
>> It's not possible without third-party externals, but for 95% of
>> applications, the existing vanilla-max solution will sound fine. Out
>> of
>> curiosity, what is the particular need for 1 sample accuracy? (also
>> note that you can get the existing vanilla-max solution to within 2
>> sample accuracy using poly~)
>>
>> The reason I ask is that this thread keeps coming up, and it seems
>> like
>> we should either have a dedicated object for this in the Max distro if
>> there is a need for it.
>>
>> Peter McCulloch
>>
>>
>>
>> On Jun 30, 2007, at 8:22 AM, Mattijs Kneppers wrote:
>>
>>>
>>>>
>>>>> In fact I suspect this to be fundamentally impossible in MSP.
>>>>>
>>>>> Am I right?
>>>>
>>>> i suspect that you are right.
>>>
>>> Funny, it seems such a basic operation.. maybe it's a conceptual
>>> problem. I'll go back and see where the info that results in the new
>>> frequency value is originally translated to the signal domain. Maybe
>>> I'll find the solution there.
>>>
>>>> although you might be able to find a solution with eric lyon's
>>>> sample
>>>> accurate timing objects. but that's 3rd party...
>>>
>>> But when it is fundamentally impossible I don't think eric lyon will
>>> have made a workaround.
>>>
>>> Thanks,
>>> Mattijs
>>> --
>>> SmadSteck - http://www.smadsteck.nl
>>> Hard- and software for interactive audiovisual sampling
>>>
>>>
>> www.petermcculloch.com
>>
>>
> ----------------------------------------------------
>
>
> --
> SmadSteck - http://www.smadsteck.nl
> Hard- and software for interactive audiovisual sampling
>
>
www.petermcculloch.com

Roman Thilenius's icon

> Funny, it seems such a basic operation.. maybe it's a conceptual problem. I'll go back and see where the info that results in the new frequency value is originally translated to the signal domain. Maybe I'll find the solution there.
>

i have not looked at your patches but i think i have a similar problem here.

i basically want a steady signal to change (for example from 7.0 to 8.0) at a certain sample.

the transition from 7.0 sig to 8.0 sig is coming at an unknown timepoint, and i want my steady signal to change to 8.0 at the next
phasor~ loop start coming from elsewhere. (as opposed to immediately)

it really makes me crazy, its so simple but i cant find a signal only solution.

Roman Thilenius's icon

the whole problem is almost like "set 8." for signals.

:)

-110

jvkr's icon

>Out of
> curiosity, what is the particular need for 1 sample accuracy? (also
> note that you can get the existing vanilla-max solution to within 2
> sample accuracy using poly~)
>
> The reason I ask is that this thread keeps coming up, and it seems like
> we should either have a dedicated object for this in the Max distro if
> there is a need for it.

A good reason would be to apply algorithmic (I don't mean FM) processes on the level of sound generation using oscillators and the like (think of Gendy or Vosim).

I have a ppc only external, programmed by a friend, that takes a frequency input like a phasor, determining the slope, but samples upon wrap on the right input a value that it use as the next wrap point. In short, where phasor always wraps at zero, this object will refresh its wrap point every cycle. There are two outlets, one giving the incrementing signal, the second the wrap point as a signal. Dividing the first by the second will result in a ramp from zero to one, of which the speed can be change sample accurate. Mattijs, I think you use windows, right? I might have the code somewhere, it is of any use, let me know.

_
johan

volker böhm's icon

hi all,

On 30 Jun 2007, at 20:15, Mattijs Kneppers wrote:

> . The only way would be to make a custom phasor~ with this
> behaviour built in.

have done that already, as mentioned in the other thread.
it's a pretty simple "surgical correction" of what i would suppose to
be the normal phasor~ code.
osx ub only, but source included.
i throw it in here for anybody who wants to try.

volker.

justin's icon

hi volker,

am i misunderstanding you, or are you saying you have coded a phasor object which changes speed on end of ramp? if so, please share! :o

thanx,

j

volker böhm's icon

On 01 Jul 2007, at 12:37, justin wrote:

>
> hi volker,
>
> am i misunderstanding you, or are you saying you have coded a
> phasor object which changes speed on end of ramp?

yes.

> if so, please share! :o

i did send a .zip to the mailing list with my last post, but
obviously the forum is neglecting (my) attachments.
sorry.

i don't have a website right now where i can deposit my stuff (am
fighting with myself to finally do this stupid work and set one up).
so in the meanwhile i thought about posting it to cycling/share.

if you are interested in a copy right now, i can send it to you
privately.

volker.

volker böhm's icon
Roman Thilenius's icon

> >Out of
> > curiosity, what is the particular need for 1 sample accuracy?
> > there is a need for it.

> A good reason would be to apply algorithmic (I don't mean FM) >processes on the level of sound generation using oscillators and >the like (think of Gendy or Vosim).

exactly, for example in most cases where wave~ is used with phasor~.

both these objects interpolate, and in the signal itself (the one which phasor~ produces) you can not see at which (nearest) sample phasor reaches its end.
but it is needed to know as soon as you want to change the loop points of phasor~ without getting an audio click.

-110

Stefan Tiedje's icon

Mattijs Kneppers schrieb:
> I'm working on a granular time stretcher/pitch shifter and I need the
> grains to update their play speed and length only when they've
> finished playing. The sound will distort if the updates are done
> mid-grain.

Just don't use one phasor, use two or line~ objects, as soon one is
ready, fire the second...
If your grain size is much smaller than the vector size, you'll need
accordingly more to switch between maybe use a poly~...

By the way, I am not sure if the distortion you expect is audible at
all, it would just change its pitch in the middle of the grain, versus
the next grain has a changed pitch. I doubt that this would make any
difference, the pitch change is just not as immediate as you want it in
theory...

Stefan

--
Stefan Tiedje------------x-------
--_____-----------|--------------
--(_|_ ----|-----|-----()-------
-- _|_)----|-----()--------------
----------()--------www.ccmix.com

Mattijs's icon

Quote: Stefan Tiedje wrote on Tue, 03 July 2007 19:47
----------------------------------------------------
> Mattijs Kneppers schrieb:
> > I'm working on a granular time stretcher/pitch shifter and I need the
> > grains to update their play speed and length only when they've
> > finished playing. The sound will distort if the updates are done
> > mid-grain.
>
> Just don't use one phasor, use two or line~ objects, as soon one is
> ready, fire the second...
> If your grain size is much smaller than the vector size, you'll need
> accordingly more to switch between maybe use a poly~...

I found that it is highly preferable to keep things in signal domain. I'm not working on a granular playback engine for all kinds of funny effects, this one is made especially for time/pitch modifications without artifacts. At the moment the quality is already as good as the ableton live / reaktor engine, something that as far as I know hasn't been achieved in max up to know.

>
> By the way, I am not sure if the distortion you expect is audible at
> all, it would just change its pitch in the middle of the grain, versus
> the next grain has a changed pitch. I doubt that this would make any
> difference, the pitch change is just not as immediate as you want it in
> theory...

It is definitly audible. When you change the grain size or playback speed without waiting until it stopped playing you'll get pitch artifacts.

I'll currently looking into whether I can make this granular max patch available for free.

Mattijs

micha's icon

hi mattijs,

i had the same problem (out of the same reasons - granular synthesis) sometime ago, resulting in a quick and dirty mxj~ external. it's not superdocumentated, but works, and has exact the function you need.

see:

(mode 7 should be the right one, with the modulator specifying the grainsize)

if you are finished, i am of course interested in your patch...

@volker
if you send me the source, i could do a windows build if you are interested...

micha

Mattijs's icon

Thanks micha,

This can indeed be quite useful. For me it is a bit too elaborate though, at the moment. A simple phasor~ that adapts its frequency only when it reached the top of its ramp would be ideal. Would be nice if cycling added it to the current phasor~..

Mattijs

micha's icon

too elaborate is a nice euphemism for badly documented ;-).

try this:

Max Patch
Copy patch and select New From Clipboard in Max.

Mattijs's icon

Ah! :)

It works nicely. I'll see if I can build this into the granular patch.

Thanks,
Mattijs

Quote: micha wrote on Wed, 04 July 2007 13:29
----------------------------------------------------
> too elaborate is a nice euphemism for badly documented ;-).
>
> try this:
>
> #P window setfont "Sans Serif" 9.;
> #P window linecount 4;
> #P comment 161 44 123 9109513 if you set the size to 10000 and then 50 , the 10sec ramp will finish first , before the new speed is set.;
> #P window linecount 1;
> #P comment 195 107 16 9109513 2.;
> #P message 196 130 18 9109513 50;
> #P message 162 130 33 9109513 10000;
> #P flonum 162 153 66 9 0 0 0 139 0 0 0 221 221 221 222 222 222 0 0 0;
> #P newex 162 175 43 9109513 sig~ 100;
> #P toggle 71 150 15 0;
> #P newex 71 175 33 9109513 sig~ 1;
> #P user scope~ 71 257 185 313 256 3 128 -1. 1. 0 0. 0 0. 63 188 217 99 99 99 0;
> #P newex 71 205 100 9109513 mxj~ trigger @mode 7;
> #P comment 89 150 40 9109513 on / off;
> #P comment 232 152 161 9109513 ms grainsize (1000/frequency);
> #P comment 161 107 16 9109513 1.;
> #P fasten 10 0 8 0 201 150 167 150;
> #P connect 9 0 8 0;
> #P connect 8 0 7 0;
> #P connect 7 0 3 1;
> #P connect 6 0 5 0;
> #P connect 5 0 3 0;
> #P connect 3 0 4 0;
> #P window clipboard copycount 13;
>
----------------------------------------------------

roger.carruthers's icon

I didn't like to say, but now you mention it...
This looks really interesting for something I'm
working on atm, but I couldn't quite get my head round
it from the .help patch - any more secret
documentation hidden away somewhere...? :-)
cheers
Roger

--- micha wrote:

>
> too elaborate is a nice euphemism for badly
> documented ;-).

micha's icon

secret documentation is the source code ;-). ok, let me give some quick explanation:

- left inlet trigger the ramp upon a click (or any signal above zero). the amplitude of the click can also have some influence on the ramp, for this see the table on the right. f.e. if the mode is set to 6, the amplitude of the click sets the depth/amplitude of the ramp. if the signal is no click but a rather steady one, the ramp will retrigger as soon as is has finished (like the normal phasor).
- all the settings are updated upon a finished ramp, if you don't want that, set the "update"-attribute to one.
- if you set the retrigger attribute to one, you can retrigger the phase with a click while it is active.
- the right inlet acts like a crossfade for the time values specified by the low and high boundarie.
- if you use a mode>4, you can specify the ramptime with the right inlet either in ms or seconds.

hope this is a little bit clearer now...

micha

Mattijs's icon

Writing good documentation is really hard, maybe even harder than writing the code. If you design the docs as if everyone that sees it has an attention disorder, you're coming close ;)

Mattijs

Quote: micha wrote on Wed, 04 July 2007 14:57
----------------------------------------------------
> secret documentation is the source code ;-). ok, let me give some quick explanation:
>
> - left inlet trigger the ramp upon a click (or any signal above zero). the amplitude of the click can also have some influence on the ramp, for this see the table on the right. f.e. if the mode is set to 6, the amplitude of the click sets the depth/amplitude of the ramp. if the signal is no click but a rather steady one, the ramp will retrigger as soon as is has finished (like the normal phasor).
> - all the settings are updated upon a finished ramp, if you don't want that, set the "update"-attribute to one.
> - if you set the retrigger attribute to one, you can retrigger the phase with a click while it is active.
> - the right inlet acts like a crossfade for the time values specified by the low and high boundarie.
> - if you use a mode>4, you can specify the ramptime with the right inlet either in ms or seconds.
>
> hope this is a little bit clearer now...
>
> micha
----------------------------------------------------

micha's icon

yepp, true words. perfect situation should be:

50% coding
50% documentation

but often writing the documentation is as boring as programming the userinterface...

Mattijs's icon

Quote: micha wrote on Wed, 04 July 2007 15:24
----------------------------------------------------
> but often writing the documentation is as boring as programming the userinterface...
>

That's why 'interface design' is a whole different field of practice. Pity this is not acknowledged by most software developers.

Anyways, we're getting seriously off-topic here.

..it's all the fault of this national tv film crew running up and down our studio today :p Let's see if I can get some nice max startup screen pics ;)

Mattijs

micha's icon

thanks to volker, i could make a port of the vb.phasor0 external. the windows version can be found here:

works well!

micha

volker böhm's icon
micha's icon

added it to the zip package...

Anthony Palomba's icon

Sweet! Thanks Volker and Micha, this is a very useful external.

Mark Durham's icon

Sorry for raising a really old thread, but what is the current thinking on this issue? I've been using vb.phasor0~ on my Mac with 6.1.4 but it doesn't seem to work on my pc. Is there a solution?

Mark Durham's icon

Just realised the vb.phasor0~ external does not work with 64bit 6.1.6 on PC. I guess I can install the latest 32bit. Would be nice if the vanilla phasor~ had this capability built in.

Dave Mollen's icon
Max Patch
Copy patch and select New From Clipboard in Max.

I tried to make a phasor like this in gen~ a while back. It doesn't respond well to negative frequencies though. Maybe you can hack it or make a different one yourself if you own gen. Or maybe you can find another gen~ solution floating around the forum.

Dave Mollen's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Oh, wait. This might be better.