1 // Copyright 2013 Olivier Gillet. 2 // 3 // Author: Olivier Gillet (ol.gillet@gmail.com) 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 // 23 // See http://creativecommons.org/licenses/MIT/ for more information. 24 // 25 // ----------------------------------------------------------------------------- 26 // 27 // Poly LFO. 28 29 #ifndef FRAMES_POLY_LFO_H_ 30 #define FRAMES_POLY_LFO_H_ 31 32 #include "stmlib/stmlib.h" 33 34 #include "frames/keyframer.h" 35 36 namespace frames { 37 38 class PolyLfo { 39 public: PolyLfo()40 PolyLfo() { } ~PolyLfo()41 ~PolyLfo() { } 42 43 void Init(); 44 void Render(int32_t frequency); 45 set_shape(uint16_t shape)46 inline void set_shape(uint16_t shape) { 47 shape_ = shape; 48 } set_shape_spread(uint16_t shape_spread)49 inline void set_shape_spread(uint16_t shape_spread) { 50 shape_spread_ = static_cast<int16_t>(shape_spread - 32768) >> 1; 51 } set_spread(uint16_t spread)52 inline void set_spread(uint16_t spread) { 53 if (spread < 32768) { 54 int32_t x = spread - 32768; 55 int32_t scaled = -(x * x >> 15); 56 spread_ = (x + 3 * scaled) >> 2; 57 } else { 58 spread_ = spread - 32768; 59 } 60 } set_coupling(uint16_t coupling)61 inline void set_coupling(uint16_t coupling) { 62 int32_t x = coupling - 32768; 63 int32_t scaled = x * x >> 15; 64 scaled = x > 0 ? scaled : - scaled; 65 scaled = (x + 3 * scaled) >> 2; 66 coupling_ = (scaled >> 4) * 10; 67 68 } level(uint8_t index)69 inline uint8_t level(uint8_t index) const { 70 return level_[index]; 71 } color()72 inline const uint8_t* color() const { 73 return &color_[0]; 74 } dac_code(uint8_t index)75 inline const uint16_t dac_code(uint8_t index) const { 76 return dac_code_[index]; 77 } 78 static uint32_t FrequencyToPhaseIncrement(int32_t frequency); 79 80 void Reset(); 81 void Randomize(); 82 83 private: 84 static const uint8_t rainbow_[17][3]; 85 86 uint16_t shape_; 87 int16_t shape_spread_; 88 int32_t spread_; 89 int16_t coupling_; 90 91 int16_t value_[kNumChannels]; 92 uint32_t phase_[kNumChannels]; 93 uint8_t level_[kNumChannels]; 94 uint16_t dac_code_[kNumChannels]; 95 uint8_t color_[3]; 96 97 DISALLOW_COPY_AND_ASSIGN(PolyLfo); 98 }; 99 100 } // namespace frames 101 102 #endif // FRAMES_POLY_LFO_H_ 103