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);
458 cerr << "MDS written: " << frames_written << " - read: " << frames_read <<
459 " = " << frames_written - frames_read
460 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
462 assert (frames_read <= frames_written);
464 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
473 MidiDiskstream::set_pending_overwrite (bool yn)
475 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
477 _pending_overwrite = yn;
478 overwrite_frame = playback_sample;
482 MidiDiskstream::overwrite_existing_buffers ()
484 /* This is safe as long as the butler thread is suspended, which it should be */
485 _playback_buf->reset ();
487 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
488 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
490 cerr << name() << " FWTRB reset to zero for overwrite\n";
492 read (overwrite_frame, disk_io_chunk_frames, false);
493 file_frame = overwrite_frame; // it was adjusted by ::read()
494 overwrite_queued = false;
495 _pending_overwrite = false;
501 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
503 Glib::Mutex::Lock lm (state_lock);
506 _playback_buf->reset();
507 _capture_buf->reset();
508 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
509 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
511 cerr << name() << " FWTRB reset to zero for seek\n";
513 playback_sample = frame;
516 if (complete_refill) {
517 while ((ret = do_refill_with_alloc ()) > 0) ;
519 ret = do_refill_with_alloc ();
526 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
528 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
529 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
530 return ((frames_written - frames_read) < distance);
534 MidiDiskstream::internal_playback_seek (framecnt_t distance)
536 first_recordable_frame += distance;
537 playback_sample += distance;
542 /** @a start is set to the new frame position (TIME) read up to */
544 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
546 framecnt_t this_read = 0;
548 framepos_t loop_end = 0;
549 framepos_t loop_start = 0;
554 framecnt_t loop_length = 0;
556 /* Make the use of a Location atomic for this read operation.
558 Note: Locations don't get deleted, so all we care about
559 when I say "atomic" is that we are always pointing to
560 the same one and using a start/length values obtained
564 if ((loc = loop_location) != 0) {
565 loop_start = loc->start();
566 loop_end = loc->end();
567 loop_length = loop_end - loop_start;
570 /* if we are looping, ensure that the first frame we read is at the correct
571 position within the loop.
574 if (loc && (start >= loop_end)) {
575 //cerr << "start adjusted from " << start;
576 start = loop_start + ((start - loop_start) % loop_length);
577 //cerr << "to " << start << endl;
579 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
584 /* take any loop into account. we can't read past the end of the loop. */
586 if (loc && (loop_end - start <= dur)) {
587 this_read = loop_end - start;
588 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
595 if (this_read == 0) {
599 this_read = min(dur,this_read);
601 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
602 error << string_compose(
603 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
604 id(), this_read, start) << endmsg;
608 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
609 cerr << "FWTRB added " << this_read << " now " << g_atomic_int_get (&_frames_written_to_ringbuffer) << endl;
613 // Swap note ons with note offs here. etc?
614 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
615 // CC values etc. hard.
619 /* if we read to the end of the loop, go back to the beginning */
622 // Synthesize LoopEvent here, because the next events
623 // written will have non-monotonic timestamps.
624 _playback_buf->write(loop_end - 1, LoopEventType, sizeof (framepos_t), (uint8_t *) &loop_start);
632 //offset += this_read;
639 MidiDiskstream::do_refill_with_alloc ()
645 MidiDiskstream::do_refill ()
648 size_t write_space = _playback_buf->write_space();
649 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
651 if (write_space == 0) {
659 /* at end: nothing to do */
660 if (file_frame == max_framepos) {
664 // At this point we...
665 assert(_playback_buf->write_space() > 0); // ... have something to write to, and
666 assert(file_frame <= max_framepos); // ... something to write
668 // now calculate how much time is in the ringbuffer.
669 // and lets write as much as we need to get this to be midi_readahead;
670 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
671 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
672 if ((frames_written - frames_read) >= midi_readahead) {
676 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
678 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
679 // << frames_written - frames_read << endl;
681 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
683 if (read (file_frame, to_read, reversed)) {
690 /** Flush pending data to disk.
692 * Important note: this function will write *AT MOST* disk_io_chunk_frames
693 * of data to disk. it will never write more than that. If it writes that
694 * much and there is more than that waiting to be written, it will return 1,
695 * otherwise 0 on success or -1 on failure.
697 * If there is less than disk_io_chunk_frames to be written, no data will be
698 * written at all unless @a force_flush is true.
701 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
707 if (!_write_source) {
711 assert (!destructive());
713 total = _session.transport_frame() - _write_source->last_write_end();
716 _capture_buf->read_space() == 0 ||
717 (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
721 /* if there are 2+ chunks of disk i/o possible for
722 this track, let the caller know so that it can arrange
723 for us to be called again, ASAP.
725 if we are forcing a flush, then if there is* any* extra
726 work, let the caller know.
728 if we are no longer recording and there is any extra work,
729 let the caller know too.
732 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
737 /* push out everything we have, right now */
738 to_write = max_framecnt;
740 to_write = disk_io_chunk_frames;
743 if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
744 if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
745 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
755 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
757 bool more_work = true;
759 boost::shared_ptr<MidiRegion> region;
760 MidiRegion::SourceList srcs;
761 MidiRegion::SourceList::iterator src;
762 vector<CaptureInfo*>::iterator ci;
766 /* butler is already stopped, but there may be work to do
767 to flush remaining data to disk.
770 while (more_work && !err) {
771 switch (do_flush (TransportContext, true)) {
778 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
783 /* XXX is there anything we can do if err != 0 ? */
784 Glib::Mutex::Lock lm (capture_info_lock);
786 if (capture_info.empty()) {
787 goto no_capture_stuff_to_do;
793 _write_source->mark_for_remove ();
794 _write_source->drop_references ();
795 _write_source.reset();
798 /* new source set up in "out" below */
802 assert(_write_source);
804 framecnt_t total_capture = 0;
805 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
806 total_capture += (*ci)->frames;
809 if (_write_source->length (capture_info.front()->start) != 0) {
811 /* phew, we have data */
813 /* figure out the name for this take */
815 srcs.push_back (_write_source);
817 _write_source->set_timeline_position (capture_info.front()->start);
818 _write_source->set_captured_for (_name);
820 /* set length in beats to entire capture length */
822 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
823 const double total_capture_beats = converter.from (total_capture);
824 _write_source->set_length_beats (total_capture_beats);
826 /* flush to disk: this step differs from the audio path,
827 where all the data is already on disk.
830 _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
832 /* we will want to be able to keep (over)writing the source
833 but we don't want it to be removable. this also differs
834 from the audio situation, where the source at this point
835 must be considered immutable. luckily, we can rely on
836 MidiSource::mark_streaming_write_completed() to have
837 already done the necessary work for that.
840 string whole_file_region_name;
841 whole_file_region_name = region_name_from_path (_write_source->name(), true);
843 /* Register a new region with the Session that
844 describes the entire source. Do this first
845 so that any sub-regions will obviously be
846 children of this one (later!)
852 plist.add (Properties::name, whole_file_region_name);
853 plist.add (Properties::whole_file, true);
854 plist.add (Properties::automatic, true);
855 plist.add (Properties::start, 0);
856 plist.add (Properties::length, total_capture);
857 plist.add (Properties::layer, 0);
859 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
861 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
862 region->special_set_position (capture_info.front()->start);
866 catch (failed_constructor& err) {
867 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
871 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
873 _playlist->clear_changes ();
874 _playlist->freeze ();
876 /* Session frame time of the initial capture in this pass, which is where the source starts */
877 framepos_t initial_capture = 0;
878 if (!capture_info.empty()) {
879 initial_capture = capture_info.front()->start;
882 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
886 RegionFactory::region_name (region_name, _write_source->name(), false);
888 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
893 /* start of this region is the offset between the start of its capture and the start of the whole pass */
894 plist.add (Properties::start, (*ci)->start - initial_capture);
895 plist.add (Properties::length, (*ci)->frames);
896 plist.add (Properties::length_beats, converter.from((*ci)->frames));
897 plist.add (Properties::name, region_name);
899 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
900 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
903 catch (failed_constructor& err) {
904 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
905 continue; /* XXX is this OK? */
908 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
911 _playlist->add_region (region, (*ci)->start);
916 _session.add_command (new StatefulDiffCommand(_playlist));
920 /* No data was recorded, so this capture will
921 effectively be aborted; do the same as we
922 do for an explicit abort.
926 _write_source->mark_for_remove ();
927 _write_source->drop_references ();
928 _write_source.reset();
934 use_new_write_source (0);
936 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
940 capture_info.clear ();
941 capture_start_frame = 0;
943 no_capture_stuff_to_do:
949 MidiDiskstream::transport_looped (framepos_t transport_frame)
953 // adjust the capture length knowing that the data will be recorded to disk
954 // only necessary after the first loop where we're recording
955 if (capture_info.size() == 0) {
956 capture_captured += _capture_offset;
958 if (_alignment_style == ExistingMaterial) {
959 capture_captured += _session.worst_output_latency();
961 capture_captured += _roll_delay;
967 // the next region will start recording via the normal mechanism
968 // we'll set the start position to the current transport pos
969 // no latency adjustment or capture offset needs to be made, as that already happened the first time
970 capture_start_frame = transport_frame;
971 first_recordable_frame = transport_frame; // mild lie
972 last_recordable_frame = max_framepos;
973 was_recording = true;
976 if (!Config->get_seamless_loop()) {
982 MidiDiskstream::finish_capture ()
984 was_recording = false;
986 if (capture_captured == 0) {
990 // Why must we destroy?
991 assert(!destructive());
993 CaptureInfo* ci = new CaptureInfo;
995 ci->start = capture_start_frame;
996 ci->frames = capture_captured;
998 /* XXX theoretical race condition here. Need atomic exchange ?
999 However, the circumstances when this is called right
1000 now (either on record-disable or transport_stopped)
1001 mean that no actual race exists. I think ...
1002 We now have a capture_info_lock, but it is only to be used
1003 to synchronize in the transport_stop and the capture info
1004 accessors, so that invalidation will not occur (both non-realtime).
1007 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1009 capture_info.push_back (ci);
1010 capture_captured = 0;
1014 MidiDiskstream::set_record_enabled (bool yn)
1016 if (!recordable() || !_session.record_enabling_legal()) {
1020 assert(!destructive());
1022 /* yes, i know that this not proof against race conditions, but its
1023 good enough. i think.
1026 if (record_enabled() != yn) {
1028 engage_record_enable ();
1030 disengage_record_enable ();
1036 MidiDiskstream::engage_record_enable ()
1038 bool const rolling = _session.transport_speed() != 0.0f;
1040 g_atomic_int_set (&_record_enabled, 1);
1042 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1044 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1045 sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
1048 RecordEnableChanged (); /* EMIT SIGNAL */
1052 MidiDiskstream::disengage_record_enable ()
1054 g_atomic_int_set (&_record_enabled, 0);
1055 RecordEnableChanged (); /* EMIT SIGNAL */
1059 MidiDiskstream::get_state ()
1061 XMLNode& node (Diskstream::get_state());
1063 LocaleGuard lg (X_("POSIX"));
1065 node.add_property("channel-mode", enum_2_string(get_channel_mode()));
1066 snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
1067 node.add_property("channel-mask", buf);
1069 if (_write_source && _session.get_record_enabled()) {
1071 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1072 XMLNode* cs_grandchild;
1074 cs_grandchild = new XMLNode (X_("file"));
1075 cs_grandchild->add_property (X_("path"), _write_source->path());
1076 cs_child->add_child_nocopy (*cs_grandchild);
1078 /* store the location where capture will start */
1082 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1083 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1085 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1088 cs_child->add_property (X_("at"), buf);
1089 node.add_child_nocopy (*cs_child);
1096 MidiDiskstream::set_state (const XMLNode& node, int version)
1098 const XMLProperty* prop;
1099 XMLNodeList nlist = node.children();
1100 XMLNodeIterator niter;
1101 XMLNode* capture_pending_node = 0;
1102 LocaleGuard lg (X_("POSIX"));
1104 /* prevent write sources from being created */
1106 in_set_state = true;
1108 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1109 assert ((*niter)->name() != IO::state_node_name);
1111 if ((*niter)->name() == X_("CapturingSources")) {
1112 capture_pending_node = *niter;
1116 if (Diskstream::set_state (node, version)) {
1120 ChannelMode channel_mode = AllChannels;
1121 if ((prop = node.property ("channel-mode")) != 0) {
1122 channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode));
1125 unsigned int channel_mask = 0xFFFF;
1126 if ((prop = node.property ("channel-mask")) != 0) {
1127 sscanf (prop->value().c_str(), "0x%x", &channel_mask);
1128 if (channel_mask & (~0xFFFF)) {
1129 warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg;
1134 if (capture_pending_node) {
1135 use_pending_capture_data (*capture_pending_node);
1138 set_channel_mode (channel_mode, channel_mask);
1140 in_set_state = false;
1146 MidiDiskstream::use_new_write_source (uint32_t n)
1148 if (!_session.writable() || !recordable()) {
1154 _write_source.reset();
1157 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1158 _session.create_midi_source_for_session (0, name ()));
1160 if (!_write_source) {
1161 throw failed_constructor();
1165 catch (failed_constructor &err) {
1166 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1167 _write_source.reset();
1174 list<boost::shared_ptr<Source> >
1175 MidiDiskstream::steal_write_sources()
1177 list<boost::shared_ptr<Source> > ret;
1179 /* put some data on the disk, even if its just a header for an empty file */
1180 boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
1182 /* never let it go away */
1183 _write_source->mark_nonremovable ();
1185 ret.push_back (_write_source);
1189 use_new_write_source (0);
1195 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1197 if (!_session.writable() || !recordable()) {
1201 if (_write_source && mark_write_complete) {
1202 _write_source->mark_streaming_write_completed ();
1204 use_new_write_source (0);
1208 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1213 MidiDiskstream::allocate_temporary_buffers ()
1218 MidiDiskstream::ensure_jack_monitors_input (bool yn)
1220 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1223 sp->ensure_jack_monitors_input (yn);
1228 MidiDiskstream::set_align_style_from_io ()
1230 if (_alignment_choice != Automatic) {
1234 /* XXX Not sure what, if anything we can do with MIDI
1235 as far as capture alignment etc.
1238 set_align_style (ExistingMaterial);
1243 MidiDiskstream::playback_buffer_load () const
1245 /* For MIDI it's not trivial to differentiate the following two cases:
1247 1. The playback buffer is empty because the system has run out of time to fill it.
1248 2. The playback buffer is empty because there is no more data on the playlist.
1250 If we use a simple buffer load computation, we will report that the MIDI diskstream
1251 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1252 are so low compared to audio, just give a pretend answer here.
1259 MidiDiskstream::capture_buffer_load () const
1261 /* We don't report playback buffer load, so don't report capture load either */
1267 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1272 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1273 * so that an event at playback_sample has time = 0
1276 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1279 assert(dst.size() == 0);
1282 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1283 "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
1284 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes));
1285 // cerr << "================\n";
1286 // _playback_buf->dump (cerr);
1287 // cerr << "----------------\n";
1289 const size_t events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1290 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1291 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1292 _name, events_read, playback_sample, playback_sample + nframes,
1293 _playback_buf->read_space(), _playback_buf->write_space(),
1294 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1296 _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1299 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1300 cerr << name() << " FRFB advanced by " << nframes << " to " << g_atomic_int_get (&_frames_read_from_ringbuffer) << endl;
1304 MidiDiskstream::set_name (string const & name)
1306 Diskstream::set_name (name);
1308 /* get a new write source so that its name reflects the new diskstream name */
1309 use_new_write_source (0);
1314 boost::shared_ptr<MidiBuffer>
1315 MidiDiskstream::get_gui_feed_buffer () const
1317 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1319 Glib::Mutex::Lock lm (_gui_feed_buffer_mutex);
1320 b->copy (_gui_feed_buffer);
1325 MidiDiskstream::reset_tracker ()
1327 _playback_buf->reset_tracker ();
1329 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1332 mp->clear_note_trackers ();