Skip to content

Commit

Permalink
Merge pull request #3515 from jeetee/269603_unwind_RepeatList_followup
Browse files Browse the repository at this point in the history
fix #269603, fix #148276 unwind followup especially with regards to DS having playRepeats enabled
  • Loading branch information
lasconic authored Mar 7, 2018
2 parents 9feaa9b + 79d4227 commit b097bf8
Show file tree
Hide file tree
Showing 11 changed files with 1,041 additions and 130 deletions.
18 changes: 11 additions & 7 deletions libmscore/rendermidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,15 +453,19 @@ void Score::updateRepeatList(bool expandRepeats)
for (RepeatSegment* s : *repeatList())
delete s;
repeatList()->clear();
Measure* m = lastMeasure();
Measure* m = firstMeasure();
if (m == 0)
return;
RepeatSegment* s = new RepeatSegment;
s->tick = 0;
s->len = m->tick() + m->ticks();
s->utick = 0;
s->utime = 0.0;
s->timeOffset = 0.0;
do {
s->addMeasure(m);
m = m->nextMeasure();
}
while (m);
repeatList()->append(s);
}
else
Expand Down Expand Up @@ -632,7 +636,7 @@ void Score::renderStaff(EventMap* events, Staff* staff)
Measure* lastMeasure = 0;
for (const RepeatSegment* rs : *repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
int tickOffset = rs->utick - rs->tick;
for (Measure* m = tick2measure(startTick); m; m = m->nextMeasure()) {
if (lastMeasure && m->isRepeatMeasure(staff)) {
Expand All @@ -659,7 +663,7 @@ void Score::renderSpanners(EventMap* events, int staffIdx)
int tickOffset = rs->utick - rs->tick;
int utick1 = rs->utick;
int tick1 = repeatList()->utick2tick(utick1);
int tick2 = tick1 + rs->len;
int tick2 = tick1 + rs->len();
std::map<int, std::vector<std::pair<int, bool>>> channelPedalEvents = std::map<int, std::vector<std::pair<int, bool>>>();
for (const auto& sp : _spanner.map()) {
Spanner* s = sp.second;
Expand Down Expand Up @@ -689,8 +693,8 @@ void Score::renderSpanners(EventMap* events, int staffIdx)
}
if (s->tick2() >= tick1 && s->tick2() <= tick2) {
int t = s->tick2() + tickOffset + 1;
if (t > repeatList()->last()->utick + repeatList()->last()->len)
t = repeatList()->last()->utick + repeatList()->last()->len;
if (t > repeatList()->last()->utick + repeatList()->last()->len())
t = repeatList()->last()->utick + repeatList()->last()->len();
channelPedalEvents.at(channel).push_back(std::pair<int, bool>(t, false));
}
}
Expand Down Expand Up @@ -1767,7 +1771,7 @@ void Score::renderMidi(EventMap* events)
// add metronome ticks
for (const RepeatSegment* rs : *repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
int tickOffset = rs->utick - rs->tick;

//
Expand Down
465 changes: 354 additions & 111 deletions libmscore/repeatlist.cpp

Large diffs are not rendered by default.

23 changes: 19 additions & 4 deletions libmscore/repeatlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,30 @@ namespace Ms {

class Score;
class Measure;
class Volta;
class Jump;

//---------------------------------------------------------
// RepeatSegment
//---------------------------------------------------------

class RepeatSegment {
private:
QList<std::pair<Measure*, int>> measureList; //measure, playbackCount
public:
int tick; // start tick
int len;
int utick;
qreal utime;
qreal timeOffset;

RepeatSegment();
RepeatSegment(RepeatSegment * const, Measure * const fromMeasure, Measure * const untilMeasure);
void addMeasure(Measure * const);
bool containsMeasure(Measure const * const) const;
int len() const;
int playbackCount(Measure * const) const;

friend class RepeatList;
};

//---------------------------------------------------------
Expand All @@ -43,10 +53,15 @@ class RepeatList: public QList<RepeatSegment*>
mutable unsigned idx1, idx2; // cached values

RepeatSegment* rs; // tmp value during unwind()
std::map<Volta*, Measure*> _voltaRanges; // open volta possibly ends past the end of its spanner, used during unwind
std::set<Jump*> _jumpsTaken; // take the jumps only once, so track them during unwind

void unwindSection(Measure* fm, Measure* em);
Measure* findStartRepeat(Measure*);
int findStartFromRepeatCount(Measure * const startFrom, Measure * const sectionEndMeasure);
void preProcessVoltas();
std::map<Volta*, Measure*>::const_iterator searchVolta(Measure * const) const;
void unwindSection(Measure * const fm, Measure * const em);
Measure* findStartRepeat(Measure * const) const;
int findStartFromRepeatCount(Measure * const startFrom) const;
bool isFinalPlaythrough(Measure * const measure, QList<RepeatSegment*>::const_iterator repeatSegmentIt) const;

public:
RepeatList(Score* s);
Expand Down
4 changes: 2 additions & 2 deletions libmscore/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3833,7 +3833,7 @@ QString Score::extractLyrics()
// follow the repeat segments
for (const RepeatSegment* rs : *repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
for (Measure* m = tick2measure(startTick); m; m = m->nextMeasure()) {
int playCount = m->playbackCount();
for (Segment* seg = m->first(st); seg; seg = seg->next(st)) {
Expand Down Expand Up @@ -3922,7 +3922,7 @@ int Score::duration()
{
updateRepeatList(true);
RepeatSegment* rs = repeatList()->last();
return lrint(utick2utime(rs->utick + rs->len));
return lrint(utick2utime(rs->utick + rs->len()));
}

//---------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion libmscore/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ class Score : public QObject, ScoreElement {

void updateHairpin(Hairpin*); // add/modify hairpin to pitchOffset list
void removeHairpin(Hairpin*); // remove hairpin from pitchOffset list
Volta* searchVolta(int tick) const;

MasterScore* masterScore() const { return _masterScore; }
void setMasterScore(MasterScore* s) { _masterScore = s; }
void createRevision();
Expand Down
6 changes: 3 additions & 3 deletions mscore/exportmidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void ExportMidi::writeHeader()
TimeSigMap* sigmap = cs->sigmap();
foreach(const RepeatSegment* rs, *cs->repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
int tickOffset = rs->utick - rs->tick;

auto bs = sigmap->lower_bound(startTick);
Expand Down Expand Up @@ -136,7 +136,7 @@ void ExportMidi::writeHeader()
bool initialKeySigFound = false;
for (const RepeatSegment* rs : *cs->repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
int tickOffset = rs->utick - rs->tick;

auto sk = keys->lower_bound(startTick);
Expand Down Expand Up @@ -340,7 +340,7 @@ void ExportMidi::PauseMap::calculate(const Score* s)

foreach(const RepeatSegment* rs, *s->repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
int tickOffset = rs->utick - rs->tick;

auto se = tempomap->lower_bound(startTick);
Expand Down
2 changes: 1 addition & 1 deletion mscore/savePositions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ bool savePositions(Score* score, const QString& name, bool segments)
score->updateRepeatList(true);
foreach(const RepeatSegment* rs, *score->repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len;
int endTick = startTick + rs->len();
int tickOffset = rs->utick - rs->tick;
for (Measure* m = score->tick2measureMM(startTick); m; m = m->nextMeasureMM()) {
if (segments)
Expand Down
224 changes: 224 additions & 0 deletions mtest/libmscore/repeat/repeat48.mscx
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.00">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle">Repeat Test</metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<instrumentId>keyboard.piano</instrumentId>
<clef staff="2">F</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>95</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>
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
<bottomGap>1</bottomGap>
<Text>
<style>Title</style>
<text>Repeat Test</text>
</Text>
<Text>
<style>Subtitle</style>
<text>Jump into first Volta</text>
</Text>
</VBox>
<TBox>
<height>1</height>
<topGap>0</topGap>
<leftMargin>1</leftMargin>
<rightMargin>1</rightMargin>
<topMargin>1</topMargin>
<bottomMargin>1</bottomMargin>
<Text>
<style>Frame</style>
<text>Assume the composer is 'right' and rewind that far for 'final' playthrough:
1,2,3,4,1,5,6,7,3,4,1,5,8</text>
</Text>
</TBox>
<Measure number="1">
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Tempo>
<tempo>5</tempo>
<followText>1</followText>
<text><sym>metNoteQuarterUp</sym> = 300</text>
</Tempo>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>60</pitch>
<tpc>14</tpc>
</Note>
</Chord>
</Measure>
<Measure number="2">
<Volta id="2">
<endHookType>1</endHookType>
<beginText>1.</beginText>
<endings>1</endings>
</Volta>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>62</pitch>
<tpc>16</tpc>
</Note>
</Chord>
</Measure>
<Measure number="3">
<Marker>
<style>Repeat Text Left</style>
<text><sym>segno</sym></text>
<label>segno</label>
</Marker>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</Measure>
<Measure number="4">
<endRepeat>2</endRepeat>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>65</pitch>
<tpc>13</tpc>
</Note>
</Chord>
</Measure>
<Measure number="5">
<Marker>
<style>Repeat Text Right</style>
<text>To Coda</text>
<label>coda</label>
</Marker>
<endSpanner id="2"/>
<Volta id="3">
<beginText>2.</beginText>
<endings>2</endings>
</Volta>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</Measure>
<Measure number="6">
<endSpanner id="3"/>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</Measure>
<Measure number="7">
<Jump>
<style>Repeat Text Right</style>
<text>D.S. al Coda</text>
<jumpTo>segno</jumpTo>
<playUntil>coda</playUntil>
<continueAt>codab</continueAt>
</Jump>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<BarLine>
<subtype>double</subtype>
</BarLine>
</Measure>
<HBox>
<width>5</width>
</HBox>
<Measure number="8">
<Marker>
<style>Repeat Text Left</style>
<text><sym>coda</sym></text>
<label>codab</label>
</Marker>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>72</pitch>
<tpc>14</tpc>
</Note>
</Chord>
</Measure>
</Staff>
</Score>
</museScore>
Loading

0 comments on commit b097bf8

Please sign in to comment.