From 4a473adb8d21bc0e3af1595486f017091eed87a8 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 21 Aug 2017 18:00:21 -0400 Subject: [PATCH] refacto/redesign beatbox SMF "export" so that we end up with a viable SMF file AND a valid Source --- libs/ardour/ardour/beatbox.h | 8 +++- libs/ardour/beatbox.cc | 73 ++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/libs/ardour/ardour/beatbox.h b/libs/ardour/ardour/beatbox.h index 405cfc8f98..02bd2b7b70 100644 --- a/libs/ardour/ardour/beatbox.h +++ b/libs/ardour/ardour/beatbox.h @@ -37,6 +37,9 @@ namespace ARDOUR { +class Source; +class SMFSource; + typedef uint64_t superclock_t; static const superclock_t superclock_ticks_per_second = 508032000; // 2^10 * 3^4 * 5^3 * 7^2 @@ -75,7 +78,7 @@ class BeatBox : public ARDOUR::Processor { XMLNode& state(bool full); XMLNode& get_state(void); - bool export_to_path (std::string const & path); + bool fill_source (boost::shared_ptr); private: bool _start_requested; @@ -134,6 +137,9 @@ class BeatBox : public ARDOUR::Processor { RingBuffer add_queue; RingBuffer remove_queue; + + bool fill_midi_source (boost::shared_ptr); + }; } /* namespace */ diff --git a/libs/ardour/beatbox.cc b/libs/ardour/beatbox.cc index 478131df3d..af6f23fbc3 100644 --- a/libs/ardour/beatbox.cc +++ b/libs/ardour/beatbox.cc @@ -28,11 +28,11 @@ #include "pbd/i18n.h" #include "evoral/midi_events.h" -#include "evoral/SMF.hpp" #include "ardour/beatbox.h" #include "ardour/midi_buffer.h" #include "ardour/session.h" +#include "ardour/smf_source.h" using std::cerr; using std::endl; @@ -473,39 +473,48 @@ BeatBox::add_note (int note, int velocity, Timecode::BBT_Time at) } bool -BeatBox::export_to_path (std::string const & path) +BeatBox::fill_source (boost::shared_ptr src) { - Evoral::SMF smf; + boost::shared_ptr msrc = boost::dynamic_pointer_cast (src); - double smf_delta = 0; - superclock_t last_time = 0; - Evoral::event_id_t note_id = 0; - - try { - if (smf.create (path)) { - return false; - } - } catch (...) { - return false; + if (msrc) { + return fill_midi_source (msrc); } - smf.begin_write (); - - for (Events::const_iterator e = _current_events.begin(); e != _current_events.end(); ++e) { - smf_delta = (*e)->time - last_time; - /* convert to quarter notes */ - smf_delta /= beat_superclocks * (4.0 / _meter_beat_type); - /* convert to pulses/ticks */ - smf_delta *= Timecode::BBT_Time::ticks_per_beat; - smf.append_event_delta (llrint (smf_delta), (*e)->size, (*e)->buf, note_id++); - last_time = (*e)->time; - } - - try { - smf.end_write (path); - } catch (...) { - return false; - } - - return true; + return false; +} + +bool +BeatBox::fill_midi_source (boost::shared_ptr src) +{ + Evoral::Beats smf_beats; + + if (_current_events.empty()) { + return false; + } + + Source::Lock lck (src->mutex()); + + try { + src->mark_streaming_midi_write_started (lck, Sustained); + src->begin_write (); + + for (Events::const_iterator e = _current_events.begin(); e != _current_events.end(); ++e) { + /* convert to quarter notes */ + smf_beats = Evoral::Beats ((*e)->time / (beat_superclocks * (4.0 / _meter_beat_type))); + Evoral::Event ee (Evoral::MIDI_EVENT, smf_beats, (*e)->size, (*e)->buf, false); + src->append_event_beats (lck, ee); + last_time = (*e)->time; + } + + src->end_write (src->path()); + src->mark_nonremovable (); + src->mark_streaming_write_completed (lck); + return true; + + } catch (...) { + cerr << "Exception during beatbox write to SMF... " << endl; + } + + return false; }