34 template <
typename Type>
37 static void fillRandom (
Random& random, Type* buffer,
size_t n)
39 for (
size_t i = 0; i < n; ++i)
40 buffer[i] = (2.0f * random.
nextFloat()) - 1.0f;
43 static bool checkArrayIsSimilar (Type* a, Type* b,
size_t n) noexcept
45 for (
size_t i = 0; i < n; ++i)
46 if (std::abs (a[i] - b[i]) > 1e-6f)
54 template <
typename Type>
64 return Helpers<Type>::checkArrayIsSimilar (
reinterpret_cast<Type*
> (a),
65 reinterpret_cast<Type*
> (b),
71 template <
typename Type>
72 static void fillRandom (
Random& random, Type* buffer,
size_t n) { Helpers<Type>::fillRandom (random, buffer, n); }
74 template <
typename Type>
75 static bool checkArrayIsSimilar (Type* a, Type* b,
size_t n) noexcept {
return Helpers<Type>::checkArrayIsSimilar (a, b, n); }
79 template <
typename SampleType,
typename NumericType>
80 static void reference (
const NumericType* firCoefficients,
size_t numCoefficients,
81 const SampleType* input, SampleType* output,
size_t n) noexcept
83 if (numCoefficients == 0)
85 zeromem (output,
sizeof (SampleType) * n);
97 SampleType* buffer = scratchBuffer.
getData();
100 zeromem (buffer,
sizeof (SampleType) * numCoefficients);
102 for (
size_t i = 0; i < n; ++i)
104 for (
size_t j = (numCoefficients - 1); j >= 1; --j)
105 buffer[j] = buffer[j-1];
107 buffer[0] = input[i];
111 for (
size_t j = 0; j < numCoefficients; ++j)
112 sum += buffer[j] * firCoefficients[j];
119 struct LargeBlockTest
121 template <
typename FloatType>
132 struct SampleBySampleTest
134 template <
typename FloatType>
137 for (
size_t i = 0; i < n; ++i)
142 struct SplitBlockTest
144 template <
typename FloatType>
148 for (
size_t i = 0; i < n; i += len)
150 len = jmin (n - i, n / 3);
151 auto* src = input + i;
152 auto* dst = output + i;
164 template <
typename TheTest,
typename SampleType,
typename NumericType>
165 void runTestForType()
169 for (
auto size : {1, 2, 4, 8, 12, 13, 25})
171 constexpr
size_t n = 813;
175 fillRandom (random, input.getChannelPointer (0), n);
185 reference<SampleType, NumericType> (fir.
getChannelPointer (0),
static_cast<size_t> (size),
188 TheTest::template run<SampleType> (filter, input.getChannelPointer (0), output.getChannelPointer (0), n);
193 template <
typename TheTest>
194 void runTestForAllTypes (
const char* unitTestName)
198 runTestForType<TheTest, float, float>();
199 runTestForType<TheTest, double, double>();
201 runTestForType<TheTest, SIMDRegister<float>,
float>();
202 runTestForType<TheTest, SIMDRegister<double>,
double>();
209 :
UnitTest (
"FIR Filter", UnitTestCategories::dsp)
214 runTestForAllTypes<LargeBlockTest> (
"Large Blocks");
215 runTestForAllTypes<SampleBySampleTest> (
"Sample by Sample");
216 runTestForAllTypes<SplitBlockTest> (
"Split Block");
220 static FIRFilterTest firFilterUnitTest;
ElementType * getData() const noexcept
Returns a raw pointer to the allocated data.
A random number generator.
float nextFloat() noexcept
Returns the next random floating-point number.
This is a base class for classes that perform a unit test.
UnitTest(const String &name, const String &category=String())
Creates a test with the given name and optionally places it in a category.
void beginTest(const String &testName)
Tells the system that a new subsection of tests is beginning.
void expect(bool testResult, const String &failureMessage=String())
Checks that the result of a test is true, and logs this result.
Minimal and lightweight data-structure which contains a list of pointers to channels containing some ...
SampleType * getChannelPointer(size_t channel) const noexcept
Returns a raw pointer into one of the channels in this block.
void runTest() override
Implement this method in your subclass to actually run your tests.
A processing class that can perform FIR filtering on an audio signal, in the time domain.
void process(const ProcessContext &context) noexcept
Processes a block of samples.
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Processes a single sample, without any locking.
void prepare(const ProcessSpec &spec) noexcept
Prepare this filter for processing.
A set of coefficients for use in an FIRFilter object.
Contains context information that is passed into an algorithm's process method.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...
A wrapper around the platform's native SIMD register type.
static ElementType * getNextSIMDAlignedPtr(ElementType *ptr) noexcept
Returns the next position in memory where isSIMDAligned returns true.