Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: musescore/MuseScore
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f57d66e1f09d
Choose a base ref
...
head repository: musescore/MuseScore
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1a0d54074e51
Choose a head ref
  • 10 commits
  • 7 files changed
  • 2 contributors

Commits on Jan 28, 2015

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    464b1b5 View commit details
  2. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    265b7ff View commit details
  3. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    8960ea2 View commit details
  4. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    a5bd477 View commit details
  5. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    6018e3c View commit details
  6. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    1302d3d View commit details
  7. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    977a661 View commit details
  8. Update percussion tests

    trig-ger committed Jan 28, 2015
    Copy the full SHA
    5250d04 View commit details
  9. Copy the full SHA
    c78e83c View commit details
  10. Merge pull request #1695 from trig-ger/midi_instruments

    Better Ms instrument search for MIDI import
    wschweer committed Jan 28, 2015
    Copy the full SHA
    1a0d540 View commit details
135 changes: 114 additions & 21 deletions mscore/importmidi/importmidi.cpp
Original file line number Diff line number Diff line change
@@ -826,17 +826,60 @@ bool hasNotDefinedDrumPitch(const std::set<int> &trackPitches, const std::set<in
return hasNotDefinedPitch;
}

std::vector<InstrumentTemplate *> findInstrumentsForProgram(const MTrack &track)
const InstrumentTemplate* findInstrument(const QString &groupId, const QString &instrId)
{
std::vector<InstrumentTemplate *> suitableTemplates;
const InstrumentTemplate* instr = nullptr;

for (const InstrumentGroup *group: instrumentGroups) {
if (group->id == groupId) {
for (const InstrumentTemplate *templ: group->instrumentTemplates) {
if (templ->id == instrId) {
instr = templ;
break;
}
}
break;
}
}
return instr;
}

// find instrument with maximum MIDI program
// that is less than the track MIDI program, i.e. suitable instrument
const InstrumentTemplate* findClosestInstrument(const MTrack &track)
{
int maxLessProgram = -1;

for (const InstrumentGroup *group: instrumentGroups) {
for (const InstrumentTemplate *templ: group->instrumentTemplates) {
if (templ->staffGroup == StaffGroup::TAB)
continue;
const bool isDrumTemplate = (templ->useDrumset != DrumsetKind::NONE);
if (track.mtrack->drumTrack() != isDrumTemplate)
continue;
for (const auto &channel: templ->channel) {
if (channel.program < track.program
&& channel.program > maxLessProgram) {
maxLessProgram = channel.program;
return templ;
}
}
}
}
return nullptr;
}

std::vector<const InstrumentTemplate *> findInstrumentsForProgram(const MTrack &track)
{
std::vector<const InstrumentTemplate *> suitableTemplates;
const int program = track.program;

std::set<int> trackPitches;
if (track.mtrack->drumTrack())
trackPitches = findAllPitches(track);

for (const auto &group: instrumentGroups) {
for (const auto &templ: group->instrumentTemplates) {
for (const InstrumentGroup *group: instrumentGroups) {
for (const InstrumentTemplate *templ: group->instrumentTemplates) {
if (templ->staffGroup == StaffGroup::TAB)
continue;
const bool isDrumTemplate = (templ->useDrumset != DrumsetKind::NONE);
@@ -859,6 +902,50 @@ std::vector<InstrumentTemplate *> findInstrumentsForProgram(const MTrack &track)
}
}
}

if (suitableTemplates.empty()) {
// Ms instruments with the desired MIDI program were not found
// so we will find the most matching instrument

if (program == 55) { // GM "Orchestra Hit" sound
auto instr = findInstrument("electronic-instruments", "brass-synthesizer");
if (instr)
suitableTemplates.push_back(instr);
}
else if (program == 110) { // GM "Fiddle" sound
auto instr = findInstrument("strings", "violin");
if (instr)
suitableTemplates.push_back(instr);
}
else if (program >= 80 && program <= 103) {
auto instr = findInstrument("electronic-instruments", "effect-synth");
if (instr)
suitableTemplates.push_back(instr); // generic synth
}
else if (program >= 112 && program <= 127) {
auto instr = findInstrument("unpitched-percussion", "snare-drum");
if (instr)
suitableTemplates.push_back(instr); // 1-line percussion staff
}
else if (program == 36 || program == 37) {
// slightly improve slap bass match:
// match to the instruments with program 33
// instead of 35 according to the algorithm below
auto instr = findInstrument("plucked-strings", "electric-bass");
if (instr)
suitableTemplates.push_back(instr);
instr = findInstrument("plucked-strings", "5-string-electric-bass");
if (instr)
suitableTemplates.push_back(instr);
}
else { // find instrument with maximum MIDI program
// that is less than the track MIDI program, i.e. suitable instrument
auto instr = findClosestInstrument(track);
if (instr)
suitableTemplates.push_back(instr);
}
}

return suitableTemplates;
}

@@ -891,8 +978,17 @@ int findMaxPitchDiff(const std::pair<int, int> &minMaxPitch, const InstrumentTem
return diff;
}

bool hasCommonGenre(QList<InstrumentGenre *> genres)
{
for (InstrumentGenre *genre: genres) {
if (genre->id == "common")
return true;
}
return false;
}

void sortInstrumentTemplates(
std::vector<InstrumentTemplate *> &templates,
std::vector<const InstrumentTemplate *> &templates,
const std::pair<int, int> &minMaxPitch)
{
std::sort(templates.begin(), templates.end(),
@@ -908,33 +1004,30 @@ void sortInstrumentTemplates(
if (templ1->drumset && !templ2->drumset)
return true;
if (!templ1->drumset && templ2->drumset)
return false;
// prefer instruments with the "common" genre
const bool hasCommon1 = hasCommonGenre(templ1->genres);
const bool hasCommon2 = hasCommonGenre(templ2->genres);
if (hasCommon1 && !hasCommon2)
return true;
if (!hasCommon1 && hasCommon2)
return false;
return templ1->genres.size() > templ2->genres.size();
});
}

std::vector<InstrumentTemplate *> findSuitableInstruments(const MTrack &track)
std::vector<const InstrumentTemplate *> findSuitableInstruments(const MTrack &track)
{
std::vector<InstrumentTemplate *> templates = findInstrumentsForProgram(track);
std::vector<const InstrumentTemplate *> templates = findInstrumentsForProgram(track);
if (templates.empty())
return templates;

const std::pair<int, int> minMaxPitch = findMinMaxPitch(track);
sortInstrumentTemplates(templates, minMaxPitch);
// instruments here are sorted primarily by valid pitch range difference,
// so first nonzero difference means that current
// and all successive instruments are unsuitable;
// but if all instruments are unsuitable then leave them all in list
for (auto it = templates.begin(); it != templates.end(); ++it) {
const int diff = findMaxPitchDiff(minMaxPitch, *it);
if (diff > 0) {
if (it != templates.begin())
templates.erase(it, templates.end());
else // add empty template option
templates.push_back(nullptr);
break;
}
}

// add empty instrument to show no-instrument option
if (!templates.empty())
templates.push_back(nullptr);

return templates;
}
24 changes: 0 additions & 24 deletions mscore/importmidi/importmidi_model.cpp
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ class TracksModel::Column
virtual int width() const { return -1; }
virtual bool isEditable(int /*trackIndex*/) const { return true; }
virtual bool isForAllTracksOnly() const { return false; }
virtual QVariant textColor(int /*trackIndex*/) const { return QVariant(); }

protected:
MidiOperations::Opers &_opers;
@@ -182,23 +181,6 @@ void TracksModel::reset(const MidiOperations::Opers &opers,
list.append(instrName(instr));
return list;
}
QVariant textColor(int trackIndex) const override
{
const auto &trackInstrList = _opers.msInstrList.value(trackIndex);
if (trackInstrList.empty())
return QVariant(); // default color
const int instrIndex = _opers.msInstrIndex.value(trackIndex);
// if the last instrument is empty - notes of each instrument
// are out of corresponding "amateur" pitch range
// (see suitable instruments search code in importmidi.cpp)
const bool isValid = (trackInstrList.back() != nullptr);
const bool isLastIndex = (instrIndex == (int)trackInstrList.size() - 1);
// if the current instrument does not fit in pitch range
// and insrument index is not last in the list
// (which is empty instrument "-")
// then show the "invalid" instrument in red
return (!isValid && !isLastIndex) ? QBrush(Qt::red) : QVariant();
}

private:
static QString instrName(const InstrumentTemplate *instr)
@@ -905,12 +887,6 @@ QVariant TracksModel::data(const QModelIndex &index, int role) const
}
}
break;
case Qt::ForegroundRole:
if (_columns[index.column()]->isVisible(trackIndex)) {
const QVariant color = _columns[index.column()]->textColor(trackIndex);
if (color.type() == QVariant::Brush)
return color;
}
case Qt::SizeHintRole:
return QSize(_columns[index.column()]->width(), -1);
break;
5 changes: 3 additions & 2 deletions mscore/importmidi/importmidi_operations.h
Original file line number Diff line number Diff line change
@@ -132,8 +132,9 @@ struct Opers
TrackOp<int> channel = TrackOp<int>(int());
TrackOp<std::string> staffName = TrackOp<std::string>(std::string()); // will be converted to unicode later
TrackOp<QString> midiInstrName = TrackOp<QString>(QString());
TrackOp<std::vector<InstrumentTemplate *> > msInstrList
= TrackOp<std::vector<InstrumentTemplate *> >(std::vector<InstrumentTemplate *>());
TrackOp<std::vector<const InstrumentTemplate *> > msInstrList
= TrackOp<std::vector<const InstrumentTemplate *> >(
std::vector<const InstrumentTemplate *>());
TrackOp<bool> isDrumTrack = TrackOp<bool>(false);

// operations for all tracks
42 changes: 34 additions & 8 deletions mtest/importmidi/perc_no_grand_staff.mscx
Original file line number Diff line number Diff line change
@@ -100,15 +100,16 @@
</Part>
<Part>
<Staff id="2">
<StaffType group="percussion">
<name>perc5Line</name>
<keysig>0</keysig>
<StaffType group="pitched">
</StaffType>
<defaultClef>PERC</defaultClef>
</Staff>
<trackName>Percussion</trackName>
<Instrument>
<longName pos="0">Percussion</longName>
<trackName></trackName>
<shortName pos="0">Drs.</shortName>
<trackName>Drumset</trackName>
<instrumentId>drum.group.set</instrumentId>
<useDrumset>1</useDrumset>
<Drum pitch="35">
<head>0</head>
@@ -292,6 +293,35 @@
<name>Low Conga</name>
<stem>1</stem>
</Drum>
<clef>PERC</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<controller ctrl="0" value="1"/>
<program value="16"/>
@@ -334,10 +364,6 @@
</Staff>
<Staff id="2">
<Measure number="1">
<Clef>
<concertClefType>PERC</concertClefType>
<transposingClefType>PERC</transposingClefType>
</Clef>
<TimeSig>
<sigN>12</sigN>
<sigD>8</sigD>
42 changes: 34 additions & 8 deletions mtest/importmidi/perc_respect_beat.mscx
Original file line number Diff line number Diff line change
@@ -42,15 +42,16 @@
</PageList>
<Part>
<Staff id="1">
<StaffType group="percussion">
<name>perc5Line</name>
<keysig>0</keysig>
<StaffType group="pitched">
</StaffType>
<defaultClef>PERC</defaultClef>
</Staff>
<trackName>Percussion</trackName>
<Instrument>
<longName pos="0">Percussion</longName>
<trackName></trackName>
<shortName pos="0">Drs.</shortName>
<trackName>Drumset</trackName>
<instrumentId>drum.group.set</instrumentId>
<useDrumset>1</useDrumset>
<Drum pitch="35">
<head>0</head>
@@ -234,6 +235,35 @@
<name>Low Conga</name>
<stem>1</stem>
</Drum>
<clef>PERC</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<controller ctrl="0" value="1"/>
<program value="51"/>
@@ -242,10 +272,6 @@
</Part>
<Staff id="1">
<Measure number="1">
<Clef>
<concertClefType>PERC</concertClefType>
<transposingClefType>PERC</transposingClefType>
</Clef>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
42 changes: 34 additions & 8 deletions mtest/importmidi/perc_triplet.mscx
Original file line number Diff line number Diff line change
@@ -42,15 +42,16 @@
</PageList>
<Part>
<Staff id="1">
<StaffType group="percussion">
<name>perc5Line</name>
<keysig>0</keysig>
<StaffType group="pitched">
</StaffType>
<defaultClef>PERC</defaultClef>
</Staff>
<trackName>Percussion</trackName>
<Instrument>
<longName pos="0">Percussion</longName>
<trackName></trackName>
<shortName pos="0">Drs.</shortName>
<trackName>Drumset</trackName>
<instrumentId>drum.group.set</instrumentId>
<useDrumset>1</useDrumset>
<Drum pitch="35">
<head>0</head>
@@ -234,6 +235,35 @@
<name>Low Conga</name>
<stem>1</stem>
</Drum>
<clef>PERC</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<controller ctrl="0" value="1"/>
<program value="51"/>
@@ -242,10 +272,6 @@
</Part>
<Staff id="1">
<Measure number="1">
<Clef>
<concertClefType>PERC</concertClefType>
<transposingClefType>PERC</transposingClefType>
</Clef>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
42 changes: 34 additions & 8 deletions mtest/importmidi/perc_tuplet_simplify2.mscx
Original file line number Diff line number Diff line change
@@ -42,15 +42,16 @@
</PageList>
<Part>
<Staff id="1">
<StaffType group="percussion">
<name>perc5Line</name>
<keysig>0</keysig>
<StaffType group="pitched">
</StaffType>
<defaultClef>PERC</defaultClef>
</Staff>
<trackName>Percussion</trackName>
<Instrument>
<longName pos="0">Percussion</longName>
<trackName></trackName>
<shortName pos="0">Drs.</shortName>
<trackName>Drumset</trackName>
<instrumentId>drum.group.set</instrumentId>
<useDrumset>1</useDrumset>
<Drum pitch="35">
<head>0</head>
@@ -234,6 +235,35 @@
<name>Low Conga</name>
<stem>1</stem>
</Drum>
<clef>PERC</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<controller ctrl="0" value="1"/>
<program value="21"/>
@@ -242,10 +272,6 @@
</Part>
<Staff id="1">
<Measure number="1">
<Clef>
<concertClefType>PERC</concertClefType>
<transposingClefType>PERC</transposingClefType>
</Clef>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>