OpenShot Audio Library | OpenShotAudio 0.4.0
Loading...
Searching...
No Matches
juce_ProcessorChain_test.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce::dsp
27{
28
29class ProcessorChainTest final : public UnitTest
30{
31 template <int AddValue>
32 struct MockProcessor
33 {
34 void prepare (const ProcessSpec&) noexcept { isPrepared = true; }
35 void reset() noexcept { isReset = true; }
36
37 template <typename Context>
38 void process (const Context& context) noexcept
39 {
40 bufferWasClear = approximatelyEqual (context.getInputBlock().getSample (0, 0), 0.0f);
41
42 if (! context.isBypassed)
43 context.getOutputBlock().add (AddValue);
44 }
45
46 bool isPrepared = false;
47 bool isReset = false;
48 bool bufferWasClear = false;
49 };
50
51public:
52 ProcessorChainTest()
53 : UnitTest ("ProcessorChain", UnitTestCategories::dsp) {}
54
55 void runTest() override
56 {
57 beginTest ("After calling setBypass, processor is bypassed");
58 {
59 ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain;
60
61 setBypassed<0> (chain, true);
62 expect (isBypassed<0> (chain));
63 setBypassed<0> (chain, false);
64 expect (! isBypassed<0> (chain));
65
66 setBypassed<1> (chain, true);
67 expect (isBypassed<1> (chain));
68 setBypassed<1> (chain, false);
69 expect (! isBypassed<1> (chain));
70 }
71
72 beginTest ("After calling prepare, all processors are prepared");
73 {
74 ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain;
75
76 expect (! get<0> (chain).isPrepared);
77 expect (! get<1> (chain).isPrepared);
78
79 chain.prepare (ProcessSpec{});
80
81 expect (get<0> (chain).isPrepared);
82 expect (get<1> (chain).isPrepared);
83 }
84
85 beginTest ("After calling reset, all processors are reset");
86 {
87 ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain;
88
89 expect (! get<0> (chain).isReset);
90 expect (! get<1> (chain).isReset);
91
92 chain.reset();
93
94 expect (get<0> (chain).isReset);
95 expect (get<1> (chain).isReset);
96 }
97
98 beginTest ("After calling process, all processors contribute to processing");
99 {
100 ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain;
101
102 AudioBuffer<float> buffer (1, 1);
103 AudioBlock<float> block (buffer);
104 ProcessContextReplacing<float> context (block);
105
106 block.clear();
107 chain.process (context);
108 expectEquals (buffer.getSample (0, 0), 3.0f);
109 expect (get<0> (chain).bufferWasClear);
110 expect (! get<1> (chain).bufferWasClear);
111
112 setBypassed<0> (chain, true);
113 block.clear();
114 chain.process (context);
115 expectEquals (buffer.getSample (0, 0), 2.0f);
116 expect (get<0> (chain).bufferWasClear);
117 expect (get<1> (chain).bufferWasClear);
118
119 setBypassed<1> (chain, true);
120 block.clear();
121 chain.process (context);
122 expectEquals (buffer.getSample (0, 0), 0.0f);
123 expect (get<0> (chain).bufferWasClear);
124 expect (get<1> (chain).bufferWasClear);
125
126 setBypassed<0> (chain, false);
127 block.clear();
128 chain.process (context);
129 expectEquals (buffer.getSample (0, 0), 1.0f);
130 expect (get<0> (chain).bufferWasClear);
131 expect (! get<1> (chain).bufferWasClear);
132 }
133
134 beginTest ("Chains with trailing items that only support replacing contexts can be built");
135 {
136 AudioBuffer<float> inBuf (1, 1), outBuf (1, 1);
137 juce::dsp::AudioBlock<float> in (inBuf), out (outBuf);
138
139 struct OnlyReplacing
140 {
141 void prepare (const juce::dsp::ProcessSpec&) {}
142 void process (const juce::dsp::ProcessContextReplacing<float>& c)
143 {
144 c.getOutputBlock().multiplyBy (2.0f);
145 }
146 void reset() {}
147 };
148
149 {
150 juce::dsp::ProcessorChain<juce::dsp::Gain<float>, OnlyReplacing, OnlyReplacing> c;
152 get<0> (c).setGainLinear (1.0f);
153 c.prepare (ProcessSpec{});
154 inBuf.setSample (0, 0, 1.0f);
155 c.process (context);
156 expectEquals (outBuf.getSample (0, 0), 4.0f);
157 }
158 }
159 }
160};
161
162static ProcessorChainTest processorChainUnitTest;
163
164} // namespace juce::dsp
void expectEquals(ValueType actual, ValueType expected, String failureMessage=String())
UnitTest(const String &name, const String &category=String())
void beginTest(const String &testName)
void expect(bool testResult, const String &failureMessage=String())
void prepare(const ProcessSpec &spec)
void process(const ProcessContext &context) noexcept
AudioBlockType & getOutputBlock() const noexcept