PT import: Use multitrack MIDI import support based on ptformat update

This commit is contained in:
Damien Zammit 2018-03-17 22:41:44 +11:00
parent cce575eb72
commit 8b925fc395
1 changed files with 107 additions and 52 deletions

View File

@ -123,16 +123,17 @@ Editor::do_ptimport (std::string ptpath,
bool onefailed = false;
PTFFormat ptf;
samplepos_t pos = -1;
uint32_t srate = _session->sample_rate();
vector<ptflookup_t> ptfwavpair;
vector<ptflookup_t> ptfregpair;
if (ptf.load(ptpath, _session->sample_rate()) == -1) {
if (ptf.load(ptpath, srate) == -1) {
MessageDialog msg (_("Doesn't seem to be a valid PT session file"));
msg.run ();
return;
} else {
MessageDialog msg (string_compose (_("PT v%1 Session @ %2Hz\n\n%3 audio files\n%4 regions\n%5 active regions\n\nContinue..."), (int)ptf.version, ptf.sessionrate, ptf.audiofiles.size(), ptf.regions.size(), ptf.tracks.size()));
MessageDialog msg (string_compose (_("PT v%1 Session @ %2Hz\n\n%3 audio files\n%4 audio regions\n%5 active audio regions\n%6 midi regions\n%7 active midi regions\n\nContinue..."), (int)ptf.version, ptf.sessionrate, ptf.audiofiles.size(), ptf.regions.size() - ptf.midiregions.size(), ptf.tracks.size(), ptf.midiregions.size(), ptf.miditracks.size()));
msg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
int result = msg.run ();
@ -178,20 +179,6 @@ Editor::do_ptimport (std::string ptpath,
msg.run ();
}
// Create a dummy midi track first to get a midi Source
list<boost::shared_ptr<MidiTrack> > mt (
_session->new_midi_track (ChanCount (DataType::MIDI, 1),
ChanCount (DataType::MIDI, 1),
true,
instrument, (Plugin::PresetRecord*) 0,
(RouteGroup*) 0,
1,
string(),
PresentationInfo::max_order));
if (mt.empty()) {
return;
}
for (vector<PTFFormat::region_t>::iterator a = ptf.regions.begin();
a != ptf.regions.end(); ++a) {
for (vector<ptflookup_t>::iterator p = ptfwavpair.begin();
@ -225,42 +212,6 @@ Editor::do_ptimport (std::string ptpath,
}
}
}
if (strcmp(a->wave.filename.c_str(), "") == 0) {
/* Empty wave - assume MIDI region */
boost::shared_ptr<MidiTrack> midi_track = mt.back();
boost::shared_ptr<Playlist> playlist = midi_track->playlist();
samplepos_t f = (samplepos_t)a->startpos;
samplecnt_t length = (samplecnt_t)a->length;
MusicSample pos (f, 0);
boost::shared_ptr<Source> src = _session->create_midi_source_by_stealing_name (midi_track);
PropertyList plist;
plist.add (ARDOUR::Properties::start, 0);
plist.add (ARDOUR::Properties::length, length);
plist.add (ARDOUR::Properties::name, PBD::basename_nosuffix(src->name()));
boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
/* sets beat position */
region->set_position (pos.sample, pos.division);
midi_track->playlist()->add_region (region, pos.sample, 1.0, false, pos.division);
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
boost::shared_ptr<MidiModel> mm = mr->midi_source(0)->model();
MidiModel::NoteDiffCommand *midicmd;
midicmd = mm->new_note_diff_command ("Import ProTools MIDI");
for (vector<PTFFormat::midi_ev_t>::iterator
j = a->midi.begin();
j != a->midi.end(); ++j) {
Temporal::Beats start = (Temporal::Beats)(j->pos/960000.);
Temporal::Beats len = (Temporal::Beats)(j->length/960000.);
// PT C-2 = 0, Ardour C-1 = 0, subtract twelve to convert...
midicmd->add(boost::shared_ptr<Evoral::Note<Temporal::Beats> >
(new Evoral::Note<Temporal::Beats>( (uint8_t)1, start, len, j->note - 12, j->velocity )));
}
mm->apply_command (_session, midicmd);
boost::shared_ptr<Region> copy (RegionFactory::create (mr, true));
playlist->clear_changes ();
playlist->add_region (copy, a->startpos);
}
}
boost::shared_ptr<AudioTrack> existing_track;
@ -326,6 +277,110 @@ Editor::do_ptimport (std::string ptpath,
}
}
// MIDI - Find list of unique midi tracks first
typedef struct midipair {
uint16_t ptfindex;
string trname;
} midipair_t;
vector<midipair_t> uniquetr;
uint16_t ith = 0;
bool found;
for (vector<PTFFormat::track_t>::iterator a = ptf.miditracks.begin();
a != ptf.miditracks.end(); ++a) {
found = false;
for (vector<midipair_t>::iterator b = uniquetr.begin();
b != uniquetr.end(); ++b) {
if (b->trname == a->name) {
found = true;
break;
}
}
if (!found) {
uniquetr.push_back({ith, a->name});
//printf(" : %d : %s\n", ith, a->name.c_str());
ith++;
}
}
// MIDI - Create unique midi tracks and a lookup table for used tracks
for (vector<midipair_t>::iterator a = uniquetr.begin();
a != uniquetr.end(); ++a) {
ptflookup_t miditr;
list<boost::shared_ptr<MidiTrack> > mt (_session->new_midi_track (
ChanCount (DataType::MIDI, 1),
ChanCount (DataType::MIDI, 1),
true,
instrument, (Plugin::PresetRecord*) 0,
(RouteGroup*) 0,
1,
a->trname,
PresentationInfo::max_order,
Normal));
}
// Select all MIDI tracks by selecting all tracks then subsetting to midi
select_all_tracks();
TrackViewList miditracks;
MidiTimeAxisView* mtv;
TrackSelection::iterator x;
for (x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
mtv = dynamic_cast<MidiTimeAxisView*>(*x);
if (!mtv) {
continue;
} else if (mtv->is_midi_track()) {
miditracks.push_back(dynamic_cast<TimeAxisView*>(*x));
}
}
selection->set(miditracks);
// MIDI - Add midi regions one-by-one to corresponding midi tracks
for (vector<PTFFormat::track_t>::iterator a = ptf.miditracks.begin();
a != ptf.miditracks.end(); ++a) {
boost::shared_ptr<MidiTrack> midi_track = get_nth_selected_midi_track(a->index);
boost::shared_ptr<Playlist> playlist = midi_track->playlist();
samplepos_t f = (samplepos_t)a->reg.startpos * srate / 1920000.;
samplecnt_t length = (samplecnt_t)a->reg.length * srate / 1920000.;
MusicSample pos (f, 0);
boost::shared_ptr<Source> src = _session->create_midi_source_by_stealing_name (midi_track);
PropertyList plist;
plist.add (ARDOUR::Properties::start, 0);
plist.add (ARDOUR::Properties::length, length);
plist.add (ARDOUR::Properties::name, PBD::basename_nosuffix(src->name()));
//printf(" : %d - trackname: (%s)\n", a->index, src->name().c_str());
boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
// sets beat position
region->set_position (pos.sample, pos.division);
midi_track->playlist()->add_region (region, pos.sample, 1.0, false, pos.division);
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
boost::shared_ptr<MidiModel> mm = mr->midi_source(0)->model();
MidiModel::NoteDiffCommand *midicmd;
midicmd = mm->new_note_diff_command ("Import ProTools MIDI");
for (vector<PTFFormat::midi_ev_t>::iterator
j = a->reg.midi.begin();
j != a->reg.midi.end(); ++j) {
//printf(" : MIDI : pos=%f len=%f\n", (float)j->pos / 960000., (float)j->length / 960000.);
Temporal::Beats start = (Temporal::Beats)(j->pos / 960000.);
Temporal::Beats len = (Temporal::Beats)(j->length / 960000.);
// PT C-2 = 0, Ardour C-1 = 0, subtract twelve to convert ?
midicmd->add(boost::shared_ptr<Evoral::Note<Temporal::Beats> >
(new Evoral::Note<Temporal::Beats>( (uint8_t)1, start, len, j->note, j->velocity )));
}
mm->apply_command (_session, midicmd);
boost::shared_ptr<Region> copy (RegionFactory::create (mr, true));
playlist->clear_changes ();
playlist->add_region (copy, f);
}
import_status.sources.clear();
if (ok) {