Skip to content

Commit b84a886

Browse files
committed
2 parents 60d7b7b + cb5342e commit b84a886

File tree

7 files changed

+376
-4
lines changed

7 files changed

+376
-4
lines changed

Sources/CSoundpipeAudioKit/Effects/CostelloReverbDSP.mm

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@
77
enum CostelloReverbParameter : AUParameterAddress {
88
CostelloReverbParameterFeedback,
99
CostelloReverbParameterCutoffFrequency,
10+
CostelloReverbParameterBalance,
1011
};
1112

1213
class CostelloReverbDSP : public SoundpipeDSPBase {
1314
private:
1415
sp_revsc *revsc;
1516
ParameterRamper feedbackRamp;
1617
ParameterRamper cutoffFrequencyRamp;
18+
ParameterRamper balanceRamp{1.0};
1719

1820
public:
1921
CostelloReverbDSP() {
2022
parameters[CostelloReverbParameterFeedback] = &feedbackRamp;
2123
parameters[CostelloReverbParameterCutoffFrequency] = &cutoffFrequencyRamp;
24+
parameters[CostelloReverbParameterBalance] = &balanceRamp;
2225
}
2326

2427
void init(int channelCount, double sampleRate) override {
@@ -47,14 +50,20 @@ void process(FrameRange range) override {
4750
float leftIn = inputSample(0, i);
4851
float rightIn = inputSample(1, i);
4952

50-
float &leftOut = outputSample(0, i);
51-
float &rightOut = outputSample(1, i);
53+
float leftWet;
54+
float rightWet;
5255

53-
sp_revsc_compute(sp, revsc, &leftIn, &rightIn, &leftOut, &rightOut);
56+
sp_revsc_compute(sp, revsc, &leftIn, &rightIn, &leftWet, &rightWet);
57+
58+
float bal = balanceRamp.getAndStep();
59+
60+
outputSample(0, i) = bal * leftWet + (1-bal) * leftIn;
61+
outputSample(1, i) = bal * rightWet + (1-bal) * rightIn;
5462
}
5563
}
5664
};
5765

5866
AK_REGISTER_DSP(CostelloReverbDSP, "rvsc")
5967
AK_REGISTER_PARAMETER(CostelloReverbParameterFeedback)
6068
AK_REGISTER_PARAMETER(CostelloReverbParameterCutoffFrequency)
69+
AK_REGISTER_PARAMETER(CostelloReverbParameterBalance)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright AudioKit. All Rights Reserved.
2+
3+
#include "SoundpipeDSPBase.h"
4+
#include "ParameterRamper.h"
5+
#include "Soundpipe.h"
6+
7+
enum DiodeLadderFilterParameter : AUParameterAddress {
8+
DiodeLadderFilterParameterCutoffFrequency,
9+
DiodeLadderFilterParameterResonance,
10+
};
11+
12+
class DiodeLadderFilterDSP : public SoundpipeDSPBase {
13+
private:
14+
sp_diode *diode0;
15+
sp_diode *diode1;
16+
ParameterRamper cutoffFrequencyRamp;
17+
ParameterRamper resonanceRamp;
18+
19+
public:
20+
DiodeLadderFilterDSP() {
21+
parameters[DiodeLadderFilterParameterCutoffFrequency] = &cutoffFrequencyRamp;
22+
parameters[DiodeLadderFilterParameterResonance] = &resonanceRamp;
23+
}
24+
25+
void init(int channelCount, double sampleRate) override {
26+
SoundpipeDSPBase::init(channelCount, sampleRate);
27+
sp_diode_create(&diode0);
28+
sp_diode_init(sp, diode0);
29+
sp_diode_create(&diode1);
30+
sp_diode_init(sp, diode1);
31+
}
32+
33+
void deinit() override {
34+
SoundpipeDSPBase::deinit();
35+
sp_diode_destroy(&diode0);
36+
sp_diode_destroy(&diode1);
37+
}
38+
39+
void reset() override {
40+
SoundpipeDSPBase::reset();
41+
if (!isInitialized) return;
42+
sp_diode_init(sp, diode0);
43+
sp_diode_init(sp, diode1);
44+
}
45+
46+
void process(FrameRange range) override {
47+
for (int i : range) {
48+
49+
diode0->freq = diode1->freq = cutoffFrequencyRamp.getAndStep();
50+
diode0->res = diode1->res = resonanceRamp.getAndStep();
51+
52+
float leftIn = inputSample(0, i);
53+
float rightIn = inputSample(1, i);
54+
55+
float &leftOut = outputSample(0, i);
56+
float &rightOut = outputSample(1, i);
57+
58+
sp_diode_compute(sp, diode0, &leftIn, &leftOut);
59+
sp_diode_compute(sp, diode1, &rightIn, &rightOut);
60+
}
61+
}
62+
};
63+
64+
AK_REGISTER_DSP(DiodeLadderFilterDSP, "diod")
65+
AK_REGISTER_PARAMETER(DiodeLadderFilterParameterCutoffFrequency)
66+
AK_REGISTER_PARAMETER(DiodeLadderFilterParameterResonance)

Sources/SoundpipeAudioKit/Effects/CostelloReverb.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ public class CostelloReverb: Node {
4646
/// Low-pass cutoff frequency.
4747
@Parameter(cutoffFrequencyDef) public var cutoffFrequency: AUValue
4848

49+
/// Dry/wet mix.
50+
public static let balanceDef = NodeParameterDef(
51+
identifier: "balance",
52+
name: "Balance",
53+
address: akGetParameterAddress("CostelloReverbParameterBalance"),
54+
defaultValue: 1,
55+
range: 0 ... 1,
56+
unit: .percent
57+
)
58+
59+
/// Dry/wet mix. Should be a value between 0-1.
60+
@Parameter(balanceDef) public var balance: AUValue
61+
4962
// MARK: - Initialization
5063

5164
/// Initialize this reverb node
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright AudioKit. All Rights Reserved. Revision History at http://github.com/AudioKit/SoundpipeAudioKit/
2+
3+
import AudioKit
4+
import AudioKitEX
5+
import AVFoundation
6+
import CAudioKitEX
7+
8+
/// Diode Ladder Filter is an new digital implementation of the VCS3 ladder filter
9+
/// based on the work of Will Pirkle
10+
/// "Virtual Analog (VA) Diode Ladder Filter"
11+
///
12+
public class DiodeLadderFilter: Node {
13+
let input: Node
14+
15+
/// Connected nodes
16+
public var connections: [Node] { [input] }
17+
18+
/// Underlying AVAudioNode
19+
public var avAudioNode = instantiate(effect: "diod")
20+
21+
// MARK: - Parameters
22+
23+
/// Specification for cutoffFrequency (still determining best ranges)
24+
public static let cutoffFrequencyDef = NodeParameterDef(
25+
identifier: "cutoffFrequency",
26+
name: "Cutoff Frequency",
27+
address: akGetParameterAddress("DiodeLadderFilterParameterCutoffFrequency"),
28+
defaultValue: 1000.0,
29+
range: 12.0 ... 20000.0,
30+
unit: .hertz
31+
)
32+
33+
/// Filter cutoff frequency
34+
@Parameter(cutoffFrequencyDef) public var cutoffFrequency: AUValue
35+
36+
/// Specification for resonance (still determining best ranges)
37+
public static let resonanceDef = NodeParameterDef(
38+
identifier: "resonance",
39+
name: "Resonance",
40+
address: akGetParameterAddress("DiodeLadderFilterParameterResonance"),
41+
defaultValue: 0.5,
42+
range: 0.0 ... 1.0,
43+
unit: .generic
44+
)
45+
46+
/// Resonance
47+
@Parameter(resonanceDef) public var resonance: AUValue
48+
49+
// MARK: - Initialization
50+
51+
/// Initialize this filter node
52+
///
53+
/// - Parameters:
54+
/// - input: Input node to process
55+
/// - cutoffFrequency: Filter cutoff frequency
56+
/// - resonance: Resonance
57+
///
58+
public init(
59+
_ input: Node,
60+
cutoffFrequency: AUValue = cutoffFrequencyDef.defaultValue,
61+
resonance: AUValue = resonanceDef.defaultValue
62+
) {
63+
self.input = input
64+
65+
setupParameters()
66+
67+
self.cutoffFrequency = cutoffFrequency
68+
self.resonance = resonance
69+
}
70+
}

0 commit comments

Comments
 (0)