sequencer
delay.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 
6 #include <chrono>
7 #include <mutex>
8 #include <numeric>
9 #include <thread>
10 #include <vector>
11 
13 {
14  class delay_t
15  {
16  public:
17  using size_type = std::vector< float >::size_type;
18 
19  explicit delay_t( size_type frame_count = 0, float gain = 1.0f )
20  : buffer_( frame_count, 0.0f ), gain_{gain}
21  {
22  }
23 
25  {
26  std::lock_guard lock{mutex_};
27  buffer_.resize( frame_count, 0.0f );
28  if ( frame_count > 0 )
29  {
30  current_ = current_ % buffer_.size();
31  reset_unlocked();
32  }
33  }
34 
35  size_type frame_count() const noexcept
36  {
37  std::lock_guard lock{mutex_};
38  return buffer_.size();
39  }
40 
41  float operator()( float x ) noexcept
42  {
43  std::lock_guard lock{mutex_};
44  if ( buffer_.empty() )
45  {
46  return 0;
47  }
48 
49  const auto y = buffer_[ current_ ];
50  buffer_[ current_ ] = x;
51  current_ = ( ++current_ ) % buffer_.size();
52  return gain_ * y;
53  }
54 
55  void reset() noexcept
56  {
57  std::lock_guard lock{mutex_};
58  reset_unlocked();
59  }
60 
61  void set_gain( float gain ) noexcept
62  {
63  gain_ = gain;
64  }
65 
66  float gain() const noexcept
67  {
68  return gain_;
69  }
70 
71  delay_t( const delay_t& other )
72  {
73  std::lock_guard lock{other.mutex_};
74  buffer_ = other.buffer_;
75  current_ = other.current_;
76  gain_ = other.gain_;
77  }
78 
79  delay_t& operator=( const delay_t& other )
80  {
81  if ( this == &other )
82  {
83  return *this;
84  }
85 
86  std::lock( mutex_, other.mutex_ );
87  std::lock_guard lock{mutex_, std::adopt_lock};
88  std::lock_guard lock_other{other.mutex_, std::adopt_lock};
89 
90  buffer_ = other.buffer_;
91  current_ = other.current_;
92  gain_ = other.gain_;
93  return *this;
94  }
95 
96  private:
97  void reset_unlocked() noexcept
98  {
99  for ( auto& entry : buffer_ )
100  {
101  entry = 0;
102  }
103  }
104 
105  mutable std::mutex mutex_;
106  std::vector< float > buffer_{};
107  size_type current_{0};
108  copyable_atomic< float > gain_{1};
109  };
110 
111  template < class Delay >
113  {
114  public:
115  using size_type = typename Delay::size_type;
116 
117  explicit repeated_delay_t( size_type delay_count = 0, size_type frame_count = 0,
118  float gain = 1.0f )
119  : delays_( delay_count, Delay{frame_count, gain} )
120  {
121  }
122 
123  float operator()( float x ) noexcept
124  {
125  std::lock_guard lock{mutex_};
126  return std::accumulate( begin( delays_ ), end( delays_ ), float( 0 ),
127  [&x]( float z, auto& delay ) {
128  x = delay( x );
129  return z += x;
130  } );
131  }
132 
133  void set_frame_count( std::vector< float >::size_type frame_count ) noexcept
134  {
135  std::lock_guard lock{mutex_};
136  for ( auto& delay : delays_ )
137  {
138  delay.set_frame_count( frame_count );
139  }
140  }
141 
142  void reset() noexcept
143  {
144  std::lock_guard lock{mutex_};
145  for ( auto& delay : delays_ )
146  {
147  delay.reset();
148  }
149  }
150 
151  void set_gain( float gain ) noexcept
152  {
153  std::lock_guard lock{mutex_};
154  for ( auto& delay : delays_ )
155  {
156  delay.set_gain( gain );
157  }
158  }
159 
160  void set_delay_count( std::vector< delay_t >::size_type count )
161  {
162  std::lock_guard lock{mutex_};
163  const auto non_empty = !delays_.empty();
164 
165  delays_.resize( count, delay_t{non_empty ? delays_.front().frame_count() : 0,
166  non_empty ? delays_.front().gain() : 1.0f} );
167  }
168 
169  private:
170  std::mutex mutex_;
171  std::vector< Delay > delays_{};
172  };
173 
174  template < class Delay >
175  class stereo_delay_t : public Delay
176  {
177  public:
178  using Delay::Delay;
179 
180  std::pair< float, float > operator()( float x ) noexcept
181  {
182  const auto y = Delay::operator()( x );
183  return {( 1.0f - ratio_ ) * y, ratio_ * y};
184  }
185 
186  void set_stereo_ratio( float ratio ) noexcept
187  {
188  ratio_ = ratio;
189  }
190 
191  private:
192  float ratio_{0.5};
193  };
194 
196 } // namespace sequencer::audio
size_type frame_count() const noexcept
Definition: delay.hpp:35
delay_t(size_type frame_count=0, float gain=1.0f)
Definition: delay.hpp:19
float operator()(float x) noexcept
Definition: delay.hpp:41
Definition: delay.hpp:175
void set_frame_count(std::vector< float >::size_type frame_count) noexcept
Definition: delay.hpp:133
typename Delay::size_type size_type
Definition: delay.hpp:115
void set_gain(float gain) noexcept
Definition: delay.hpp:61
float operator()(float x) noexcept
Definition: delay.hpp:123
void set_gain(float gain) noexcept
Definition: delay.hpp:151
std::vector< float >::size_type size_type
Definition: delay.hpp:17
void reset() noexcept
Definition: delay.hpp:142
void set_frame_count(size_type frame_count)
Definition: delay.hpp:24
float gain() const noexcept
Definition: delay.hpp:66
Definition: delay.hpp:12
void set_delay_count(std::vector< delay_t >::size_type count)
Definition: delay.hpp:160
Definition: delay.hpp:14
std::pair< float, float > operator()(float x) noexcept
Definition: delay.hpp:180
void set_stereo_ratio(float ratio) noexcept
Definition: delay.hpp:186
Definition: delay.hpp:112
void reset() noexcept
Definition: delay.hpp:55
repeated_delay_t(size_type delay_count=0, size_type frame_count=0, float gain=1.0f)
Definition: delay.hpp:117
delay_t & operator=(const delay_t &other)
Definition: delay.hpp:79
delay_t(const delay_t &other)
Definition: delay.hpp:71