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.

83 lines
2.5KB

  1. #pragma once
  2. #include "SawOscillator.h"
  3. #include "LookupTable.h"
  4. #include "AudioMath.h"
  5. template<typename T> class SinOscillatorParams;
  6. template<typename T> class SinOscillatorState;
  7. /**
  8. * A simple sin oscillator based on lookup table.
  9. * Advantage:
  10. * fast.
  11. * frequency may be changed without phase discontinuity.
  12. * Optional quadrature output.
  13. * Disadvantage:
  14. * Not the best spectral purity (significant amount of phase jitter)
  15. */
  16. template<typename T, bool frequencyCanBeNegative>
  17. class SinOscillator
  18. {
  19. public:
  20. static void setFrequency(SinOscillatorParams<T>&, T frequency);
  21. static T run(SinOscillatorState<T>&, const SinOscillatorParams<T>&);
  22. static void runQuadrature(T& output, T& outputQuadrature, SinOscillatorState<T>&, const SinOscillatorParams<T>&);
  23. };
  24. template<typename T, bool frequencyCanBeNegative>
  25. inline void SinOscillator<T, frequencyCanBeNegative>::setFrequency(SinOscillatorParams<T>& params, T frequency)
  26. {
  27. std::function<double(double)> f = AudioMath::makeFunc_Sin();
  28. // TODO: figure out a better initialization strategy
  29. // and a better strategy for table size
  30. if (!params.lookupParams.isValid()) {
  31. LookupTable<T>::init(params.lookupParams, 4096, 0, 1, f);
  32. }
  33. SawOscillator<T, true>::setFrequency(params.sawParams, frequency);
  34. }
  35. template<typename T, bool frequencyCanBeNegative>
  36. inline T SinOscillator<T, frequencyCanBeNegative>::run(
  37. SinOscillatorState<T>& state, const SinOscillatorParams<T>& params)
  38. {
  39. const T temp = SawOscillator<T, frequencyCanBeNegative>::run(state.sawState, params.sawParams);
  40. const T ret = LookupTable<T>::lookup(params.lookupParams, temp);
  41. return ret;
  42. }
  43. template<typename T, bool frequencyCanBeNegative>
  44. inline void SinOscillator<T, frequencyCanBeNegative>::runQuadrature(
  45. T& output, T& outputQuadrature, SinOscillatorState<T>& state, const SinOscillatorParams<T>& params)
  46. {
  47. T saw, quadratureSaw;
  48. SawOscillator<T, frequencyCanBeNegative>::runQuadrature(saw, quadratureSaw, state.sawState, params.sawParams);
  49. output = LookupTable<T>::lookup(params.lookupParams, saw);
  50. outputQuadrature = LookupTable<T>::lookup(params.lookupParams, quadratureSaw);
  51. };
  52. template<typename T>
  53. class SinOscillatorParams
  54. {
  55. public:
  56. SawOscillatorParams<T> sawParams;
  57. LookupTableParams<T> lookupParams;
  58. SinOscillatorParams()
  59. {
  60. }
  61. SinOscillatorParams(const SinOscillatorParams&) = delete;
  62. };
  63. template<typename T>
  64. class SinOscillatorState
  65. {
  66. public:
  67. SawOscillatorState<T> sawState;
  68. };