COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :

Go Back   Cockos Incorporated Forums > Other Software Discussion > WDL users forum

Reply
 
Thread Tools Display Modes
Old 08-04-2018, 11:31 AM   #1
hannesmenzel
Human being with feelings
 
Join Date: Jul 2018
Posts: 24
Default Implementing this compressor with Dry/Wet control

Hey there,

can somebody help me? I'm learning C++ and plugin creation, and now I want to implement this open source comp algorithm: https://github.com/music-dsp-collect...r/simpleSource

First thing I've done is replacing the void process functions with doubles, and added a

Code:
return in1;
so that can process by

Code:
*out1 *= SimpleCompressor.process(*in1, *in2);
for each channel. First question would be, how the implementation was intended here. I guess, it should be:

Code:
SimpleCompressor.process(*in1, *in2);
because it should do the process inside the function, not just returning a value to process. Also tried "return gr" instead, but it should be intended in another way.

What I actually want to do is adding a dry/wet to it, but it seems almost impossible for a noob like me to get the dry signal, because the compressor will get an already gain reduced signal for every sample. Thought about a complete new stereo channel pair for the dry path, but I hope I can do that without this, because I should then process each filter four times instead of 2.

Some help?

Thanks!
hannesmenzel is offline   Reply With Quote
Old 08-04-2018, 12:49 PM   #2
hannesmenzel
Human being with feelings
 
Join Date: Jul 2018
Posts: 24
Default

Forget what I said, of course it can't be already gain reduced, because it comes from my input stream.

But the other question remain:

1. How is this compressor intended to be implemented?

2. How can I rewrite the class, so that I can get values out of it (such as gain reduction and so on).

For example I have no idea how to calculate a parallel processed signal, because after calling the void funcion, everything is done already.

By the way, the process function of it looks like this, so that you don't have to head over to the link:

Code:
 /*
 *	Simple Compressor (runtime function)
 *
 *  File		: SimpleCompProcess.inl
 *	Library		: SimpleSource
 *  Version		: 1.12
 *  Implements	: void SimpleComp::process( double &in1, double &in2 )
 *				  void SimpleComp::process( double &in1, double &in2, double keyLinked )
 *				  void SimpleCompRms::process( double &in1, double &in2 )
 *
 *	© 2006, ChunkWare Music Software, OPEN-SOURCE
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a
 *	copy of this software and associated documentation files (the "Software"),
 *	to deal in the Software without restriction, including without limitation
 *	the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *	and/or sell copies of the Software, and to permit persons to whom the
 *	Software is furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 *	THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *	DEALINGS IN THE SOFTWARE.
 */


#ifndef __SIMPLE_COMP_PROCESS_INL__
#define __SIMPLE_COMP_PROCESS_INL__

namespace chunkware_simple
{
	//-------------------------------------------------------------
	INLINE void SimpleComp::process( double &in1, double &in2 )
	{
		// create sidechain

		double rect1 = fabs( in1 );	// rectify input
		double rect2 = fabs( in2 );

		/* if desired, one could use another EnvelopeDetector to smooth
		 * the rectified signal.
		 */

		double link = std::max( rect1, rect2 );	// link channels with greater of 2

		process( in1, in2, link );	// rest of process
	}

	//-------------------------------------------------------------
	INLINE void SimpleComp::process( double &in1, double &in2, double keyLinked )
	{
		keyLinked = fabs( keyLinked );		// rectify (just in case)

		// convert key to dB
		keyLinked += DC_OFFSET;				// add DC offset to avoid log( 0 )
		double keydB = lin2dB( keyLinked );	// convert linear -> dB

		// threshold
		double overdB = keydB - threshdB_;	// delta over threshold
		if ( overdB < 0.0 )
			overdB = 0.0;

		// attack/release

		overdB += DC_OFFSET;					// add DC offset to avoid denormal
		AttRelEnvelope::run( overdB, envdB_ );	// run attack/release envelope
		overdB = envdB_ - DC_OFFSET;			// subtract DC offset

		/* REGARDING THE DC OFFSET: In this case, since the offset is added before 
		 * the attack/release processes, the envelope will never fall below the offset,
		 * thereby avoiding denormals. However, to prevent the offset from causing
		 * constant gain reduction, we must subtract it from the envelope, yielding
		 * a minimum value of 0dB.
		 */

		// transfer function
		double gr = overdB * ( ratio_ - 1.0 );	// gain reduction (dB)
		gr = dB2lin( gr );						// convert dB -> linear

		// output gain
		in1 *= gr;	// apply gain reduction to input
		in2 *= gr;
	}

	//-------------------------------------------------------------
	INLINE void SimpleCompRms::process( double &in1, double &in2 )
	{
		// create sidechain

		double inSq1 = in1 * in1;	// square input
		double inSq2 = in2 * in2;

		double sum = inSq1 + inSq2;			// power summing
		sum += DC_OFFSET;					// DC offset, to prevent denormal
		ave_.run( sum, aveOfSqrs_ );		// average of squares
		double rms = sqrt( aveOfSqrs_ );	// rms (sort of ...)

		/* REGARDING THE RMS AVERAGER: Ok, so this isn't a REAL RMS
		 * calculation. A true RMS is an FIR moving average. This
		 * approximation is a 1-pole IIR. Nonetheless, in practice,
		 * and in the interest of simplicity, this method will suffice,
		 * giving comparable results.
		 */

		SimpleComp::process( in1, in2, rms );	// rest of process
	}

}	// end namespace chunkware_simple

#endif	// end __SIMPLE_COMP_PROCESS_INL__
hannesmenzel is offline   Reply With Quote
Old 08-05-2018, 10:23 AM   #3
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

I suppose it should be something like :

Code:
double leftcopy = *in1;
double rightcopy = *in2;
SimpleCompressor.process(*in1, *in2);
*in1 = leftcopy*(1.0-wetlevel)+*in1*wetlevel;
*in2 = rightcopy*(1.0-wetlevel)+*in2*wetlevel;
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 08-28-2018, 01:14 AM   #4
hannesmenzel
Human being with feelings
 
Join Date: Jul 2018
Posts: 24
Default

Many thanks, I got it meanwhile. And I need to find this forums "notify me" function.
hannesmenzel is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 04:28 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.