Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

771 lines
29KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. namespace dsp
  21. {
  22. /** Abstract class for the provided oversampling stages used internally in
  23. the Oversampling class.
  24. */
  25. template <typename SampleType>
  26. struct Oversampling<SampleType>::OversamplingStage
  27. {
  28. OversamplingStage (size_t numChans, size_t newFactor) : numChannels (numChans), factor (newFactor) {}
  29. virtual ~OversamplingStage() {}
  30. //==============================================================================
  31. virtual SampleType getLatencyInSamples() const = 0;
  32. virtual void initProcessing (size_t maximumNumberOfSamplesBeforeOversampling)
  33. {
  34. buffer.setSize (static_cast<int> (numChannels),
  35. static_cast<int> (maximumNumberOfSamplesBeforeOversampling * factor),
  36. false, false, true);
  37. }
  38. virtual void reset()
  39. {
  40. buffer.clear();
  41. }
  42. AudioBlock<SampleType> getProcessedSamples (size_t numSamples)
  43. {
  44. return AudioBlock<SampleType> (buffer).getSubBlock (0, numSamples);
  45. }
  46. virtual void processSamplesUp (const AudioBlock<const SampleType>&) = 0;
  47. virtual void processSamplesDown (AudioBlock<SampleType>&) = 0;
  48. AudioBuffer<SampleType> buffer;
  49. size_t numChannels, factor;
  50. };
  51. //==============================================================================
  52. /** Dummy oversampling stage class which simply copies and pastes the input
  53. signal, which could be equivalent to a "one time" oversampling processing.
  54. */
  55. template <typename SampleType>
  56. struct OversamplingDummy : public Oversampling<SampleType>::OversamplingStage
  57. {
  58. using ParentType = typename Oversampling<SampleType>::OversamplingStage;
  59. OversamplingDummy (size_t numChans) : ParentType (numChans, 1) {}
  60. //==============================================================================
  61. SampleType getLatencyInSamples() const override
  62. {
  63. return 0;
  64. }
  65. void processSamplesUp (const AudioBlock<const SampleType>& inputBlock) override
  66. {
  67. jassert (inputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));
  68. jassert (inputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));
  69. for (size_t channel = 0; channel < inputBlock.getNumChannels(); ++channel)
  70. ParentType::buffer.copyFrom (static_cast<int> (channel), 0,
  71. inputBlock.getChannelPointer (channel), static_cast<int> (inputBlock.getNumSamples()));
  72. }
  73. void processSamplesDown (AudioBlock<SampleType>& outputBlock) override
  74. {
  75. jassert (outputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));
  76. jassert (outputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));
  77. outputBlock.copyFrom (ParentType::getProcessedSamples (outputBlock.getNumSamples()));
  78. }
  79. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OversamplingDummy)
  80. };
  81. //==============================================================================
  82. /** Oversampling stage class performing 2 times oversampling using the Filter
  83. Design FIR Equiripple method. The resulting filter is linear phase,
  84. symmetric, and has every two samples but the middle one equal to zero,
  85. leading to specific processing optimizations.
  86. */
  87. template <typename SampleType>
  88. struct Oversampling2TimesEquirippleFIR : public Oversampling<SampleType>::OversamplingStage
  89. {
  90. using ParentType = typename Oversampling<SampleType>::OversamplingStage;
  91. Oversampling2TimesEquirippleFIR (size_t numChans,
  92. SampleType normalisedTransitionWidthUp,
  93. SampleType stopbandAmplitudedBUp,
  94. SampleType normalisedTransitionWidthDown,
  95. SampleType stopbandAmplitudedBDown)
  96. : ParentType (numChans, 2)
  97. {
  98. coefficientsUp = *FilterDesign<SampleType>::designFIRLowpassHalfBandEquirippleMethod (normalisedTransitionWidthUp, stopbandAmplitudedBUp);
  99. coefficientsDown = *FilterDesign<SampleType>::designFIRLowpassHalfBandEquirippleMethod (normalisedTransitionWidthDown, stopbandAmplitudedBDown);
  100. auto N = coefficientsUp.getFilterOrder() + 1;
  101. stateUp.setSize (static_cast<int> (this->numChannels), static_cast<int> (N));
  102. N = coefficientsDown.getFilterOrder() + 1;
  103. auto Ndiv2 = N / 2;
  104. auto Ndiv4 = Ndiv2 / 2;
  105. stateDown.setSize (static_cast<int> (this->numChannels), static_cast<int> (N));
  106. stateDown2.setSize (static_cast<int> (this->numChannels), static_cast<int> (Ndiv4 + 1));
  107. position.resize (static_cast<int> (this->numChannels));
  108. }
  109. //==============================================================================
  110. SampleType getLatencyInSamples() const override
  111. {
  112. return static_cast<SampleType> (coefficientsUp.getFilterOrder() + coefficientsDown.getFilterOrder()) * 0.5f;
  113. }
  114. void reset() override
  115. {
  116. ParentType::reset();
  117. stateUp.clear();
  118. stateDown.clear();
  119. stateDown2.clear();
  120. position.fill (0);
  121. }
  122. void processSamplesUp (const AudioBlock<const SampleType>& inputBlock) override
  123. {
  124. jassert (inputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));
  125. jassert (inputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));
  126. // Initialization
  127. auto fir = coefficientsUp.getRawCoefficients();
  128. auto N = coefficientsUp.getFilterOrder() + 1;
  129. auto Ndiv2 = N / 2;
  130. auto numSamples = inputBlock.getNumSamples();
  131. // Processing
  132. for (size_t channel = 0; channel < inputBlock.getNumChannels(); ++channel)
  133. {
  134. auto bufferSamples = ParentType::buffer.getWritePointer (static_cast<int> (channel));
  135. auto buf = stateUp.getWritePointer (static_cast<int> (channel));
  136. auto samples = inputBlock.getChannelPointer (channel);
  137. for (size_t i = 0; i < numSamples; ++i)
  138. {
  139. // Input
  140. buf[N - 1] = 2 * samples[i];
  141. // Convolution
  142. auto out = static_cast<SampleType> (0.0);
  143. for (size_t k = 0; k < Ndiv2; k += 2)
  144. out += (buf[k] + buf[N - k - 1]) * fir[k];
  145. // Outputs
  146. bufferSamples[i << 1] = out;
  147. bufferSamples[(i << 1) + 1] = buf[Ndiv2 + 1] * fir[Ndiv2];
  148. // Shift data
  149. for (size_t k = 0; k < N - 2; k += 2)
  150. buf[k] = buf[k + 2];
  151. }
  152. }
  153. }
  154. void processSamplesDown (AudioBlock<SampleType>& outputBlock) override
  155. {
  156. jassert (outputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));
  157. jassert (outputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));
  158. // Initialization
  159. auto fir = coefficientsDown.getRawCoefficients();
  160. auto N = coefficientsDown.getFilterOrder() + 1;
  161. auto Ndiv2 = N / 2;
  162. auto Ndiv4 = Ndiv2 / 2;
  163. auto numSamples = outputBlock.getNumSamples();
  164. // Processing
  165. for (size_t channel = 0; channel < outputBlock.getNumChannels(); ++channel)
  166. {
  167. auto bufferSamples = ParentType::buffer.getWritePointer (static_cast<int> (channel));
  168. auto buf = stateDown.getWritePointer (static_cast<int> (channel));
  169. auto buf2 = stateDown2.getWritePointer (static_cast<int> (channel));
  170. auto samples = outputBlock.getChannelPointer (channel);
  171. auto pos = position.getUnchecked (static_cast<int> (channel));
  172. for (size_t i = 0; i < numSamples; ++i)
  173. {
  174. // Input
  175. buf[N - 1] = bufferSamples[i << 1];
  176. // Convolution
  177. auto out = static_cast<SampleType> (0.0);
  178. for (size_t k = 0; k < Ndiv2; k += 2)
  179. out += (buf[k] + buf[N - k - 1]) * fir[k];
  180. // Output
  181. out += buf2[pos] * fir[Ndiv2];
  182. buf2[pos] = bufferSamples[(i << 1) + 1];
  183. samples[i] = out;
  184. // Shift data
  185. for (size_t k = 0; k < N - 2; ++k)
  186. buf[k] = buf[k + 2];
  187. // Circular buffer
  188. pos = (pos == 0 ? Ndiv4 : pos - 1);
  189. }
  190. position.setUnchecked (static_cast<int> (channel), pos);
  191. }
  192. }
  193. private:
  194. //==============================================================================
  195. FIR::Coefficients<SampleType> coefficientsUp, coefficientsDown;
  196. AudioBuffer<SampleType> stateUp, stateDown, stateDown2;
  197. Array<size_t> position;
  198. //==============================================================================
  199. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling2TimesEquirippleFIR)
  200. };
  201. //==============================================================================
  202. /** Oversampling stage class performing 2 times oversampling using the Filter
  203. Design IIR Polyphase Allpass Cascaded method. The resulting filter is minimum
  204. phase, and provided with a method to get the exact resulting latency.
  205. */
  206. template <typename SampleType>
  207. struct Oversampling2TimesPolyphaseIIR : public Oversampling<SampleType>::OversamplingStage
  208. {
  209. using ParentType = typename Oversampling<SampleType>::OversamplingStage;
  210. Oversampling2TimesPolyphaseIIR (size_t numChans,
  211. SampleType normalisedTransitionWidthUp,
  212. SampleType stopbandAmplitudedBUp,
  213. SampleType normalisedTransitionWidthDown,
  214. SampleType stopbandAmplitudedBDown)
  215. : ParentType (numChans, 2)
  216. {
  217. auto structureUp = FilterDesign<SampleType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalisedTransitionWidthUp, stopbandAmplitudedBUp);
  218. auto coeffsUp = getCoefficients (structureUp);
  219. latency = static_cast<SampleType> (-(coeffsUp.getPhaseForFrequency (0.0001, 1.0)) / (0.0001 * MathConstants<double>::twoPi));
  220. auto structureDown = FilterDesign<SampleType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalisedTransitionWidthDown, stopbandAmplitudedBDown);
  221. auto coeffsDown = getCoefficients (structureDown);
  222. latency += static_cast<SampleType> (-(coeffsDown.getPhaseForFrequency (0.0001, 1.0)) / (0.0001 * MathConstants<double>::twoPi));
  223. for (auto i = 0; i < structureUp.directPath.size(); ++i)
  224. coefficientsUp.add (structureUp.directPath.getObjectPointer (i)->coefficients[0]);
  225. for (auto i = 1; i < structureUp.delayedPath.size(); ++i)
  226. coefficientsUp.add (structureUp.delayedPath.getObjectPointer (i)->coefficients[0]);
  227. for (auto i = 0; i < structureDown.directPath.size(); ++i)
  228. coefficientsDown.add (structureDown.directPath.getObjectPointer (i)->coefficients[0]);
  229. for (auto i = 1; i < structureDown.delayedPath.size(); ++i)
  230. coefficientsDown.add (structureDown.delayedPath.getObjectPointer (i)->coefficients[0]);
  231. v1Up.setSize (static_cast<int> (this->numChannels), coefficientsUp.size());
  232. v1Down.setSize (static_cast<int> (this->numChannels), coefficientsDown.size());
  233. delayDown.resize (static_cast<int> (this->numChannels));
  234. }
  235. //==============================================================================
  236. SampleType getLatencyInSamples() const override
  237. {
  238. return latency;
  239. }
  240. void reset() override
  241. {
  242. ParentType::reset();
  243. v1Up.clear();
  244. v1Down.clear();
  245. delayDown.fill (0);
  246. }
  247. void processSamplesUp (const AudioBlock<const SampleType>& inputBlock) override
  248. {
  249. jassert (inputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));
  250. jassert (inputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));
  251. // Initialization
  252. auto coeffs = coefficientsUp.getRawDataPointer();
  253. auto numStages = coefficientsUp.size();
  254. auto delayedStages = numStages / 2;
  255. auto directStages = numStages - delayedStages;
  256. auto numSamples = inputBlock.getNumSamples();
  257. // Processing
  258. for (size_t channel = 0; channel < inputBlock.getNumChannels(); ++channel)
  259. {
  260. auto bufferSamples = ParentType::buffer.getWritePointer (static_cast<int> (channel));
  261. auto lv1 = v1Up.getWritePointer (static_cast<int> (channel));
  262. auto samples = inputBlock.getChannelPointer (channel);
  263. for (size_t i = 0; i < numSamples; ++i)
  264. {
  265. // Direct path cascaded allpass filters
  266. auto input = samples[i];
  267. for (auto n = 0; n < directStages; ++n)
  268. {
  269. auto alpha = coeffs[n];
  270. auto output = alpha * input + lv1[n];
  271. lv1[n] = input - alpha * output;
  272. input = output;
  273. }
  274. // Output
  275. bufferSamples[i << 1] = input;
  276. // Delayed path cascaded allpass filters
  277. input = samples[i];
  278. for (auto n = directStages; n < numStages; ++n)
  279. {
  280. auto alpha = coeffs[n];
  281. auto output = alpha * input + lv1[n];
  282. lv1[n] = input - alpha * output;
  283. input = output;
  284. }
  285. // Output
  286. bufferSamples[(i << 1) + 1] = input;
  287. }
  288. }
  289. #if JUCE_DSP_ENABLE_SNAP_TO_ZERO
  290. snapToZero (true);
  291. #endif
  292. }
  293. void processSamplesDown (AudioBlock<SampleType>& outputBlock) override
  294. {
  295. jassert (outputBlock.getNumChannels() <= static_cast<size_t> (ParentType::buffer.getNumChannels()));
  296. jassert (outputBlock.getNumSamples() * ParentType::factor <= static_cast<size_t> (ParentType::buffer.getNumSamples()));
  297. // Initialization
  298. auto coeffs = coefficientsDown.getRawDataPointer();
  299. auto numStages = coefficientsDown.size();
  300. auto delayedStages = numStages / 2;
  301. auto directStages = numStages - delayedStages;
  302. auto numSamples = outputBlock.getNumSamples();
  303. // Processing
  304. for (size_t channel = 0; channel < outputBlock.getNumChannels(); ++channel)
  305. {
  306. auto bufferSamples = ParentType::buffer.getWritePointer (static_cast<int> (channel));
  307. auto lv1 = v1Down.getWritePointer (static_cast<int> (channel));
  308. auto samples = outputBlock.getChannelPointer (channel);
  309. auto delay = delayDown.getUnchecked (static_cast<int> (channel));
  310. for (size_t i = 0; i < numSamples; ++i)
  311. {
  312. // Direct path cascaded allpass filters
  313. auto input = bufferSamples[i << 1];
  314. for (auto n = 0; n < directStages; ++n)
  315. {
  316. auto alpha = coeffs[n];
  317. auto output = alpha * input + lv1[n];
  318. lv1[n] = input - alpha * output;
  319. input = output;
  320. }
  321. auto directOut = input;
  322. // Delayed path cascaded allpass filters
  323. input = bufferSamples[(i << 1) + 1];
  324. for (auto n = directStages; n < numStages; ++n)
  325. {
  326. auto alpha = coeffs[n];
  327. auto output = alpha * input + lv1[n];
  328. lv1[n] = input - alpha * output;
  329. input = output;
  330. }
  331. // Output
  332. samples[i] = (delay + directOut) * static_cast<SampleType> (0.5);
  333. delay = input;
  334. }
  335. delayDown.setUnchecked (static_cast<int> (channel), delay);
  336. }
  337. #if JUCE_DSP_ENABLE_SNAP_TO_ZERO
  338. snapToZero (false);
  339. #endif
  340. }
  341. void snapToZero (bool snapUpProcessing)
  342. {
  343. if (snapUpProcessing)
  344. {
  345. for (auto channel = 0; channel < ParentType::buffer.getNumChannels(); ++channel)
  346. {
  347. auto lv1 = v1Up.getWritePointer (channel);
  348. auto numStages = coefficientsUp.size();
  349. for (auto n = 0; n < numStages; ++n)
  350. util::snapToZero (lv1[n]);
  351. }
  352. }
  353. else
  354. {
  355. for (auto channel = 0; channel < ParentType::buffer.getNumChannels(); ++channel)
  356. {
  357. auto lv1 = v1Down.getWritePointer (channel);
  358. auto numStages = coefficientsDown.size();
  359. for (auto n = 0; n < numStages; ++n)
  360. util::snapToZero (lv1[n]);
  361. }
  362. }
  363. }
  364. private:
  365. //==============================================================================
  366. /** This function calculates the equivalent high order IIR filter of a given
  367. polyphase cascaded allpass filters structure.
  368. */
  369. IIR::Coefficients<SampleType> getCoefficients (typename FilterDesign<SampleType>::IIRPolyphaseAllpassStructure& structure) const
  370. {
  371. constexpr auto one = static_cast<SampleType> (1.0);
  372. Polynomial<SampleType> numerator1 ({ one }), denominator1 ({ one }),
  373. numerator2 ({ one }), denominator2 ({ one });
  374. for (auto* i : structure.directPath)
  375. {
  376. auto coeffs = i->getRawCoefficients();
  377. if (i->getFilterOrder() == 1)
  378. {
  379. numerator1 = numerator1 .getProductWith (Polynomial<SampleType> ({ coeffs[0], coeffs[1] }));
  380. denominator1 = denominator1.getProductWith (Polynomial<SampleType> ({ one, coeffs[2] }));
  381. }
  382. else
  383. {
  384. numerator1 = numerator1 .getProductWith (Polynomial<SampleType> ({ coeffs[0], coeffs[1], coeffs[2] }));
  385. denominator1 = denominator1.getProductWith (Polynomial<SampleType> ({ one, coeffs[3], coeffs[4] }));
  386. }
  387. }
  388. for (auto* i : structure.delayedPath)
  389. {
  390. auto coeffs = i->getRawCoefficients();
  391. if (i->getFilterOrder() == 1)
  392. {
  393. numerator2 = numerator2 .getProductWith (Polynomial<SampleType> ({ coeffs[0], coeffs[1] }));
  394. denominator2 = denominator2.getProductWith (Polynomial<SampleType> ({ one, coeffs[2] }));
  395. }
  396. else
  397. {
  398. numerator2 = numerator2 .getProductWith (Polynomial<SampleType> ({ coeffs[0], coeffs[1], coeffs[2] }));
  399. denominator2 = denominator2.getProductWith (Polynomial<SampleType> ({ one, coeffs[3], coeffs[4] }));
  400. }
  401. }
  402. auto numeratorf1 = numerator1.getProductWith (denominator2);
  403. auto numeratorf2 = numerator2.getProductWith (denominator1);
  404. auto numerator = numeratorf1.getSumWith (numeratorf2);
  405. auto denominator = denominator1.getProductWith (denominator2);
  406. IIR::Coefficients<SampleType> coeffs;
  407. coeffs.coefficients.clear();
  408. auto inversion = one / denominator[0];
  409. for (int i = 0; i <= numerator.getOrder(); ++i)
  410. coeffs.coefficients.add (numerator[i] * inversion);
  411. for (int i = 1; i <= denominator.getOrder(); ++i)
  412. coeffs.coefficients.add (denominator[i] * inversion);
  413. return coeffs;
  414. }
  415. //==============================================================================
  416. Array<SampleType> coefficientsUp, coefficientsDown;
  417. SampleType latency;
  418. AudioBuffer<SampleType> v1Up, v1Down;
  419. Array<SampleType> delayDown;
  420. //==============================================================================
  421. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling2TimesPolyphaseIIR)
  422. };
  423. //==============================================================================
  424. template <typename SampleType>
  425. Oversampling<SampleType>::Oversampling (size_t newNumChannels)
  426. : numChannels (newNumChannels)
  427. {
  428. jassert (numChannels > 0);
  429. addDummyOversamplingStage();
  430. }
  431. template <typename SampleType>
  432. Oversampling<SampleType>::Oversampling (size_t newNumChannels, size_t newFactor,
  433. FilterType newType, bool isMaximumQuality,
  434. bool useIntegerLatency)
  435. : numChannels (newNumChannels), shouldUseIntegerLatency (useIntegerLatency)
  436. {
  437. jassert (isPositiveAndBelow (newFactor, 5) && numChannels > 0);
  438. if (newFactor == 0)
  439. {
  440. addDummyOversamplingStage();
  441. }
  442. else if (newType == FilterType::filterHalfBandPolyphaseIIR)
  443. {
  444. for (size_t n = 0; n < newFactor; ++n)
  445. {
  446. auto twUp = (isMaximumQuality ? 0.10f : 0.12f) * (n == 0 ? 0.5f : 1.0f);
  447. auto twDown = (isMaximumQuality ? 0.12f : 0.15f) * (n == 0 ? 0.5f : 1.0f);
  448. auto gaindBStartUp = (isMaximumQuality ? -90.0f : -70.0f);
  449. auto gaindBStartDown = (isMaximumQuality ? -75.0f : -60.0f);
  450. auto gaindBFactorUp = (isMaximumQuality ? 10.0f : 8.0f);
  451. auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f);
  452. addOversamplingStage (FilterType::filterHalfBandPolyphaseIIR,
  453. twUp, gaindBStartUp + gaindBFactorUp * (float) n,
  454. twDown, gaindBStartDown + gaindBFactorDown * (float) n);
  455. }
  456. }
  457. else if (newType == FilterType::filterHalfBandFIREquiripple)
  458. {
  459. for (size_t n = 0; n < newFactor; ++n)
  460. {
  461. auto twUp = (isMaximumQuality ? 0.10f : 0.12f) * (n == 0 ? 0.5f : 1.0f);
  462. auto twDown = (isMaximumQuality ? 0.12f : 0.15f) * (n == 0 ? 0.5f : 1.0f);
  463. auto gaindBStartUp = (isMaximumQuality ? -90.0f : -70.0f);
  464. auto gaindBStartDown = (isMaximumQuality ? -75.0f : -60.0f);
  465. auto gaindBFactorUp = (isMaximumQuality ? 10.0f : 8.0f);
  466. auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f);
  467. addOversamplingStage (FilterType::filterHalfBandFIREquiripple,
  468. twUp, gaindBStartUp + gaindBFactorUp * (float) n,
  469. twDown, gaindBStartDown + gaindBFactorDown * (float) n);
  470. }
  471. }
  472. }
  473. template <typename SampleType>
  474. Oversampling<SampleType>::~Oversampling()
  475. {
  476. stages.clear();
  477. }
  478. //==============================================================================
  479. template <typename SampleType>
  480. void Oversampling<SampleType>::addDummyOversamplingStage()
  481. {
  482. stages.add (new OversamplingDummy<SampleType> (numChannels));
  483. }
  484. template <typename SampleType>
  485. void Oversampling<SampleType>::addOversamplingStage (FilterType type,
  486. float normalisedTransitionWidthUp,
  487. float stopbandAmplitudedBUp,
  488. float normalisedTransitionWidthDown,
  489. float stopbandAmplitudedBDown)
  490. {
  491. if (type == FilterType::filterHalfBandPolyphaseIIR)
  492. {
  493. stages.add (new Oversampling2TimesPolyphaseIIR<SampleType> (numChannels,
  494. normalisedTransitionWidthUp, stopbandAmplitudedBUp,
  495. normalisedTransitionWidthDown, stopbandAmplitudedBDown));
  496. }
  497. else
  498. {
  499. stages.add (new Oversampling2TimesEquirippleFIR<SampleType> (numChannels,
  500. normalisedTransitionWidthUp, stopbandAmplitudedBUp,
  501. normalisedTransitionWidthDown, stopbandAmplitudedBDown));
  502. }
  503. factorOversampling *= 2;
  504. }
  505. template <typename SampleType>
  506. void Oversampling<SampleType>::clearOversamplingStages()
  507. {
  508. stages.clear();
  509. factorOversampling = 1u;
  510. }
  511. //==============================================================================
  512. template <typename SampleType>
  513. void Oversampling<SampleType>::setUsingIntegerLatency (bool useIntegerLatency) noexcept
  514. {
  515. shouldUseIntegerLatency = useIntegerLatency;
  516. }
  517. template <typename SampleType>
  518. SampleType Oversampling<SampleType>::getLatencyInSamples() const noexcept
  519. {
  520. auto latency = getUncompensatedLatency();
  521. return shouldUseIntegerLatency ? latency + fractionalDelay : latency;
  522. }
  523. template <typename SampleType>
  524. SampleType Oversampling<SampleType>::getUncompensatedLatency() const noexcept
  525. {
  526. auto latency = static_cast<SampleType> (0);
  527. size_t order = 1;
  528. for (auto* stage : stages)
  529. {
  530. order *= stage->factor;
  531. latency += stage->getLatencyInSamples() / static_cast<SampleType> (order);
  532. }
  533. return latency;
  534. }
  535. template <typename SampleType>
  536. size_t Oversampling<SampleType>::getOversamplingFactor() const noexcept
  537. {
  538. return factorOversampling;
  539. }
  540. //==============================================================================
  541. template <typename SampleType>
  542. void Oversampling<SampleType>::initProcessing (size_t maximumNumberOfSamplesBeforeOversampling)
  543. {
  544. jassert (! stages.isEmpty());
  545. auto currentNumSamples = maximumNumberOfSamplesBeforeOversampling;
  546. for (auto* stage : stages)
  547. {
  548. stage->initProcessing (currentNumSamples);
  549. currentNumSamples *= stage->factor;
  550. }
  551. ProcessSpec spec = { 0.0, (uint32) maximumNumberOfSamplesBeforeOversampling, (uint32) numChannels };
  552. delay.prepare (spec);
  553. updateDelayLine();
  554. isReady = true;
  555. reset();
  556. }
  557. template <typename SampleType>
  558. void Oversampling<SampleType>::reset() noexcept
  559. {
  560. jassert (! stages.isEmpty());
  561. if (isReady)
  562. for (auto* stage : stages)
  563. stage->reset();
  564. delay.reset();
  565. }
  566. template <typename SampleType>
  567. AudioBlock<SampleType> Oversampling<SampleType>::processSamplesUp (const AudioBlock<const SampleType>& inputBlock) noexcept
  568. {
  569. jassert (! stages.isEmpty());
  570. if (! isReady)
  571. return {};
  572. auto* firstStage = stages.getUnchecked (0);
  573. firstStage->processSamplesUp (inputBlock);
  574. auto block = firstStage->getProcessedSamples (inputBlock.getNumSamples() * firstStage->factor);
  575. for (int i = 1; i < stages.size(); ++i)
  576. {
  577. stages[i]->processSamplesUp (block);
  578. block = stages[i]->getProcessedSamples (block.getNumSamples() * stages[i]->factor);
  579. }
  580. return block;
  581. }
  582. template <typename SampleType>
  583. void Oversampling<SampleType>::processSamplesDown (AudioBlock<SampleType>& outputBlock) noexcept
  584. {
  585. jassert (! stages.isEmpty());
  586. if (! isReady)
  587. return;
  588. auto currentNumSamples = outputBlock.getNumSamples();
  589. for (int n = 0; n < stages.size() - 1; ++n)
  590. currentNumSamples *= stages.getUnchecked(n)->factor;
  591. for (int n = stages.size() - 1; n > 0; --n)
  592. {
  593. auto& stage = *stages.getUnchecked(n);
  594. auto audioBlock = stages.getUnchecked (n - 1)->getProcessedSamples (currentNumSamples);
  595. stage.processSamplesDown (audioBlock);
  596. currentNumSamples /= stage.factor;
  597. }
  598. stages.getFirst()->processSamplesDown (outputBlock);
  599. if (shouldUseIntegerLatency && fractionalDelay > static_cast<SampleType> (0.0))
  600. {
  601. auto context = ProcessContextReplacing<SampleType> (outputBlock);
  602. delay.process (context);
  603. }
  604. }
  605. template <typename SampleType>
  606. void Oversampling<SampleType>::updateDelayLine()
  607. {
  608. auto latency = getUncompensatedLatency();
  609. fractionalDelay = static_cast<SampleType> (1.0) - (latency - std::floor (latency));
  610. if (fractionalDelay == static_cast<SampleType> (1.0))
  611. fractionalDelay = static_cast<SampleType> (0.0);
  612. else if (fractionalDelay < static_cast<SampleType> (0.618))
  613. fractionalDelay += static_cast<SampleType> (1.0);
  614. delay.setDelay (fractionalDelay);
  615. }
  616. template class Oversampling<float>;
  617. template class Oversampling<double>;
  618. } // namespace dsp
  619. } // namespace juce