, _frames_written_to_ringbuffer(0)
, _frames_read_from_ringbuffer(0)
{
- /* prevent any write sources from being created */
-
in_set_state = true;
init ();
if (_write_source) {
_write_source->set_timeline_position (position);
}
- seek(position, false);
+ seek (position, false);
}
}
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 ();
}
_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)
{
return 0;
}
+ if (_source_port == 0) {
+ return 1;
+ }
+
Glib::Mutex::Lock sm (state_lock, Glib::TRY_LOCK);
if (!sm.locked()) {
}
}
-
if (can_record && !_last_capture_sources.empty()) {
_last_capture_sources.clear ();
}
/* called from audio thread, so we can use the read ptr and playback sample as we wish */
_pending_overwrite = yn;
-
overwrite_frame = playback_sample;
}
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;
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;
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
_write_source.reset();
}
}
-
+
mark_write_completed = true;
}
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()) {
}
cs_child->add_property (X_("at"), buf);
- node->add_child_nocopy (*cs_child);
+ node.add_child_nocopy (*cs_child);
}
- if (_extra_xml) {
- node->add_child_copy (*_extra_xml);
- }
-
- 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();
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")) {
}
}
- /* 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;
}
}
- set_channel_mode(channel_mode, channel_mask);
-
- if ((prop = node.property ("playlist")) == 0) {
- return -1;
- }
-
- {
- 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 (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;
_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();
return -1;
}
- _write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
-
return 0;
}
{
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.
- */
+ /* 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 ();
- boost::dynamic_pointer_cast<MidiSource>(_write_source)->session_saved ();
-
- /* make it visible/present */
- _write_source->unstubify ();
/* never let it go away */
_write_source->mark_nonremovable ();
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*/)
{
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);
}
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
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;
+}
+