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/threads.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/audioengine.h"
42 #include "ardour/butler.h"
43 #include "ardour/debug.h"
44 #include "ardour/io.h"
45 #include "ardour/midi_diskstream.h"
46 #include "ardour/midi_model.h"
47 #include "ardour/midi_playlist.h"
48 #include "ardour/midi_port.h"
49 #include "ardour/midi_region.h"
50 #include "ardour/playlist_factory.h"
51 #include "ardour/region_factory.h"
52 #include "ardour/session.h"
53 #include "ardour/session_playlists.h"
54 #include "ardour/smf_source.h"
55 #include "ardour/types.h"
56 #include "ardour/utils.h"
58 #include "midi++/types.h"
64 using namespace ARDOUR;
67 framecnt_t MidiDiskstream::midi_readahead = 4096;
69 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
70 : Diskstream(sess, name, flag)
73 , _note_mode(Sustained)
74 , _frames_written_to_ringbuffer(0)
75 , _frames_read_from_ringbuffer(0)
76 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
82 use_new_write_source (0);
86 assert(!destructive());
89 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
90 : Diskstream(sess, node)
93 , _note_mode(Sustained)
94 , _frames_written_to_ringbuffer(0)
95 , _frames_read_from_ringbuffer(0)
96 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
102 if (set_state (node, Stateful::loading_state_version)) {
103 in_set_state = false;
104 throw failed_constructor();
107 use_new_write_source (0);
109 in_set_state = false;
113 MidiDiskstream::init ()
115 /* there are no channels at this point, so these
116 two calls just get speed_buffer_size and wrap_buffer
117 size setup without duplicating their code.
120 set_block_size (_session.get_block_size());
121 allocate_temporary_buffers ();
123 const size_t size = _session.butler()->midi_diskstream_buffer_size();
124 _playback_buf = new MidiRingBuffer<framepos_t>(size);
125 _capture_buf = new MidiRingBuffer<framepos_t>(size);
127 _n_channels = ChanCount(DataType::MIDI, 1);
129 assert(recordable());
132 MidiDiskstream::~MidiDiskstream ()
134 Glib::Threads::Mutex::Lock lm (state_lock);
139 MidiDiskstream::non_realtime_locate (framepos_t position)
142 _write_source->set_timeline_position (position);
144 seek (position, false);
149 MidiDiskstream::non_realtime_input_change ()
152 Glib::Threads::Mutex::Lock lm (state_lock);
154 if (input_change_pending.type == IOChange::NoChange) {
158 if (input_change_pending.type & IOChange::ConfigurationChanged) {
159 uint32_t ni = _io->n_ports().n_midi();
161 if (ni != _n_channels.n_midi()) {
162 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
165 _n_channels, input_change_pending.type)
170 _source_port.reset ();
172 _source_port = _io->midi(0);
176 if (input_change_pending.type & IOChange::ConnectionsChanged) {
177 set_capture_offset ();
178 set_align_style_from_io ();
181 input_change_pending.type = IOChange::NoChange;
183 /* implicit unlock */
186 /* unlike with audio, there is never any need to reset write sources
187 based on input configuration changes because ... a MIDI track
188 has just 1 MIDI port as input, always.
191 /* now refill channel buffers */
193 if (speed() != 1.0f || speed() != -1.0f) {
194 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
197 seek (_session.transport_frame());
201 _write_source->set_last_write_end (_session.transport_frame());
206 MidiDiskstream::find_and_use_playlist (const string& name)
208 boost::shared_ptr<MidiPlaylist> playlist;
210 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
211 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
215 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't an midi playlist"), name) << endmsg;
219 return use_playlist (playlist);
223 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
225 assert(boost::dynamic_pointer_cast<MidiPlaylist>(playlist));
227 Diskstream::use_playlist(playlist);
233 MidiDiskstream::use_new_playlist ()
236 boost::shared_ptr<MidiPlaylist> playlist;
238 if (!in_set_state && destructive()) {
243 newname = Playlist::bump_name (_playlist->name(), _session);
245 newname = Playlist::bump_name (_name, _session);
248 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
249 DataType::MIDI, _session, newname, hidden()))) != 0) {
251 return use_playlist (playlist);
259 MidiDiskstream::use_copy_playlist ()
261 assert(midi_playlist());
267 if (_playlist == 0) {
268 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
273 boost::shared_ptr<MidiPlaylist> playlist;
275 newname = Playlist::bump_name (_playlist->name(), _session);
277 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
278 return use_playlist (playlist);
284 /** Overloaded from parent to die horribly
287 MidiDiskstream::set_destructive (bool yn)
289 yn = 0; // stop pedantic gcc complaints about unused parameter
290 assert( ! destructive());
296 MidiDiskstream::set_note_mode (NoteMode m)
299 midi_playlist()->set_note_mode(m);
300 if (_write_source && _write_source->model())
301 _write_source->model()->set_note_mode(m);
305 MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance)
307 framecnt_t rec_offset = 0;
308 framecnt_t rec_nframes = 0;
309 bool nominally_recording;
310 bool re = record_enabled ();
311 bool can_record = _session.actively_recording ();
313 playback_distance = 0;
315 check_record_status (transport_frame, can_record);
317 nominally_recording = (can_record && re);
323 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
329 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
335 adjust_capture_position = 0;
337 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
338 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
340 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
342 if (rec_nframes && !was_recording) {
343 _write_source->mark_write_starting_now ();
344 capture_captured = 0;
345 was_recording = true;
349 if (can_record && !_last_capture_sources.empty()) {
350 _last_capture_sources.clear ();
353 if (nominally_recording || rec_nframes) {
355 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
356 MidiBuffer& buf = sp->get_midi_buffer(nframes);
357 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
358 const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
361 if (DEBUG::MidiIO & PBD::debug_bits) {
362 const uint8_t* __data = ev.buffer();
364 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
365 for (size_t i=0; i < ev.size(); ++i) {
366 DEBUG_STR_APPEND(a,hex);
367 DEBUG_STR_APPEND(a,"0x");
368 DEBUG_STR_APPEND(a,(int)__data[i]);
369 DEBUG_STR_APPEND(a,' ');
371 DEBUG_STR_APPEND(a,'\n');
372 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
375 _capture_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer());
378 if (buf.size() != 0) {
379 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
382 /* Copy this data into our GUI feed buffer and tell the GUI
383 that it can read it if it likes.
385 _gui_feed_buffer.clear ();
387 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
388 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
389 the end of the world if it does.
391 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
395 DataRecorded (_write_source); /* EMIT SIGNAL */
408 /* data will be written to disk */
410 if (rec_nframes == nframes && rec_offset == 0) {
411 playback_distance = nframes;
414 adjust_capture_position = rec_nframes;
416 } else if (nominally_recording) {
418 /* XXXX do this for MIDI !!!
419 can't do actual capture yet - waiting for latency effects to finish before we start
422 playback_distance = nframes;
426 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
428 playback_distance = nframes;
436 MidiDiskstream::commit (framecnt_t playback_distance)
438 bool need_butler = false;
440 if (_actual_speed < 0.0) {
441 playback_sample -= playback_distance;
443 playback_sample += playback_distance;
446 if (adjust_capture_position != 0) {
447 capture_captured += adjust_capture_position;
448 adjust_capture_position = 0;
451 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
452 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
455 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
456 " = " << frames_written - frames_read
457 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
460 /* frames_read will generally be less than frames_written, but
461 * immediately after an overwrite, we can end up having read some data
462 * before we've written any. we don't need to trip an assert() on this,
463 * but we do need to check so that the decision on whether or not we
464 * need the butler is done correctly.
467 if (frames_read <= frames_written) {
468 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
478 MidiDiskstream::set_pending_overwrite (bool yn)
480 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
482 _pending_overwrite = yn;
483 overwrite_frame = playback_sample;
487 MidiDiskstream::overwrite_existing_buffers ()
489 /* This is safe as long as the butler thread is suspended, which it should be */
490 _playback_buf->reset ();
492 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
493 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
495 read (overwrite_frame, disk_io_chunk_frames, false);
496 file_frame = overwrite_frame; // it was adjusted by ::read()
497 overwrite_queued = false;
498 _pending_overwrite = false;
504 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
506 Glib::Threads::Mutex::Lock lm (state_lock);
509 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
510 /* we haven't read anything since the last seek,
511 so flush all note trackers to prevent
517 _playback_buf->reset();
518 _capture_buf->reset();
519 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
520 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
522 playback_sample = frame;
525 if (complete_refill) {
526 while ((ret = do_refill_with_alloc ()) > 0) ;
528 ret = do_refill_with_alloc ();
535 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
537 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
538 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
539 return ((frames_written - frames_read) < distance);
543 MidiDiskstream::internal_playback_seek (framecnt_t distance)
545 first_recordable_frame += distance;
546 playback_sample += distance;
551 /** @a start is set to the new frame position (TIME) read up to */
553 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
555 framecnt_t this_read = 0;
557 framepos_t loop_end = 0;
558 framepos_t loop_start = 0;
563 framecnt_t loop_length = 0;
565 /* Make the use of a Location atomic for this read operation.
567 Note: Locations don't get deleted, so all we care about
568 when I say "atomic" is that we are always pointing to
569 the same one and using a start/length values obtained
573 if ((loc = loop_location) != 0) {
574 loop_start = loc->start();
575 loop_end = loc->end();
576 loop_length = loop_end - loop_start;
579 /* if we are looping, ensure that the first frame we read is at the correct
580 position within the loop.
583 if (loc && (start >= loop_end)) {
584 //cerr << "start adjusted from " << start;
585 start = loop_start + ((start - loop_start) % loop_length);
586 //cerr << "to " << start << endl;
588 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
593 /* take any loop into account. we can't read past the end of the loop. */
595 if (loc && (loop_end - start <= dur)) {
596 this_read = loop_end - start;
597 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
604 if (this_read == 0) {
608 this_read = min(dur,this_read);
610 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
611 error << string_compose(
612 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
613 id(), this_read, start) << endmsg;
617 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
621 // Swap note ons with note offs here. etc?
622 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
623 // CC values etc. hard.
627 /* if we read to the end of the loop, go back to the beginning */
630 // Synthesize LoopEvent here, because the next events
631 // written will have non-monotonic timestamps.
632 _playback_buf->write(loop_end - 1, LoopEventType, sizeof (framepos_t), (uint8_t *) &loop_start);
640 //offset += this_read;
647 MidiDiskstream::do_refill_with_alloc ()
653 MidiDiskstream::do_refill ()
656 size_t write_space = _playback_buf->write_space();
657 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
659 if (write_space == 0) {
667 /* at end: nothing to do */
668 if (file_frame == max_framepos) {
672 // At this point we...
673 assert(_playback_buf->write_space() > 0); // ... have something to write to, and
674 assert(file_frame <= max_framepos); // ... something to write
676 // now calculate how much time is in the ringbuffer.
677 // and lets write as much as we need to get this to be midi_readahead;
678 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
679 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
680 if ((frames_written - frames_read) >= midi_readahead) {
684 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
686 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
687 // << frames_written - frames_read << endl;
689 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
691 if (read (file_frame, to_read, reversed)) {
698 /** Flush pending data to disk.
700 * Important note: this function will write *AT MOST* disk_io_chunk_frames
701 * of data to disk. it will never write more than that. If it writes that
702 * much and there is more than that waiting to be written, it will return 1,
703 * otherwise 0 on success or -1 on failure.
705 * If there is less than disk_io_chunk_frames to be written, no data will be
706 * written at all unless @a force_flush is true.
709 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
715 if (!_write_source) {
719 assert (!destructive());
721 total = _session.transport_frame() - _write_source->last_write_end();
724 _capture_buf->read_space() == 0 ||
725 (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
729 /* if there are 2+ chunks of disk i/o possible for
730 this track, let the caller know so that it can arrange
731 for us to be called again, ASAP.
733 if we are forcing a flush, then if there is* any* extra
734 work, let the caller know.
736 if we are no longer recording and there is any extra work,
737 let the caller know too.
740 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
745 /* push out everything we have, right now */
746 to_write = max_framecnt;
748 to_write = disk_io_chunk_frames;
751 if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
752 if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
753 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
763 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
765 bool more_work = true;
767 boost::shared_ptr<MidiRegion> region;
768 MidiRegion::SourceList srcs;
769 MidiRegion::SourceList::iterator src;
770 vector<CaptureInfo*>::iterator ci;
774 /* butler is already stopped, but there may be work to do
775 to flush remaining data to disk.
778 while (more_work && !err) {
779 switch (do_flush (TransportContext, true)) {
786 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
791 /* XXX is there anything we can do if err != 0 ? */
792 Glib::Threads::Mutex::Lock lm (capture_info_lock);
794 if (capture_info.empty()) {
795 goto no_capture_stuff_to_do;
801 _write_source->mark_for_remove ();
802 _write_source->drop_references ();
803 _write_source.reset();
806 /* new source set up in "out" below */
810 assert(_write_source);
812 framecnt_t total_capture = 0;
813 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
814 total_capture += (*ci)->frames;
817 if (_write_source->length (capture_info.front()->start) != 0) {
819 /* phew, we have data */
821 /* figure out the name for this take */
823 srcs.push_back (_write_source);
825 _write_source->set_timeline_position (capture_info.front()->start);
826 _write_source->set_captured_for (_name);
828 /* set length in beats to entire capture length */
830 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
831 const double total_capture_beats = converter.from (total_capture);
832 _write_source->set_length_beats (total_capture_beats);
834 /* flush to disk: this step differs from the audio path,
835 where all the data is already on disk.
838 _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
840 /* we will want to be able to keep (over)writing the source
841 but we don't want it to be removable. this also differs
842 from the audio situation, where the source at this point
843 must be considered immutable. luckily, we can rely on
844 MidiSource::mark_streaming_write_completed() to have
845 already done the necessary work for that.
848 string whole_file_region_name;
849 whole_file_region_name = region_name_from_path (_write_source->name(), true);
851 /* Register a new region with the Session that
852 describes the entire source. Do this first
853 so that any sub-regions will obviously be
854 children of this one (later!)
860 plist.add (Properties::name, whole_file_region_name);
861 plist.add (Properties::whole_file, true);
862 plist.add (Properties::automatic, true);
863 plist.add (Properties::start, 0);
864 plist.add (Properties::length, total_capture);
865 plist.add (Properties::layer, 0);
867 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
869 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
870 region->special_set_position (capture_info.front()->start);
874 catch (failed_constructor& err) {
875 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
879 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
881 _playlist->clear_changes ();
882 _playlist->freeze ();
884 /* Session frame time of the initial capture in this pass, which is where the source starts */
885 framepos_t initial_capture = 0;
886 if (!capture_info.empty()) {
887 initial_capture = capture_info.front()->start;
890 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
894 RegionFactory::region_name (region_name, _write_source->name(), false);
896 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
901 /* start of this region is the offset between the start of its capture and the start of the whole pass */
902 plist.add (Properties::start, (*ci)->start - initial_capture);
903 plist.add (Properties::length, (*ci)->frames);
904 plist.add (Properties::length_beats, converter.from((*ci)->frames));
905 plist.add (Properties::name, region_name);
907 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
908 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
911 catch (failed_constructor& err) {
912 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
913 continue; /* XXX is this OK? */
916 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
919 _playlist->add_region (region, (*ci)->start);
924 _session.add_command (new StatefulDiffCommand(_playlist));
928 /* No data was recorded, so this capture will
929 effectively be aborted; do the same as we
930 do for an explicit abort.
934 _write_source->mark_for_remove ();
935 _write_source->drop_references ();
936 _write_source.reset();
942 use_new_write_source (0);
944 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
948 capture_info.clear ();
949 capture_start_frame = 0;
951 no_capture_stuff_to_do:
957 MidiDiskstream::transport_looped (framepos_t transport_frame)
961 // adjust the capture length knowing that the data will be recorded to disk
962 // only necessary after the first loop where we're recording
963 if (capture_info.size() == 0) {
964 capture_captured += _capture_offset;
966 if (_alignment_style == ExistingMaterial) {
967 capture_captured += _session.worst_output_latency();
969 capture_captured += _roll_delay;
975 // the next region will start recording via the normal mechanism
976 // we'll set the start position to the current transport pos
977 // no latency adjustment or capture offset needs to be made, as that already happened the first time
978 capture_start_frame = transport_frame;
979 first_recordable_frame = transport_frame; // mild lie
980 last_recordable_frame = max_framepos;
981 was_recording = true;
984 if (!Config->get_seamless_loop()) {
990 MidiDiskstream::finish_capture ()
992 was_recording = false;
994 if (capture_captured == 0) {
998 // Why must we destroy?
999 assert(!destructive());
1001 CaptureInfo* ci = new CaptureInfo;
1003 ci->start = capture_start_frame;
1004 ci->frames = capture_captured;
1006 /* XXX theoretical race condition here. Need atomic exchange ?
1007 However, the circumstances when this is called right
1008 now (either on record-disable or transport_stopped)
1009 mean that no actual race exists. I think ...
1010 We now have a capture_info_lock, but it is only to be used
1011 to synchronize in the transport_stop and the capture info
1012 accessors, so that invalidation will not occur (both non-realtime).
1015 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1017 capture_info.push_back (ci);
1018 capture_captured = 0;
1022 MidiDiskstream::set_record_enabled (bool yn)
1024 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1028 assert(!destructive());
1030 /* yes, i know that this not proof against race conditions, but its
1031 good enough. i think.
1034 if (record_enabled() != yn) {
1036 engage_record_enable ();
1038 disengage_record_enable ();
1044 MidiDiskstream::prep_record_enable ()
1046 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1050 bool const rolling = _session.transport_speed() != 0.0f;
1052 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1054 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1055 sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
1058 RecordEnableChanged (); /* EMIT SIGNAL */
1064 MidiDiskstream::prep_record_disable ()
1066 g_atomic_int_set (&_record_enabled, 0);
1067 RecordEnableChanged (); /* EMIT SIGNAL */
1073 MidiDiskstream::get_state ()
1075 XMLNode& node (Diskstream::get_state());
1077 LocaleGuard lg (X_("POSIX"));
1079 node.add_property("channel-mode", enum_2_string(get_channel_mode()));
1080 snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
1081 node.add_property("channel-mask", buf);
1083 if (_write_source && _session.get_record_enabled()) {
1085 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1086 XMLNode* cs_grandchild;
1088 cs_grandchild = new XMLNode (X_("file"));
1089 cs_grandchild->add_property (X_("path"), _write_source->path());
1090 cs_child->add_child_nocopy (*cs_grandchild);
1092 /* store the location where capture will start */
1096 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1097 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1099 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1102 cs_child->add_property (X_("at"), buf);
1103 node.add_child_nocopy (*cs_child);
1110 MidiDiskstream::set_state (const XMLNode& node, int version)
1112 const XMLProperty* prop;
1113 XMLNodeList nlist = node.children();
1114 XMLNodeIterator niter;
1115 XMLNode* capture_pending_node = 0;
1116 LocaleGuard lg (X_("POSIX"));
1118 /* prevent write sources from being created */
1120 in_set_state = true;
1122 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1123 assert ((*niter)->name() != IO::state_node_name);
1125 if ((*niter)->name() == X_("CapturingSources")) {
1126 capture_pending_node = *niter;
1130 if (Diskstream::set_state (node, version)) {
1134 ChannelMode channel_mode = AllChannels;
1135 if ((prop = node.property ("channel-mode")) != 0) {
1136 channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode));
1139 unsigned int channel_mask = 0xFFFF;
1140 if ((prop = node.property ("channel-mask")) != 0) {
1141 sscanf (prop->value().c_str(), "0x%x", &channel_mask);
1142 if (channel_mask & (~0xFFFF)) {
1143 warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg;
1148 if (capture_pending_node) {
1149 use_pending_capture_data (*capture_pending_node);
1152 set_channel_mode (channel_mode, channel_mask);
1154 in_set_state = false;
1160 MidiDiskstream::use_new_write_source (uint32_t n)
1162 if (!_session.writable() || !recordable()) {
1168 _write_source.reset();
1171 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1172 _session.create_midi_source_for_session (0, name ()));
1174 if (!_write_source) {
1175 throw failed_constructor();
1179 catch (failed_constructor &err) {
1180 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1181 _write_source.reset();
1188 list<boost::shared_ptr<Source> >
1189 MidiDiskstream::steal_write_sources()
1191 list<boost::shared_ptr<Source> > ret;
1193 /* put some data on the disk, even if its just a header for an empty file */
1194 boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
1196 /* never let it go away */
1197 _write_source->mark_nonremovable ();
1199 ret.push_back (_write_source);
1203 use_new_write_source (0);
1209 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1211 if (!_session.writable() || !recordable()) {
1215 if (_write_source && mark_write_complete) {
1216 _write_source->mark_streaming_write_completed ();
1218 use_new_write_source (0);
1222 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1227 MidiDiskstream::allocate_temporary_buffers ()
1232 MidiDiskstream::ensure_jack_monitors_input (bool yn)
1234 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1237 sp->ensure_jack_monitors_input (yn);
1242 MidiDiskstream::set_align_style_from_io ()
1244 if (_alignment_choice != Automatic) {
1248 /* XXX Not sure what, if anything we can do with MIDI
1249 as far as capture alignment etc.
1252 set_align_style (ExistingMaterial);
1257 MidiDiskstream::playback_buffer_load () const
1259 /* For MIDI it's not trivial to differentiate the following two cases:
1261 1. The playback buffer is empty because the system has run out of time to fill it.
1262 2. The playback buffer is empty because there is no more data on the playlist.
1264 If we use a simple buffer load computation, we will report that the MIDI diskstream
1265 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1266 are so low compared to audio, just give a pretend answer here.
1273 MidiDiskstream::capture_buffer_load () const
1275 /* We don't report playback buffer load, so don't report capture load either */
1281 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1287 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1289 _playback_buf->flush (start, end);
1290 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1293 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1294 * so that an event at playback_sample has time = 0
1297 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1300 assert(dst.size() == 0);
1303 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1304 "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
1305 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes));
1306 // cerr << "================\n";
1307 // _playback_buf->dump (cerr);
1308 // cerr << "----------------\n";
1310 const size_t events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1311 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1312 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1313 _name, events_read, playback_sample, playback_sample + nframes,
1314 _playback_buf->read_space(), _playback_buf->write_space(),
1315 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1317 _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1320 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1324 MidiDiskstream::set_name (string const & name)
1326 Diskstream::set_name (name);
1328 /* get a new write source so that its name reflects the new diskstream name */
1329 use_new_write_source (0);
1334 boost::shared_ptr<MidiBuffer>
1335 MidiDiskstream::get_gui_feed_buffer () const
1337 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1339 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1340 b->copy (_gui_feed_buffer);
1345 MidiDiskstream::reset_tracker ()
1347 _playback_buf->reset_tracker ();
1349 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1352 mp->clear_note_trackers ();