diff --git a/Sources/CSoundpipeAudioKit/Effects/DynamicRangeCompressorDSP.mm b/Sources/CSoundpipeAudioKit/Effects/DynamicRangeCompressorDSP.mm index 474f261..ce07c5e 100644 --- a/Sources/CSoundpipeAudioKit/Effects/DynamicRangeCompressorDSP.mm +++ b/Sources/CSoundpipeAudioKit/Effects/DynamicRangeCompressorDSP.mm @@ -9,6 +9,8 @@ DynamicRangeCompressorParameterThreshold, DynamicRangeCompressorParameterAttackDuration, DynamicRangeCompressorParameterReleaseDuration, + DynamicRangeCompressorParameterGain, + DynamicRangeCompressorParameterDryWetMix, }; class DynamicRangeCompressorDSP : public SoundpipeDSPBase { @@ -19,6 +21,8 @@ ParameterRamper thresholdRamp; ParameterRamper attackDurationRamp; ParameterRamper releaseDurationRamp; + ParameterRamper gainRamp; + ParameterRamper dryWetMixRamp; public: DynamicRangeCompressorDSP() { @@ -26,6 +30,8 @@ parameters[DynamicRangeCompressorParameterThreshold] = &thresholdRamp; parameters[DynamicRangeCompressorParameterAttackDuration] = &attackDurationRamp; parameters[DynamicRangeCompressorParameterReleaseDuration] = &releaseDurationRamp; + parameters[DynamicRangeCompressorParameterGain] = &gainRamp; + parameters[DynamicRangeCompressorParameterDryWetMix] = &dryWetMixRamp; } void init(int channelCount, double sampleRate) override { @@ -64,6 +70,14 @@ void process(FrameRange range) override { sp_compressor_compute(sp, compressor0, &leftIn, &leftOut); sp_compressor_compute(sp, compressor1, &rightIn, &rightOut); + + float gain = gainRamp.getAndStep(); + leftOut *= gain; + rightOut *= gain; + + float dryWetMix = dryWetMixRamp.getAndStep(); + outputSample(0, i) = dryWetMix * leftOut + (1.0f - dryWetMix) * leftIn; + outputSample(1, i) = dryWetMix * rightOut + (1.0f - dryWetMix) * rightIn; } } }; @@ -73,3 +87,5 @@ void process(FrameRange range) override { AK_REGISTER_PARAMETER(DynamicRangeCompressorParameterThreshold) AK_REGISTER_PARAMETER(DynamicRangeCompressorParameterAttackDuration) AK_REGISTER_PARAMETER(DynamicRangeCompressorParameterReleaseDuration) +AK_REGISTER_PARAMETER(DynamicRangeCompressorParameterGain) +AK_REGISTER_PARAMETER(DynamicRangeCompressorParameterDryWetMix) diff --git a/Sources/SoundpipeAudioKit/Effects/DynamicRangeCompressor.swift b/Sources/SoundpipeAudioKit/Effects/DynamicRangeCompressor.swift index 9110be2..919a11c 100644 --- a/Sources/SoundpipeAudioKit/Effects/DynamicRangeCompressor.swift +++ b/Sources/SoundpipeAudioKit/Effects/DynamicRangeCompressor.swift @@ -70,6 +70,32 @@ public class DynamicRangeCompressor: Node { /// Release Duration @Parameter(releaseDurationDef) public var releaseDuration: AUValue + /// Specification details for gain + public static let gainDef = NodeParameterDef( + identifier: "gain", + name: "Makeup Gain", + address: akGetParameterAddress("DynamicRangeCompressorParameterGain"), + defaultValue: 1.0, + range: 0.0 ... 8.0, + unit: .linearGain + ) + + /// Makeup gain applied only to processed signal + @Parameter(gainDef) public var gain: AUValue + + /// Specification details for dryWetMix + public static let dryWetMixDef = NodeParameterDef( + identifier: "dryWetMix", + name: "Dry/Wet Mix", + address: akGetParameterAddress("DynamicRangeCompressorParameterDryWetMix"), + defaultValue: 1.0, + range: 0.0 ... 1.0, + unit: .percent + ) + + /// Dry/Wet Mix + @Parameter(dryWetMixDef) public var dryWetMix: AUValue + // MARK: - Initialization /// Initialize this compressor node @@ -80,13 +106,17 @@ public class DynamicRangeCompressor: Node { /// - threshold: Threshold (in dB) 0 = max /// - attackDuration: Attack duration /// - releaseDuration: Release Duration + /// - gain: Makeup gain (applied only to processing) + /// - dryWetMix: Dry/Wet Mix /// public init( _ input: Node, ratio: AUValue = ratioDef.defaultValue, threshold: AUValue = thresholdDef.defaultValue, attackDuration: AUValue = attackDurationDef.defaultValue, - releaseDuration: AUValue = releaseDurationDef.defaultValue + releaseDuration: AUValue = releaseDurationDef.defaultValue, + gain: AUValue = gainDef.defaultValue, + dryWetMix: AUValue = dryWetMixDef.defaultValue ) { self.input = input @@ -96,5 +126,7 @@ public class DynamicRangeCompressor: Node { self.threshold = threshold self.attackDuration = attackDuration self.releaseDuration = releaseDuration + self.gain = gain + self.dryWetMix = dryWetMix } }