| @@ -53,6 +53,14 @@ | |||
| using namespace dsp; | |||
| template <typename T> | |||
| static T* toBasePointer (SIMDRegister<T>* r) noexcept | |||
| { | |||
| return reinterpret_cast<T*> (r); | |||
| } | |||
| constexpr auto registerSize = dsp::SIMDRegister<float>::size(); | |||
| //============================================================================== | |||
| struct SIMDRegisterDemoDSP | |||
| { | |||
| @@ -73,33 +81,44 @@ struct SIMDRegisterDemoDSP | |||
| iir->prepare (monoSpec); | |||
| } | |||
| template <typename SampleType> | |||
| auto prepareChannelPointers (const AudioBlock<SampleType>& block) | |||
| { | |||
| std::array<SampleType*, registerSize> result {}; | |||
| for (size_t ch = 0; ch < result.size(); ++ch) | |||
| result[ch] = (ch < block.getNumChannels() ? block.getChannelPointer (ch) : zero.getChannelPointer (ch)); | |||
| return result; | |||
| } | |||
| void process (const ProcessContextReplacing<float>& context) | |||
| { | |||
| jassert (context.getInputBlock().getNumSamples() == context.getOutputBlock().getNumSamples()); | |||
| jassert (context.getInputBlock().getNumChannels() == context.getOutputBlock().getNumChannels()); | |||
| auto& input = context.getInputBlock(); | |||
| auto& output = context.getOutputBlock(); | |||
| auto n = (int) input.getNumSamples(); | |||
| auto* inout = channelPointers.getData(); | |||
| for (size_t ch = 0; ch < SIMDRegister<float>::size(); ++ch) | |||
| inout[ch] = (ch < input.getNumChannels() ? const_cast<float*> (input.getChannelPointer (ch)) : zero.getChannelPointer (ch)); | |||
| using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst>; | |||
| using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>; | |||
| const auto& input = context.getInputBlock(); | |||
| const auto numSamples = (int) input.getNumSamples(); | |||
| DstSampleType dstData (interleaved.getChannelPointer (0), (int) interleaved.getNumChannels()); | |||
| SrcSampleType srcData (inout); | |||
| auto inChannels = prepareChannelPointers (input); | |||
| dstData.convertSamples (srcData, n); | |||
| AudioData::interleaveSamples<AudioData::Float32, AudioData::NativeEndian, | |||
| AudioData::Float32, AudioData::NativeEndian> (inChannels.data(), | |||
| registerSize, | |||
| toBasePointer (interleaved.getChannelPointer (0)), | |||
| registerSize, | |||
| numSamples); | |||
| iir->process (ProcessContextReplacing<SIMDRegister<float>> (interleaved)); | |||
| for (size_t ch = 0; ch < input.getNumChannels(); ++ch) | |||
| inout[ch] = output.getChannelPointer (ch); | |||
| auto outChannels = prepareChannelPointers (context.getOutputBlock()); | |||
| srcData.convertSamples (dstData, n); | |||
| AudioData::deinterleaveSamples<AudioData::Float32, AudioData::NativeEndian, | |||
| AudioData::Float32, AudioData::NativeEndian> (toBasePointer (interleaved.getChannelPointer (0)), | |||
| registerSize, | |||
| outChannels.data(), | |||
| registerSize, | |||
| numSamples); | |||
| } | |||
| void reset() | |||
| @@ -132,7 +151,6 @@ struct SIMDRegisterDemoDSP | |||
| AudioBlock<float> zero; | |||
| HeapBlock<char> interleavedBlockData, zeroData; | |||
| HeapBlock<const float*> channelPointers { SIMDRegister<float>::size() }; | |||
| ChoiceParameter typeParam { { "Low-pass", "High-pass", "Band-pass" }, 1, "Type" }; | |||
| SliderParameter cutoffParam { { 20.0, 20000.0 }, 0.5, 440.0f, "Cutoff", "Hz" }; | |||