I have a problem, that is partly of my own making and need to air this on the list for advice. This isn't a rant, just a frustrating situation.
As some of you know I have been working on a textbook for Pd for some time. In the final stages and adding the practical exercises and the problem is this:
The book is completely for vanilla Pd to keep things simple and I really don't want to change this.
I have three crucial exercises that use [delta~]
[delta~] does not exist in vanilla Pd
[delta~] must be recreated _EXACTLY_ as the external behaves.
It IS possible to recreate [delta~] exactly using [z~]
[z~] does not exist in vanilla
It is not, as far as I can see, possible to emulate [delta~] using [rzero~] or any other signal domain method, in a way that doesn't confuse the hell out of the reader or provide unsatisfactory results.
I am left with these options:
Drop three of the most interesting exercises from the textbook.
Change my policy and make the textbook require pd-extended on account of
only _one_ object!
Find a vanilla replacement for [delta~] that is simple. (less than three objects)
Convince Miller to include [delta~] in vanilla
Convince Miller to include [z~] in vanilla
To the list: I'm hoping some bright spark will solve (3). Be warned, it isn't as simple as it seems, AFAICS. [rzero~] should provide a differentiator response in theory. In practice dealing with the offsets and scales ruins the whole show and leads to over-complex and unstable patches. Using [biquad~] is extremely confusing to most readers and I don't want to do this. You cannot obtain a single sample delay using [delwrite~] as far as I know, if you can it certainly means [samplerate~] must be added to all patches to make sure they run at different sr, which is mucho annoying.
To Miller: Please consider admitting [z~] or [delta~] (I actually prefer the former because it is more educational to see differentiator built from sample delay) into the vanilla distro. This would need to be time for release quite soon. I'm sure it would greatly benefit Pd to do this.
Best regards 2 all,
Andy
I'd say, you can't go wrong with fexpr~. Works for any kind of discrete time difference equations & has many amazing /creative uses.
Chuck
On Thu, Mar 20, 2008 at 6:40 PM, Andy Farnell padawan12@obiwannabe.co.uk wrote:
I have a problem, that is partly of my own making and need to air this on the list for advice. This isn't a rant, just a frustrating situation.
As some of you know I have been working on a textbook for Pd for some time. In the final stages and adding the practical exercises and the problem is this:
The book is completely for vanilla Pd to keep things simple and I really don't want to change this.
I have three crucial exercises that use [delta~]
[delta~] does not exist in vanilla Pd
[delta~] must be recreated _EXACTLY_ as the external behaves.
It IS possible to recreate [delta~] exactly using [z~]
[z~] does not exist in vanilla
It is not, as far as I can see, possible to emulate [delta~] using [rzero~] or any other signal domain method, in a way that doesn't confuse the hell out of the reader or provide unsatisfactory results.
I am left with these options:
Drop three of the most interesting exercises from the textbook.
Change my policy and make the textbook require pd-extended on account of
only _one_ object!
Find a vanilla replacement for [delta~] that is simple. (less than three objects)
Convince Miller to include [delta~] in vanilla
Convince Miller to include [z~] in vanilla
To the list: I'm hoping some bright spark will solve (3). Be warned, it isn't as simple as it seems, AFAICS. [rzero~] should provide a differentiator response in theory. In practice dealing with the offsets and scales ruins the whole show and leads to over-complex and unstable patches. Using [biquad~] is extremely confusing to most readers and I don't want to do this. You cannot obtain a single sample delay using [delwrite~] as far as I know, if you can it certainly means [samplerate~] must be added to all patches to make sure they run at different sr, which is mucho annoying.
To Miller: Please consider admitting [z~] or [delta~] (I actually prefer the former because it is more educational to see differentiator built from sample delay) into the vanilla distro. This would need to be time for release quite soon. I'm sure it would greatly benefit Pd to do this.
Best regards 2 all,
Andy
-- Use the source
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Thanks guys,
Marius and Charles, you've both suggested using [fexpr~] and I think I might reconsider introducing this object.
So far the aim has been to keep the object set very small and show how things are built from primitives, but all said this makes a good example of where it can be a Swiss army knife for problems, and it does satisfy my "one or two object" constraint.
Use the source
Hi Andy
If I'm doing it for myself, I run sig~ into rzero~ 1. But for visitors I'd make a table, loadbang a 1 into the first element (send the message 0 1) and use tabplay~ to get it as an audio signal.
cheers M
On Fri, Mar 21, 2008 at 01:32:27AM +0000, Andy Farnell wrote:
Thanks guys,
Marius and Charles, you've both suggested using [fexpr~] and I think I might reconsider introducing this object.
So far the aim has been to keep the object set very small and show how things are built from primitives, but all said this makes a good example of where it can be a Swiss army knife for problems, and it does satisfy my "one or two object" constraint.
a.
Use the source
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Hallo, Miller Puckette hat gesagt: // Miller Puckette wrote:
If I'm doing it for myself, I run sig~ into rzero~ 1.
For all I know, [rzero~ 1] is the same as [delta~]: Both compute the difference between the current and the previous sample. Or am I missing something? Some time ago I added this to the CVS (now SVN) as abstractions/purepd/delta~.pd
Frank Barknecht _ ______footils.org__
I've put an example here so you can hear that they are not the same
These differences are important.
[rzero~] and [delwrite~] methods come out louder and with apparently less dynamics. Using [z~] and [fexpr~] I get much closer results to [delta~], more detail in the poured water sound.
As I said I needed an _EXACT_ replacement for [delta~] for other patches too, which are much more sensitive to the differences. (so this is all about how it behaves in practice not in theory :)
I'm really not sure why this happens. Suppose I should hook them up to a graph and read sample by sample to see what's really going on. But, it doesn't help me because without changing the source the fact is
[delta~] is the same as [z~] [z~] is as good as [fexpr~] [rzero~ 1] and [delwrite~] are not the same
Unless... If you hear no difference it could be an architecture thing... Tell me what machines you're running on, I wonder if that has anything to do with it?
cheers,
Andy
On Fri, 21 Mar 2008 10:47:44 +0100 Frank Barknecht fbar@footils.org wrote:
Hallo, Miller Puckette hat gesagt: // Miller Puckette wrote:
If I'm doing it for myself, I run sig~ into rzero~ 1.
For all I know, [rzero~ 1] is the same as [delta~]: Both compute the difference between the current and the previous sample. Or am I missing something? Some time ago I added this to the CVS (now SVN) as abstractions/purepd/delta~.pd
Ciao
Frank Barknecht _ ______footils.org__
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Hi,
Using the source:
pd/src/d_filter.c/sigrzero_perform()
t_sample next = *in1++;
t_sample coef = *in2++;
*out++ = next - coef * last;
last = next;
pure-data/externals/cxc/delta~.c/delta_perform()
float f = *(in++);
// *out++ = (f > 0 ? f : -f);
*out++ = (f > x->x_last ? fabs(f - x->x_last) : -fabs(f -
x->x_last)); x->x_last = f;
which mathematically translates thus:
f>l ? |f-l| : -|f-l|
== f>l ? f-l : -|f-l| (f>l => f-l > 0 => |f-l| == f-l) == f>l ? f-l : f-l (f<=l => f-l <= 0 => |f-l| == l-f) == f-l
which is entirely equivalent to rzero~ when coef is 1.
BUT: IEEE floating point doesn't respect normal mathematical rules, so weird stuff is probably going on in delta~...
Hope this helps, personally I wouldn't want to use delta~ given the weirdness of its code (eg, using float instead of t_sample, using comparisons, using fabs() (which converts to double and back, iirc), etc) but there might be some reason for it that I can't fathom, similar to Miller's tabfudge stuff in phasor~ making it 5x-10x faster than my naive implementation.
Claude
Andy Farnell wrote:
I've put an example here so you can hear that they are not the same
These differences are important.
[rzero~] and [delwrite~] methods come out louder and with apparently less dynamics. Using [z~] and [fexpr~] I get much closer results to [delta~], more detail in the poured water sound.
As I said I needed an _EXACT_ replacement for [delta~] for other patches too, which are much more sensitive to the differences. (so this is all about how it behaves in practice not in theory :)
I'm really not sure why this happens. Suppose I should hook them up to a graph and read sample by sample to see what's really going on. But, it doesn't help me because without changing the source the fact is
[delta~] is the same as [z~] [z~] is as good as [fexpr~] [rzero~ 1] and [delwrite~] are not the same
Unless... If you hear no difference it could be an architecture thing... Tell me what machines you're running on, I wonder if that has anything to do with it?
cheers,
Andy
On Fri, 21 Mar 2008 10:47:44 +0100 Frank Barknecht fbar@footils.org wrote:
Hallo, Miller Puckette hat gesagt: // Miller Puckette wrote:
If I'm doing it for myself, I run sig~ into rzero~ 1.
For all I know, [rzero~ 1] is the same as [delta~]: Both compute the difference between the current and the previous sample. Or am I missing something? Some time ago I added this to the CVS (now SVN) as abstractions/purepd/delta~.pd
Ciao
Frank Barknecht _ ______footils.org__
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Hallo, Claude Heiland-Allen hat gesagt: // Claude Heiland-Allen wrote:
Hi,
Using the source:
pd/src/d_filter.c/sigrzero_perform()
t_sample next = *in1++; t_sample coef = *in2++; *out++ = next - coef * last; last = next;
pure-data/externals/cxc/delta~.c/delta_perform()
float f = *(in++); // *out++ = (f > 0 ? f : -f); *out++ = (f > x->x_last ? fabs(f - x->x_last) : -fabs(f -
x->x_last)); x->x_last = f;
Oops, another nameclash: I wasn't aware of delta~ from cxc and was referring to delta~ from Cyclone. Anyway, seems they do the same in the end.
Frank
hmm, first, i think you need [swap 1000] instead of [swap 1], because you want to delay by 1000/44100 milliseconds and not 1/44100 milliseconds. and then, there is this problem that delwrite~/delread~ is sensitive to the order of creation. I attached a small patch, you can see that a delwrite/read that is created before the line~ object works similar to z~, wheras the delwrite/delread that is created after the line~ is one vector behind. I attach a patch for clarification... marius.
Andy Farnell wrote:
I've put an example here so you can hear that they are not the same
These differences are important.
[rzero~] and [delwrite~] methods come out louder and with apparently less dynamics. Using [z~] and [fexpr~] I get much closer results to [delta~], more detail in the poured water sound.
As I said I needed an _EXACT_ replacement for [delta~] for other patches too, which are much more sensitive to the differences. (so this is all about how it behaves in practice not in theory :)
I'm really not sure why this happens. Suppose I should hook them up to a graph and read sample by sample to see what's really going on. But, it doesn't help me because without changing the source the fact is
[delta~] is the same as [z~] [z~] is as good as [fexpr~] [rzero~ 1] and [delwrite~] are not the same
Unless... If you hear no difference it could be an architecture thing... Tell me what machines you're running on, I wonder if that has anything to do with it?
cheers,
Andy
On Fri, 21 Mar 2008 10:47:44 +0100 Frank Barknecht fbar@footils.org wrote:
Hallo, Miller Puckette hat gesagt: // Miller Puckette wrote:
If I'm doing it for myself, I run sig~ into rzero~ 1.
For all I know, [rzero~ 1] is the same as [delta~]: Both compute the difference between the current and the previous sample. Or am I missing something? Some time ago I added this to the CVS (now SVN) as abstractions/purepd/delta~.pd
Ciao
Frank Barknecht _ ______footils.org__
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
#N canvas 347 124 927 603 10; #X text 50 457 order of creation; #X obj 119 263 cnv 15 100 150 empty empty empty 20 12 0 14 -233017 -66577 0; #X obj 267 135 cnv 15 200 300 empty empty empty 20 12 0 14 -233017 -66577 0; #X obj 553 120 cnv 15 200 300 empty empty empty 20 12 0 14 -233017 -66577 0; #X obj 600 186 samplerate~; #X obj 600 257 /; #X obj 600 205 t b f; #X msg 620 163 bang; #X obj 600 142 loadbang; #X obj 127 367 print~ del; #X msg 162 12 bang; #X obj 128 296 delwrite~ d 10; #X msg 600 229 1000; #X obj 128 328 delread~ d; #X obj 305 227 line~; #X obj 305 288 z~; #X obj 305 365 print~ z; #X msg 305 199 1 , 100 10000; #X obj 626 349 delread~ d; #X obj 626 317 delwrite~ after 10; #X obj 626 389 print~ delafter; #X obj 162 37 t b b b b; #X text 150 438 first; #X text 292 450 second; #X text 622 445 third; #X connect 4 0 6 0; #X connect 5 0 13 0; #X connect 5 0 18 0; #X connect 6 0 12 0; #X connect 6 1 5 1; #X connect 7 0 4 0; #X connect 8 0 4 0; #X connect 10 0 21 0; #X connect 12 0 5 0; #X connect 13 0 9 0; #X connect 14 0 15 0; #X connect 14 0 11 0; #X connect 14 0 19 0; #X connect 15 0 16 0; #X connect 17 0 14 0; #X connect 18 0 20 0; #X connect 21 0 17 0; #X connect 21 1 20 0; #X connect 21 2 16 0; #X connect 21 3 9 0;
On Fri, 21 Mar 2008 18:38:19 -0400 marius schebella marius.schebella@gmail.com wrote:
want to delay by 1000/44100 milliseconds and not 1/44100 milliseconds.
Ah yes, sorry that's a typo as I rushed those examples together.
and then, there is this problem that delwrite~/delread~ is sensitive to the order of creation. I attached a small patch, you can see that a delwrite/read that is created before the line~ object works similar to z~, wheras the delwrite/delread that is created after the line~ is one vector behind.
This is much more like it, good thinking Marius. One block of difference would explain the magnitude discrepency. And that's the sort of thing I really want to avoid having to explain in the text.
Claude also pointed out a possible sign discrepency around zero for [delta~] which uses IEEE floats instead of t_sample. This one is most dangerous if the object is followed by a [wrap~]
Clearly these methods are subtley different and if you're using them in a sensitive context the effects are important.
I'm going to stick with your first suggestion of [fexpr~], because it works well, and you've made me realise it's a useful object to introduce.
cheers,
Andy
On Fri, 2008-03-21 at 18:38 -0400, marius schebella wrote:
hmm, first, i think you need [swap 1000] instead of [swap 1], because you want to delay by 1000/44100 milliseconds and not 1/44100 milliseconds. and then, there is this problem that delwrite~/delread~ is sensitive to the order of creation. I attached a small patch, you can see that a delwrite/read that is created before the line~ object works similar to z~, wheras the delwrite/delread that is created after the line~ is one vector behind. I attach a patch for clarification... marius.
Andy Farnell wrote:
[rzero~] and [delwrite~] methods come out louder and with apparently less dynamics. Using [z~] and [fexpr~] I get much closer results to [delta~], more detail in the poured water sound.
let me mention a clean way to solve the issue with a block delay without having to care about creation order. have a look at the doc:
3.audio.examples/G05.execution.oder.pd
roman
___________________________________________________________ Der frühe Vogel fängt den Wurm. Hier gelangen Sie zum neuen Yahoo! Mail: http://mail.yahoo.de
On Sat, 2008-03-22 at 13:34 +0100, Roman Haefeli wrote:
On Fri, 2008-03-21 at 18:38 -0400, marius schebella wrote:
hmm, first, i think you need [swap 1000] instead of [swap 1], because you want to delay by 1000/44100 milliseconds and not 1/44100 milliseconds. and then, there is this problem that delwrite~/delread~ is sensitive to the order of creation. I attached a small patch, you can see that a delwrite/read that is created before the line~ object works similar to z~, wheras the delwrite/delread that is created after the line~ is one vector behind. I attach a patch for clarification... marius.
Andy Farnell wrote:
[rzero~] and [delwrite~] methods come out louder and with apparently less dynamics. Using [z~] and [fexpr~] I get much closer results to [delta~], more detail in the poured water sound.
let me mention a clean way to solve the issue with a block delay without having to care about creation order. have a look at the doc:
3.audio.examples/G05.execution.oder.pd
Yes! Andy: if you can get delread~/delwrite~ to do what you want using the G05 style of execution order forcing, wouldn't that be a cleaner solution for your book? I mean this from the point of view that the expr~ family are really externals. I also think that fexpr~'s syntax is quite confusing, and might interrupt the flow of your discussion if you are the sound design concepts are to be in the 'foreground' rather than learning how to use the objects... or maybe that's just my personal (anti-expr) taste coming through ;-)
Jamie
I have to say that the problem is not that the delread~ was created after the delwrite~, but that the delwrite~ was created after the line~... as soon as delwrite~ is created after line~ it already *writes* (!) with a delay of one sampleblock. it might be true that delread is working correctly in relation to delwrite (which means it is also one sampleblock delayed), but actually both of them are delayed. the solution with subpatches only helps, if they are connected with a signal inlet~/outlet~. see attached patch. (see also the additional questions in the patch - what happens if you create a feedback with subpatches, are we then back to "order of creation"??)
delwrite~ and delread~ can produce a big mess. maybe there is a better way to "sort" delaylines? I think it is a bug that delwrite~ can be one vector late. and I also think it is also a bug that delread~ can be one vector behind the correlating delwrite~. otoh, I have no solution what to do with signal feedback loops then. maybe delread~ should accept a sorting message? can Pd reorder the signal chain at all?? actually I see no way to bring the for humans obvious logic into the pd signal chain...
marius.
Roman Haefeli wrote:
On Fri, 2008-03-21 at 18:38 -0400, marius schebella wrote:
hmm, first, i think you need [swap 1000] instead of [swap 1], because you want to delay by 1000/44100 milliseconds and not 1/44100 milliseconds. and then, there is this problem that delwrite~/delread~ is sensitive to the order of creation. I attached a small patch, you can see that a delwrite/read that is created before the line~ object works similar to z~, wheras the delwrite/delread that is created after the line~ is one vector behind. I attach a patch for clarification... marius.
Andy Farnell wrote:
[rzero~] and [delwrite~] methods come out louder and with apparently less dynamics. Using [z~] and [fexpr~] I get much closer results to [delta~], more detail in the poured water sound.
let me mention a clean way to solve the issue with a block delay without having to care about creation order. have a look at the doc:
3.audio.examples/G05.execution.oder.pd
roman
___________________________________________________________ Der frühe Vogel fängt den Wurm. Hier gelangen Sie zum neuen Yahoo! Mail: http://mail.yahoo.de
#N canvas 369 121 927 603 10; #X obj 433 120 cnv 15 200 300 empty empty empty 20 12 0 14 -233017 -66577 0; #X msg 570 143 bang; #N canvas 73 80 496 339 delay-writer 0; #X obj 96 107 inlet~; #X obj 96 181 outlet~; #X obj 116 144 delwrite~ $0-a 10; #X connect 0 0 1 0; #X connect 0 0 2 0; #X restore 442 281 pd delay-writer; #X obj 147 135 cnv 15 200 300 empty empty empty 20 12 0 14 -233017 -66577 0; #X obj 550 166 samplerate~; #X obj 550 237 /; #X obj 550 185 t b f; #X obj 550 122 loadbang; #X msg 219 87 bang; #X msg 550 209 1000; #X obj 185 227 line~; #X obj 185 288 z~; #X obj 185 365 print~ z; #X msg 185 199 1 , 100 10000; #X obj 219 112 t b b b b; #N canvas 38 479 463 341 delay-reader 0; #X obj 159 297 outlet~; #X obj 169 249 delread~ $0-a; #X obj 179 211 inlet; #X obj 76 141 inlet~; #X text 38 93 need to have a signal inlet , and that inlet has to be connected from outside (not inside...); #X connect 1 0 0 0; #X connect 2 0 1 0; #X restore 442 350 pd delay-reader; #X obj 442 380 print~ delafter2; #X text 454 310 <-- delete this and see that this will delay the delread~/delwrite~ by one vector.; #X text 217 60 trigger printout (turn audio on); #N canvas 365 143 633 335 another_question 0; #X text 94 71 and how do you solve the order in this case???; #N canvas 139 48 450 300 del1 0; #X obj 105 58 inlet~; #X obj 166 140 delwrite~ x; #X obj 105 184 outlet~; #X obj 166 100 delread~ z; #X connect 3 0 1 0; #X connect 3 0 2 0; #X restore 145 156 pd del1; #N canvas 139 48 450 300 del2 0; #X obj 105 58 inlet~; #X obj 105 184 outlet~; #X obj 166 110 delread~ x; #X obj 166 144 delwrite~ y; #X connect 2 0 1 0; #X connect 2 0 3 0; #X restore 252 187 pd del2; #N canvas 139 48 450 300 del3 0; #X obj 105 58 inlet~; #X obj 105 184 outlet~; #X obj 166 110 delread~ y; #X obj 166 144 delwrite~ z; #X connect 2 0 1 0; #X connect 2 0 3 0; #X restore 112 226 pd del3; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 1 0; #X restore 329 474 pd another_question; #X text 182 473 only for the brave -->; #X connect 1 0 4 0; #X connect 2 0 15 0; #X connect 4 0 6 0; #X connect 5 0 15 1; #X connect 6 0 9 0; #X connect 6 1 5 1; #X connect 7 0 4 0; #X connect 8 0 14 0; #X connect 9 0 5 0; #X connect 10 0 11 0; #X connect 10 0 2 0; #X connect 11 0 12 0; #X connect 13 0 10 0; #X connect 14 0 13 0; #X connect 14 2 12 0; #X connect 14 3 16 0; #X connect 15 0 16 0;
Hallo, marius schebella hat gesagt: // marius schebella wrote:
what happens if you create a feedback with subpatches, are we then back to "order of creation"??)
delwrite~/delread~ loops with feedback *always* have at least one block delay. That's a general issue with block-based, realtime synthesis systems. See the respective chapter(s) in Miller's book on recirculating delay lines for a full explanation.
Frank Barknecht
hello, i think it's quite simple to emulate z~ with a simple delread~ / delwrite~.
cyrille
Andy Farnell a écrit :
I have a problem, that is partly of my own making and need to air this on the list for advice. This isn't a rant, just a frustrating situation.
As some of you know I have been working on a textbook for Pd for some time. In the final stages and adding the practical exercises and the problem is this:
The book is completely for vanilla Pd to keep things simple and I really don't want to change this.
I have three crucial exercises that use [delta~]
[delta~] does not exist in vanilla Pd
[delta~] must be recreated _EXACTLY_ as the external behaves.
It IS possible to recreate [delta~] exactly using [z~]
[z~] does not exist in vanilla
It is not, as far as I can see, possible to emulate [delta~] using [rzero~] or any other signal domain method, in a way that doesn't confuse the hell out of the reader or provide unsatisfactory results.
I am left with these options:
Drop three of the most interesting exercises from the textbook.
Change my policy and make the textbook require pd-extended on account of
only _one_ object!
Find a vanilla replacement for [delta~] that is simple. (less than three objects)
Convince Miller to include [delta~] in vanilla
Convince Miller to include [z~] in vanilla
To the list: I'm hoping some bright spark will solve (3). Be warned, it isn't as simple as it seems, AFAICS. [rzero~] should provide a differentiator response in theory. In practice dealing with the offsets and scales ruins the whole show and leads to over-complex and unstable patches. Using [biquad~] is extremely confusing to most readers and I don't want to do this. You cannot obtain a single sample delay using [delwrite~] as far as I know, if you can it certainly means [samplerate~] must be added to all patches to make sure they run at different sr, which is mucho annoying.
To Miller: Please consider admitting [z~] or [delta~] (I actually prefer the former because it is more educational to see differentiator built from sample delay) into the vanilla distro. This would need to be time for release quite soon. I'm sure it would greatly benefit Pd to do this.
Best regards 2 all,
Andy
On Thu, 2008-03-20 at 23:40 +0000, Andy Farnell wrote:
You cannot obtain a single sample delay using [delwrite~] as far as I know, if you can it certainly means [samplerate~] must be added to all patches to make sure they run at different sr, which is mucho annoying.
yo.. it _is_ possible to use [delwrite~] and [delread~] to achieve exactly one sample delay. actually i don't follow your argument, that having to use a [samplerate~] to convert one sample length into ms should be such a problem. why not just making your own [z~] abstraction and use that inside your patches? i don't think, that it would make your examples less readable (except you want to generally avoid having to use abstractions).
though, i agree, that [z~] would be 'primitive enough' to have it included into pd-vanilla.
roman
___________________________________________________________ Der frühe Vogel fängt den Wurm. Hier gelangen Sie zum neuen Yahoo! Mail: http://mail.yahoo.de