Page 1 of 1

Need some help with this Code

PostPosted: Fri Oct 28, 2016 5:20 am
by Father
Hi
I was analyzing some parts of a compressor. I need some help understanding it so maybe i could do it in C++.
Maybe someone can answer these questions for me.
a) Whats the goal with the 'Level' module (inside Transfer)? Whats happening in stage 0 and 2?
b) Can't we do all the 'Transfer' module all in green? After all the output is a float array.
c) And if you have experience maybe some helpers with the actual codes.
Thanks.

Re: Need some help with this Code

PostPosted: Fri Oct 28, 2016 11:00 am
by TheOm
Father wrote:a) Whats the goal with the 'Level' module (inside Transfer)? Whats happening in stage 0 and 2?

It's just a linear ramp from some start level (-96dB) that reaches a target level (0dB) after 2048 samples.
stage 0 initializes the accumulator variable "count" with the start level.
stage 2 just adds the precalculated value "add" to the accumulator each sample
Father wrote:b) Can't we do all the 'Transfer' module all in green? After all the output is a float array.

Yes it could be done in green or ruby.

Re: Need some help with this Code

PostPosted: Fri Oct 28, 2016 3:39 pm
by Father
Hey TheOm
Correct me if i'm wrong, stage 2 (Count = Count+add) is being called for each sample, so its a loop like this:
Code: Select all
count = init;
for (int i=0; i<Sample_Rate; i++)
output_array[i] = count+add;

At the end the 'Analyser' prime takes 2048 samples from that. So we need to use a interpolate function to resample it to a new array with a size of 2048.
My confusion is about the stream code. How many times does 'Count = Count+add' is being executed? Sample Rate right?
If we want to do the loop for 2048 times, do we need to change the 'add' value too?

Re: Need some help with this Code

PostPosted: Fri Oct 28, 2016 7:09 pm
by TheOm
That's not quite correct. The sample rate is not involved at all actually.

First stage 0 is executed exactly once.
Then stage 2 is executed 2048 times (or however much you specified on the Analyzer prim).

This would be the analogous C code:
Code: Select all
float count = init;
for(int i = 0; i < 2048; i++) {
    output[i] = count;
    count += add;
}

Re: Need some help with this Code [solved]

PostPosted: Fri Oct 28, 2016 9:42 pm
by Father
TheOm wrote:That's not quite correct. The sample rate is not involved at all actually.
First stage 0 is executed exactly once.
Then stage 2 is executed 2048 times (or however much you specified on the Analyzer prim).

Oh i get it now. Thanks!
Now about the read out module.
read.jpg
read.jpg (36.97 KiB) Viewed 31141 times

I don't have the original dsp code for the part that produces the IndexA, IndexB and Modulus. from assembly code i gather this:
Code: Select all
streamin base; streamout indexA; streamout indexB; streamout modulus;
intindex = whatever happens to(base-0.5);
indexA = intindex;
indexB= indexA+1;
modulus = base-intindex;

that 'whatever happens' i didn't get was this part:
Code: Select all
movaps smIntVarTemp,xmm0;
fld smIntVarTemp[0];
frndint;
fstp smIntVarTemp[0];
fld smIntVarTemp[1];
frndint;
fstp smIntVarTemp[1];
fld smIntVarTemp[2];
frndint;
fstp smIntVarTemp[2];
fld smIntVarTemp[3];
frndint;
fstp smIntVarTemp[3];
movaps xmm0,smIntVarTemp;

What happens here?
There are some crossing channels and stuff like that i don't understand exactly. Some seem unnecessary..
read2.jpg
read2.jpg (45.16 KiB) Viewed 31141 times

read3.jpg
read3.jpg (62.56 KiB) Viewed 31141 times

Re: Need some help with this Code

PostPosted: Sat Oct 29, 2016 2:20 pm
by TheOm
That readout module is a simple linear interpolation table lookup module.
Father wrote:that 'whatever happens' i didn't get was this part:

Code: Select all
movaps smIntVarTemp,xmm0;
fld smIntVarTemp[0];
frndint;
fstp smIntVarTemp[0];
fld smIntVarTemp[1];
frndint;
fstp smIntVarTemp[1];
fld smIntVarTemp[2];
frndint;
fstp smIntVarTemp[2];
fld smIntVarTemp[3];
frndint;
fstp smIntVarTemp[3];
movaps xmm0,smIntVarTemp;


What happens here?

This is the old (pre SSE2) way of flooring an sse register. It floors the 4 floats seperately on the x87 float stack.
This is inefficient. Today you would just do
Code: Select all
cvtps2dq xmm0, xmm0
cvtdq2ps xmm0, xmm0

The code looks like it comes completely unaltered from the output of a DSPCode Module.

The unpack-pack business should better be done with shufps instructions.
It's done to get the value in the table at IndexA into the lower 2 floats and the value at IndexB(which is just IndexA + 1) into the upper two floats.
Then the linear interpolation between the values is done in the X-fade module.

Re: Need some help with this Code

PostPosted: Sat Oct 29, 2016 10:58 pm
by Father
Ok let me see if i got it right, if that means just rounding to int basically we have to this in read out:
Code: Select all
IndexA = RoundToInt[(Base*2048+1)-0.5];
IndexB = IndexA+1;
Modulu = Base - IndexA;
Readout = ArrayFromTransfer[Index a] * (1-Modulu) + ArrayFromTransfer[Index b] * Modulu

I'm guessing 'wave read' prim does something like index=max(input_index, array_size) so we also need a max(base,1) at the beginning.

Re: Need some help with this Code

PostPosted: Sun Oct 30, 2016 6:38 pm
by TheOm
Yes that's almost correct. Just a small mistake.
Code: Select all
temp = (Base*2048+1)
IndexA = RoundToInt[temp-0.5];
IndexB = IndexA+1;
Modulu = temp - IndexA;
Readout = ArrayFromTransfer[IndexA] * (1-Modulu) + ArrayFromTransfer[IndexB] * Modulu


Father wrote:I'm guessing 'wave read' prim does something like index=max(input_index, array_size) so we also need a max(base,1) at the beginning.

I think you mean index=min(input_index, array_size - 1) and min(base, 1.0).
However, even if you clamp base to be less or equal to 1.0 the highest index that the code tries to access would still be 2048 + 1 + 1 (=2050).
I'm not sure what the point of the "+ 1" in "Base*2048+1" is to be honest.

Re: Compressor - Need some help with the Code

PostPosted: Mon Oct 31, 2016 11:29 pm
by Father
TheOm wrote:Yes that's almost correct. Just a small mistake.

You are right. I make those kind of mistakes all the time.
I finished rewriting the codes and its kind of working. There are few bugs crashing it, which i have to find.
After that I'll check if the outputs from both plug-ins are close enough.
Thanks so much for the help TheOm, appreciate it.