@@ -335,6 +335,11 @@ class Resampler {
335335 int maxChannels,
336336 int maxBlockSize);
337337
338+ template <typename T>
339+ typename std::enable_if_t <
340+ resinc_traits::is_juce_type<std::decay_t <T>>::value>
341+ resample (T&& input, T& output);
342+
338343 template <typename T>
339344 typename std::enable_if_t <
340345 resinc_traits::is_single_channel<std::decay_t <T>>::value>
@@ -781,5 +786,75 @@ void Resampler<TYPE, SINC_RADIUS, RESOLUTION>::configure(TYPE sampleRate,
781786}
782787
783788// =============================================================================
784- // IMPLEMENTATIONS: Interpolate
785- // =============================================================================
789+ // IMPLEMENTATIONS: Resample
790+ // =============================================================================
791+ template <typename TYPE, int SINC_RADIUS, int RESOLUTION>
792+ template <typename T>
793+ typename std::enable_if_t <resinc_traits::is_juce_type<std::decay_t <T>>::value>
794+ Resampler<TYPE, SINC_RADIUS, RESOLUTION>::resample(T&& input, T& output) {
795+ resample_helper (input.getArrayOfReadPointers (),
796+ output.getArrayOfWritePointers (),
797+ input.getNumChannels (),
798+ output.getNumSamples ());
799+ }
800+
801+ template <typename TYPE, int SINC_RADIUS, int RESOLUTION>
802+ template <typename T>
803+ typename std::enable_if_t <
804+ resinc_traits::is_single_channel<std::decay_t <T>>::value>
805+ Resampler<TYPE, SINC_RADIUS, RESOLUTION>::resample(T&& input, T& output) {
806+ const TYPE* ptr = input.data ();
807+ TYPE* outPtr = output.data ();
808+ resample_helper (&ptr, &outPtr, 1 , static_cast <int >(input.size ()));
809+ }
810+
811+ template <typename TYPE, int SINC_RADIUS, int RESOLUTION>
812+ template <typename T>
813+ typename std::enable_if_t <
814+ resinc_traits::is_multi_channel<std::decay_t <T>>::value>
815+ Resampler<TYPE, SINC_RADIUS, RESOLUTION>::resample(T&& input, T& output) {
816+ int channels = static_cast <int >(input.size ());
817+ if (channels == 0 ) return ;
818+ std::vector<const TYPE*> inPtrs (channels);
819+ std::vector<TYPE*> outPtrs (channels);
820+ for (int i = 0 ; i < channels; i++) {
821+ inPtrs[i] = input[i].data ();
822+ outPtrs[i] = output[i].data ();
823+ }
824+ resample_helper (inPtrs.data (),
825+ outPtrs.data (),
826+ channels,
827+ static_cast <int >(input[0 ].size ()));
828+ }
829+
830+ template <typename TYPE, int SINC_RADIUS, int RESOLUTION>
831+ void Resampler<TYPE, SINC_RADIUS, RESOLUTION>::resample(
832+ const TYPE* const * ptrToInBuffers,
833+ TYPE* const * ptrToBuffers,
834+ int numChannels,
835+ int numSamples) {
836+ resample_helper (ptrToInBuffers, ptrToBuffers, numChannels, numSamples);
837+ }
838+
839+ // =============================================================================
840+ // IMPLEMENTATIONS: Helpers
841+ // =============================================================================
842+ template <typename TYPE, int SINC_RADIUS, int RESOLUTION>
843+ void Resampler<TYPE, SINC_RADIUS, RESOLUTION>::resample_helper(
844+ const TYPE* const * ptrToInBuffers,
845+ TYPE* const * ptrToOutBuffers,
846+ int numChannels,
847+ int numSamples) {
848+ if (numChannels <= 0 || numSamples <= 0 ) {
849+ throw std::invalid_argument (
850+ " Number of channels and samples must be positive." );
851+ }
852+
853+ if (static_cast <size_t >(numChannels) > x.size () ||
854+ static_cast <size_t >(numSamples + SINC_RADIUS) > x[0 ].size ())
855+ throw std::runtime_error (
856+ " Resampler: Input size exceeds configured maxBlockSize." );
857+
858+ // TODO: Implement resampling logic using the Sinc table and phase
859+ // accumulator.
860+ }
0 commit comments