PT import: Use multitrack MIDI import support based on ptformat update
This commit is contained in:
parent
cce575eb72
commit
8b925fc395
@ -123,16 +123,17 @@ Editor::do_ptimport (std::string ptpath,
|
|||||||
bool onefailed = false;
|
bool onefailed = false;
|
||||||
PTFFormat ptf;
|
PTFFormat ptf;
|
||||||
samplepos_t pos = -1;
|
samplepos_t pos = -1;
|
||||||
|
uint32_t srate = _session->sample_rate();
|
||||||
|
|
||||||
vector<ptflookup_t> ptfwavpair;
|
vector<ptflookup_t> ptfwavpair;
|
||||||
vector<ptflookup_t> ptfregpair;
|
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"));
|
MessageDialog msg (_("Doesn't seem to be a valid PT session file"));
|
||||||
msg.run ();
|
msg.run ();
|
||||||
return;
|
return;
|
||||||
} else {
|
} 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);
|
msg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
||||||
|
|
||||||
int result = msg.run ();
|
int result = msg.run ();
|
||||||
@ -178,20 +179,6 @@ Editor::do_ptimport (std::string ptpath,
|
|||||||
msg.run ();
|
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();
|
for (vector<PTFFormat::region_t>::iterator a = ptf.regions.begin();
|
||||||
a != ptf.regions.end(); ++a) {
|
a != ptf.regions.end(); ++a) {
|
||||||
for (vector<ptflookup_t>::iterator p = ptfwavpair.begin();
|
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;
|
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();
|
import_status.sources.clear();
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
Loading…
Reference in New Issue
Block a user