X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_track.cc;h=ce07fa8f24991f2bcad3344e200e9377bf1aef03;hb=6c50971eba37d879f1b8690ee231bb412ee1cda6;hp=3866eb4d80844f4790bbb418725911a69736d4a3;hpb=ad017365f7a73f8ba57f667cc1aa36478b48c50e;p=ardour.git diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 3866eb4d80..ce07fa8f24 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -16,6 +16,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + +#ifdef COMPILER_MSVC +#include + +// 'std::isinf()' and 'std::isnan()' are not available in MSVC. +#define isinf_local(val) !((bool)_finite((double)val)) +#define isnan_local(val) (bool)_isnan((double)val) +#else +#define isinf_local std::isinf +#define isnan_local std::isnan +#endif #include "pbd/ffs.h" #include "pbd/enumwriter.h" @@ -25,11 +37,13 @@ #include "ardour/buffer_set.h" #include "ardour/debug.h" #include "ardour/delivery.h" +#include "ardour/event_type_map.h" #include "ardour/meter.h" #include "ardour/midi_diskstream.h" #include "ardour/midi_playlist.h" #include "ardour/midi_port.h" #include "ardour/midi_track.h" +#include "ardour/parameter_types.h" #include "ardour/port.h" #include "ardour/processor.h" #include "ardour/session.h" @@ -536,36 +550,62 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framep * the last argument ("stop on overflow in destination") so that we'll * ship the rest out next time. * - * the (nframes-1) argument puts all these events at the last + * the Port::port_offset() + (nframes-1) argument puts all these events at the last * possible position of the output buffer, so that we do not - * violate monotonicity when writing. + * violate monotonicity when writing. Port::port_offset() will + * be non-zero if we're in a split process cycle. */ - - _immediate_events.read (buf, 0, 1, nframes-1, true); + _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true); } } int -MidiTrack::export_stuff (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framecnt_t /*nframes*/, - boost::shared_ptr /*endpoint*/, bool /*include_endpoint*/, bool /*for_export*/, bool /*for_freeze*/) -{ - return -1; +MidiTrack::export_stuff (BufferSet& buffers, + framepos_t start, + framecnt_t nframes, + boost::shared_ptr endpoint, + bool include_endpoint, + bool for_export, + bool for_freeze) +{ + if (buffers.count().n_midi() == 0) { + return -1; + } + + boost::shared_ptr diskstream = midi_diskstream(); + + Glib::Threads::RWLock::ReaderLock rlock (_processor_lock); + + boost::shared_ptr mpl = boost::dynamic_pointer_cast(diskstream->playlist()); + if (!mpl) { + return -2; + } + + buffers.get_midi(0).clear(); + if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) { + return -1; + } + + //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze); + + return 0; } boost::shared_ptr -MidiTrack::bounce (InterThreadInfo& /*itt*/) +MidiTrack::bounce (InterThreadInfo& itt) { - std::cerr << "MIDI bounce currently unsupported" << std::endl; - return boost::shared_ptr (); + return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false); } - boost::shared_ptr -MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/, - boost::shared_ptr /*endpoint*/, bool /*include_endpoint*/) +MidiTrack::bounce_range (framepos_t start, + framepos_t end, + InterThreadInfo& itt, + boost::shared_ptr endpoint, + bool include_endpoint) { - std::cerr << "MIDI bounce range currently unsupported" << std::endl; - return boost::shared_ptr (); + vector > srcs; + return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false); } void @@ -618,8 +658,8 @@ MidiTrack::write_immediate_event(size_t size, const uint8_t* buf) cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl; return false; } - const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]); - return (_immediate_events.write(0, type, size, buf) == size); + const uint32_t type = midi_parameter_type(buf[0]); + return (_immediate_events.write (0, type, size, buf) == size); } void @@ -643,15 +683,18 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st void MidiTrack::MidiControl::set_value(double val) { + const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter(); + const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter); + bool valid = false; - if (isinf(val)) { + if (isinf_local(val)) { cerr << "MIDIControl value is infinity" << endl; - } else if (isnan(val)) { + } else if (isnan_local(val)) { cerr << "MIDIControl value is NaN" << endl; - } else if (val < _list->parameter().min()) { - cerr << "MIDIControl value is < " << _list->parameter().min() << endl; - } else if (val > _list->parameter().max()) { - cerr << "MIDIControl value is > " << _list->parameter().max() << endl; + } else if (val < desc.lower) { + cerr << "MIDIControl value is < " << desc.lower << endl; + } else if (val > desc.upper) { + cerr << "MIDIControl value is > " << desc.upper << endl; } else { valid = true; } @@ -660,14 +703,14 @@ MidiTrack::MidiControl::set_value(double val) return; } - assert(val <= _list->parameter().max()); - if ( ! automation_playback()) { + assert(val <= desc.upper); + if ( ! _list || ! automation_playback()) { size_t size = 3; - uint8_t ev[3] = { _list->parameter().channel(), uint8_t (val), 0 }; - switch(_list->parameter().type()) { + uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 }; + switch(parameter.type()) { case MidiCCAutomation: ev[0] += MIDI_CMD_CONTROL; - ev[1] = _list->parameter().id(); + ev[1] = parameter.id(); ev[2] = int(val); break;