sequencer
wave_form.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <array>
5 #include <cassert>
6 #include <chrono>
7 #include <cmath>
8 #include <random>
9 
11 {
12  inline double normalize_time( double t ) noexcept
13  {
14  auto result = std::fmod( t, 1.0 );
15  if ( result < 0.0 )
16  result += 1;
17  return result;
18  }
19 
20  class pulse_t
21  {
22  public:
23  constexpr explicit pulse_t( double pulse_width ) noexcept : pulse_width_( pulse_width )
24  {
25  }
26 
27  double operator()( double t ) const noexcept
28  {
29  t = normalize_time( t );
30  return ( t < pulse_width_ ) ? 1 : 0;
31  }
32 
33  private:
34  double pulse_width_;
35  };
36 
37  template < int N >
38  std::array< double, N > create_sine_sample() noexcept
39  {
40  std::array< double, N > sample;
41  typename std::array< double, N >::size_type counter = 0;
42  std::generate( begin( sample ), end( sample ),
43  [&counter] { return std::sin( 2 * M_PI * double( counter++ ) / N ); } );
44  return sample;
45  }
46 
47  inline double sine( double t )
48  {
49  constexpr auto sample_rate = 4 * 44100u;
50  static const auto sample = create_sine_sample< sample_rate >();
51  return sample[ std::size_t( t * sample_rate ) % sample_rate ];
52  }
53 
54  template < int N >
55  std::array< double, N > create_cosine_sample() noexcept
56  {
57  std::array< double, N > sample;
58  typename std::array< double, N >::size_type counter = 0;
59  std::generate( begin( sample ), end( sample ),
60  [&counter] { return std::cos( 2 * M_PI * double( counter++ ) / N ); } );
61  return sample;
62  }
63 
64  inline double cosine( double t )
65  {
66  constexpr auto sample_rate = 4 * 44100u;
67  static const auto sample = create_cosine_sample< sample_rate >();
68  return sample[ std::size_t( t * sample_rate ) % sample_rate ];
69  }
70 
71  inline double sinc( double cutoff, int i )
72  {
73  if ( i == 0 )
74  {
75  return 2 * cutoff;
76  }
77  if ( i < 0 )
78  {
79  return -sine( cutoff * -i ) / ( M_PI * i );
80  }
81  return sine( cutoff * i ) / ( M_PI * i );
82  }
83 
84  inline double square( double t ) noexcept
85  {
86  return normalize_time( t ) < 0.5 ? 1 : -1;
87  }
88 
89  inline double triangular( double t ) noexcept
90  {
91  t = normalize_time( t + 0.25 );
92  const auto value = -1 + 4 * std::fmod( t, 0.5 );
93  return t < 0.5 ? value : -value;
94  }
95 
96  inline double saw( double t ) noexcept
97  {
98  return 1 - 2 * normalize_time( t );
99  }
100 
101  class exp_t
102  {
103  public:
104  constexpr explicit exp_t( double scale ) noexcept : scale_{scale}
105  {
106  }
107 
108  double operator()( double t ) const noexcept
109  {
110  return std::exp( -scale_ * normalize_time( t ) );
111  }
112 
113  private:
114  double scale_{1};
115  };
116 
117  class ramp_t
118  {
119  public:
120  constexpr explicit ramp_t( double slope ) noexcept : slope_{slope}
121  {
122  }
123 
124  double operator()( double t ) const noexcept
125  {
126  t = normalize_time( t );
127  return ( t > ( 1 / slope_ ) ) ? 0 : ( slope_ * t );
128  }
129 
130  private:
131  double slope_{1};
132  };
133 
134  inline double random()
135  {
136  using clock = std::chrono::system_clock;
137 
138  static const auto seed =
139  clock::from_time_t( std::time( nullptr ) ).time_since_epoch().count();
140  static std::minstd_rand engine( seed );
141  static std::uniform_real_distribution< double > distribution{};
142 
143  return distribution( engine, std::uniform_real_distribution< double >::param_type{
144  -1, 1 + std::numeric_limits< double >::epsilon()} );
145  }
146 } // namespace sequencer::wave_form
std::array< double, N > create_cosine_sample() noexcept
Definition: wave_form.hpp:55
std::array< double, N > create_sine_sample() noexcept
Definition: wave_form.hpp:38
constexpr exp_t(double scale) noexcept
Definition: wave_form.hpp:104
double square(double t) noexcept
Definition: wave_form.hpp:84
double operator()(double t) const noexcept
Definition: wave_form.hpp:108
Definition: wave_form.hpp:101
double operator()(double t) const noexcept
Definition: wave_form.hpp:27
double saw(double t) noexcept
Definition: wave_form.hpp:96
Definition: wave_form.hpp:117
double operator()(double t) const noexcept
Definition: wave_form.hpp:124
double sine(double t)
Definition: wave_form.hpp:47
Definition: wave_form.hpp:10
constexpr pulse_t(double pulse_width) noexcept
Definition: wave_form.hpp:23
double sinc(double cutoff, int i)
Definition: wave_form.hpp:71
double cosine(double t)
Definition: wave_form.hpp:64
constexpr ramp_t(double slope) noexcept
Definition: wave_form.hpp:120
double normalize_time(double t) noexcept
Definition: wave_form.hpp:12
Definition: wave_form.hpp:20
double random()
Definition: wave_form.hpp:134
double triangular(double t) noexcept
Definition: wave_form.hpp:89