Support

If you have a problem or need to report a bug please email : support@dsprobotics.com

There are 3 sections to this support area:

DOWNLOADS: access to product manuals, support files and drivers

HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects

USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here

Need some help with this Code

DSP related issues, mathematics, processing and techniques

Need some help with this Code

Postby Father » Fri Oct 28, 2016 5:20 am

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.
Attachments
level.fsm
(3.95 KiB) Downloaded 430 times
Father
 
Posts: 177
Joined: Thu Jan 09, 2014 5:48 pm

Re: Need some help with this Code

Postby TheOm » Fri Oct 28, 2016 11:00 am

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.
TheOm
 
Posts: 101
Joined: Tue Jan 28, 2014 7:35 pm
Location: Germany

Re: Need some help with this Code

Postby Father » Fri Oct 28, 2016 3:39 pm

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?
Father
 
Posts: 177
Joined: Thu Jan 09, 2014 5:48 pm

Re: Need some help with this Code

Postby TheOm » Fri Oct 28, 2016 7:09 pm

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;
}
TheOm
 
Posts: 101
Joined: Tue Jan 28, 2014 7:35 pm
Location: Germany

Re: Need some help with this Code [solved]

Postby Father » Fri Oct 28, 2016 9:42 pm

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 18799 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 18799 times

read3.jpg
read3.jpg (62.56 KiB) Viewed 18799 times
Father
 
Posts: 177
Joined: Thu Jan 09, 2014 5:48 pm

Re: Need some help with this Code

Postby TheOm » Sat Oct 29, 2016 2:20 pm

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.
TheOm
 
Posts: 101
Joined: Tue Jan 28, 2014 7:35 pm
Location: Germany

Re: Need some help with this Code

Postby Father » Sat Oct 29, 2016 10:58 pm

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.
Father
 
Posts: 177
Joined: Thu Jan 09, 2014 5:48 pm

Re: Need some help with this Code

Postby TheOm » Sun Oct 30, 2016 6:38 pm

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.
TheOm
 
Posts: 101
Joined: Tue Jan 28, 2014 7:35 pm
Location: Germany

Re: Compressor - Need some help with the Code

Postby Father » Mon Oct 31, 2016 11:29 pm

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.
Father
 
Posts: 177
Joined: Thu Jan 09, 2014 5:48 pm


Return to DSP

Who is online

Users browsing this forum: k brown and 4 guests