preparations for clip data display (MIDI) while recording
This commit is contained in:
parent
c03c3dd918
commit
7c944687c9
@ -45,6 +45,7 @@
|
||||
#include "evoral/PatchChange.h"
|
||||
#include "evoral/SMF.h"
|
||||
|
||||
#include "ardour/event_ring_buffer.h"
|
||||
#include "ardour/midi_model.h"
|
||||
#include "ardour/midi_state_tracker.h"
|
||||
#include "ardour/processor.h"
|
||||
@ -777,8 +778,10 @@ struct SlotArmInfo {
|
||||
~SlotArmInfo();
|
||||
|
||||
Trigger& slot;
|
||||
Temporal::timepos_t start;
|
||||
Temporal::timepos_t end;
|
||||
Temporal::Beats start_beats;
|
||||
samplepos_t start_samples;
|
||||
Temporal::Beats end_beats;
|
||||
samplepos_t end_samples;
|
||||
RTMidiBufferBeats* midi_buf;
|
||||
AudioTrigger::AudioData audio_buf;
|
||||
RubberBand::RubberBandStretcher* stretcher;
|
||||
@ -931,8 +934,12 @@ class LIBARDOUR_API TriggerBox : public Processor, public std::enable_shared_fro
|
||||
void send_property_change (PBD::PropertyChange pc);
|
||||
static PBD::Signal2<void,PBD::PropertyChange,int> TriggerBoxPropertyChange;
|
||||
|
||||
std::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
|
||||
|
||||
void dump (std::ostream &) const;
|
||||
|
||||
PBD::Signal0<void> Captured;
|
||||
|
||||
private:
|
||||
struct Requests {
|
||||
std::atomic<bool> stop_all;
|
||||
@ -966,8 +973,6 @@ class LIBARDOUR_API TriggerBox : public Processor, public std::enable_shared_fro
|
||||
void maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes);
|
||||
void finish_recording (BufferSet& bufs);
|
||||
void set_armed (SlotArmInfo*);
|
||||
SlotArmInfo* capture_info() const { return _arm_info; }
|
||||
PBD::Signal0<void> Captured;
|
||||
|
||||
/* These four are accessed (read/write) only from process() context */
|
||||
|
||||
@ -1025,6 +1030,12 @@ class LIBARDOUR_API TriggerBox : public Processor, public std::enable_shared_fro
|
||||
PBD::ScopedConnection stop_all_connection;
|
||||
std::atomic<SlotArmInfo*> _arm_info;
|
||||
|
||||
/** A buffer that we use to put newly-arrived MIDI data in for
|
||||
* the GUI to read (so that it can update itself).
|
||||
*/
|
||||
mutable EventRingBuffer<samplepos_t> _gui_feed_fifo;
|
||||
mutable Glib::Threads::Mutex _gui_feed_reset_mutex;
|
||||
|
||||
typedef std::map<std::vector<uint8_t>,std::pair<int,int> > CustomMidiMap;
|
||||
static CustomMidiMap _custom_midi_map;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <glibmm.h>
|
||||
|
||||
@ -3417,8 +3418,8 @@ Trigger::make_property_quarks ()
|
||||
|
||||
SlotArmInfo::SlotArmInfo (Trigger& s)
|
||||
: slot (s)
|
||||
, start (0)
|
||||
, end (0)
|
||||
, start_samples (0)
|
||||
, end_samples (0)
|
||||
, midi_buf (nullptr)
|
||||
, stretcher (nullptr)
|
||||
{
|
||||
@ -3498,6 +3499,7 @@ TriggerBox::TriggerBox (Session& s, DataType dt)
|
||||
, _record_state (Disabled)
|
||||
, requests (1024)
|
||||
, _arm_info (nullptr)
|
||||
, _gui_feed_fifo (std::min<size_t> (64000, std::max<size_t> (s.sample_rate() / 10, 2 * AudioEngine::instance()->raw_buffer_size (DataType::MIDI))))
|
||||
{
|
||||
set_display_to_user (false);
|
||||
|
||||
@ -3549,7 +3551,8 @@ TriggerBox::arm_from_another_thread (Trigger& slot, samplepos_t now, uint32_t ch
|
||||
slot.compute_quantized_transition (now, now_beats, std::numeric_limits<Beats>::max(),
|
||||
t_bbt, t_beats, t_samples, tmap, slot.quantization());
|
||||
|
||||
ai->start = t_samples;
|
||||
ai->start_samples = t_samples;
|
||||
ai->start_beats = t_beats;
|
||||
|
||||
_arm_info = ai;
|
||||
}
|
||||
@ -3583,7 +3586,7 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||
bool reached_end = false;
|
||||
|
||||
if (!ai->slot.armed()) {
|
||||
if (!ai->end) {
|
||||
if (!ai->end_samples) {
|
||||
/* disarmed: compute end */
|
||||
Beats start_b;
|
||||
Beats end_b;
|
||||
@ -3595,7 +3598,8 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||
|
||||
ai->slot.compute_quantized_transition (start_sample, now_beats, std::numeric_limits<Beats>::max(),
|
||||
t_bbt, t_beats, t_samples, tmap, ai->slot.quantization());
|
||||
ai->end = t_samples;
|
||||
ai->end_samples = t_samples;
|
||||
ai->end_beats = t_beats;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3609,25 +3613,25 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||
return;
|
||||
}
|
||||
|
||||
if (ai->end.samples() != 0 && (start_sample > ai->end.samples())) {
|
||||
if (ai->end_samples != 0 && (start_sample > ai->end_samples)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (start_sample < ai->start.samples() && end_sample < ai->start.samples() ) {
|
||||
if (start_sample < ai->start_samples && end_sample < ai->start_samples) {
|
||||
/* Have not yet reached the start of capture */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ai->start.samples() >= start_sample && ai->start.samples() < end_sample) {
|
||||
if (ai->start_samples >= start_sample && ai->start_samples < end_sample) {
|
||||
/* Let's get going */
|
||||
offset = ai->start.samples() - start_sample;
|
||||
offset = ai->start_samples - start_sample;
|
||||
nframes -= offset;
|
||||
_record_state = Recording;
|
||||
}
|
||||
|
||||
if ((ai->end.samples() != 0) && (start_sample <= ai->end.samples() && ai->end.samples() < end_sample)) {
|
||||
if ((ai->end_samples != 0) && (start_sample <= ai->end_samples && ai->end_samples < end_sample)) {
|
||||
/* we're going to stop */
|
||||
nframes -= (end_sample - ai->end.samples());
|
||||
nframes -= (end_sample - ai->end_samples);
|
||||
reached_end = true;
|
||||
}
|
||||
|
||||
@ -3678,9 +3682,16 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||
}
|
||||
|
||||
if (!skip_event && (!filter || !filter->filter(ev.buffer(), ev.size()))) {
|
||||
const samplepos_t event_time (start_sample + ev.time() - ai->start.samples());
|
||||
if (!ai->end || (event_time < ai->end.samples())) {
|
||||
ai->midi_buf->write (tmap->quarters_at_sample (event_time), ev.event_type(), ev.size(), ev.buffer());
|
||||
const samplepos_t event_time (start_sample + ev.time());
|
||||
if (!ai->end_samples || (event_time < ai->end_samples)) {
|
||||
/* First write (to an * * RTMidiBufferBeats) uses beat time.
|
||||
* Second write (to a FIFO) uses sample time.
|
||||
*
|
||||
* Both are relative to where we
|
||||
* started capturing.
|
||||
*/
|
||||
ai->midi_buf->write (tmap->quarters_at_sample (event_time) - ai->start_beats, ev.event_type(), ev.size(), ev.buffer());
|
||||
_gui_feed_fifo.write (event_time - ai->start_samples, Evoral::MIDI_EVENT, ev.size(), ev.buffer());
|
||||
send_signal = true;
|
||||
}
|
||||
}
|
||||
@ -3688,6 +3699,7 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||
}
|
||||
|
||||
if (send_signal) {
|
||||
std::cerr << "SEND CAPTURED\n";
|
||||
Captured(); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
@ -5699,3 +5711,21 @@ TriggerBoxThread::build_midi_source (MIDITrigger* t)
|
||||
|
||||
t->set_region_in_worker_thread_from_capture (copy);
|
||||
}
|
||||
|
||||
std::shared_ptr<MidiBuffer>
|
||||
TriggerBox::get_gui_feed_buffer () const
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (_gui_feed_reset_mutex);
|
||||
std::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
|
||||
|
||||
std::vector<MIDI::byte> buffer (_gui_feed_fifo.capacity());
|
||||
samplepos_t time;
|
||||
Evoral::EventType type;
|
||||
uint32_t size;
|
||||
|
||||
while (_gui_feed_fifo.read (&time, &type, &size, &buffer[0])) {
|
||||
b->push_back (time, type, size, &buffer[0]);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user