summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-05-03 21:55:43 +0000
committerDavid Robillard <d@drobilla.net>2008-05-03 21:55:43 +0000
commite55e3fde7cec89c49e01046a2db276b2d8f30958 (patch)
tree13ed43fe3303e559ca2ee2a30c9074e1f220aa3d /libs
parentd2465f311fa1102e99e1639b3a643268f0da3bb1 (diff)
Comment out excessive terminal output.
Write all events (not just notes) to SMF file from MidiModel (just use iterator instead of hand-hacked MidiModel::write_to). Various MIDI bug fixes. git-svn-id: svn://localhost/ardour2/branches/3.0@3312 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/midi_model.h6
-rw-r--r--libs/ardour/ardour/smf_source.h1
-rw-r--r--libs/ardour/ardour/sndfilesource.h1
-rw-r--r--libs/ardour/audioengine.cc12
-rw-r--r--libs/ardour/automation_event.cc4
-rw-r--r--libs/ardour/midi_model.cc100
-rw-r--r--libs/ardour/midi_region.cc6
-rw-r--r--libs/ardour/parameter.cc2
-rw-r--r--libs/ardour/smf_source.cc63
9 files changed, 75 insertions, 120 deletions
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
index ea915d0a45..39987dfe7a 100644
--- a/libs/ardour/ardour/midi_model.h
+++ b/libs/ardour/ardour/midi_model.h
@@ -63,7 +63,7 @@ public:
*/
class MidiModel : public boost::noncopyable, public Automatable {
public:
- MidiModel(MidiSource *s, size_t size=0);
+ MidiModel(MidiSource* s, size_t size=0);
void write_lock();
void write_unlock();
@@ -91,7 +91,6 @@ public:
inline size_t n_notes() const { return _notes.size(); }
inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; }
-
inline static bool note_time_comparator (const boost::shared_ptr<const Note> a,
const boost::shared_ptr<const Note> b) {
return a->time() < b->time();
@@ -149,7 +148,8 @@ public:
void set_edited(bool yn) { _edited = yn; }
bool write_to(boost::shared_ptr<MidiSource> source);
- // MidiModel doesn't use the normal AutomationList serialisation code, as CC data is in the .mid
+ // MidiModel doesn't use the normal AutomationList serialisation code
+ // since controller data is stored in the .mid
XMLNode& get_state();
int set_state(const XMLNode&) { return 0; }
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
index dd8fd61926..9e215bf5a2 100644
--- a/libs/ardour/ardour/smf_source.h
+++ b/libs/ardour/ardour/smf_source.h
@@ -110,6 +110,7 @@ class SMFSource : public MidiSource {
bool writable() const { return _flags & Writable; }
int open();
+ void close();
void seek_to_end();
void write_footer();
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
index dc83fc6ec1..4ad967c132 100644
--- a/libs/ardour/ardour/sndfilesource.h
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -78,7 +78,6 @@ class SndFileSource : public AudioFileSource {
void init ();
int open();
- void close();
int setup_broadcast_info (nframes_t when, struct tm&, time_t);
/* destructive */
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 9f7d67fb6d..8bbed46733 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -556,7 +556,7 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input,
{
Port* newport = 0;
- cerr << "trying to register port with name " << portname << endl;
+ /*cerr << "trying to register port with name " << portname << endl;*/
try {
if (dtype == DataType::AUDIO) {
newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle());
@@ -566,16 +566,16 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input,
throw unknown_type();
}
- cerr << "successfully got port " << portname << " with address " << newport << endl;
+ /*cerr << "successfully got port " << portname << " with address " << newport << endl;*/
RCUWriter<Ports> writer (ports);
boost::shared_ptr<Ports> ps = writer.get_copy ();
- cerr << "Address of ports list: " << ps << endl
- << "Ports set size before insert: " << ps->size() << endl;
+ /*cerr << "Address of ports list: " << ps << endl
+ << "Ports set size before insert: " << ps->size() << endl;*/
ps->insert (ps->begin(), newport);
- cerr << "Ports set size after insert: " << ps->size() << endl;
- /* writer goes out of scope, forces update */
+ /*cerr << "Ports set size after insert: " << ps->size() << endl;*/
+ /* writer goes out of scope, forces update */
return newport;
}
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index e47de7510d..af390953f4 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -1436,10 +1436,6 @@ AutomationList::get_state ()
XMLNode&
AutomationList::state (bool full)
{
- cerr << "getting ";
- if(full)
- cerr << "full ";
- cerr << "state for AutomationList " << _parameter.to_string() << " list size: " << size() << endl;
XMLNode* root = new XMLNode (X_("AutomationList"));
char buf[64];
LocaleGuard lg (X_("POSIX"));
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index d599e7187c..3e009bcb8f 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -136,7 +136,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
_locked = false;
}
} else {
- printf("MIDI Iterator = %X @ %lf\n", _event.type(), _event.time());
+ //printf("New MIDI Iterator = %X @ %lf\n", _event.type(), _event.time());
}
}
@@ -161,7 +161,7 @@ const MidiModel::const_iterator& MidiModel::const_iterator::operator++()
assert((_event.is_note() || _event.is_cc() || _event.is_pgm_change() || _event.is_pitch_bender() || _event.is_channel_aftertouch()));
// Increment past current control event
- if (_control_iter != _control_iters.end() && _control_iter->automation_list && _event.is_cc()) {
+ if (!_event.is_note() && _control_iter != _control_iters.end() && _control_iter->automation_list) {
double x, y;
cerr << "control_iter x:" << _control_iter->x << " y:" << _control_iter->y << endl;
const bool ret = _control_iter->automation_list->rt_safe_earliest_event_unlocked(
@@ -212,24 +212,24 @@ const MidiModel::const_iterator& MidiModel::const_iterator::operator++()
// Use the next earliest controller iff it's earlier than the note event
if (_control_iter != _control_iters.end()
&& _control_iter->x != DBL_MAX
- && _control_iter != old_control_iter)
+ )//&& _control_iter != old_control_iter)
if (type == NIL || _control_iter->x < t)
type = AUTOMATION;
if (type == NOTE_ON) {
- cerr << "********** MIDI Iterator = note on" << endl;
+ //cerr << "********** MIDI Iterator = note on" << endl;
_event = MIDI::Event((*_note_iter)->on_event(), false);
_active_notes.push(*_note_iter);
++_note_iter;
} else if (type == NOTE_OFF) {
- cerr << "********** MIDI Iterator = note off" << endl;
+ //cerr << "********** MIDI Iterator = note off" << endl;
_event = MIDI::Event(_active_notes.top()->off_event(), false);
_active_notes.pop();
} else if (type == AUTOMATION) {
- cerr << "********** MIDI Iterator = AUTOMATION" << endl;
+ //cerr << "********** MIDI Iterator = Automation" << endl;
_model->control_to_midi_event(_event, *_control_iter);
} else {
- cerr << "********** MIDI Iterator = END" << endl;
+ //cerr << "********** MIDI Iterator = End" << endl;
_is_end = true;
}
@@ -483,7 +483,8 @@ void MidiModel::append(const MIDI::Event& ev)
write_lock();
_edited = true;
- cerr << "MidiModel::append event type: " << hex << "0x" << int(ev.type()) << endl;
+ /*cerr << "MidiModel append event type: "
+ << hex << "0x" << (int)ev.type() << endl;*/
assert(_notes.empty() || ev.time() >= _notes.back()->time());
assert(_writing);
@@ -507,7 +508,7 @@ void MidiModel::append(const MIDI::Event& ev)
append_automation_event_unlocked(MidiChannelAftertouchAutomation,
ev.channel(), ev.time(), ev.channel_aftertouch(), 0);
} else {
- printf("MM Unknown event type %X\n", ev.type());
+ printf("WARNING: MidiModel: Unknown event type %X\n", ev.type());
}
write_unlock();
@@ -607,7 +608,7 @@ void MidiModel::append_automation_event_unlocked(AutomationType type,
Parameter param(type, id, chan);
boost::shared_ptr<AutomationControl> control = Automatable::control(param, true);
control->list()->fast_simple_add(time, value);
- cerr << "control list size after fast simple add: " << control->list()->size() << endl;
+ /*cerr << "control list size after fast simple add: " << control->list()->size() << endl;*/
}
void MidiModel::add_note_unlocked(const boost::shared_ptr<Note> note)
@@ -877,76 +878,27 @@ struct EventTimeComparator {
}
};
+/** Write the model to a MidiSource (i.e. save the model).
+ * This is different from manually using read to write to a source in that
+ * note off events are written regardless of the track mode. This is so the
+ * user can switch a recorded track (with note durations from some instrument)
+ * to percussive, save, reload, then switch it back to sustained without
+ * destroying the original note durations.
+ */
bool MidiModel::write_to(boost::shared_ptr<MidiSource> source)
{
- cerr << "Writing model to " << source->name() << endl;
-
- /* This could be done using a temporary MidiRingBuffer and using
- * MidiModel::read and MidiSource::write, but this is more efficient
- * and doesn't require any buffer size assumptions (ie it's worth
- * the code duplication).
- *
- * This is also different from read in that note off events are written
- * regardless of the track mode. This is so the user can switch a
- * recorded track (with note durations from some instrument) to percussive,
- * save, reload, then switch it back to sustained preserving the original
- * note durations.
- */
-
read_lock();
- LaterNoteEndComparator cmp;
- ActiveNotes active_notes(cmp);
-
- EventTimeComparator comp;
- typedef std::priority_queue<
- const MIDI::Event*,
- std::deque<const MIDI::Event*>,
- EventTimeComparator> MidiEvents;
-
- MidiEvents events(comp);
-
- /* Why sort manually, when a priority queue does the job for us,
- * (I am probably wrong here, but I needed that to test program
- * change code quickly) ???
- * */
- // Foreach note
- for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n) {
-
- // Write any pending note offs earlier than this note on
- while ( !active_notes.empty() ) {
- const boost::shared_ptr<const Note> earliest_off =
- active_notes.top();
- const MIDI::Event& off_ev = earliest_off->off_event();
- if (off_ev.time() <= (*n)->time()) {
- events.push(&off_ev);
- active_notes.pop();
- } else {
- break;
- }
- }
-
- // Write this note on
- events.push(&(*n)->on_event());
- if ((*n)->duration() > 0)
- active_notes.push(*n);
- }
-
- // Write any trailing note offs
- while ( !active_notes.empty() ) {
- events.push(&active_notes.top()->off_event());
- active_notes.pop();
- }
-
- while (!events.empty()) {
- source->append_event_unlocked(Frames, *events.top());
- //cerr << "MidiModel::write_to appending event with time:" << dec << int(events.top()->time()) << hex << " buffer: 0x" << int(events.top()->buffer()[0]) << " 0x" << int(events.top()->buffer()[1]) << " 0x" << int(events.top()->buffer()[2]) << endl;
- events.pop();
- }
-
- _edited = false;
+ const NoteMode old_note_mode = _note_mode;
+ _note_mode = Sustained;
+ for (const_iterator i = begin(); i != end(); ++i)
+ source->append_event_unlocked(Frames, *i);
+
+ _note_mode = old_note_mode;
+
read_unlock();
+ _edited = false;
return true;
}
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index c3ce6db327..e29fb1e659 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -131,8 +131,8 @@ MidiRegion::master_read_at (MidiRingBuffer& out, nframes_t position, nframes_t d
nframes_t
MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
{
- cerr << "reading from region " << _name << " position: " << _position << " start: " << _start << endl;
- cerr << _name << "._read_at(" << position << ") - " << position << " duration: " << dur << endl;
+ /*cerr << "MidiRegion " << _name << "._read_at(" << position << ") - "
+ << position << " duration: " << dur << endl;*/
nframes_t internal_offset = 0;
nframes_t src_offset = 0;
@@ -174,7 +174,7 @@ MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t pos
nframes_t output_buffer_position = 0;
nframes_t negative_output_buffer_position = 0;
- if(_position >= _start) {
+ if (_position >= _start) {
// handle resizing of beginnings of regions correctly
output_buffer_position = _position - _start;
} else {
diff --git a/libs/ardour/parameter.cc b/libs/ardour/parameter.cc
index aa480e47a2..528d7e114c 100644
--- a/libs/ardour/parameter.cc
+++ b/libs/ardour/parameter.cc
@@ -56,8 +56,6 @@ Parameter::Parameter(const std::string& str)
sscanf(str.c_str(), "midicc-%d-%d", &channel, &_id);
assert(channel < 16);
_channel = channel;
- cout << "LOADED PARAMETER " << str << " chan " << _channel << " id " << _id << endl;
- //_id = atoi(str.c_str()+7);
} else {
PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
}
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 371824b833..dadb919b17 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -133,6 +133,14 @@ SMFSource::init (string pathstr, bool must_exist)
return 0;
}
+/** Attempt to open the SMF file for reading and writing.
+ *
+ * Currently SMFSource is always read/write.
+ *
+ * \return 0 on success
+ * -1 if the file can not be opened for reading,
+ * -2 if the file can not be opened for writing
+ */
int
SMFSource::open()
{
@@ -153,6 +161,11 @@ SMFSource::open()
// We're making a new file
} else {
_fd = fopen(path().c_str(), "w+");
+ if (_fd == NULL) {
+ cerr << "ERROR: Can not open SMF file " << path() << " for writing: " <<
+ strerror(errno) << endl;
+ return -2;
+ }
_track_size = 4;
// Write a tentative header just to pad things out so writing happens in the right spot
@@ -160,18 +173,29 @@ SMFSource::open()
write_footer();
seek_to_end();
}
-
+
return (_fd == 0) ? -1 : 0;
}
void
+SMFSource::close()
+{
+ if (_fd) {
+ flush_header();
+ flush_footer();
+ fclose(_fd);
+ _fd = NULL;
+ }
+}
+
+void
SMFSource::seek_to_end()
{
fseek(_fd, -4, SEEK_END);
}
int
-SMFSource::flush_header ()
+SMFSource::flush_header()
{
// FIXME: write timeline position somehow?
@@ -211,8 +235,6 @@ SMFSource::flush_footer()
void
SMFSource::write_footer()
{
- //cerr << "SMF " << name() << " writing EOT at byte " << ftell(_fd) << endl;
-
write_var_len(0);
char eot[3] = { 0xFF, 0x2F, 0x00 }; // end-of-track meta-event
fwrite(eot, 1, 3, _fd);
@@ -318,11 +340,11 @@ SMFSource::read_event(uint32_t* delta_t, uint32_t* size, Byte** buf) const
if (event_size > 1)
fread((*buf) + 1, 1, *size - 1, _fd);
- printf("%s read event: delta = %u, size = %u, data = ", _name.c_str(), *delta_t, *size);
+ /*printf("%s read event: delta = %u, size = %u, data = ", _name.c_str(), *delta_t, *size);
for (size_t i=0; i < *size; ++i) {
printf("%X ", (*buf)[i]);
}
- printf("\n");
+ printf("\n");*/
return (int)*size;
}
@@ -451,12 +473,13 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
void
SMFSource::append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev)
{
- //printf("%s - append chan = %u, time = %lf, size = %u, data = ", _path.c_str(), (unsigned)ev.channel(), ev.time(), ev.size());
+ /*printf("%s - append chan = %u, time = %lf, size = %u, data = ",
+ name().c_str(), (unsigned)ev.channel(), ev.time(), ev.size());
for (size_t i=0; i < ev.size(); ++i) {
printf("%X ", ev.buffer()[i]);
}
- printf("\n");
-
+ printf("\n");*/
+
assert(ev.time() >= 0);
assert(ev.time() >= _last_ev_time);
@@ -535,6 +558,7 @@ SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_fra
{
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
_last_ev_time = 0;
+ fseek(_fd, _header_size, 0);
}
void
@@ -546,20 +570,9 @@ SMFSource::mark_streaming_write_completed ()
return;
}
+ _model->set_edited(false);
flush_header();
flush_footer();
-
-#if 0
- Glib::Mutex::Lock lm (_lock);
-
-
- next_peak_clear_should_notify = true;
-
- if (_peaks_built || pending_peak_builds.empty()) {
- _peaks_built = true;
- PeaksReady (); /* EMIT SIGNAL */
- }
-#endif
}
void
@@ -861,13 +874,8 @@ SMFSource::load_model(bool lock, bool force_reload)
if (lock)
Glib::Mutex::Lock lm (_lock);
- if (_model && !force_reload && !_model->empty()) {
- //cerr << _name << " NOT reloading model " << _model.get() << " (" << _model->n_notes()
- // << " notes)" << endl;
+ if (_model && !force_reload && !_model->empty())
return;
- } else {
- cerr << _name << " loading model" << endl;
- }
if (! _model) {
_model = boost::shared_ptr<MidiModel>(new MidiModel(this));
@@ -912,6 +920,7 @@ SMFSource::load_model(bool lock, bool force_reload)
}
_model->end_write(false);
+ _model->set_edited(false);
free(ev.buffer());
}