What is wrong with this code?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Hi,

I'm trying to build simple compressor.

Everything is fine.I can see that compressor is working on meter with seekgain.But i can't make it work with "gain".There is no any process.

Code: Select all

    double gain = seekgain = 1;
    double c = 8.65617025;
    
    double t = 0;
    double b = -exp(-62.83185307 / GetSampleRate() );
    double a = 1.0 + b;
    
    double threshDB = mThr;
    double thresh = exp(threshDB/c);
    double ratio = 1/20;
    
    double attack = exp( threshDB / (10*GetSampleRate()/1000) / c);
    double release = exp( threshDB / (100*GetSampleRate()/1000) / c );
    
    
  
    
    seekgain = 1;
    
    double rms = std::max( fabs(*in1) , fabs(*in2) );
    rms = std::max( sqrt( (t = a*rms-b*t) ) , rms);
    
    if (rms > thresh)
      seekgain = exp((threshDB + (log(rms)*c-threshDB)*ratio) /c) / rms;
    else
      seekgain = 1;
    
    
    
    if (gain > seekgain)
      gain = std::max( gain*attack , seekgain );
    else
      gain = std::min( gain/release , seekgain );
    
    *out1 = *in1 * gain ;
    *out2 = *in2 * gain ;
http://analogobsession.com/ VST, AU, AAX for WIN & MAC

Post

First start by correcting your source-code constants such as:
double ratio = 1/20;
corrected as
double ratio = 1.0/20.0;

doing this specifies a double precision float constant, the way you are doing it specifies an integer. A float would look like 1.f/20.f

also this part:
-62.83185307
not sure if you are intending to multiply -2pi by 10, but thats what it looks like.

Post

camsr wrote:First start by correcting your source-code constants such as:
double ratio = 1/20;
Oh yeah, this specifies that we should do integer division of 1 by 20, which results in 0, and then assign the value into a double precision variable. That's probably not what you want.

Also the "rms" calc doesn't calculate meaningful "rms" and not sure why you're doing sqrt there when you aren't squaring the input.

Post

camsr wrote:First start by correcting your source-code constants such as:
double ratio = 1/20;
corrected as
double ratio = 1.0/20.0;

doing this specifies a double precision float constant, the way you are doing it specifies an integer. A float would look like 1.f/20.f

also this part:
-62.83185307
not sure if you are intending to multiply -2pi by 10, but thats what it looks like.
Thanks.

I corrected ratio.

My envelope is ok?Why envelope can't process "gain"?
http://analogobsession.com/ VST, AU, AAX for WIN & MAC

Post

Seperate that code from vst, make a command line app and print the variables while the code is working.
~stratum~

Post

stratum wrote:Seperate that code from vst, make a command line app and print the variables while the code is working.
Thanks but why should i seperate code?Can't make it work like this?

And can you give me some advice about seperating code?

Thanks.
http://analogobsession.com/ VST, AU, AAX for WIN & MAC

Post

Because you can't print something to the console and still expect it to achieve realtime performance.
~stratum~

Post

stratum wrote:Because you can't print something to the console and still expect it to achieve realtime performance.
Hmm i see.

You mean that my envelope not working in real time to make gain works?
http://analogobsession.com/ VST, AU, AAX for WIN & MAC

Post

No, I mean you have to debug that code using whatever means you have (we are no better at reading your code than you), including old fashioned printf hooks, which will prevent it from achieving realtime performance, therefore it will no longer be working as a vst while you do that.
~stratum~

Post

Actually one thing that's kinda nice for debugging audio code is to just process single channel, which then allows you to output various other signals on the other channel.. or you could make it output multiple channels but that takes more effort to hook up in a host then.

Post

Now i made it works.

But envelope working with only very fast attack and sound distorted.
http://analogobsession.com/ VST, AU, AAX for WIN & MAC

Post

But envelope working with only very fast attack and sound distorted.
Looks like a progress. I guess it shouldn't be too hard to type a coefficient that makes it work better :clown:

An analog version here looks like a low pass filter after a rectifier. Model it, but use a bridge rectifier instead, not a single diode :wink: The capacitor in the circuit charges very fast, discharges much slower. The chunkware code should have what it takes. (Opps don't look at it for cheating)

https://electronics.stackexchange.com/q ... e-detector

This detects the level. The next step would be to google what would be called 2:1 compression, for example, so that the signal is adjusted based on the the detected level and the desired level. The adjustment should probably be smooth too. (another low pass filtered variable?, who knows, try it - if the level detection result is already smooth enough probably that's unnecessary)

p.s. another issue: should the smoothing filter attached to instantaneous gain variable be working on linear gain level or dB values? something to think about.
~stratum~

Post

One way I would debug if in a plugin, is to make a two-channel mono test file, same audio on left and right channels. Rather than play the file and listen, I would render the test file to disk thru the plugin, only modifying for instance the right audio channel. Then the stereo audio rendered file can be opened in a stereo editor with the original audio in left channel, and the changed audio in right channel, so the differences can be micro-examined and compared.

The same could be done, looking at the output file in the DAW audio display window, if the DAW audio display window is good enough. I don't have every modern DAW. Maybe some of them have wonderfully accurate audio display windows. I like reaper for sequencing but for debugging fine details in the waveform display cooledit pro/adobe audition is better to me. If you have a DAW with an absolutely wonderful wave display window then you don't need the extra step of examining results in a stereo editor program.

Along the same lines, your plugin during dev/debug doesn't have to output audio. You could process the dual-mono file as above, with no change to the left channel, but print the envelope output to the right channel rather than audio, and look at the results in an audio editor. If you play a file with the envelope written into a track it would sound awful or at least useless, but a good audio editor will DISPLAY the behavior of the envelope in response to the audio, so you can see the source audio in the left (top) wave display and see the resultant envelope in the right (bottom) wave display, to help see and figure out what is working right vs what is working wrong.

Until fairly well-along with a plugin, my test files would probably be variations of simple sine wave signals or other geometric waves, not "real music". The real music is only tested after the plugin seems to be dealing correctly with simple signals. For instance a compressor test file might be various durations and levels of sine wave (at various sine frequency). Maybe 1 second of -18 dB sine wave then 100 ms step of 0 dB sine wave, returning to another 1 second of -18 dB sine wave or whatever you think you need to test.

And as stratum said, if stepping thru the code is necessary to find problems, putting the code into a shell that reads the test file off disk and writes the results back to disk makes it lots easier to debug some things. In the past I had a little command line shell that would read file input and file output name lines from a text file, along with whatever parms I might want to change via text file. It could have been made fancier, but given the basic code shell that would read the simple control file, open the input/output files, read from input file, convert to float, an empty process routine, then covert from float and write to the output file-- I could just make copies of that simple small program source code and paste in different "process code" in-between the file-read and file-write, whatever I needed to test.

It sometimes seemed good for rough code efficiency timing as well-- For instance if it takes the program 2.1 seconds to simply read/write the file doing nothing else, then any time over and above that 2.1 seconds is the overhead required by whatever code I insert into the processing function.

Post

Attaching to and debugging with VST Plugin Analyser can be helpful. It can graph your compressor transfer function for example.

Only any use if you're compiling 32 bit VSTs on windows IIRC.

Post

tunca wrote: I corrected ratio.

My envelope is ok?Why envelope can't process "gain"?
Correct ALL the constants, not only ratio. :scared:

Post Reply

Return to “DSP and Plugin Development”