mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Smarter division handling
This commit is contained in:
parent
a116648d23
commit
1eb64d2e55
|
@ -215,9 +215,23 @@ void VLPlistVisitor::VisitChord(VLChord & c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// We try to keep the number of divisions as small as possible, so we keep track
|
||||||
|
// of all note onsets per quarter note. In addition, we keep track of potential
|
||||||
|
// swing 8ths [0, 1/8]->[0,1/6] and
|
||||||
|
// swing 16ths [0,1/16]->[0,1/12] [1/8,3/16]->[1/8,1/6]
|
||||||
|
// so we can recognize swing songs containing triplets and note them with 3 (6)
|
||||||
|
// divisions instead of 6 (12)
|
||||||
|
//
|
||||||
|
enum {
|
||||||
|
kPotentialSwing8th = 12,
|
||||||
|
kPotentialSwing16th
|
||||||
|
};
|
||||||
|
|
||||||
- (void)readMelody:(NSArray *)melody inMeasure:(size_t)measNo onsets:(int *)onsets
|
- (void)readMelody:(NSArray *)melody inMeasure:(size_t)measNo onsets:(int *)onsets
|
||||||
{
|
{
|
||||||
VLFraction at(0);
|
VLFraction at(0);
|
||||||
|
int lastOnset = 0;
|
||||||
VLFraction tiedStart(0);
|
VLFraction tiedStart(0);
|
||||||
VLLyricsNote tiedNote;
|
VLLyricsNote tiedNote;
|
||||||
uint8_t prevKind[20];
|
uint8_t prevKind[20];
|
||||||
|
@ -284,8 +298,23 @@ void VLPlistVisitor::VisitChord(VLChord & c)
|
||||||
song->AddNote(note, measNo, at);
|
song->AddNote(note, measNo, at);
|
||||||
|
|
||||||
if (!(note.fTied & VLNote::kTiedWithPrev)) {
|
if (!(note.fTied & VLNote::kTiedWithPrev)) {
|
||||||
VLFraction inQuarter = at % VLFraction(1,4);
|
VLFraction inQuarter = at % VLFraction(1,4);
|
||||||
++onsets[inQuarter.fNum * 48 / inQuarter.fDenom];
|
int onset = inQuarter.fNum * 48 / inQuarter.fDenom;
|
||||||
|
++onsets[onset];
|
||||||
|
switch (onset) {
|
||||||
|
case 3:
|
||||||
|
if (lastOnset == 0)
|
||||||
|
++onsets[kPotentialSwing16th];
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (lastOnset == 0)
|
||||||
|
++onsets[kPotentialSwing8th];
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
if (lastOnset == 6 || lastOnset == 3 || lastOnset == 0)
|
||||||
|
++onsets[kPotentialSwing16th];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
advanceAt:
|
advanceAt:
|
||||||
at += note.fDuration;
|
at += note.fDuration;
|
||||||
|
@ -319,7 +348,7 @@ advanceAt:
|
||||||
std::vector<size_t> repeatStack;
|
std::vector<size_t> repeatStack;
|
||||||
|
|
||||||
size_t measNo = 0;
|
size_t measNo = 0;
|
||||||
int onsets[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
int onsets[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
for (NSEnumerator * me = [measures objectEnumerator];
|
for (NSEnumerator * me = [measures objectEnumerator];
|
||||||
NSDictionary * mdict = [me nextObject];
|
NSDictionary * mdict = [me nextObject];
|
||||||
++measNo
|
++measNo
|
||||||
|
@ -389,13 +418,23 @@ advanceAt:
|
||||||
song->fMeasures.pop_back();
|
song->fMeasures.pop_back();
|
||||||
if (!song->fProperties.back().fDivisions) {
|
if (!song->fProperties.back().fDivisions) {
|
||||||
if (!(onsets[1]+onsets[5]+onsets[7]+onsets[11]))
|
if (!(onsets[1]+onsets[5]+onsets[7]+onsets[11]))
|
||||||
if (!(onsets[3]+onsets[9]))
|
if (!(onsets[3]+onsets[9]-onsets[kPotentialSwing16th]))
|
||||||
if (!(onsets[2]+onsets[4]+onsets[8]+onsets[10]))
|
if (onsets[kPotentialSwing16th]) {
|
||||||
|
song->fProperties.back().fDivisions = 12;
|
||||||
|
song->ChangeDivisions(song->fProperties.size()-1, 6);
|
||||||
|
} else if (!(onsets[2]+onsets[4]+onsets[8]+onsets[10])) {
|
||||||
song->fProperties.back().fDivisions = 2;
|
song->fProperties.back().fDivisions = 2;
|
||||||
else if (!(onsets[2]+onsets[6]+onsets[10]))
|
} else if (!(onsets[2]+onsets[10]
|
||||||
song->fProperties.back().fDivisions = 3;
|
+ onsets[6]-onsets[kPotentialSwing8th])) {
|
||||||
else
|
if (onsets[kPotentialSwing8th]) {
|
||||||
|
song->fProperties.back().fDivisions = 6;
|
||||||
|
song->ChangeDivisions(song->fProperties.size()-1, 3);
|
||||||
|
} else {
|
||||||
|
song->fProperties.back().fDivisions = 3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
song->fProperties.back().fDivisions = 6;
|
song->fProperties.back().fDivisions = 6;
|
||||||
|
}
|
||||||
else if (!(onsets[2]+onsets[4]+onsets[8]+onsets[10]))
|
else if (!(onsets[2]+onsets[4]+onsets[8]+onsets[10]))
|
||||||
song->fProperties.back().fDivisions = 4;
|
song->fProperties.back().fDivisions = 4;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue
Block a user