13
0

PT import: Add MIDI import functionality

This change adds support for importing all MIDI regions
from a PT session onto a single track.

Unfortunately, currently we don't know how to set the start
offset of MIDI regions reliably, therefore all midi regions
get dumped at the beginning of the Ardour session.

Signed-off-by: Damien Zammit <damien@zamaudio.com>
This commit is contained in:
Damien Zammit 2017-02-17 20:03:21 +11:00 committed by Robin Gareus
parent cb0189845e
commit 4f4400b764

View File

@ -36,6 +36,7 @@
#include "ardour/audioregion.h"
#include "ardour/midi_region.h"
#include "ardour/midi_track.h"
#include "ardour/midi_model.h"
#include "ardour/operations.h"
#include "ardour/region_factory.h"
#include "ardour/smf_source.h"
@ -179,11 +180,25 @@ 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();
p != ptfwavpair.end(); ++p) {
if (p->index1 == a->wave.index) {
if ((p->index1 == a->wave.index) && (strcmp(a->wave.filename.c_str(), "") != 0)) {
for (SourceList::iterator x = imported.begin();
x != imported.end(); ++x) {
if ((*x)->id() == p->id) {
@ -212,6 +227,42 @@ 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();
framepos_t f = (framepos_t)a->startpos;
framecnt_t length = (framecnt_t)a->length;
MusicFrame 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.frame, pos.division);
midi_track->playlist()->add_region (region, pos.frame, 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) {
Evoral::Beats start = (Evoral::Beats)(j->pos/960000.);
Evoral::Beats len = (Evoral::Beats)(j->length/960000.);
// PT C-2 = 0, Ardour C-1 = 0, subtract twelve to convert...
midicmd->add(boost::shared_ptr<Evoral::Note<Evoral::Beats> >
(new Evoral::Note<Evoral::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;