|
libpsynth 0.2.1
|
00001 00012 #ifndef PSYNTH_SYNTH_OSCILLATOR_H 00013 #define PSYNTH_SYNTH_OSCILLATOR_H 00014 00015 #include <cmath> 00016 #include <psynth/base/misc.hpp> 00017 #include <psynth/sound/typedefs.hpp> 00018 #include <psynth/synth/wave_table.hpp> 00019 00020 namespace psynth 00021 { 00022 namespace synth 00023 { 00024 00025 /* TODO: Find a way to avoid this. */ 00026 class envelope_simple; 00027 00028 struct sine_generator 00029 { 00030 PSYNTH_FORCEINLINE sound::bits32sf 00031 operator () (float x) 00032 { return std::sin (2 * M_PI * x); } 00033 }; 00034 00035 struct square_generator 00036 { 00037 PSYNTH_FORCEINLINE sound::bits32sf 00038 operator () (float x) 00039 { return base::phase (x) > 0.5f ? -1.0 : 1.0; } 00040 }; 00041 00042 struct triangle_generator 00043 { 00044 PSYNTH_FORCEINLINE sound::bits32sf 00045 operator () (float x) 00046 { 00047 float p = base::phase (x); 00048 if (p <= 0.25f) 00049 return p * 4.0f; 00050 else if (p <= 0.75f) 00051 return 2.0f - p * 4.0f; 00052 return p * 4.0f - 4.0f; 00053 } 00054 }; 00055 00056 struct sawtooth_generator 00057 { 00058 PSYNTH_FORCEINLINE sound::bits32sf 00059 operator () (float x) 00060 { 00061 return -1.0f + base::phase(x) * 2.0f; 00062 } 00063 }; 00064 00065 struct moogsaw_generator 00066 { 00067 PSYNTH_FORCEINLINE sound::bits32sf 00068 operator () (float x) 00069 { 00070 float p = base::phase (x); 00071 if(p < 0.5f ) 00072 return -1.0f + p * 4.0f; 00073 return 1.0f - 2.0f * p; 00074 } 00075 }; 00076 00077 struct exp_generator 00078 { 00079 PSYNTH_FORCEINLINE sound::bits32sf 00080 operator () (float x) 00081 { 00082 float p = base::phase (x); 00083 if(p > 0.5f) 00084 p = 1.0f - p; 00085 return -1.0f + 8.0f * p * p; 00086 } 00087 }; 00088 00089 00090 template <class Generator = sine_generator> 00091 class oscillator 00092 { 00093 public: 00095 static const std::size_t default_table_size = 1 << 12; 00096 00097 oscillator (std::size_t frame_rate, 00098 float freq = 220.0f, 00099 float ampl = 1.0f, 00100 float phase = 0.0f, 00101 bool wave_table = true) 00102 : _frame_rate (frame_rate) 00103 , _speed (freq / frame_rate) 00104 , _x (phase) 00105 , _freq (freq) 00106 , _ampl (ampl) 00107 , _phase (phase) 00108 , _wave_table (wave_table) 00109 { 00110 if (wave_table && !s_table_init) 00111 initialize_table (); 00112 } 00113 00114 void restart () 00115 { _x = 0.0f; } 00116 00117 void set_frame_rate (std::size_t frame_rate) 00118 { _frame_rate = frame_rate; _speed = _freq / frame_rate; } 00119 00120 void set_frequency (float freq) 00121 { _freq = freq; _speed = freq / _frame_rate; } 00122 00123 void set_amplitude (float ampl) 00124 { _ampl = ampl; } 00125 00126 void set_phase (float phase) 00127 { _x += phase - _phase; _phase = phase; } 00128 00129 void set_wave_table (bool wave_table) 00130 { 00131 if (wave_table && !s_table_init) 00132 initialize_table (); 00133 _wave_table = wave_table; 00134 } 00135 00136 template <class Range1> 00137 void update (const Range1& out_buf); 00138 00139 template <class Range1, class Range2> 00140 void update_fm (const Range1& out_buf, const Range2& mod_buf); 00141 00142 template <class Range1, class Range2> 00143 void update_pm (const Range1& out_buf, const Range2& mod_buf); 00144 00145 template <class Range1, class Range2> 00146 void update_am (const Range1& out_buf, const Range2& mod_buf); 00147 00148 private: 00149 static wave_table<sound::mono32sf_buffer> s_wave_table; 00150 static bool s_table_init; 00151 00152 Generator _gen; 00153 std::size_t _frame_rate; 00154 float _speed; 00155 float _x; 00156 float _freq; 00157 float _ampl; 00158 float _phase; 00159 bool _wave_table; 00160 00161 void initialize_table (); 00162 }; 00163 00164 } /* namespace synth */ 00165 } /* namespace psynth */ 00166 00167 #include <psynth/synth/oscillator.tpp> 00168 00169 #endif /* PSYNTH_OSCILLATOR_H */
1.7.4