/*
Copyright (C) 2006 Paul Davis
- Written by Dave Robillard, 2006
+ Author: David Robillard
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
if (init(_path, false)) {
throw failed_constructor ();
}
-
+
/* file is not opened until write */
}
{
if (create (_path)) {
return -1;
- }
+ }
_open = true;
return 0;
}
if (ev.size() == 0) {
return;
}
-
- /* printf("SMFSource: %s - append_event_unlocked_beats ID = %d time = %lf, size = %u, data = ",
+
+ /*printf("SMFSource: %s - append_event_unlocked_beats ID = %d time = %lf, size = %u, data = ",
name().c_str(), ev.id(), ev.time(), ev.size());
- for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
+ for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
assert(ev.time() >= 0);
if (ev.time() < _last_ev_time_beats) {
}
if (_model) {
- const Evoral::Event<double> beat_ev (ev.event_type(),
- ev_time_beats,
- ev.size(),
+ const Evoral::Event<double> beat_ev (ev.event_type(),
+ ev_time_beats,
+ ev.size(),
(uint8_t*)ev.buffer());
_model->append (beat_ev, event_id);
- }
+ }
_length_beats = max(_length_beats, ev_time_beats);
if (!_open && open_for_write()) {
error << string_compose (_("cannot open MIDI file %1 for write"), _path) << endmsg;
/* XXX should probably throw or return something */
- return;
+ return;
}
MidiSource::mark_streaming_midi_write_started (mode);
if (_model) {
_model->set_edited(false);
}
-
+
Evoral::SMF::end_write ();
/* data in the file now, not removable */
- mark_nonremovable ();
+ mark_nonremovable ();
}
bool
while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
time += delta_t;
-
+
if (ret == 0) {
/* meta-event : did we get an event ID ?
}
continue;
- }
-
- if (ret > 0) {
+ }
+
+ if (ret > 0) {
/* not a meta-event */
ev.set_event_type(EventTypeMap::instance().midi_event_type(buf[0]));
if (!have_event_id) {
- event_id = Evoral::next_event_id();
+ event_id = Evoral::next_event_id();
}
#ifndef NDEBUG
std::string ss;
-
+
for (uint32_t xx = 0; xx < size; ++xx) {
char b[8];
snprintf (b, sizeof (b), "0x%x ", buf[xx]);
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
delta_t, time, size, ss , ev.event_type(), name()));
#endif
-
+
_model->append (ev, event_id);
if (ev.size() > scratch_size) {
scratch_size = ev.size();
}
-
+
ev.size() = scratch_size; // ensure read_event only allocates if necessary
-
+
_length_beats = max(_length_beats, ev.time());
}
/* event ID's must immediately precede the event they are for
*/
-
+
have_event_id = false;
}
Evoral::SMF::end_write();
/* data in the file means its no longer removable */
- mark_nonremovable ();
+ mark_nonremovable ();
}
void
FileSource::set_path (p);
SMF::set_path (_path);
}
+
+/** Ensure that this source has some file on disk, even if it's just a SMF header */
+void
+SMFSource::ensure_disk_file ()
+{
+ if (_model) {
+ /* We have a model, so write it to disk; see MidiSource::session_saved
+ for an explanation of what we are doing here.
+ */
+ boost::shared_ptr<MidiModel> mm = _model;
+ _model.reset ();
+ mm->sync_to_source ();
+ _model = mm;
+ } else {
+ /* No model; if it's not already open, it's an empty source, so create
+ and open it for writing.
+ */
+ if (!_open) {
+ open_for_write ();
+ }
+
+ /* Flush, which will definitely put something on disk */
+ flush_midi ();
+ }
+}
+