triggerbox: skeleton framework for MIDI triggers (non-functional)

This commit is contained in:
Paul Davis
2021-10-20 16:19:09 -06:00
parent 6695423fe7
commit d4ef49b504
2 changed files with 277 additions and 0 deletions

View File

@@ -37,6 +37,8 @@
#include "temporal/tempo.h"
#include "ardour/processor.h"
#include "ardour/rt_midibuffer.h"
#include "ardour/libardour_visibility.h"
class XMLNode;
@@ -46,6 +48,7 @@ namespace ARDOUR {
class Session;
class AudioRegion;
class MidiRegion;
class TriggerBox;
class SideChain;
@@ -266,6 +269,58 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
void compute_and_set_length ();
};
class LIBARDOUR_API MIDITrigger : public Trigger {
public:
MIDITrigger (uint64_t index, TriggerBox&);
~MIDITrigger ();
int run (BufferSet&, pframes_t nframes, pframes_t offset, bool first);
void set_start (timepos_t const &);
void set_end (timepos_t const &);
void set_legato_offset (timepos_t const &);
timepos_t current_pos() const;
/* this accepts timepos_t because the origin is assumed to be the start */
void set_length (timecnt_t const &);
timepos_t start_offset () const;
timepos_t end() const; /* offset from start of data */
timepos_t current_length() const; /* offset from start of data */
timepos_t natural_length() const; /* offset from start of data */
double position_as_fraction() const;
int set_region (boost::shared_ptr<Region>);
void startup ();
void jump_start ();
void jump_stop ();
XMLNode& get_state (void);
int set_state (const XMLNode&, int version);
void tempo_map_change ();
protected:
void retrigger ();
void set_usable_length ();
private:
PBD::ID data_source;
RTMidiBuffer* data;
Temporal::Beats last_read;
Temporal::Beats data_length;
Temporal::BBT_Offset _start_offset;
Temporal::BBT_Offset _legato_offset;
Temporal::Beats usable_length;
Temporal::Beats last;
void drop_data ();
int load_data (boost::shared_ptr<MidiRegion>);
RunResult at_end ();
void compute_and_set_length ();
};
class LIBARDOUR_API TriggerBox : public Processor
{
public:

View File

@@ -16,6 +16,7 @@
#include "ardour/audio_buffer.h"
#include "ardour/debug.h"
#include "ardour/midi_buffer.h"
#include "ardour/midi_region.h"
#include "ardour/minibpm.h"
#include "ardour/port.h"
#include "ardour/region_factory.h"
@@ -944,6 +945,227 @@ AudioTrigger::run (BufferSet& bufs, pframes_t nframes, pframes_t dest_offset, bo
return 0;
}
/*--------------------*/
MIDITrigger::MIDITrigger (uint64_t n, TriggerBox& b)
: Trigger (n, b)
, data (0)
, last_read (0, 0)
, data_length (0, 0)
, _start_offset (0, 0, 0)
, _legato_offset (0, 0, 0)
, usable_length (0, 0)
, last (0, 0)
{
}
MIDITrigger::~MIDITrigger ()
{
delete data;
}
void
MIDITrigger::startup ()
{
Trigger::startup ();
retrigger ();
}
void
MIDITrigger::jump_start ()
{
Trigger::jump_start ();
retrigger ();
}
void
MIDITrigger::jump_stop ()
{
Trigger::jump_stop ();
retrigger ();
}
double
MIDITrigger::position_as_fraction () const
{
if (!active()) {
return 0.0;
}
Temporal::DoubleableBeats lr (last_read);
Temporal::DoubleableBeats ul (usable_length);
return lr.to_double() / ul.to_double();
}
XMLNode&
MIDITrigger::get_state (void)
{
XMLNode& node (Trigger::get_state());
node.set_property (X_("start"), start_offset());
node.set_property (X_("length"), timepos_t (usable_length));
return node;
}
int
MIDITrigger::set_state (const XMLNode& node, int version)
{
timepos_t t;
if (!Trigger::set_state (node, version)) {
return -1;
}
node.get_property (X_("start"), t);
Temporal::Beats b (t.beats());
/* XXX need to deal with bar offsets */
_start_offset = Temporal::BBT_Offset (0, b.get_beats(), b.get_ticks());
node.get_property (X_("length"), t);
usable_length = t.beats();
return 0;
}
void
MIDITrigger::set_start (timepos_t const & s)
{
/* XXX need to handle bar offsets */
Temporal::Beats b (s.beats());
_start_offset = Temporal::BBT_Offset (0, b.get_beats(), b.get_ticks());
}
void
MIDITrigger::set_end (timepos_t const & e)
{
/* XXX need to handle bar offsets */
set_length (timecnt_t (e.beats() - Temporal::Beats (_start_offset.beats, _start_offset.ticks), start_offset()));
}
void
MIDITrigger::set_legato_offset (timepos_t const & offset)
{
/* XXX need to handle bar offsets */
Temporal::Beats b (offset.beats());
_legato_offset = Temporal::BBT_Offset (0, b.get_beats(), b.get_ticks());
}
timepos_t
MIDITrigger::current_pos() const
{
return timepos_t (last_read);
}
timepos_t
MIDITrigger::end() const
{
/* XXX need to handle bar offsets */
return timepos_t (Temporal::Beats (_start_offset.beats, _start_offset.ticks) + usable_length);
}
void
MIDITrigger::set_length (timecnt_t const & newlen)
{
}
void
MIDITrigger::set_usable_length ()
{
if (!_region) {
return;
}
switch (_launch_style) {
case Repeat:
break;
default:
usable_length = data_length;
return;
}
if (_quantization == Temporal::BBT_Offset ()) {
usable_length = data_length;
return;
}
/* XXX MUST HANDLE BAR-LEVEL QUANTIZATION */
timecnt_t len (Temporal::Beats (_quantization.beats, _quantization.ticks), timepos_t (Temporal::Beats()));
usable_length = len.beats();
}
timepos_t
MIDITrigger::current_length() const
{
if (_region) {
return timepos_t (data_length);
}
return timepos_t (Temporal::BeatTime);
}
timepos_t
MIDITrigger::natural_length() const
{
if (_region) {
return timepos_t::from_ticks (_region->length().magnitude());
}
return timepos_t (Temporal::BeatTime);
}
int
MIDITrigger::set_region (boost::shared_ptr<Region> r)
{
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion> (r);
if (!mr) {
return -1;
}
set_region_internal (r);
load_data (mr);
set_length (mr->length());
PropertyChanged (ARDOUR::Properties::name);
return 0;
}
void
MIDITrigger::tempo_map_change ()
{
}
void
MIDITrigger::drop_data ()
{
delete data;
}
int
MIDITrigger::load_data (boost::shared_ptr<MidiRegion> mr)
{
return 0;
}
void
MIDITrigger::retrigger ()
{
/* XXX need to deal with bar offsets */
const Temporal::BBT_Offset o = _start_offset + _legato_offset;
last_read = Temporal::Beats (o.beats, o.ticks);
_legato_offset = Temporal::BBT_Offset ();
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 retriggered to %2\n", _index, last_read));
}
int
MIDITrigger::run (BufferSet& bufs, pframes_t nframes, pframes_t dest_offset, bool first)
{
return 0;
}
/**************/
void