diff --git a/Sources/CSoundpipeAudioKit/Effects/BitCrusherDSP.mm b/Sources/CSoundpipeAudioKit/Effects/BitCrusherDSP.mm index df5e738..2bebedc 100644 --- a/Sources/CSoundpipeAudioKit/Effects/BitCrusherDSP.mm +++ b/Sources/CSoundpipeAudioKit/Effects/BitCrusherDSP.mm @@ -7,6 +7,7 @@ enum BitCrusherParameter : AUParameterAddress { BitCrusherParameterBitDepth, BitCrusherParameterSampleRate, + BitCrusherParameterDryWetMix }; class BitCrusherDSP : public SoundpipeDSPBase { @@ -15,11 +16,13 @@ sp_bitcrush *bitcrush1; ParameterRamper bitDepthRamp; ParameterRamper sampleRateRamp; + ParameterRamper dryWetMixRamp; public: BitCrusherDSP() { parameters[BitCrusherParameterBitDepth] = &bitDepthRamp; parameters[BitCrusherParameterSampleRate] = &sampleRateRamp; + parameters[BitCrusherParameterDryWetMix] = &dryWetMixRamp; } void init(int channelCount, double sampleRate) override { @@ -57,6 +60,10 @@ void process(FrameRange range) override { sp_bitcrush_compute(sp, bitcrush0, &leftIn, &leftOut); sp_bitcrush_compute(sp, bitcrush1, &rightIn, &rightOut); + + float dryWetMix = dryWetMixRamp.getAndStep(); + outputSample(0, i) = dryWetMix * leftOut + (1.0f - dryWetMix) * leftIn; + outputSample(1, i) = dryWetMix * rightOut + (1.0f - dryWetMix) * rightIn; } } }; @@ -64,3 +71,4 @@ void process(FrameRange range) override { AK_REGISTER_DSP(BitCrusherDSP, "btcr") AK_REGISTER_PARAMETER(BitCrusherParameterBitDepth) AK_REGISTER_PARAMETER(BitCrusherParameterSampleRate) +AK_REGISTER_PARAMETER(BitCrusherParameterDryWetMix) diff --git a/Sources/CSoundpipeAudioKit/Effects/PhaserDSP.mm b/Sources/CSoundpipeAudioKit/Effects/PhaserDSP.mm index 97266cf..aa99c1d 100644 --- a/Sources/CSoundpipeAudioKit/Effects/PhaserDSP.mm +++ b/Sources/CSoundpipeAudioKit/Effects/PhaserDSP.mm @@ -14,6 +14,7 @@ PhaserParameterFeedback, PhaserParameterInverted, PhaserParameterLfoBPM, + PhaserParameterDryWetMix }; class PhaserDSP : public SoundpipeDSPBase { @@ -28,6 +29,7 @@ ParameterRamper feedbackRamp; ParameterRamper invertedRamp; ParameterRamper lfoBPMRamp; + ParameterRamper dryWetMixRamp; public: PhaserDSP() { @@ -40,6 +42,7 @@ parameters[PhaserParameterFeedback] = &feedbackRamp; parameters[PhaserParameterInverted] = &invertedRamp; parameters[PhaserParameterLfoBPM] = &lfoBPMRamp; + parameters[PhaserParameterDryWetMix] = &dryWetMixRamp; } void init(int channelCount, double sampleRate) override { @@ -79,6 +82,10 @@ void process(FrameRange range) override { float &rightOut = outputSample(1, i); sp_phaser_compute(sp, phaser, &leftIn, &rightIn, &leftOut, &rightOut); + + float dryWetMix = dryWetMixRamp.getAndStep(); + outputSample(0, i) = dryWetMix * leftOut + (1.0f - dryWetMix) * leftIn; + outputSample(1, i) = dryWetMix * rightOut + (1.0f - dryWetMix) * rightIn; } } }; @@ -93,3 +100,4 @@ void process(FrameRange range) override { AK_REGISTER_PARAMETER(PhaserParameterFeedback) AK_REGISTER_PARAMETER(PhaserParameterInverted) AK_REGISTER_PARAMETER(PhaserParameterLfoBPM) +AK_REGISTER_PARAMETER(PhaserParameterDryWetMix) diff --git a/Sources/CSoundpipeAudioKit/Effects/PitchShifterDSP.mm b/Sources/CSoundpipeAudioKit/Effects/PitchShifterDSP.mm index c0720f7..b01e335 100644 --- a/Sources/CSoundpipeAudioKit/Effects/PitchShifterDSP.mm +++ b/Sources/CSoundpipeAudioKit/Effects/PitchShifterDSP.mm @@ -8,6 +8,7 @@ PitchShifterParameterShift, PitchShifterParameterWindowSize, PitchShifterParameterCrossfade, + PitchShifterParameterDryWetMix }; class PitchShifterDSP : public SoundpipeDSPBase { @@ -17,12 +18,14 @@ ParameterRamper shiftRamp; ParameterRamper windowSizeRamp; ParameterRamper crossfadeRamp; + ParameterRamper dryWetMixRamp; public: PitchShifterDSP() { parameters[PitchShifterParameterShift] = &shiftRamp; parameters[PitchShifterParameterWindowSize] = &windowSizeRamp; parameters[PitchShifterParameterCrossfade] = &crossfadeRamp; + parameters[PitchShifterParameterDryWetMix] = &dryWetMixRamp; } void init(int channelCount, double sampleRate) override { @@ -65,6 +68,10 @@ void process(FrameRange range) override { sp_pshift_compute(sp, pshift0, &leftIn, &leftOut); sp_pshift_compute(sp, pshift1, &rightIn, &rightOut); + + float dryWetMix = dryWetMixRamp.getAndStep(); + outputSample(0, i) = dryWetMix * leftOut + (1.0f - dryWetMix) * leftIn; + outputSample(1, i) = dryWetMix * rightOut + (1.0f - dryWetMix) * rightIn; } } }; @@ -73,3 +80,4 @@ void process(FrameRange range) override { AK_REGISTER_PARAMETER(PitchShifterParameterShift) AK_REGISTER_PARAMETER(PitchShifterParameterWindowSize) AK_REGISTER_PARAMETER(PitchShifterParameterCrossfade) +AK_REGISTER_PARAMETER(PitchShifterParameterDryWetMix) diff --git a/Sources/CSoundpipeAudioKit/Effects/VariableDelayDSP.mm b/Sources/CSoundpipeAudioKit/Effects/VariableDelayDSP.mm index e7c109b..1e3de49 100644 --- a/Sources/CSoundpipeAudioKit/Effects/VariableDelayDSP.mm +++ b/Sources/CSoundpipeAudioKit/Effects/VariableDelayDSP.mm @@ -8,6 +8,7 @@ enum VariableDelayParameter : AUParameterAddress { VariableDelayParameterTime, VariableDelayParameterFeedback, + VariableDelayParameterDryWetMix }; class VariableDelayDSP : public SoundpipeDSPBase { @@ -17,11 +18,13 @@ float maximumTime = 10.0; ParameterRamper timeRamp; ParameterRamper feedbackRamp; + ParameterRamper dryWetMixRamp; public: VariableDelayDSP() : SoundpipeDSPBase(1, false) { parameters[VariableDelayParameterTime] = &timeRamp; parameters[VariableDelayParameterFeedback] = &feedbackRamp; + parameters[VariableDelayParameterDryWetMix] = &dryWetMixRamp; } void setMaximumTime(float maxTime) { @@ -68,6 +71,10 @@ void process(FrameRange range) override { sp_vdelay_compute(sp, vdelay0, &leftIn, &leftOut); sp_vdelay_compute(sp, vdelay1, &rightIn, &rightOut); + + float dryWetMix = dryWetMixRamp.getAndStep(); + outputSample(0, i) = dryWetMix * leftOut + (1.0f - dryWetMix) * leftIn; + outputSample(1, i) = dryWetMix * rightOut + (1.0f - dryWetMix) * rightIn; } } }; @@ -81,3 +88,4 @@ void akVariableDelaySetMaximumTime(DSPRef dspRef, float maximumTime) { AK_REGISTER_DSP(VariableDelayDSP, "vdla") AK_REGISTER_PARAMETER(VariableDelayParameterTime) AK_REGISTER_PARAMETER(VariableDelayParameterFeedback) +AK_REGISTER_PARAMETER(VariableDelayParameterDryWetMix) diff --git a/Sources/SoundpipeAudioKit/Effects/BitCrusher.swift b/Sources/SoundpipeAudioKit/Effects/BitCrusher.swift index 3101cd0..c394df1 100644 --- a/Sources/SoundpipeAudioKit/Effects/BitCrusher.swift +++ b/Sources/SoundpipeAudioKit/Effects/BitCrusher.swift @@ -44,6 +44,19 @@ public class BitCrusher: Node { /// The sample rate of signal output. @Parameter(sampleRateDef) public var sampleRate: AUValue + /// Specification details for dryWetMix + public static let dryWetMixDef = NodeParameterDef( + identifier: "dryWetMix", + name: "Dry/Wet Mix", + address: akGetParameterAddress("BitCrusherParameterDryWetMix"), + defaultValue: 1.0, + range: 0.0 ... 1.0, + unit: .percent + ) + + /// Dry/Wet Mix + @Parameter(dryWetMixDef) public var dryWetMix: AUValue + // MARK: - Initialization /// Initialize this bitcrusher node @@ -52,11 +65,13 @@ public class BitCrusher: Node { /// - input: Input node to process /// - bitDepth: The bit depth of signal output. Typically in range (1-24). Non-integer values are OK. /// - sampleRate: The sample rate of signal output. + /// - dryWetMix: Dry/Wet Mix /// public init( _ input: Node, bitDepth: AUValue = bitDepthDef.defaultValue, - sampleRate: AUValue = sampleRateDef.defaultValue + sampleRate: AUValue = sampleRateDef.defaultValue, + dryWetMix: AUValue = dryWetMixDef.defaultValue ) { self.input = input @@ -64,5 +79,6 @@ public class BitCrusher: Node { self.bitDepth = bitDepth self.sampleRate = sampleRate + self.dryWetMix = dryWetMix } } diff --git a/Sources/SoundpipeAudioKit/Effects/Phaser.swift b/Sources/SoundpipeAudioKit/Effects/Phaser.swift index 5a41c57..e1233a3 100644 --- a/Sources/SoundpipeAudioKit/Effects/Phaser.swift +++ b/Sources/SoundpipeAudioKit/Effects/Phaser.swift @@ -135,6 +135,19 @@ public class Phaser: Node { /// Between 24 and 360 @Parameter(lfoBPMDef) public var lfoBPM: AUValue + /// Specification details for dryWetMix + public static let dryWetMixDef = NodeParameterDef( + identifier: "dryWetMix", + name: "Dry/Wet Mix", + address: akGetParameterAddress("PhaserParameterDryWetMix"), + defaultValue: 1.0, + range: 0.0 ... 1.0, + unit: .percent + ) + + /// Dry/Wet Mix + @Parameter(dryWetMixDef) public var dryWetMix: AUValue + // MARK: - Initialization /// Initialize this phaser node @@ -150,6 +163,7 @@ public class Phaser: Node { /// - feedback: Between 0 and 1 /// - inverted: 1 or 0 /// - lfoBPM: Between 24 and 360 + /// - dryWetMix: Dry/Wet Mix /// public init( _ input: Node, @@ -161,7 +175,8 @@ public class Phaser: Node { depth: AUValue = depthDef.defaultValue, feedback: AUValue = feedbackDef.defaultValue, inverted: AUValue = invertedDef.defaultValue, - lfoBPM: AUValue = lfoBPMDef.defaultValue + lfoBPM: AUValue = lfoBPMDef.defaultValue, + dryWetMix: AUValue = dryWetMixDef.defaultValue ) { self.input = input @@ -176,5 +191,6 @@ public class Phaser: Node { self.feedback = feedback self.inverted = inverted self.lfoBPM = lfoBPM + self.dryWetMix = dryWetMix } } diff --git a/Sources/SoundpipeAudioKit/Effects/PitchShifter.swift b/Sources/SoundpipeAudioKit/Effects/PitchShifter.swift index 9ba2423..ae025e5 100644 --- a/Sources/SoundpipeAudioKit/Effects/PitchShifter.swift +++ b/Sources/SoundpipeAudioKit/Effects/PitchShifter.swift @@ -57,6 +57,19 @@ public class PitchShifter: Node { /// Crossfade (in samples) @Parameter(crossfadeDef) public var crossfade: AUValue + /// Specification details for dryWetMix + public static let dryWetMixDef = NodeParameterDef( + identifier: "dryWetMix", + name: "Dry/Wet Mix", + address: akGetParameterAddress("PitchShifterParameterDryWetMix"), + defaultValue: 1.0, + range: 0.0 ... 1.0, + unit: .percent + ) + + /// Dry/Wet Mix + @Parameter(dryWetMixDef) public var dryWetMix: AUValue + // MARK: - Initialization /// Initialize this pitchshifter node @@ -66,12 +79,14 @@ public class PitchShifter: Node { /// - shift: Pitch shift (in semitones) /// - windowSize: Window size (in samples) /// - crossfade: Crossfade (in samples) + /// - dryWetMix: Dry/Wet Mix /// public init( _ input: Node, shift: AUValue = shiftDef.defaultValue, windowSize: AUValue = windowSizeDef.defaultValue, - crossfade: AUValue = crossfadeDef.defaultValue + crossfade: AUValue = crossfadeDef.defaultValue, + dryWetMix: AUValue = dryWetMixDef.defaultValue ) { self.input = input @@ -80,5 +95,6 @@ public class PitchShifter: Node { self.shift = shift self.windowSize = windowSize self.crossfade = crossfade + self.dryWetMix = dryWetMix } } diff --git a/Sources/SoundpipeAudioKit/Effects/VariableDelay.swift b/Sources/SoundpipeAudioKit/Effects/VariableDelay.swift index 06512e6..4776ba0 100644 --- a/Sources/SoundpipeAudioKit/Effects/VariableDelay.swift +++ b/Sources/SoundpipeAudioKit/Effects/VariableDelay.swift @@ -43,6 +43,19 @@ public class VariableDelay: Node { /// Feedback amount. Should be a value between 0-1. @Parameter(feedbackDef) public var feedback: AUValue + + /// Specification details for dryWetMix + public static let dryWetMixDef = NodeParameterDef( + identifier: "dryWetMix", + name: "Dry/Wet Mix", + address: akGetParameterAddress("VariableDelayParameterDryWetMix"), + defaultValue: 1.0, + range: 0.0 ... 1.0, + unit: .percent + ) + + /// Dry/Wet Mix + @Parameter(dryWetMixDef) public var dryWetMix: AUValue // MARK: - Initialization @@ -53,12 +66,14 @@ public class VariableDelay: Node { /// - time: Delay time (in seconds) This value must not exceed the maximum delay time. /// - feedback: Feedback amount. Should be a value between 0-1. /// - maximumTime: The maximum delay time, in seconds. + /// - dryWetMix: Dry/Wet Mix /// public init( _ input: Node, time: AUValue = timeDef.defaultValue, feedback: AUValue = feedbackDef.defaultValue, - maximumTime: AUValue = 5 + maximumTime: AUValue = 5, + dryWetMix: AUValue = dryWetMixDef.defaultValue ) { self.input = input @@ -68,5 +83,6 @@ public class VariableDelay: Node { self.time = time self.feedback = feedback + self.dryWetMix = dryWetMix } }