Remove some unused PostTransport enums and renumber others.
[ardour.git] / libs / ardour / midi_diskstream.cc
index 89a497cf018f208d448837cb483bd1ce01325374..1c34ff9c0368ff7b757f374a433ef5aa75c5cb5b 100644 (file)
@@ -79,8 +79,6 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
        , _frames_written_to_ringbuffer(0)
        , _frames_read_from_ringbuffer(0)
 {
-       /* prevent any write sources from being created */
-
        in_set_state = true;
 
        init ();
@@ -148,7 +146,7 @@ MidiDiskstream::non_realtime_locate (framepos_t position)
        if (_write_source) {
                _write_source->set_timeline_position (position);
        }
-       seek(position, false);
+       seek (position, false);
 }
 
 
@@ -163,19 +161,25 @@ MidiDiskstream::non_realtime_input_change ()
                }
 
                if (input_change_pending.type & IOChange::ConfigurationChanged) {
-                       if (_io->n_ports().n_midi() != _n_channels.n_midi()) {
-                               error << "Can not feed IO " << _io->n_ports()
-                                       << " with diskstream " << _n_channels << endl;
+                       uint32_t ni = _io->n_ports().n_midi();
+
+                       if (ni != _n_channels.n_midi()) {
+                               error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
+                                                        name(),
+                                                        _io->n_ports(),
+                                                        _n_channels, input_change_pending.type)
+                                     << endmsg;
                        }
-               }
 
-               get_input_sources ();
-               set_capture_offset ();
+                       if (ni == 0) {
+                               _source_port = 0;
+                       } else {
+                               _source_port = _io->midi(0);
+                       }
+               }
 
-               if (first_input_change) {
-                       set_align_style (_persistent_alignment_style);
-                       first_input_change = false;
-               } else {
+               if (input_change_pending.type & IOChange::ConnectionsChanged) {
+                       set_capture_offset ();
                        set_align_style_from_io ();
                }
 
@@ -201,23 +205,6 @@ MidiDiskstream::non_realtime_input_change ()
        _last_flush_frame = _session.transport_frame();
 }
 
-void
-MidiDiskstream::get_input_sources ()
-{
-       uint32_t ni = _io->n_ports().n_midi();
-
-       if (ni == 0) {
-               return;
-       }
-
-       // This is all we do for now at least
-       assert(ni == 1);
-
-       _source_port = _io->midi(0);
-
-       // do... stuff?
-}
-
 int
 MidiDiskstream::find_and_use_playlist (const string& name)
 {
@@ -506,6 +493,10 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can
                return 0;
        }
 
+       if (_source_port == 0) {
+               return 1;
+       }
+
        Glib::Mutex::Lock sm (state_lock, Glib::TRY_LOCK);
 
        if (!sm.locked()) {
@@ -526,7 +517,6 @@ MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can
                }
        }
 
-
        if (can_record && !_last_capture_sources.empty()) {
                _last_capture_sources.clear ();
        }
@@ -629,7 +619,6 @@ MidiDiskstream::set_pending_overwrite (bool yn)
        /* called from audio thread, so we can use the read ptr and playback sample as we wish */
 
        _pending_overwrite = yn;
-
        overwrite_frame = playback_sample;
 }
 
@@ -643,6 +632,7 @@ MidiDiskstream::overwrite_existing_buffers ()
        g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
 
        read (overwrite_frame, disk_io_chunk_frames, false);
+       file_frame = overwrite_frame; // it was adjusted by ::read()
        overwrite_queued = false;
        _pending_overwrite = false;
 
@@ -888,8 +878,8 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
        assert(!destructive());
 
        if (record_enabled() &&
-            ((_session.transport_frame() - _last_flush_frame > disk_io_chunk_frames) ||
-             force_flush)) {
+           ((_session.transport_frame() - _last_flush_frame > disk_io_chunk_frames) ||
+            force_flush)) {
                if ((!_write_source) || _write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
                        error << string_compose(_("MidiDiskstream %1: cannot write to disk"), _id) << endmsg;
                        return -1;
@@ -943,6 +933,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
 
                if (_write_source) {
                        _write_source->mark_for_remove ();
+                       _write_source->drop_references ();
                        _write_source.reset();
                }
 
@@ -980,10 +971,6 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
                        const double total_capture_beats = converter.from(total_capture);
                        _write_source->set_length_beats(total_capture_beats);
 
-                       /* make it not a stub anymore */
-
-                       _write_source->unstubify ();
-
                        /* we will want to be able to keep (over)writing the source
                           but we don't want it to be removable. this also differs
                           from the audio situation, where the source at this point
@@ -1069,7 +1056,21 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
 
                        _playlist->thaw ();
                        _session.add_command (new StatefulDiffCommand(_playlist));
-               }
+
+               } else {
+
+                       /* No data was recorded, so this capture will
+                          effectively be aborted; do the same as we
+                          do for an explicit abort.
+                       */
+
+                       if (_write_source) {
+                               _write_source->mark_for_remove ();
+                               _write_source->drop_references ();
+                               _write_source.reset();
+                       }
+               }
+
 
                mark_write_completed = true;
        }
@@ -1189,38 +1190,19 @@ void
 MidiDiskstream::disengage_record_enable ()
 {
        g_atomic_int_set (&_record_enabled, 0);
-       if (_source_port && Config->get_monitoring_model() == HardwareMonitoring) {
-               if (_source_port) {
-                       _source_port->request_monitor_input (false);
-               }
-       }
-
        RecordEnableChanged (); /* EMIT SIGNAL */
 }
 
 XMLNode&
 MidiDiskstream::get_state ()
 {
-       XMLNode* node = new XMLNode ("Diskstream");
+       XMLNode& node (Diskstream::get_state());
        char buf[64];
        LocaleGuard lg (X_("POSIX"));
 
-       snprintf (buf, sizeof(buf), "0x%x", _flags);
-       node->add_property ("flags", buf);
-
-       node->add_property("channel-mode", enum_2_string(get_channel_mode()));
-
+       node.add_property("channel-mode", enum_2_string(get_channel_mode()));
        snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
-       node->add_property("channel-mask", buf);
-
-       node->add_property ("playlist", _playlist->name());
-
-       snprintf (buf, sizeof(buf), "%f", _visible_speed);
-       node->add_property ("speed", buf);
-
-       node->add_property("name", _name);
-       id().print(buf, sizeof(buf));
-       node->add_property("id", buf);
+       node.add_property("channel-mask", buf);
 
        if (_write_source && _session.get_record_enabled()) {
 
@@ -1242,18 +1224,14 @@ MidiDiskstream::get_state ()
                }
 
                cs_child->add_property (X_("at"), buf);
-               node->add_child_nocopy (*cs_child);
-       }
-
-       if (_extra_xml) {
-               node->add_child_copy (*_extra_xml);
+               node.add_child_nocopy (*cs_child);
        }
 
-       return* node;
+       return node;
 }
 
 int
-MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
+MidiDiskstream::set_state (const XMLNode& node, int version)
 {
        const XMLProperty* prop;
        XMLNodeList nlist = node.children();
@@ -1261,12 +1239,11 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
        XMLNode* capture_pending_node = 0;
        LocaleGuard lg (X_("POSIX"));
 
+       /* prevent write sources from being created */
+
        in_set_state = true;
 
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               /*if ((*niter)->name() == IO::state_node_name) {
-                       deprecated_io_node = new XMLNode (**niter);
-               }*/
                assert ((*niter)->name() != IO::state_node_name);
 
                if ((*niter)->name() == X_("CapturingSources")) {
@@ -1274,20 +1251,8 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
                }
        }
 
-       /* prevent write sources from being created */
-
-       in_set_state = true;
-
-       if ((prop = node.property ("name")) != 0) {
-               _name = prop->value();
-       }
-
-       if ((prop = node.property ("id")) != 0) {
-               _id = prop->value ();
-       }
-
-       if ((prop = node.property ("flags")) != 0) {
-               _flags = Flag (string_2_enum (prop->value(), _flags));
+       if (Diskstream::set_state (node, version)) {
+               return -1;
        }
 
        ChannelMode channel_mode = AllChannels;
@@ -1303,36 +1268,12 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
                }
        }
 
-       set_channel_mode(channel_mode, channel_mask);
 
-       if ((prop = node.property ("playlist")) == 0) {
-               return -1;
+       if (capture_pending_node) {
+               use_pending_capture_data (*capture_pending_node);
        }
 
-       {
-               bool had_playlist = (_playlist != 0);
-
-               if (find_and_use_playlist (prop->value())) {
-                       return -1;
-               }
-
-               if (!had_playlist) {
-                       _playlist->set_orig_diskstream_id (id());
-               }
-
-               if (capture_pending_node) {
-                       use_pending_capture_data (*capture_pending_node);
-               }
-
-       }
-
-       if ((prop = node.property ("speed")) != 0) {
-               double sp = atof (prop->value().c_str());
-
-               if (realtime_set_speed (sp, false)) {
-                       non_realtime_set_speed ();
-               }
-       }
+       set_channel_mode (channel_mode, channel_mask);
 
        in_set_state = false;
 
@@ -1351,13 +1292,8 @@ MidiDiskstream::use_new_write_source (uint32_t n)
        _write_source.reset();
 
        try {
-               /* file starts off as a stub file, it will be converted
-                  when we're done with a capture pass, or when "stolen"
-                  by the GUI.
-               */
-
                _write_source = boost::dynamic_pointer_cast<SMFSource>(
-                       _session.create_midi_source_for_session (0, name (), true));
+                       _session.create_midi_source_for_session (0, name ()));
 
                if (!_write_source) {
                        throw failed_constructor();
@@ -1370,8 +1306,6 @@ MidiDiskstream::use_new_write_source (uint32_t n)
                return -1;
        }
 
-       _write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
-
        return 0;
 }
 
@@ -1380,16 +1314,9 @@ MidiDiskstream::steal_write_sources()
 {
        list<boost::shared_ptr<Source> > ret;
 
-       /* put some data on the disk, even if its just a header for an empty file.
-          XXX should we not have a more direct method for doing this? Maybe not
-          since we don't want to mess around with the model/disk relationship
-          that the Source has to pay attention to.
-       */
-
-       boost::dynamic_pointer_cast<MidiSource>(_write_source)->session_saved ();
+       /* put some data on the disk, even if its just a header for an empty file */
+       boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
 
-       /* make it visible/present */
-       _write_source->unstubify ();
        /* never let it go away */
        _write_source->mark_nonremovable ();
 
@@ -1415,16 +1342,6 @@ MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
        use_new_write_source (0);
 }
 
-int
-MidiDiskstream::rename_write_sources ()
-{
-       if (_write_source != 0) {
-               _write_source->set_source_name (_name.val(), destructive());
-               /* XXX what to do if this fails ? */
-       }
-       return 0;
-}
-
 void
 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
 {
@@ -1445,23 +1362,15 @@ MidiDiskstream::monitor_input (bool yn)
 void
 MidiDiskstream::set_align_style_from_io ()
 {
-       bool have_physical = false;
-
-       if (_io == 0) {
+       if (_alignment_choice != Automatic) {
                return;
        }
 
-       get_input_sources ();
-
-       if (_source_port && _source_port->flags() & JackPortIsPhysical) {
-               have_physical = true;
-       }
+       /* XXX Not sure what, if anything we can do with MIDI
+          as far as capture alignment etc.
+       */
 
-       if (have_physical) {
-               set_align_style (ExistingMaterial);
-       } else {
-               set_align_style (CaptureTime);
-       }
+       set_align_style (ExistingMaterial);
 }
 
 
@@ -1499,13 +1408,23 @@ MidiDiskstream::get_playback (MidiBuffer& dst, framepos_t start, framepos_t end)
                return;
        }
 
-       // Translates stamps to be relative to start
+       // Translate stamps to be relative to start
 
 
 #ifndef NDEBUG
+       DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
+                            "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
+                            _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), start, end));
+//        cerr << "================\n";
+//        _playback_buf->dump (cerr);
+//        cerr << "----------------\n";
+
        const size_t events_read = _playback_buf->read(dst, start, end);
-       DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6\n", _name, events_read, start, end,
-                                                             _playback_buf->read_space(), _playback_buf->write_space()));
+       DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
+                            "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
+                            _name, events_read, start, end,
+                            _playback_buf->read_space(), _playback_buf->write_space(),
+                        _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
 #else
        _playback_buf->read(dst, start, end);
 #endif
@@ -1514,3 +1433,14 @@ MidiDiskstream::get_playback (MidiBuffer& dst, framepos_t start, framepos_t end)
        g_atomic_int_add(&_frames_read_from_ringbuffer, frames_read);
 }
 
+bool
+MidiDiskstream::set_name (string const & name)
+{
+       Diskstream::set_name (name);
+
+       /* get a new write source so that its name reflects the new diskstream name */
+       use_new_write_source (0);
+
+       return true;
+}
+