2 Copyright (C) 2000-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include "pbd/error.h"
33 #include "pbd/basename.h"
34 #include <glibmm/thread.h>
35 #include "pbd/xml++.h"
36 #include "pbd/memento_command.h"
37 #include "pbd/enumwriter.h"
38 #include "pbd/stateful_diff_command.h"
39 #include "pbd/stacktrace.h"
41 #include "ardour/ardour.h"
42 #include "ardour/audioengine.h"
43 #include "ardour/butler.h"
44 #include "ardour/configuration.h"
45 #include "ardour/cycle_timer.h"
46 #include "ardour/debug.h"
47 #include "ardour/io.h"
48 #include "ardour/midi_diskstream.h"
49 #include "ardour/midi_model.h"
50 #include "ardour/midi_playlist.h"
51 #include "ardour/midi_port.h"
52 #include "ardour/midi_region.h"
53 #include "ardour/playlist_factory.h"
54 #include "ardour/region_factory.h"
55 #include "ardour/route.h"
56 #include "ardour/send.h"
57 #include "ardour/session.h"
58 #include "ardour/session_playlists.h"
59 #include "ardour/smf_source.h"
60 #include "ardour/utils.h"
62 #include "midi++/types.h"
68 using namespace ARDOUR;
71 framecnt_t MidiDiskstream::midi_readahead = 4096;
73 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
74 : Diskstream(sess, name, flag)
77 , _note_mode(Sustained)
78 , _frames_written_to_ringbuffer(0)
79 , _frames_read_from_ringbuffer(0)
80 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
86 use_new_write_source (0);
90 assert(!destructive());
93 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
94 : Diskstream(sess, node)
97 , _note_mode(Sustained)
98 , _frames_written_to_ringbuffer(0)
99 , _frames_read_from_ringbuffer(0)
100 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
106 if (set_state (node, Stateful::loading_state_version)) {
107 in_set_state = false;
108 throw failed_constructor();
111 use_new_write_source (0);
113 in_set_state = false;
117 MidiDiskstream::init ()
119 /* there are no channels at this point, so these
120 two calls just get speed_buffer_size and wrap_buffer
121 size setup without duplicating their code.
124 set_block_size (_session.get_block_size());
125 allocate_temporary_buffers ();
127 const size_t size = _session.butler()->midi_diskstream_buffer_size();
128 _playback_buf = new MidiRingBuffer<framepos_t>(size);
129 _capture_buf = new MidiRingBuffer<framepos_t>(size);
131 _n_channels = ChanCount(DataType::MIDI, 1);
133 assert(recordable());
136 MidiDiskstream::~MidiDiskstream ()
138 Glib::Mutex::Lock lm (state_lock);
143 MidiDiskstream::non_realtime_locate (framepos_t position)
146 _write_source->set_timeline_position (position);
148 seek (position, false);
153 MidiDiskstream::non_realtime_input_change ()
156 Glib::Mutex::Lock lm (state_lock);
158 if (input_change_pending.type == IOChange::NoChange) {
162 if (input_change_pending.type & IOChange::ConfigurationChanged) {
163 uint32_t ni = _io->n_ports().n_midi();
165 if (ni != _n_channels.n_midi()) {
166 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
169 _n_channels, input_change_pending.type)
174 _source_port.reset ();
176 _source_port = _io->midi(0);
180 if (input_change_pending.type & IOChange::ConnectionsChanged) {
181 set_capture_offset ();
182 set_align_style_from_io ();
185 input_change_pending.type = IOChange::NoChange;
187 /* implicit unlock */
190 /* unlike with audio, there is never any need to reset write sources
191 based on input configuration changes because ... a MIDI track
192 has just 1 MIDI port as input, always.
195 /* now refill channel buffers */
197 if (speed() != 1.0f || speed() != -1.0f) {
198 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
201 seek (_session.transport_frame());
205 _write_source->set_last_write_end (_session.transport_frame());
210 MidiDiskstream::find_and_use_playlist (const string& name)
212 boost::shared_ptr<MidiPlaylist> playlist;
214 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
215 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
219 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't an midi playlist"), name) << endmsg;
223 return use_playlist (playlist);
227 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
229 assert(boost::dynamic_pointer_cast<MidiPlaylist>(playlist));
231 Diskstream::use_playlist(playlist);
237 MidiDiskstream::use_new_playlist ()
240 boost::shared_ptr<MidiPlaylist> playlist;
242 if (!in_set_state && destructive()) {
247 newname = Playlist::bump_name (_playlist->name(), _session);
249 newname = Playlist::bump_name (_name, _session);
252 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
253 DataType::MIDI, _session, newname, hidden()))) != 0) {
255 return use_playlist (playlist);
263 MidiDiskstream::use_copy_playlist ()
265 assert(midi_playlist());
271 if (_playlist == 0) {
272 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
277 boost::shared_ptr<MidiPlaylist> playlist;
279 newname = Playlist::bump_name (_playlist->name(), _session);
281 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
282 return use_playlist (playlist);
288 /** Overloaded from parent to die horribly
291 MidiDiskstream::set_destructive (bool yn)
293 yn = 0; // stop pedantic gcc complaints about unused parameter
294 assert( ! destructive());
300 MidiDiskstream::set_note_mode (NoteMode m)
303 midi_playlist()->set_note_mode(m);
304 if (_write_source && _write_source->model())
305 _write_source->model()->set_note_mode(m);
309 MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance)
311 framecnt_t rec_offset = 0;
312 framecnt_t rec_nframes = 0;
313 bool nominally_recording;
314 bool re = record_enabled ();
315 bool can_record = _session.actively_recording ();
317 playback_distance = 0;
319 check_record_status (transport_frame, can_record);
321 nominally_recording = (can_record && re);
327 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
333 Glib::Mutex::Lock sm (state_lock, Glib::TRY_LOCK);
339 adjust_capture_position = 0;
341 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
342 OverlapType ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
344 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
346 if (rec_nframes && !was_recording) {
347 _write_source->mark_write_starting_now ();
348 capture_captured = 0;
349 was_recording = true;
353 if (can_record && !_last_capture_sources.empty()) {
354 _last_capture_sources.clear ();
357 if (nominally_recording || rec_nframes) {
359 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
360 MidiBuffer& buf = sp->get_midi_buffer(nframes);
361 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
362 const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
365 if (DEBUG::MidiIO & PBD::debug_bits) {
366 const uint8_t* __data = ev.buffer();
368 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
369 for (size_t i=0; i < ev.size(); ++i) {
370 DEBUG_STR_APPEND(a,hex);
371 DEBUG_STR_APPEND(a,"0x");
372 DEBUG_STR_APPEND(a,(int)__data[i]);
373 DEBUG_STR_APPEND(a,' ');
375 DEBUG_STR_APPEND(a,'\n');
376 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
379 _capture_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer());
382 if (buf.size() != 0) {
383 Glib::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::TRY_LOCK);
386 /* Copy this data into our GUI feed buffer and tell the GUI
387 that it can read it if it likes.
389 _gui_feed_buffer.clear ();
391 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
392 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
393 the end of the world if it does.
395 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
399 DataRecorded (_write_source); /* EMIT SIGNAL */
412 /* data will be written to disk */
414 if (rec_nframes == nframes && rec_offset == 0) {
415 playback_distance = nframes;
418 adjust_capture_position = rec_nframes;
420 } else if (nominally_recording) {
422 /* XXXX do this for MIDI !!!
423 can't do actual capture yet - waiting for latency effects to finish before we start
426 playback_distance = nframes;
430 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
432 playback_distance = nframes;
440 MidiDiskstream::commit (framecnt_t playback_distance)
442 bool need_butler = false;
444 if (_actual_speed < 0.0) {
445 playback_sample -= playback_distance;
447 playback_sample += playback_distance;
450 if (adjust_capture_position != 0) {
451 capture_captured += adjust_capture_position;
452 adjust_capture_position = 0;
455 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
456 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
459 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
460 " = " << frames_written - frames_read
461 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
464 /* frames_read will generally be less than frames_written, but
465 * immediately after an overwrite, we can end up having read some data
466 * before we've written any. we don't need to trip an assert() on this,
467 * but we do need to check so that the decision on whether or not we
468 * need the butler is done correctly.
471 if (frames_read <= frames_written) {
472 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
482 MidiDiskstream::set_pending_overwrite (bool yn)
484 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
486 _pending_overwrite = yn;
487 overwrite_frame = playback_sample;
491 MidiDiskstream::overwrite_existing_buffers ()
493 /* This is safe as long as the butler thread is suspended, which it should be */
494 _playback_buf->reset ();
496 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
497 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
499 read (overwrite_frame, disk_io_chunk_frames, false);
500 file_frame = overwrite_frame; // it was adjusted by ::read()
501 overwrite_queued = false;
502 _pending_overwrite = false;
508 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
510 Glib::Mutex::Lock lm (state_lock);
513 _playback_buf->reset();
514 _capture_buf->reset();
515 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
516 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
518 playback_sample = frame;
521 if (complete_refill) {
522 while ((ret = do_refill_with_alloc ()) > 0) ;
524 ret = do_refill_with_alloc ();
531 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
533 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
534 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
535 return ((frames_written - frames_read) < distance);
539 MidiDiskstream::internal_playback_seek (framecnt_t distance)
541 first_recordable_frame += distance;
542 playback_sample += distance;
547 /** @a start is set to the new frame position (TIME) read up to */
549 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
551 framecnt_t this_read = 0;
553 framepos_t loop_end = 0;
554 framepos_t loop_start = 0;
559 framecnt_t loop_length = 0;
561 /* Make the use of a Location atomic for this read operation.
563 Note: Locations don't get deleted, so all we care about
564 when I say "atomic" is that we are always pointing to
565 the same one and using a start/length values obtained
569 if ((loc = loop_location) != 0) {
570 loop_start = loc->start();
571 loop_end = loc->end();
572 loop_length = loop_end - loop_start;
575 /* if we are looping, ensure that the first frame we read is at the correct
576 position within the loop.
579 if (loc && (start >= loop_end)) {
580 //cerr << "start adjusted from " << start;
581 start = loop_start + ((start - loop_start) % loop_length);
582 //cerr << "to " << start << endl;
584 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
589 /* take any loop into account. we can't read past the end of the loop. */
591 if (loc && (loop_end - start <= dur)) {
592 this_read = loop_end - start;
593 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
600 if (this_read == 0) {
604 this_read = min(dur,this_read);
606 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
607 error << string_compose(
608 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
609 id(), this_read, start) << endmsg;
613 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
617 // Swap note ons with note offs here. etc?
618 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
619 // CC values etc. hard.
623 /* if we read to the end of the loop, go back to the beginning */
626 // Synthesize LoopEvent here, because the next events
627 // written will have non-monotonic timestamps.
628 _playback_buf->write(loop_end - 1, LoopEventType, sizeof (framepos_t), (uint8_t *) &loop_start);
636 //offset += this_read;
643 MidiDiskstream::do_refill_with_alloc ()
649 MidiDiskstream::do_refill ()
652 size_t write_space = _playback_buf->write_space();
653 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
655 if (write_space == 0) {
663 /* at end: nothing to do */
664 if (file_frame == max_framepos) {
668 // At this point we...
669 assert(_playback_buf->write_space() > 0); // ... have something to write to, and
670 assert(file_frame <= max_framepos); // ... something to write
672 // now calculate how much time is in the ringbuffer.
673 // and lets write as much as we need to get this to be midi_readahead;
674 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
675 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
676 if ((frames_written - frames_read) >= midi_readahead) {
680 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
682 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
683 // << frames_written - frames_read << endl;
685 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
687 if (read (file_frame, to_read, reversed)) {
694 /** Flush pending data to disk.
696 * Important note: this function will write *AT MOST* disk_io_chunk_frames
697 * of data to disk. it will never write more than that. If it writes that
698 * much and there is more than that waiting to be written, it will return 1,
699 * otherwise 0 on success or -1 on failure.
701 * If there is less than disk_io_chunk_frames to be written, no data will be
702 * written at all unless @a force_flush is true.
705 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
711 if (!_write_source) {
715 assert (!destructive());
717 total = _session.transport_frame() - _write_source->last_write_end();
720 _capture_buf->read_space() == 0 ||
721 (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
725 /* if there are 2+ chunks of disk i/o possible for
726 this track, let the caller know so that it can arrange
727 for us to be called again, ASAP.
729 if we are forcing a flush, then if there is* any* extra
730 work, let the caller know.
732 if we are no longer recording and there is any extra work,
733 let the caller know too.
736 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
741 /* push out everything we have, right now */
742 to_write = max_framecnt;
744 to_write = disk_io_chunk_frames;
747 if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
748 if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
749 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
759 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
761 bool more_work = true;
763 boost::shared_ptr<MidiRegion> region;
764 MidiRegion::SourceList srcs;
765 MidiRegion::SourceList::iterator src;
766 vector<CaptureInfo*>::iterator ci;
770 /* butler is already stopped, but there may be work to do
771 to flush remaining data to disk.
774 while (more_work && !err) {
775 switch (do_flush (TransportContext, true)) {
782 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
787 /* XXX is there anything we can do if err != 0 ? */
788 Glib::Mutex::Lock lm (capture_info_lock);
790 if (capture_info.empty()) {
791 goto no_capture_stuff_to_do;
797 _write_source->mark_for_remove ();
798 _write_source->drop_references ();
799 _write_source.reset();
802 /* new source set up in "out" below */
806 assert(_write_source);
808 framecnt_t total_capture = 0;
809 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
810 total_capture += (*ci)->frames;
813 if (_write_source->length (capture_info.front()->start) != 0) {
815 /* phew, we have data */
817 /* figure out the name for this take */
819 srcs.push_back (_write_source);
821 _write_source->set_timeline_position (capture_info.front()->start);
822 _write_source->set_captured_for (_name);
824 /* set length in beats to entire capture length */
826 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
827 const double total_capture_beats = converter.from (total_capture);
828 _write_source->set_length_beats (total_capture_beats);
830 /* flush to disk: this step differs from the audio path,
831 where all the data is already on disk.
834 _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
836 /* we will want to be able to keep (over)writing the source
837 but we don't want it to be removable. this also differs
838 from the audio situation, where the source at this point
839 must be considered immutable. luckily, we can rely on
840 MidiSource::mark_streaming_write_completed() to have
841 already done the necessary work for that.
844 string whole_file_region_name;
845 whole_file_region_name = region_name_from_path (_write_source->name(), true);
847 /* Register a new region with the Session that
848 describes the entire source. Do this first
849 so that any sub-regions will obviously be
850 children of this one (later!)
856 plist.add (Properties::name, whole_file_region_name);
857 plist.add (Properties::whole_file, true);
858 plist.add (Properties::automatic, true);
859 plist.add (Properties::start, 0);
860 plist.add (Properties::length, total_capture);
861 plist.add (Properties::layer, 0);
863 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
865 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
866 region->special_set_position (capture_info.front()->start);
870 catch (failed_constructor& err) {
871 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
875 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
877 _playlist->clear_changes ();
878 _playlist->freeze ();
880 /* Session frame time of the initial capture in this pass, which is where the source starts */
881 framepos_t initial_capture = 0;
882 if (!capture_info.empty()) {
883 initial_capture = capture_info.front()->start;
886 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
890 RegionFactory::region_name (region_name, _write_source->name(), false);
892 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
897 /* start of this region is the offset between the start of its capture and the start of the whole pass */
898 plist.add (Properties::start, (*ci)->start - initial_capture);
899 plist.add (Properties::length, (*ci)->frames);
900 plist.add (Properties::length_beats, converter.from((*ci)->frames));
901 plist.add (Properties::name, region_name);
903 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
904 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
907 catch (failed_constructor& err) {
908 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
909 continue; /* XXX is this OK? */
912 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
915 _playlist->add_region (region, (*ci)->start);
920 _session.add_command (new StatefulDiffCommand(_playlist));
924 /* No data was recorded, so this capture will
925 effectively be aborted; do the same as we
926 do for an explicit abort.
930 _write_source->mark_for_remove ();
931 _write_source->drop_references ();
932 _write_source.reset();
938 use_new_write_source (0);
940 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
944 capture_info.clear ();
945 capture_start_frame = 0;
947 no_capture_stuff_to_do:
953 MidiDiskstream::transport_looped (framepos_t transport_frame)
957 // adjust the capture length knowing that the data will be recorded to disk
958 // only necessary after the first loop where we're recording
959 if (capture_info.size() == 0) {
960 capture_captured += _capture_offset;
962 if (_alignment_style == ExistingMaterial) {
963 capture_captured += _session.worst_output_latency();
965 capture_captured += _roll_delay;
971 // the next region will start recording via the normal mechanism
972 // we'll set the start position to the current transport pos
973 // no latency adjustment or capture offset needs to be made, as that already happened the first time
974 capture_start_frame = transport_frame;
975 first_recordable_frame = transport_frame; // mild lie
976 last_recordable_frame = max_framepos;
977 was_recording = true;
980 if (!Config->get_seamless_loop()) {
986 MidiDiskstream::finish_capture ()
988 was_recording = false;
990 if (capture_captured == 0) {
994 // Why must we destroy?
995 assert(!destructive());
997 CaptureInfo* ci = new CaptureInfo;
999 ci->start = capture_start_frame;
1000 ci->frames = capture_captured;
1002 /* XXX theoretical race condition here. Need atomic exchange ?
1003 However, the circumstances when this is called right
1004 now (either on record-disable or transport_stopped)
1005 mean that no actual race exists. I think ...
1006 We now have a capture_info_lock, but it is only to be used
1007 to synchronize in the transport_stop and the capture info
1008 accessors, so that invalidation will not occur (both non-realtime).
1011 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1013 capture_info.push_back (ci);
1014 capture_captured = 0;
1018 MidiDiskstream::set_record_enabled (bool yn)
1020 if (!recordable() || !_session.record_enabling_legal()) {
1024 assert(!destructive());
1026 /* yes, i know that this not proof against race conditions, but its
1027 good enough. i think.
1030 if (record_enabled() != yn) {
1032 engage_record_enable ();
1034 disengage_record_enable ();
1040 MidiDiskstream::engage_record_enable ()
1042 bool const rolling = _session.transport_speed() != 0.0f;
1044 g_atomic_int_set (&_record_enabled, 1);
1046 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1048 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1049 sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
1052 RecordEnableChanged (); /* EMIT SIGNAL */
1056 MidiDiskstream::disengage_record_enable ()
1058 g_atomic_int_set (&_record_enabled, 0);
1059 RecordEnableChanged (); /* EMIT SIGNAL */
1063 MidiDiskstream::get_state ()
1065 XMLNode& node (Diskstream::get_state());
1067 LocaleGuard lg (X_("POSIX"));
1069 node.add_property("channel-mode", enum_2_string(get_channel_mode()));
1070 snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
1071 node.add_property("channel-mask", buf);
1073 if (_write_source && _session.get_record_enabled()) {
1075 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1076 XMLNode* cs_grandchild;
1078 cs_grandchild = new XMLNode (X_("file"));
1079 cs_grandchild->add_property (X_("path"), _write_source->path());
1080 cs_child->add_child_nocopy (*cs_grandchild);
1082 /* store the location where capture will start */
1086 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1087 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1089 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1092 cs_child->add_property (X_("at"), buf);
1093 node.add_child_nocopy (*cs_child);
1100 MidiDiskstream::set_state (const XMLNode& node, int version)
1102 const XMLProperty* prop;
1103 XMLNodeList nlist = node.children();
1104 XMLNodeIterator niter;
1105 XMLNode* capture_pending_node = 0;
1106 LocaleGuard lg (X_("POSIX"));
1108 /* prevent write sources from being created */
1110 in_set_state = true;
1112 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1113 assert ((*niter)->name() != IO::state_node_name);
1115 if ((*niter)->name() == X_("CapturingSources")) {
1116 capture_pending_node = *niter;
1120 if (Diskstream::set_state (node, version)) {
1124 ChannelMode channel_mode = AllChannels;
1125 if ((prop = node.property ("channel-mode")) != 0) {
1126 channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode));
1129 unsigned int channel_mask = 0xFFFF;
1130 if ((prop = node.property ("channel-mask")) != 0) {
1131 sscanf (prop->value().c_str(), "0x%x", &channel_mask);
1132 if (channel_mask & (~0xFFFF)) {
1133 warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg;
1138 if (capture_pending_node) {
1139 use_pending_capture_data (*capture_pending_node);
1142 set_channel_mode (channel_mode, channel_mask);
1144 in_set_state = false;
1150 MidiDiskstream::use_new_write_source (uint32_t n)
1152 if (!_session.writable() || !recordable()) {
1158 _write_source.reset();
1161 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1162 _session.create_midi_source_for_session (0, name ()));
1164 if (!_write_source) {
1165 throw failed_constructor();
1169 catch (failed_constructor &err) {
1170 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1171 _write_source.reset();
1178 list<boost::shared_ptr<Source> >
1179 MidiDiskstream::steal_write_sources()
1181 list<boost::shared_ptr<Source> > ret;
1183 /* put some data on the disk, even if its just a header for an empty file */
1184 boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
1186 /* never let it go away */
1187 _write_source->mark_nonremovable ();
1189 ret.push_back (_write_source);
1193 use_new_write_source (0);
1199 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1201 if (!_session.writable() || !recordable()) {
1205 if (_write_source && mark_write_complete) {
1206 _write_source->mark_streaming_write_completed ();
1208 use_new_write_source (0);
1212 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1217 MidiDiskstream::allocate_temporary_buffers ()
1222 MidiDiskstream::ensure_jack_monitors_input (bool yn)
1224 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1227 sp->ensure_jack_monitors_input (yn);
1232 MidiDiskstream::set_align_style_from_io ()
1234 if (_alignment_choice != Automatic) {
1238 /* XXX Not sure what, if anything we can do with MIDI
1239 as far as capture alignment etc.
1242 set_align_style (ExistingMaterial);
1247 MidiDiskstream::playback_buffer_load () const
1249 /* For MIDI it's not trivial to differentiate the following two cases:
1251 1. The playback buffer is empty because the system has run out of time to fill it.
1252 2. The playback buffer is empty because there is no more data on the playlist.
1254 If we use a simple buffer load computation, we will report that the MIDI diskstream
1255 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1256 are so low compared to audio, just give a pretend answer here.
1263 MidiDiskstream::capture_buffer_load () const
1265 /* We don't report playback buffer load, so don't report capture load either */
1271 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1276 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1277 * so that an event at playback_sample has time = 0
1280 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1283 assert(dst.size() == 0);
1286 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1287 "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
1288 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes));
1289 // cerr << "================\n";
1290 // _playback_buf->dump (cerr);
1291 // cerr << "----------------\n";
1293 const size_t events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1294 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1295 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1296 _name, events_read, playback_sample, playback_sample + nframes,
1297 _playback_buf->read_space(), _playback_buf->write_space(),
1298 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1300 _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1303 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1307 MidiDiskstream::set_name (string const & name)
1309 Diskstream::set_name (name);
1311 /* get a new write source so that its name reflects the new diskstream name */
1312 use_new_write_source (0);
1317 boost::shared_ptr<MidiBuffer>
1318 MidiDiskstream::get_gui_feed_buffer () const
1320 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1322 Glib::Mutex::Lock lm (_gui_feed_buffer_mutex);
1323 b->copy (_gui_feed_buffer);
1328 MidiDiskstream::reset_tracker ()
1330 _playback_buf->reset_tracker ();
1332 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1335 mp->clear_note_trackers ();