mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
preparations for clip data display (MIDI) while recording
This commit is contained in:
parent
c03c3dd918
commit
7c944687c9
2 changed files with 59 additions and 18 deletions
|
|
@ -45,6 +45,7 @@
|
||||||
#include "evoral/PatchChange.h"
|
#include "evoral/PatchChange.h"
|
||||||
#include "evoral/SMF.h"
|
#include "evoral/SMF.h"
|
||||||
|
|
||||||
|
#include "ardour/event_ring_buffer.h"
|
||||||
#include "ardour/midi_model.h"
|
#include "ardour/midi_model.h"
|
||||||
#include "ardour/midi_state_tracker.h"
|
#include "ardour/midi_state_tracker.h"
|
||||||
#include "ardour/processor.h"
|
#include "ardour/processor.h"
|
||||||
|
|
@ -777,8 +778,10 @@ struct SlotArmInfo {
|
||||||
~SlotArmInfo();
|
~SlotArmInfo();
|
||||||
|
|
||||||
Trigger& slot;
|
Trigger& slot;
|
||||||
Temporal::timepos_t start;
|
Temporal::Beats start_beats;
|
||||||
Temporal::timepos_t end;
|
samplepos_t start_samples;
|
||||||
|
Temporal::Beats end_beats;
|
||||||
|
samplepos_t end_samples;
|
||||||
RTMidiBufferBeats* midi_buf;
|
RTMidiBufferBeats* midi_buf;
|
||||||
AudioTrigger::AudioData audio_buf;
|
AudioTrigger::AudioData audio_buf;
|
||||||
RubberBand::RubberBandStretcher* stretcher;
|
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);
|
void send_property_change (PBD::PropertyChange pc);
|
||||||
static PBD::Signal2<void,PBD::PropertyChange,int> TriggerBoxPropertyChange;
|
static PBD::Signal2<void,PBD::PropertyChange,int> TriggerBoxPropertyChange;
|
||||||
|
|
||||||
|
std::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
|
||||||
|
|
||||||
void dump (std::ostream &) const;
|
void dump (std::ostream &) const;
|
||||||
|
|
||||||
|
PBD::Signal0<void> Captured;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Requests {
|
struct Requests {
|
||||||
std::atomic<bool> stop_all;
|
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 maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes);
|
||||||
void finish_recording (BufferSet& bufs);
|
void finish_recording (BufferSet& bufs);
|
||||||
void set_armed (SlotArmInfo*);
|
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 */
|
/* 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;
|
PBD::ScopedConnection stop_all_connection;
|
||||||
std::atomic<SlotArmInfo*> _arm_info;
|
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;
|
typedef std::map<std::vector<uint8_t>,std::pair<int,int> > CustomMidiMap;
|
||||||
static CustomMidiMap _custom_midi_map;
|
static CustomMidiMap _custom_midi_map;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
|
|
||||||
|
|
@ -3417,8 +3418,8 @@ Trigger::make_property_quarks ()
|
||||||
|
|
||||||
SlotArmInfo::SlotArmInfo (Trigger& s)
|
SlotArmInfo::SlotArmInfo (Trigger& s)
|
||||||
: slot (s)
|
: slot (s)
|
||||||
, start (0)
|
, start_samples (0)
|
||||||
, end (0)
|
, end_samples (0)
|
||||||
, midi_buf (nullptr)
|
, midi_buf (nullptr)
|
||||||
, stretcher (nullptr)
|
, stretcher (nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -3498,6 +3499,7 @@ TriggerBox::TriggerBox (Session& s, DataType dt)
|
||||||
, _record_state (Disabled)
|
, _record_state (Disabled)
|
||||||
, requests (1024)
|
, requests (1024)
|
||||||
, _arm_info (nullptr)
|
, _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);
|
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(),
|
slot.compute_quantized_transition (now, now_beats, std::numeric_limits<Beats>::max(),
|
||||||
t_bbt, t_beats, t_samples, tmap, slot.quantization());
|
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;
|
_arm_info = ai;
|
||||||
}
|
}
|
||||||
|
|
@ -3583,7 +3586,7 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||||
bool reached_end = false;
|
bool reached_end = false;
|
||||||
|
|
||||||
if (!ai->slot.armed()) {
|
if (!ai->slot.armed()) {
|
||||||
if (!ai->end) {
|
if (!ai->end_samples) {
|
||||||
/* disarmed: compute end */
|
/* disarmed: compute end */
|
||||||
Beats start_b;
|
Beats start_b;
|
||||||
Beats end_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(),
|
ai->slot.compute_quantized_transition (start_sample, now_beats, std::numeric_limits<Beats>::max(),
|
||||||
t_bbt, t_beats, t_samples, tmap, ai->slot.quantization());
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3609,25 +3613,25 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ai->end.samples() != 0 && (start_sample > ai->end.samples())) {
|
if (ai->end_samples != 0 && (start_sample > ai->end_samples)) {
|
||||||
return;
|
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 */
|
/* Have not yet reached the start of capture */
|
||||||
return;
|
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 */
|
/* Let's get going */
|
||||||
offset = ai->start.samples() - start_sample;
|
offset = ai->start_samples - start_sample;
|
||||||
nframes -= offset;
|
nframes -= offset;
|
||||||
_record_state = Recording;
|
_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 */
|
/* we're going to stop */
|
||||||
nframes -= (end_sample - ai->end.samples());
|
nframes -= (end_sample - ai->end_samples);
|
||||||
reached_end = true;
|
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()))) {
|
if (!skip_event && (!filter || !filter->filter(ev.buffer(), ev.size()))) {
|
||||||
const samplepos_t event_time (start_sample + ev.time() - ai->start.samples());
|
const samplepos_t event_time (start_sample + ev.time());
|
||||||
if (!ai->end || (event_time < ai->end.samples())) {
|
if (!ai->end_samples || (event_time < ai->end_samples)) {
|
||||||
ai->midi_buf->write (tmap->quarters_at_sample (event_time), ev.event_type(), ev.size(), ev.buffer());
|
/* 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;
|
send_signal = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3688,6 +3699,7 @@ TriggerBox::maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send_signal) {
|
if (send_signal) {
|
||||||
|
std::cerr << "SEND CAPTURED\n";
|
||||||
Captured(); /* EMIT SIGNAL */
|
Captured(); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5699,3 +5711,21 @@ TriggerBoxThread::build_midi_source (MIDITrigger* t)
|
||||||
|
|
||||||
t->set_region_in_worker_thread_from_capture (copy);
|
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…
Add table
Add a link
Reference in a new issue