sequencer
step.hpp
Go to the documentation of this file.
1 #pragma once
2 
7 
8 #include <cstdint>
9 #include <mutex>
10 #include <optional>
11 #include <ostream>
12 
13 namespace sequencer::midi
14 {
15  class step_t
16  {
17  public:
18  constexpr explicit step_t( bool active = false ) noexcept : is_active_{active}
19  {
20  }
21 
22  constexpr explicit step_t( note_t note ) noexcept
23  : is_active_{note != no_note()}, note_{note}
24  {
25  }
26 
27  constexpr step_t( note_t note, std::uint8_t velocity ) noexcept
28  : is_active_{note != no_note()}, note_{note}, velocity_{velocity}
29  {
30  }
31 
32  constexpr step_t( note_t note, std::uint8_t velocity, beat_duration length ) noexcept
33  : is_active_{note != no_note()}, note_{note}, velocity_{velocity}, length_{length}
34  {
35  }
36 
37  step_t( const step_t& other ) noexcept
38  {
39  copy_from( other );
40  }
41 
42  step_t& operator=( const step_t& other ) noexcept
43  {
44  copy_from( other );
45  return *this;
46  }
47 
48  void set_active( bool active ) noexcept
49  {
50  is_active_ = active;
51  }
52 
53  bool is_active() const noexcept
54  {
55  return is_active_;
56  }
57 
58  void set_note( note_t note ) noexcept
59  {
60  set_active( note != no_note() );
61  note_ = note;
62  }
63 
64  constexpr const std::optional< copyable_atomic< note_t > >& note() const noexcept
65  {
66  return note_;
67  }
68 
69  void set_velocity( std::uint8_t velocity ) noexcept
70  {
71  velocity_ = velocity;
72  }
73 
74  constexpr const std::optional< copyable_atomic< std::uint8_t > >& velocity() const noexcept
75  {
76  return velocity_;
77  }
78 
79  void set_length( beat_duration length ) noexcept
80  {
81  length_ = length;
82  }
83 
84  constexpr const std::optional< copyable_atomic< beat_duration > >& length() const noexcept
85  {
86  return length_;
87  }
88 
89  template < class F >
90  void set_trig_condition( F f ) noexcept
91  {
92  std::lock_guard lock{trig_condition_mutex_};
93  trig_condition_ = f;
94  }
95 
96  bool evaluate_trig_condition() const noexcept
97  {
98  std::lock_guard lock{trig_condition_mutex_};
99  return !trig_condition_ || trig_condition_();
100  }
101 
102  private:
103  void copy_from( const step_t& other ) noexcept
104  {
105  is_active_ = other.is_active();
106  note_ = other.note();
107  velocity_ = other.velocity();
108  length_ = other.length();
109  trig_condition_ = other.trig_condition_;
110  }
111 
112  copyable_atomic< bool > is_active_{false};
113  std::optional< copyable_atomic< note_t > > note_{};
114  std::optional< copyable_atomic< std::uint8_t > > velocity_{};
115  std::optional< copyable_atomic< beat_duration > > length_{};
116  mutable std::mutex trig_condition_mutex_{};
117  trig_condition_t trig_condition_{};
118  };
119 
120  inline std::ostream& operator<<( std::ostream& os, const step_t& step )
121  {
122  return os << "(" << step.is_active() << ", "
123  << ( step.note() ? std::to_string( to_uint8_t( step.note()->load() ) )
124  : std::string( "-" ) )
125  << ","
126  << ( step.velocity() ? std::to_string( step.velocity()->load() )
127  : std::string( "-" ) )
128  << ")";
129  }
130 
131  inline bool operator==( const step_t& lhs, const step_t& rhs ) noexcept
132  {
133  return lhs.is_active() == rhs.is_active() && lhs.note() == rhs.note() &&
134  lhs.velocity() == rhs.velocity() && lhs.length() == rhs.length();
135  }
136 
137  inline bool operator!=( const step_t& lhs, const step_t& rhs ) noexcept
138  {
139  return !( lhs == rhs );
140  }
141 } // namespace sequencer::midi
constexpr const std::optional< copyable_atomic< beat_duration > > & length() const noexcept
Definition: step.hpp:84
void set_active(bool active) noexcept
Definition: step.hpp:48
note_t
Definition: note.hpp:11
constexpr step_t(note_t note, std::uint8_t velocity, beat_duration length) noexcept
Definition: step.hpp:32
void set_velocity(std::uint8_t velocity) noexcept
Definition: step.hpp:69
void set_trig_condition(F f) noexcept
Definition: step.hpp:90
bool evaluate_trig_condition() const noexcept
Definition: step.hpp:96
const auto F
Definition: note.hpp:40
constexpr step_t(bool active=false) noexcept
Definition: step.hpp:18
constexpr const std::optional< copyable_atomic< std::uint8_t > > & velocity() const noexcept
Definition: step.hpp:74
constexpr const std::optional< copyable_atomic< note_t > > & note() const noexcept
Definition: step.hpp:64
std::ostream & operator<<(std::ostream &os, const device_entry_t &entry)
Definition: device_spec.hpp:34
Definition: beat_duration.hpp:13
constexpr std::uint8_t to_uint8_t(note_t note) noexcept
Definition: note.hpp:21
step_t(const step_t &other) noexcept
Definition: step.hpp:37
constexpr step_t(note_t note) noexcept
Definition: step.hpp:22
bool operator==(const step_t &lhs, const step_t &rhs) noexcept
Definition: step.hpp:131
Definition: step.hpp:15
constexpr step_t(note_t note, std::uint8_t velocity) noexcept
Definition: step.hpp:27
step_t & operator=(const step_t &other) noexcept
Definition: step.hpp:42
Definition: clock.hpp:13
std::string_view to_string(percussion_key key)
Definition: percussion_key.hpp:69
bool is_active() const noexcept
Definition: step.hpp:53
void set_length(beat_duration length) noexcept
Definition: step.hpp:79
void set_note(note_t note) noexcept
Definition: step.hpp:58
bool operator!=(const step_t &lhs, const step_t &rhs) noexcept
Definition: step.hpp:137