From the original SynthMaker forum (2004–2014), with its members’ names and dates.
infuzion ·
I did a bit more hacking on malc's ASM de-zipper. Without the hop(), this new version is about 5 cycles faster on my C2D, but maybe 1.1 cycle slower on my AMD64, & .2 cycles slower than his original. This new one has more hand-interleaving to take advantage of (expecting) C2D to execute add & compare ops at the same time, executing up to 3 movaps at once, & a trick with the pre-loading the out into xmm6:
streamin in;streamout out;
float in1=0;float cnt=2048;
float step=0;float F1=1;
float F16=16;float F0=0;
float F2048=2048;
movaps xmm6,out;
mov eax,ecx;and eax,127;cmp eax,0;jnz endCalcStep;
// Calculate cnt
movaps xmm0,in1;
cmpps xmm0,in,0;
movaps xmm2,cnt;
movaps xmm1,xmm2; //swap
movaps xmm7,F0;
cmpps xmm2,F2048,0;
orps xmm0,xmm2;
// Add step
addps xmm6,step;
movaps out,xmm6;
Could someone please double-check the output values?
Note: I don't think I'll ever do this much hacking inside a hop() again; not worth it. The only thing makes this worth it to me is that I could have this code 64+ times in my VSTi. After removing the obvious extra movaps & the typical quick-fixes (which do make a difference inside a longer hop()), an extra 1 minute max of special hacking inside a hop is more than enough.
Zynewave ·
infuzion wrote: I did a bit more hacking on malc's ASM de-zipper.
Thanks for your efforts. I know malc is still working on the de-zipper. I got an email from him, where he presented the excellent idea that the hop should be kept constant, and only the glide period should be varied in 128 sample steps, to compensate for the different sample rates. That's sufficiently precise.
Here's a part of my reply to him:
My main concern was the factor 2 involved with 88.2/96 kHz double samplerates. While we're at it: Why not adjust the glide periods so that it is closer to a more sensible value such as 50 ms. Looks nicer if you want to write the glide time in the component reference pdf. That results in 2176 for 44.1 (49.3ms) and 2432 for 48.0 (50.7 ms).
I've also done some thinking on the de-zipper code. It struck me that the step calculation can become inaccurate for larger glide periods, due to the limited float precision. This means that the gliding can over/undershoot the target value. So, since the divide is performed in each hop block anyway I figured it could just as well recalc a more precise step value based on the decreasing glide period. It turned out to be a simpler and more efficient implementation, involving fewer compares. I was kicking myself for not having thought of this solution from the beginning:
hop(128)
{
// Use max(,1) to avoid runaway cnt and division by zero in step calc.
cnt = max(cnt - 128 + (in1 != in)&(cnt>0)&(glidePeriodPlus128-cnt), 1);
step = (cnt>1)&((in - out) / cnt);
// Copy in to out when not stepping, to compensate
// for any rounding errors in step additions.
out = (step!=0)&out + (step==0)∈
in1 = in;
}
out = out + step;
aliasant ·
Infuzion said:
Could someone please double-check the output values?
I checked and it seems to output the values correct.
I also checked with a frequency graph on all the different DeZip versions and they all shows up on the low end..... except Zynewaves new thing.
This one looks like something else.
Edit: Looking at Zynewaves new thing I noticed that the glideperiod needs to get up above 1024. Then it starts to sound good.
Zynewave ·
aliasant wrote: Edit: Looking at Zynewaves new thing I noticed that the glideperiod needs to get up above 1024. Then it starts to sound good.
You need to set the glideperiod input to 2048+128 to make it behave like the earlier de-zipper versions.
aliasant ·
Zynewave wrote:
aliasant wrote: Edit: Looking at Zynewaves new thing I noticed that the glideperiod needs to get up above 1024. Then it starts to sound good.
You need to set the glideperiod input to 2048+128 to make it behave like the earlier de-zipper versions.
Yes. I see that now. Cool. Experimenting with it. Sending a LF squarewave thru it and other stupid things =)
infuzion ·
Zynewave wrote: It struck me that the step calculation can become inaccurate for larger glide periods, due to the limited float precision. ...I was kicking myself for not having thought of this solution from the beginning:
"limited float precision"... is that another vote for SSE2? 😉
Sometimes it takes a while for me to figure out the best (often simplest) solution. :/
aliasant wrote: Infuzion said:
Could someone please double-check the output values?
I checked and it seems to output the values correct. I also checked with a frequency graph on all the different DeZip versions and they all shows up on the low end..... except Zynewaves new thing.
Thanks fro the help aliasant... is malc's/mine act like a filter?
aliasant ·
This is me running a 1kHz Saw thru the dezipper so yes. It acts like a filter of some kind.
Andrew J ·
Well that is what a de-zipper is for! You filter out higher frequencies so that you don't have big/fast changes (i.e. pops).
oddson ·
Here's one way to smooth and still avoid denormals but it won't work on data with a broad range of scale:
streamin x;
streamout y;
hop(32){
y = y + ((x<y & -2) + 1) * 0.001;
}
It moves in set step sizes and therefore avoids denormal multiplication.
It may not be appropriate for the default dezipper code because of the scale problem but if you work only with normalized parameters it might be right for someone with dozens of dezippers in their projects (and you could pick your own hop and delta values).
The existing timer mechanism could still be used to flip to the exact value after the code has got you into the ballpark.
malc ·
So based on Frits' great idea of using a fixed glide time and the code he presented earlier, here's what IMHO looks to be a good candidate for the dezipper primitive:
Download Latest Dezipper
The code is here. If you fancy waving your magic wand over it infuzion please do.
The glidePeriodPlus128 input is calculated in a green module by using sample rate and a fixed (but user defineable) glide period in millisecs.
Zynewave ·
malc wrote: The glidePeriodPlus128 input is calculated in a green module by using sample rate and a fixed (but user defineable) glide period in millisecs.
I've already notified malc by email: There's a small bug in the green module. It should add 128 to the final int output, due to the way that "cnt" is calculated in the code.
infuzion ·
Zynewave wrote:
malc wrote: The glidePeriodPlus128 input is calculated in a green module by using sample rate and a fixed (but user defineable) glide period in millisecs.
I've already notified malc by email: There's a small bug in the green module. It should add 128 to the final int output, due to the way that "cnt" is calculated in the code.
Yea, I was wondering where the +128 of the glidePeriodPlus128 went to? 🙂
Might be a day or 2 before I can really study this; I just got a 20% pay cut, so I think I'll job-hunt in the morning rather than SM-hack; depends how early I can wake up.
infuzion ·
malc wrote: The code is here. If you fancy waving your magic wand over it infuzion please do.
OK, I couldn't sleep... so here it is:
http://shup.com/Shup/33660/new-dezipper ... _saved.osm
// Remember previous in
// movaps xmm4,in;
movaps in1,xmm4;
endCalcStep:
// Add step
//movaps xmm7,out before hop
addps xmm7,step;
movaps out,xmm7;
I commented out a few commands so you know we don't need them. Considering the hop, I saved an average of 0.0625 cycles!! Without the hop, it would have been about 8 cycle-savings on both my AMD64 & C2D, which is decent. Most of that savings is from pre-loading in & out values in a xmm & using that xmm. Using an xmm for F0 (=0) was slower.
I added the 128 in the green, & did a tad of primitive reduction there.... I don't think using a Int in a Float Divide would matter speed wise for a call-once-on-load routine?
If someone can test output please? 😇 (remember malc's may not have the green +128 just before output)
malc ·
Works well here inf, thanks for looking at it!
I completely forgot to add the 128 after Zynewave pointed it out 😊
Well I think I can make a primitive from this now. If anyone finds any other issues let me know.
Thanks to everyone - top effort!
Zynewave ·
infuzion wrote: If someone can test output please? 😇 (remember malc's may not have the green +128 just before output)
Works fine here. Thanks.
I think this thing is ready for mass production!
Wrote something here? To have a post removed or your name hidden, write to [email protected].