From 80e54c6ea05d35465f50f84897f113e0a48b7afd Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 14 Feb 2009 20:52:15 +0000 Subject: [PATCH] MIDI robustness. - Separate SMF::open and SMF::create, more powerful interface for both. - Correctly handle note ons with velocity 0 as note offs in sequence. - Use SMF (i.e. libsmf) for MIDI import git-svn-id: svn://localhost/ardour2/branches/3.0@4558 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/filter.cc | 2 +- libs/ardour/import.cc | 45 +++++---- libs/ardour/smf_source.cc | 2 +- libs/evoral/evoral/Event.hpp | 2 +- libs/evoral/evoral/MIDIEvent.hpp | 10 +- libs/evoral/evoral/SMF.hpp | 20 ++-- libs/evoral/src/Event.cpp | 10 +- libs/evoral/src/SMF.cpp | 152 +++++++++++++++++++++-------- libs/evoral/src/Sequence.cpp | 26 +++-- libs/evoral/src/libsmf/smf_tempo.c | 4 + libs/evoral/test/SMFTest.cpp | 4 +- 11 files changed, 185 insertions(+), 92 deletions(-) diff --git a/libs/ardour/filter.cc b/libs/ardour/filter.cc index be382f72da..0075555773 100644 --- a/libs/ardour/filter.cc +++ b/libs/ardour/filter.cc @@ -100,7 +100,7 @@ Filter::finish (boost::shared_ptr region, SourceList& nsrcs, string regi boost::shared_ptr smfs = boost::dynamic_pointer_cast(*si); if (smfs) { smfs->set_timeline_position (region->position()); - smfs->flush_footer (); + smfs->flush (); } /* now that there is data there, requeue the file for analysis */ diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 76975d8237..97cebf1456 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include @@ -309,10 +309,11 @@ write_audio_data_to_new_files (ImportableSource* source, Session::import_status& } static void -write_midi_data_to_new_files (Evoral::SMFReader* source, Session::import_status& status, +write_midi_data_to_new_files (Evoral::SMF* source, Session::import_status& status, vector >& newfiles) { - Evoral::Event ev(0, 0.0, 4, NULL, true); + uint32_t buf_size = 4; + uint8_t* buf = (uint8_t*)malloc(buf_size); status.progress = 0.0f; @@ -329,15 +330,28 @@ write_midi_data_to_new_files (Evoral::SMFReader* source, Session::import_status& uint32_t size = 0; while (!status.cancel) { + size = buf_size; - if (source->read_event(4, ev.buffer(), &size, &delta_t) < 0) + int ret = source->read_event(&delta_t, &size, &buf); + if (size > buf_size) + buf_size = size; + + if (ret < 0) { // EOT break; - + } + t += delta_t; - ev.time() = (double)t / (double)source->ppqn(); - ev.size() = size; - smfs->append_event_unlocked(Beats, ev); + if (ret == 0) { // Meta + continue; + } + + smfs->append_event_unlocked(Beats, Evoral::Event( + 0, + (double)t / (double)source->ppqn(), + size, + buf)); + if (status.progress < 0.99) status.progress += 0.01; } @@ -358,7 +372,7 @@ write_midi_data_to_new_files (Evoral::SMFReader* source, Session::import_status& } } catch (...) { - error << "Corrupt MIDI file " << source->filename() << endl; + error << "Corrupt MIDI file " << source->path() << endl; } } @@ -388,8 +402,8 @@ Session::import_audiofiles (import_status& status) p != status.paths.end() && !status.cancel; ++p, ++cnt) { - boost::shared_ptr source; - std::auto_ptr smf_reader; + boost::shared_ptr source; + std::auto_ptr< Evoral::SMF > smf_reader; const DataType type = ((*p).rfind(".mid") != string::npos) ? DataType::MIDI : DataType::AUDIO; @@ -405,14 +419,11 @@ Session::import_audiofiles (import_status& status) } else { try { - smf_reader = std::auto_ptr(new Evoral::SMFReader(*p)); + smf_reader = std::auto_ptr< Evoral::SMF >(new Evoral::SMF()); + smf_reader->open(*p); channels = smf_reader->num_tracks(); - } catch (const Evoral::SMFReader::UnsupportedTime& err) { - error << _("Import: unsupported MIDI time stamp format") << endmsg; - status.done = status.cancel = true; - return; } catch (...) { - error << _("Import: error reading MIDI file") << endmsg; + error << _("Import: error opening MIDI file") << endmsg; status.done = status.cancel = true; return; } diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 6d80857e7b..e160d7e277 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -65,7 +65,7 @@ SMFSource::SMFSource (Session& s, std::string path, Flag flags) throw failed_constructor (); } - if (open(path)) { + if (create(path)) { throw failed_constructor (); } diff --git a/libs/evoral/evoral/Event.hpp b/libs/evoral/evoral/Event.hpp index 86a2f146bb..7703963b95 100644 --- a/libs/evoral/evoral/Event.hpp +++ b/libs/evoral/evoral/Event.hpp @@ -43,7 +43,7 @@ namespace Evoral { template struct Event { #ifdef EVORAL_EVENT_ALLOC - Event(EventType type=0, Time timestamp=0, uint32_t size=0, uint8_t* buffer=NULL, bool alloc=false); + Event(EventType type=0, Time time=0, uint32_t size=0, uint8_t* buf=NULL, bool alloc=false); /** Copy \a copy. * diff --git a/libs/evoral/evoral/MIDIEvent.hpp b/libs/evoral/evoral/MIDIEvent.hpp index d6751db0a8..c9541632d1 100644 --- a/libs/evoral/evoral/MIDIEvent.hpp +++ b/libs/evoral/evoral/MIDIEvent.hpp @@ -36,8 +36,8 @@ namespace Evoral { */ template struct MIDIEvent : public Event