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 , _frames_pending_write(0)
77 , _num_captured_loops(0)
78 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
84 use_new_write_source (0);
89 throw failed_constructor();
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 , _frames_pending_write(0)
101 , _num_captured_loops(0)
102 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
108 if (set_state (node, Stateful::loading_state_version)) {
109 in_set_state = false;
110 throw failed_constructor();
113 use_new_write_source (0);
115 in_set_state = false;
119 MidiDiskstream::init ()
121 /* there are no channels at this point, so these
122 two calls just get speed_buffer_size and wrap_buffer
123 size setup without duplicating their code.
126 set_block_size (_session.get_block_size());
127 allocate_temporary_buffers ();
129 const size_t size = _session.butler()->midi_diskstream_buffer_size();
130 _playback_buf = new MidiRingBuffer<framepos_t>(size);
131 _capture_buf = new MidiRingBuffer<framepos_t>(size);
133 _n_channels = ChanCount(DataType::MIDI, 1);
136 MidiDiskstream::~MidiDiskstream ()
138 Glib::Threads::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::Threads::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());
204 g_atomic_int_set(&_frames_pending_write, 0);
205 g_atomic_int_set(&_num_captured_loops, 0);
209 MidiDiskstream::find_and_use_playlist (const string& name)
211 boost::shared_ptr<MidiPlaylist> playlist;
213 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
214 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
218 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
222 return use_playlist (playlist);
226 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
228 if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
229 Diskstream::use_playlist(playlist);
236 MidiDiskstream::use_new_playlist ()
239 boost::shared_ptr<MidiPlaylist> playlist;
241 if (!in_set_state && destructive()) {
246 newname = Playlist::bump_name (_playlist->name(), _session);
248 newname = Playlist::bump_name (_name, _session);
251 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
252 DataType::MIDI, _session, newname, hidden()))) != 0) {
254 return use_playlist (playlist);
262 MidiDiskstream::use_copy_playlist ()
268 if (_playlist == 0) {
269 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
274 boost::shared_ptr<MidiPlaylist> playlist;
276 newname = Playlist::bump_name (_playlist->name(), _session);
278 if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
279 return use_playlist (playlist);
285 /** Overloaded from parent to die horribly
288 MidiDiskstream::set_destructive (bool yn)
294 MidiDiskstream::set_note_mode (NoteMode m)
297 midi_playlist()->set_note_mode(m);
298 if (_write_source && _write_source->model())
299 _write_source->model()->set_note_mode(m);
302 /** Get the start, end, and length of a location "atomically".
304 * Note: Locations don't get deleted, so all we care about when I say "atomic"
305 * is that we are always pointing to the same one and using start/length values
306 * obtained just once. Use this function to achieve this since location being
307 * a parameter achieves this.
310 get_location_times(const Location* location,
316 *start = location->start();
317 *end = location->end();
318 *length = *end - *start;
323 MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance)
325 framecnt_t rec_offset = 0;
326 framecnt_t rec_nframes = 0;
327 bool nominally_recording;
328 bool re = record_enabled ();
329 bool can_record = _session.actively_recording ();
331 playback_distance = 0;
333 check_record_status (transport_frame, can_record);
335 nominally_recording = (can_record && re);
341 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
347 Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
353 const Location* const loop_loc = loop_location;
354 framepos_t loop_start = 0;
355 framepos_t loop_end = 0;
356 framepos_t loop_length = 0;
357 get_location_times(loop_loc, &loop_start, &loop_end, &loop_length);
359 adjust_capture_position = 0;
361 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
362 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
364 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
366 if (rec_nframes && !was_recording) {
368 /* Loop recording, so pretend the capture started at the loop
369 start rgardless of what time it is now, so the source starts
370 at the loop start and can handle time wrapping around.
371 Otherwise, start the source right now as usual.
373 capture_captured = transport_frame - loop_start;
374 capture_start_frame = loop_start;
376 _write_source->mark_write_starting_now(
377 capture_start_frame, capture_captured, loop_length);
378 g_atomic_int_set(&_frames_pending_write, 0);
379 g_atomic_int_set(&_num_captured_loops, 0);
380 was_recording = true;
384 if (can_record && !_last_capture_sources.empty()) {
385 _last_capture_sources.clear ();
388 if (nominally_recording || rec_nframes) {
390 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
391 MidiBuffer& buf = sp->get_midi_buffer(nframes);
392 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
393 const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
395 if (DEBUG::MidiIO & PBD::debug_bits) {
396 const uint8_t* __data = ev.buffer();
398 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
399 for (size_t i=0; i < ev.size(); ++i) {
400 DEBUG_STR_APPEND(a,hex);
401 DEBUG_STR_APPEND(a,"0x");
402 DEBUG_STR_APPEND(a,(int)__data[i]);
403 DEBUG_STR_APPEND(a,' ');
405 DEBUG_STR_APPEND(a,'\n');
406 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
409 /* Write events to the capture buffer in frames from session start,
410 but ignoring looping so event time progresses monotonically.
411 The source knows the loop length so it knows exactly where the
412 event occurs in the series of recorded loops and can implement
413 any desirable behaviour. We don't want to send event with
414 transport time here since that way the source can not
415 reconstruct their actual time; future clever MIDI looping should
416 probabl be implemented in the source instead of here.
418 const framecnt_t loop_offset = _num_captured_loops * loop_length;
419 _capture_buf->write(transport_frame + loop_offset + ev.time(),
420 ev.type(), ev.size(), ev.buffer());
422 g_atomic_int_add(&_frames_pending_write, nframes);
424 if (buf.size() != 0) {
425 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
428 /* Copy this data into our GUI feed buffer and tell the GUI
429 that it can read it if it likes.
431 _gui_feed_buffer.clear ();
433 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
434 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
435 the end of the world if it does.
437 _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
441 DataRecorded (_write_source); /* EMIT SIGNAL */
454 /* data will be written to disk */
456 if (rec_nframes == nframes && rec_offset == 0) {
457 playback_distance = nframes;
460 adjust_capture_position = rec_nframes;
462 } else if (nominally_recording) {
464 /* XXXX do this for MIDI !!!
465 can't do actual capture yet - waiting for latency effects to finish before we start
468 playback_distance = nframes;
472 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
474 playback_distance = nframes;
482 MidiDiskstream::commit (framecnt_t playback_distance)
484 bool need_butler = false;
486 if (_actual_speed < 0.0) {
487 playback_sample -= playback_distance;
489 playback_sample += playback_distance;
492 if (adjust_capture_position != 0) {
493 capture_captured += adjust_capture_position;
494 adjust_capture_position = 0;
497 uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
498 uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
501 cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
502 " = " << frames_written - frames_read
503 << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
506 /* frames_read will generally be less than frames_written, but
507 * immediately after an overwrite, we can end up having read some data
508 * before we've written any. we don't need to trip an assert() on this,
509 * but we do need to check so that the decision on whether or not we
510 * need the butler is done correctly.
513 if (frames_read <= frames_written) {
514 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
524 MidiDiskstream::set_pending_overwrite (bool yn)
526 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
528 _pending_overwrite = yn;
529 overwrite_frame = playback_sample;
533 MidiDiskstream::overwrite_existing_buffers ()
535 /* This is safe as long as the butler thread is suspended, which it should be */
536 _playback_buf->reset ();
538 g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
539 g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
541 read (overwrite_frame, disk_io_chunk_frames, false);
542 file_frame = overwrite_frame; // it was adjusted by ::read()
543 overwrite_queued = false;
544 _pending_overwrite = false;
550 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
552 Glib::Threads::Mutex::Lock lm (state_lock);
555 if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
556 /* we haven't read anything since the last seek,
557 so flush all note trackers to prevent
563 _playback_buf->reset();
564 _capture_buf->reset();
565 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
566 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
568 playback_sample = frame;
571 if (complete_refill) {
572 while ((ret = do_refill_with_alloc ()) > 0) ;
574 ret = do_refill_with_alloc ();
581 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
583 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
584 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
585 return ((frames_written - frames_read) < distance);
589 MidiDiskstream::internal_playback_seek (framecnt_t distance)
591 first_recordable_frame += distance;
592 playback_sample += distance;
597 /** @a start is set to the new frame position (TIME) read up to */
599 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
601 framecnt_t this_read = 0;
603 framepos_t loop_end = 0;
604 framepos_t loop_start = 0;
605 framecnt_t loop_length = 0;
611 get_location_times(loc, &loop_start, &loop_end, &loop_length);
613 /* if we are looping, ensure that the first frame we read is at the correct
614 position within the loop.
617 if (loc && (start >= loop_end)) {
618 //cerr << "start adjusted from " << start;
619 start = loop_start + ((start - loop_start) % loop_length);
620 //cerr << "to " << start << endl;
622 // cerr << "start is " << start << " end " << start+dur << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
627 /* take any loop into account. we can't read past the end of the loop. */
629 if (loc && (loop_end - start <= dur)) {
630 this_read = loop_end - start;
631 // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl;
638 if (this_read == 0) {
642 this_read = min(dur,this_read);
644 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
645 error << string_compose(
646 _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
647 id(), this_read, start) << endmsg;
651 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
655 // Swap note ons with note offs here. etc?
656 // Fully reversing MIDI requires look-ahead (well, behind) to find previous
657 // CC values etc. hard.
661 /* if we read to the end of the loop, go back to the beginning */
663 // Synthesize LoopEvent here, because the next events
664 // written will have non-monotonic timestamps.
672 //offset += this_read;
679 MidiDiskstream::do_refill_with_alloc ()
685 MidiDiskstream::do_refill ()
688 size_t write_space = _playback_buf->write_space();
689 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
691 if (write_space == 0) {
699 /* at end: nothing to do */
700 if (file_frame == max_framepos) {
704 /* no space to write */
705 if (_playback_buf->write_space() == 0) {
709 uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
710 uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
711 if ((frames_written - frames_read) >= midi_readahead) {
715 framecnt_t to_read = midi_readahead - (frames_written - frames_read);
717 //cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
718 // << frames_written - frames_read << endl;
720 to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
722 if (read (file_frame, to_read, reversed)) {
729 /** Flush pending data to disk.
731 * Important note: this function will write *AT MOST* disk_io_chunk_frames
732 * of data to disk. it will never write more than that. If it writes that
733 * much and there is more than that waiting to be written, it will return 1,
734 * otherwise 0 on success or -1 on failure.
736 * If there is less than disk_io_chunk_frames to be written, no data will be
737 * written at all unless @a force_flush is true.
740 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
745 if (!_write_source) {
749 const framecnt_t total = g_atomic_int_get(&_frames_pending_write);
752 _capture_buf->read_space() == 0 ||
753 (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
757 /* if there are 2+ chunks of disk i/o possible for
758 this track, let the caller know so that it can arrange
759 for us to be called again, ASAP.
761 if we are forcing a flush, then if there is* any* extra
762 work, let the caller know.
764 if we are no longer recording and there is any extra work,
765 let the caller know too.
768 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
773 /* push out everything we have, right now */
774 to_write = max_framecnt;
776 to_write = disk_io_chunk_frames;
779 if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
780 if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
781 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
784 g_atomic_int_add(&_frames_pending_write, -to_write);
792 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
794 bool more_work = true;
796 boost::shared_ptr<MidiRegion> region;
797 MidiRegion::SourceList srcs;
798 MidiRegion::SourceList::iterator src;
799 vector<CaptureInfo*>::iterator ci;
803 /* butler is already stopped, but there may be work to do
804 to flush remaining data to disk.
807 while (more_work && !err) {
808 switch (do_flush (TransportContext, true)) {
815 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
820 /* XXX is there anything we can do if err != 0 ? */
821 Glib::Threads::Mutex::Lock lm (capture_info_lock);
823 if (capture_info.empty()) {
824 goto no_capture_stuff_to_do;
830 _write_source->mark_for_remove ();
831 _write_source->drop_references ();
832 _write_source.reset();
835 /* new source set up in "out" below */
839 framecnt_t total_capture = 0;
840 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
841 total_capture += (*ci)->frames;
844 if (_write_source->length (capture_info.front()->start) != 0) {
846 /* phew, we have data */
848 /* figure out the name for this take */
850 srcs.push_back (_write_source);
852 _write_source->set_timeline_position (capture_info.front()->start);
853 _write_source->set_captured_for (_name);
855 /* set length in beats to entire capture length */
857 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
858 const double total_capture_beats = converter.from (total_capture);
859 _write_source->set_length_beats (total_capture_beats);
861 /* flush to disk: this step differs from the audio path,
862 where all the data is already on disk.
865 _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
867 /* we will want to be able to keep (over)writing the source
868 but we don't want it to be removable. this also differs
869 from the audio situation, where the source at this point
870 must be considered immutable. luckily, we can rely on
871 MidiSource::mark_streaming_write_completed() to have
872 already done the necessary work for that.
875 string whole_file_region_name;
876 whole_file_region_name = region_name_from_path (_write_source->name(), true);
878 /* Register a new region with the Session that
879 describes the entire source. Do this first
880 so that any sub-regions will obviously be
881 children of this one (later!)
887 plist.add (Properties::name, whole_file_region_name);
888 plist.add (Properties::whole_file, true);
889 plist.add (Properties::automatic, true);
890 plist.add (Properties::start, 0);
891 plist.add (Properties::length, total_capture);
892 plist.add (Properties::layer, 0);
894 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
896 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
897 region->special_set_position (capture_info.front()->start);
901 catch (failed_constructor& err) {
902 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
906 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
908 _playlist->clear_changes ();
909 _playlist->freeze ();
911 /* Session frame time of the initial capture in this pass, which is where the source starts */
912 framepos_t initial_capture = 0;
913 if (!capture_info.empty()) {
914 initial_capture = capture_info.front()->start;
917 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
921 RegionFactory::region_name (region_name, _write_source->name(), false);
923 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
928 /* start of this region is the offset between the start of its capture and the start of the whole pass */
929 plist.add (Properties::start, (*ci)->start - initial_capture);
930 plist.add (Properties::length, (*ci)->frames);
931 plist.add (Properties::length_beats, converter.from((*ci)->frames));
932 plist.add (Properties::name, region_name);
934 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
935 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
938 catch (failed_constructor& err) {
939 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
940 continue; /* XXX is this OK? */
943 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
946 _playlist->add_region (region, (*ci)->start);
951 _session.add_command (new StatefulDiffCommand(_playlist));
955 /* No data was recorded, so this capture will
956 effectively be aborted; do the same as we
957 do for an explicit abort.
961 _write_source->mark_for_remove ();
962 _write_source->drop_references ();
963 _write_source.reset();
969 use_new_write_source (0);
971 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
975 capture_info.clear ();
976 capture_start_frame = 0;
978 no_capture_stuff_to_do:
984 MidiDiskstream::transport_looped (framepos_t)
986 /* Here we only keep track of the number of captured loops so monotonic
987 event times can be delivered to the write source in process(). Trying
988 to be clever here is a world of trouble, it is better to simply record
989 the input in a straightforward non-destructive way. In the future when
990 we want to implement more clever MIDI looping modes it should be done in
991 the Source and/or entirely after the capture is finished.
994 g_atomic_int_add(&_num_captured_loops, 1);
999 MidiDiskstream::finish_capture ()
1001 was_recording = false;
1003 if (capture_captured == 0) {
1007 CaptureInfo* ci = new CaptureInfo;
1009 ci->start = capture_start_frame;
1010 ci->frames = capture_captured;
1012 /* XXX theoretical race condition here. Need atomic exchange ?
1013 However, the circumstances when this is called right
1014 now (either on record-disable or transport_stopped)
1015 mean that no actual race exists. I think ...
1016 We now have a capture_info_lock, but it is only to be used
1017 to synchronize in the transport_stop and the capture info
1018 accessors, so that invalidation will not occur (both non-realtime).
1021 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1023 capture_info.push_back (ci);
1024 capture_captured = 0;
1028 MidiDiskstream::set_record_enabled (bool yn)
1030 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1034 /* yes, i know that this not proof against race conditions, but its
1035 good enough. i think.
1038 if (record_enabled() != yn) {
1040 engage_record_enable ();
1042 disengage_record_enable ();
1045 RecordEnableChanged (); /* EMIT SIGNAL */
1050 MidiDiskstream::prep_record_enable ()
1052 if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1056 bool const rolling = _session.transport_speed() != 0.0f;
1058 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1060 if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1061 sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
1068 MidiDiskstream::prep_record_disable ()
1075 MidiDiskstream::get_state ()
1077 XMLNode& node (Diskstream::get_state());
1079 LocaleGuard lg (X_("POSIX"));
1081 node.add_property("channel-mode", enum_2_string(get_channel_mode()));
1082 snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
1083 node.add_property("channel-mask", buf);
1085 if (_write_source && _session.get_record_enabled()) {
1087 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1088 XMLNode* cs_grandchild;
1090 cs_grandchild = new XMLNode (X_("file"));
1091 cs_grandchild->add_property (X_("path"), _write_source->path());
1092 cs_child->add_child_nocopy (*cs_grandchild);
1094 /* store the location where capture will start */
1098 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1099 snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1101 snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1104 cs_child->add_property (X_("at"), buf);
1105 node.add_child_nocopy (*cs_child);
1112 MidiDiskstream::set_state (const XMLNode& node, int version)
1114 const XMLProperty* prop;
1115 XMLNodeList nlist = node.children();
1116 XMLNodeIterator niter;
1117 XMLNode* capture_pending_node = 0;
1118 LocaleGuard lg (X_("POSIX"));
1120 /* prevent write sources from being created */
1122 in_set_state = true;
1124 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
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()) {
1166 _write_source.reset();
1169 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1170 _session.create_midi_source_for_session (0, name ()));
1172 if (!_write_source) {
1173 throw failed_constructor();
1177 catch (failed_constructor &err) {
1178 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1179 _write_source.reset();
1186 list<boost::shared_ptr<Source> >
1187 MidiDiskstream::steal_write_sources()
1189 list<boost::shared_ptr<Source> > ret;
1191 /* put some data on the disk, even if its just a header for an empty file */
1192 boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
1194 /* never let it go away */
1195 _write_source->mark_nonremovable ();
1197 ret.push_back (_write_source);
1201 use_new_write_source (0);
1207 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1209 if (!_session.writable() || !recordable()) {
1213 if (_write_source && mark_write_complete) {
1214 _write_source->mark_streaming_write_completed ();
1216 use_new_write_source (0);
1220 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1225 MidiDiskstream::allocate_temporary_buffers ()
1230 MidiDiskstream::ensure_jack_monitors_input (bool yn)
1232 boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1235 sp->ensure_jack_monitors_input (yn);
1240 MidiDiskstream::set_align_style_from_io ()
1242 if (_alignment_choice != Automatic) {
1246 /* XXX Not sure what, if anything we can do with MIDI
1247 as far as capture alignment etc.
1250 set_align_style (ExistingMaterial);
1255 MidiDiskstream::playback_buffer_load () const
1257 /* For MIDI it's not trivial to differentiate the following two cases:
1259 1. The playback buffer is empty because the system has run out of time to fill it.
1260 2. The playback buffer is empty because there is no more data on the playlist.
1262 If we use a simple buffer load computation, we will report that the MIDI diskstream
1263 cannot keep up when #2 happens, when in fact it can. Since MIDI data rates
1264 are so low compared to audio, just give a pretend answer here.
1271 MidiDiskstream::capture_buffer_load () const
1273 /* We don't report playback buffer load, so don't report capture load either */
1279 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1285 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1287 _playback_buf->flush (start, end);
1288 g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1291 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1292 * so that an event at playback_sample has time = 0
1295 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1299 Location* loc = loop_location;
1301 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1302 "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1303 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1304 (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1306 // cerr << "================\n";
1307 // _playback_buf->dump (cerr);
1308 // cerr << "----------------\n";
1310 size_t events_read = 0;
1313 framepos_t effective_start;
1315 if (playback_sample >= loc->end()) {
1316 effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1318 effective_start = playback_sample;
1321 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1323 if (effective_start == loc->start()) {
1324 /* We need to turn off notes that may extend
1325 beyond the loop end.
1328 _playback_buf->loop_resolve (dst, 0);
1331 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1332 /* end of loop is within the range we are reading, so
1333 split the read in two, and lie about the location
1336 framecnt_t first, second;
1338 first = loc->end() - effective_start;
1339 second = nframes - first;
1341 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1342 effective_start, loc->end(), first, second));
1345 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1346 effective_start, first));
1347 events_read = _playback_buf->read (dst, effective_start, first);
1351 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1352 loc->start(), second));
1353 events_read += _playback_buf->read (dst, loc->start(), second);
1357 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1358 effective_start, nframes));
1359 events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1362 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1365 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1366 "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1367 _name, events_read, playback_sample, playback_sample + nframes,
1368 _playback_buf->read_space(), _playback_buf->write_space(),
1369 _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1371 g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1375 MidiDiskstream::set_name (string const & name)
1377 Diskstream::set_name (name);
1379 /* get a new write source so that its name reflects the new diskstream name */
1380 use_new_write_source (0);
1385 boost::shared_ptr<MidiBuffer>
1386 MidiDiskstream::get_gui_feed_buffer () const
1388 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1390 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1391 b->copy (_gui_feed_buffer);
1396 MidiDiskstream::reset_tracker ()
1398 _playback_buf->reset_tracker ();
1400 boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1403 mp->clear_note_trackers ();