libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/synth/oscillator.hpp
Go to the documentation of this file.
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 */