46 auto spec_file = std::ifstream( spec_filename );
47 if ( !spec_file.is_open() )
49 std::cerr <<
"Error: Could not open device specification file.\n";
55 template <
class Sender,
class Receiver >
62 template <
class Clock,
class Backend,
class ClockSender,
class ClockReceiver,
class Sender >
69 template <
class Callback >
71 :
clock_comm_t< ClockSender, ClockReceiver >{ClockSender{}, ClockReceiver{callback}},
72 Sender{}, Backend{
get_spec(
"device_spec/elektron/digitakt.txt" )},
81 Backend::set_control(
id, value, Sender::sender() );
85 #define ADD_LFO_DESTINATION( section_name ) \ 87 auto& entry = device_spec_.control_parameter[ track_parameter_t::idx::section_name ]; \ 88 for ( decltype( entry.size() ) i = 0; i < entry.size(); ++i ) \ 91 .control_parameter[ track_parameter_t::idx::lfo ] \ 92 [ track_parameter_t::lfo_idx::destination ] \ 93 .str_map.push_back( #section_name + std::string( ":" ) + entry[ i ].name ); \ 94 lfo_map_.emplace_back( control_mode_t::section_name, i ); \ 305 : banks_( 16,
patterns_t( 16, midi::make_pattern< track_t >( 16, 16 ) ) ),
306 device_spec_{device_spec}
308 for (
auto& patterns : banks_ )
310 for (
auto& pattern : patterns )
312 for (
auto& track : pattern )
314 track.parameter().resize( device_spec.control_parameter.size() );
315 for ( decltype( track.parameter().size() ) i = 0;
316 i < track.parameter().size(); ++i )
318 track.parameter()[ i ].resize(
319 device_spec.control_parameter[ i ].size() );
320 for ( decltype( track.parameter()[ i ].size() ) j = 0;
321 j < track.parameter()[ i ].size(); ++j )
323 const auto value = device_spec.control_parameter[ i ][ j ].value;
324 track.parameter()[ i ][ j ] =
325 device_spec.control_parameter[ i ][ j ].map.empty()
327 : device_spec.control_parameter[ i ][ j ].map[ value ];
336 [ track_parameter_t::lfo_idx::destination ]
337 .str_map.emplace_back(
"none" );
346 [ track_parameter_t::lfo_idx::destination ]
348 std::int16_t( device_spec_
350 [ track_parameter_t::lfo_idx::destination ]
354 #undef ADD_LFO_DESTINATION 356 void set_step(
int idx,
bool value =
true ) noexcept
361 current_pattern()[ idx ].mute( !current_pattern()[ idx ].is_muted() );
364 current_track_idx_ = decltype( current_track_idx_ )( idx );
368 current_pattern_idx_ = decltype( current_pattern_idx_ )( idx );
372 current_bank_idx_ = decltype( current_bank_idx_ )( idx );
382 if ( current_step_ == idx ||
394 template <
class Sender >
399 const auto adjust_value_for_midi = [id, &value,
this] {
400 value -= spec()[ std::size_t(
id ) ].min;
403 switch ( control_mode() )
414 to_uint8_t( current_track().base_note() ) + std::uint8_t( value ) ) );
418 current_track()[ current_step_ ].set_velocity( std::uint8_t( value ) );
422 current_track()[ current_step_ ].set_length(
427 current_track()[ current_step() ].set_trig_condition(
434 current_track().parameter()[ track_parameter_t::idx::trig ][ std::size_t(
id ) ] =
436 adjust_value_for_midi();
438 current_track().channel(),
440 .control_parameter[ track_parameter_t::idx::trig ][ std::size_t(
id ) ]
447 current_track().parameter()[ track_parameter_t::idx::source ][ std::size_t(
id ) ] =
449 adjust_value_for_midi();
451 current_track().channel(),
453 .control_parameter[ track_parameter_t::idx::source ][ std::size_t(
id ) ]
461 adjust_value_for_midi();
463 current_track().channel(),
471 current_track().parameter()[ track_parameter_t::idx::amp ][ std::size_t(
id ) ] =
473 adjust_value_for_midi();
475 current_track().channel(),
477 .control_parameter[ track_parameter_t::idx::amp ][ std::size_t(
id ) ]
484 if ( spec()[ std::size_t(
id ) ].map.empty() )
493 spec()[ std::size_t(
id ) ].map[ value ];
495 const auto dest = current_track()
497 [ track_parameter_t::lfo_idx::destination ]
501 const auto target = lfo_map_[ std::size_t( dest - 1 ) ];
502 const auto& entry = spec( target.first )[ target.second ];
503 current_track().set_lfo(
504 entry.min, entry.max,
505 [cc_msb = entry.cc_msb,
506 channel = current_track().channel()]( std::uint8_t value ) {
510 adjust_value_for_midi();
515 const auto [ msb,
lsb ] = to_msb_lsb( value, spec()[ std::size_t(
id ) ].min,
516 spec()[ std::size_t(
id ) ].max );
518 current_track().channel(),
524 current_track().channel(),
532 current_track().channel(),
541 current_track().parameter()[ track_parameter_t::idx::delay ][ std::size_t(
id ) ] =
543 adjust_value_for_midi();
545 current_track().channel(),
547 .control_parameter[ track_parameter_t::idx::delay ][ std::size_t(
id ) ]
553 current_track().parameter()[ track_parameter_t::idx::reverb ][ std::size_t(
id ) ] =
555 adjust_value_for_midi();
557 current_track().channel(),
559 .control_parameter[ track_parameter_t::idx::reverb ][ std::size_t(
id ) ]
568 switch ( control_mode() )
571 return current_track()
572 .parameter()[ track_parameter_t::idx::trig ][ std::size_t(
id ) ]
575 return current_track()
576 .parameter()[ track_parameter_t::idx::source ][ std::size_t(
id ) ]
579 return current_track()
583 return current_track()
584 .parameter()[ track_parameter_t::idx::amp ][ std::size_t(
id ) ]
588 if ( spec()[ std::size_t(
id ) ].map.empty() )
590 return current_track()
594 return int( std::distance(
595 begin( spec()[ std::size_t(
id ) ].map ),
596 std::find( begin( spec()[ std::size_t(
id ) ].map ),
597 end( spec()[ std::size_t(
id ) ].map ),
602 return current_track()
603 .parameter()[ track_parameter_t::idx::delay ][ std::size_t(
id ) ]
606 return current_track()
607 .parameter()[ track_parameter_t::idx::reverb ][ std::size_t(
id ) ]
618 return current_pattern()[ step ].is_muted();
650 control_mode_ = mode;
655 return control_mode_;
658 template <
class Sender >
661 current_pattern().send_messages( message, sender );
666 return current_pattern()[ current_track_idx_ ];
671 return current_pattern()[ current_track_idx_ ];
676 return banks_[ current_bank_idx_ ][ current_pattern_idx_ ];
681 return banks_[ current_bank_idx_ ][ current_pattern_idx_ ];
686 return current_step_;
692 ? device_spec_.control_parameter[ track_parameter_t::idx::trig ]
694 ? device_spec_.control_parameter[ track_parameter_t::idx::source ]
700 .control_parameter[ track_parameter_t::idx::amp ]
702 ? device_spec_.control_parameter
705 ? device_spec_.control_parameter
706 [ track_parameter_t::idx::delay ]
707 : device_spec_.control_parameter
708 [ track_parameter_t::idx::reverb ];
711 const std::vector< midi::device_entry_t >&
spec()
const 713 return spec( control_mode() );
717 constexpr std::pair< std::uint8_t, std::uint8_t > to_msb_lsb(
int value,
int min,
718 int max )
const noexcept
720 const auto spread = max - min;
724 const auto msb = value / a;
731 banks_t::size_type current_bank_idx_ = 0;
732 patterns_t::size_type current_pattern_idx_ = 0;
736 int current_step_{-1};
738 std::vector< std::pair< control_mode_t, std::size_t > > lfo_map_;
typename std::vector< value_type >::size_type size_type
Definition: pattern.hpp:14
mode_t
Definition: digitakt.hpp:20
Definition: digitakt.hpp:63
void set_step(int idx, bool value=true) noexcept
Definition: digitakt.hpp:356
note_t
Definition: note.hpp:11
track_t & current_track() noexcept
Definition: digitakt.hpp:664
Definition: trig_condition.hpp:16
pattern_t & current_pattern() noexcept
Definition: digitakt.hpp:674
const std::vector< midi::device_entry_t > & spec() const
Definition: digitakt.hpp:711
Definition: trig_condition.hpp:36
Definition: callable.hpp:9
const std::array< double, 128 > & length_map()
Definition: digitakt_parameter.hpp:47
void filter(Container &c, TransferFunction f, double base_frequency)
Definition: transfer_function.hpp:42
std::conditional_t< greater_than< number_of_bytes, 0 >::value, std::array< std::byte, number_of_bytes >, std::vector< std::byte > > message_t
Definition: message_type.hpp:18
std::vector< patterns_t > banks_t
Definition: digitakt.hpp:302
#define SEQUENCER_ASSERT(cond)
Definition: assert.hpp:8
const std::vector< midi::device_entry_t > & spec(control_mode_t mode) const
Definition: digitakt.hpp:689
constexpr auto number_of_values_per_byte
Definition: constants.hpp:7
constexpr void set_control_mode(control_mode_t mode) noexcept
Definition: digitakt.hpp:648
void set_control(int id, int value) noexcept
Definition: digitakt.hpp:79
const track_t & current_track() const noexcept
Definition: digitakt.hpp:669
constexpr auto lsb(std::byte msb)
Definition: byte.hpp:37
void receive_clock_message(sequencer::midi::message_t< 1 > message, Sender sender)
Definition: digitakt.hpp:659
Definition: beat_duration.hpp:13
constexpr message_t< 3 > control_change(std::uint8_t channel, std::byte controller, std::byte value) noexcept
Definition: channel_voice.hpp:44
Clock([this](midi::message_t< 1 > message) { clock_comm_t< ClockSender, ClockReceiver >::clock_sender.sender()(message);})
Definition: digitakt.hpp:73
constexpr std::uint8_t to_uint8_t(note_t note) noexcept
Definition: note.hpp:21
backend_t(Callback callback)
Definition: digitakt.hpp:70
const pattern_t & current_pattern() const noexcept
Definition: digitakt.hpp:679
device_spec_cc_t read_device_spec_cc(std::istream &stream)
Definition: digitakt_parameter.hpp:251
T lfo(std::size_t pulse_count, std::size_t pulses_per_quarter_note, int speed, int phase, T min, T max, lfo_mode mode)
Definition: lfo.hpp:62
Sender clock_sender
Definition: digitakt.hpp:58
constexpr mode_t mode() const noexcept
Definition: digitakt.hpp:643
backend_impl(const device_spec_cc_t &device_spec=device_spec_cc_t{})
Definition: digitakt.hpp:304
midi::trig_condition_t get_trig_condition(int value)
Definition: digitakt.hpp:98
bool is_step_set(int step) const noexcept
Definition: digitakt.hpp:614
constexpr int current_step() const noexcept
Definition: digitakt.hpp:684
Receiver clock_receiver
Definition: digitakt.hpp:59
Definition: trig_condition.hpp:19
constexpr control_mode_t control_mode() const noexcept
Definition: digitakt.hpp:653
std::vector< pattern_t > patterns_t
Definition: digitakt.hpp:301
constexpr void set_mode(mode_t mode) noexcept
Definition: digitakt.hpp:624
Definition: pattern.hpp:10
Definition: digitakt.hpp:56
void set_control(int id, int value, Sender sender) noexcept
Definition: digitakt.hpp:395
device_spec_cc_t get_spec(const std::string &spec_filename)
Definition: digitakt.hpp:44
control_mode_t
Definition: digitakt.hpp:30
Definition: track.hpp:368
Definition: digitakt.hpp:18
int get_control_value(int id) const noexcept
Definition: digitakt.hpp:566
typename track_impl_t< Step, Parameter >::size_type size_type
Definition: track.hpp:371
Definition: digitakt.hpp:296
Definition: digitakt_parameter.hpp:53
#define ADD_LFO_DESTINATION(section_name)
Definition: digitakt.hpp:85