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/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::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::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::Mutex::Lock sm (state_lock, Glib::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::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::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::Mutex::Lock lm (state_lock);
509 _playback_buf->reset();
510 _capture_buf->reset();
511 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
512 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
514 playback_sample = frame;
517 if (complete_refill) {
518 while ((ret = do_refill_with_alloc ()) > 0) ;
520 ret = do_refill_with_alloc ();
527 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
529 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
530 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
531 return ((frames_written - frames_read) < distance);
535 MidiDiskstream::internal_playback_seek (framecnt_t distance)
537 first_recordable_frame += distance;
538 playback_sample += distance;
543 /** @a start is set to the new frame position (TIME) read up to */
545 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
547 framecnt_t this_read = 0;
549 framepos_t loop_end = 0;
550 framepos_t loop_start = 0;
555 framecnt_t loop_length = 0;
557 /* Make the use of a Location atomic for this read operation.
559 Note: Locations don't get deleted, so all we care about
560 when I say "atomic" is that we are always pointing to
561 the same one and using a start/length values obtained
565 if ((loc = loop_location) != 0) {
566 loop_start = loc->start();
567 loop_end = loc->end();
568 loop_length = loop_end - loop_start;
571 /* if we are looping, ensure that the first frame we read is at the correct
572 position within the loop.
575 if (loc && (start >= loop_end)) {
576 //cerr << "start adjusted from " << start;
577 start = loop_start + ((start - loop_start) % loop_length);
578 //cerr << "to " << start << endl;
580 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
585 /* take any loop into account. we can't read past the end of the loop. */
587 if (loc && (loop_end - start <= dur)) {
588 this_read = loop_end - start;
589 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
596 if (this_read == 0) {
600 this_read = min(dur,this_read);
602 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
603 error << string_compose(
604 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
605 id(), this_read, start) << endmsg;
609 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
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);
1303 MidiDiskstream::set_name (string const & name)
1305 Diskstream::set_name (name);
1307 /* get a new write source so that its name reflects the new diskstream name */
1308 use_new_write_source (0);
1313 boost::shared_ptr<MidiBuffer>
1314 MidiDiskstream::get_gui_feed_buffer () const
1316 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1318 Glib::Mutex::Lock lm (_gui_feed_buffer_mutex);
1319 b->copy (_gui_feed_buffer);
1324 MidiDiskstream::reset_tracker ()
1326 _playback_buf->reset_tracker ();
1328 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1331 mp->clear_note_trackers ();