Remove vestigial MMA / Partial/Visual note infrastructure

This commit is contained in:
Matthias Neeracher 2007-05-27 04:42:05 +00:00
parent 3a5c3df5ec
commit a60d6612ff
3 changed files with 1 additions and 359 deletions

View File

@ -140,7 +140,7 @@
<key>CFBundleSignature</key>
<string>VçEz</string>
<key>CFBundleVersion</key>
<string>1.0a3</string>
<string>1.0a4</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@ -92,27 +92,6 @@ static std::string PitchName(int8_t pitch, bool useSharps)
+ std::string(kVLFlatStr);
}
static std::string MMAPitchName(int8_t pitch, bool useSharps)
{
if (pitch == VLNote::kNoPitch)
return "r";
char name[3];
name[2] = 0;
name[1] = 'n';
pitch %= 12;
if (kScale[pitch] != ' ') {
name[0] = kScale[pitch];
} else if (useSharps) {
name[0] = kScale[pitch-1];
name[1] = '#';
} else {
name[0] = kScale[pitch+1];
name[1] = '&';
}
return name;
}
VLNote::VLNote(std::string name)
{
//
@ -151,77 +130,6 @@ void VLNote::Name(std::string & name, bool useSharps) const
name = PitchName(fPitch, useSharps);
}
static struct {
VLFract fVal;
const char * fName;
} sMMADur [] = {
{{1,1}, "1"},
{{1,2}, "2"},
{{1,3}, "23"},
{{1,4}, "4"},
{{1,6}, "81"},
{{1,8}, "8"},
{{1,12}, "82"},
{{1,16}, "16"},
{{1,24}, "6"},
{{1,32}, "32"},
{{1,64}, "64"},
{{0,0}, 0}
};
void VLNote::MMAName(std::string & name, VLFraction at, VLFraction dur, VLFraction prevDur, VLFraction nextDur, const VLProperties & prop) const
{
if (fTied & kTiedWithPrev) {
if (fTied & kTiedWithNext) {
name = "~<>~";
} else {
name = '~';
}
return;
}
bool useSharps = prop.fKey >= 0;
name.clear();
VLFraction prevPart(0);
while (dur.fNum) {
VLFraction part;
bool grouped = dur==nextDur ||
(prevPart!=0 ? dur==prevPart : dur==prevDur);
prop.PartialNote(at, dur, grouped, &part);
const char * durName;
for (int d=0; sMMADur[d].fName; ++d)
if (part == sMMADur[d].fVal) {
durName = sMMADur[d].fName;
break;
}
if (!strcmp(durName, "82")) {
//
// Distinguish 2nd pair of swing 8ths from regular triplet
//
const VLFraction kBeat(1, prop.fTime.fDenom);
VLFraction withinBeat = at % kBeat;
if (withinBeat != 2*kBeat/3)
durName = "3";
}
if (name.size())
name += '+';
name += durName;
prevPart = part;
dur -= part;
at += part;
}
int pitch = fTied & kTiedWithPrev ? kNoPitch : fPitch;
name += MMAPitchName(pitch, useSharps);
if (pitch != kNoPitch) {
for (int raise = (pitch-kMiddleC)/kOctave; raise>0; --raise)
name += '+';
for (int lower = (kMiddleC+kOctave-1-pitch)/kOctave; lower>0; --lower)
name += '-';
}
if (fTied & kTiedWithNext)
name += '~';
}
void VLNote::MakeRepresentable()
{
if (fDuration > 1)
@ -467,263 +375,11 @@ void VLChord::Name(std::string & base, std::string & ext, std::string & root, bo
root = PitchName(fRootPitch, useSharps);
}
//
// MMA supports a large but finite list of chords
//
static const VLChordModifier kMMAModifiers[] = {
{"", 0, 0},
{"+", _ kmAug5th, _ km5th},
{"11", _ kmMin7th | _ kmMaj9th | _ km11th, 0},
{"11b9", _ kmMin7th | _ kmMin9th | _ km11th, 0},
{"13", _ kmMin7th | _ kmMaj9th | _ km11th | _ kmMaj13th, 0},
{"5", 0, _ kmMaj3rd},
{"6", _ kmDim7th, 0},
{"69", _ kmDim7th | _ kmMaj9th, 0},
{"7", _ kmMin7th, 0},
{"7#11", _ kmMin7th | _ kmAug11th, 0},
{"7#5", _ kmMin7th | _ kmAug5th, _ km5th},
{"7#5#9", _ kmMin7th | _ kmAug5th | _ kmAug9th, _ km5th},
{"7#5b9", _ kmMin7th | _ kmAug5th | _ kmMin9th, _ km5th},
{"7#9", _ kmMin7th | _ kmAug9th, 0},
{"7#9#11", _ kmMin7th | _ kmAug9th | _ kmAug11th, 0},
{"7b5", _ kmMin7th | _ kmDim5th, _ km5th},
{"7b5#9", _ kmMin7th | _ kmDim5th | _ kmAug9th, _ km5th},
{"7b5b9", _ kmMin7th | _ kmDim5th | _ kmMin9th, _ km5th},
{"7b9", _ kmMin7th | _ kmMin9th, 0},
{"7sus", _ kmMin7th | _ km4th, _ kmMaj3rd},
{"7sus2", _ kmMin7th | _ kmMaj2nd, _ kmMaj3rd},
{"9", _ kmMin7th | _ kmMaj9th, 0},
{"9#11", _ kmMin7th | _ kmMaj9th | _ kmAug11th, 0},
{"9#5", _ kmMin7th | _ kmMaj9th | _ kmAug5th, _ km5th},
{"9b5", _ kmMin7th | _ kmMaj9th | _ kmDim5th, _ km5th},
{"9sus", _ kmMaj9th, 0},
{"M13", _ kmMaj7th | _ kmMaj13th, 0},
{"M7", _ kmMaj7th, 0},
{"M7#11", _ kmMaj7th | _ kmMaj9th | _ kmAug11th, 0},
{"M7#5", _ kmMaj7th | _ kmAug5th, _ km5th},
{"M7b5", _ kmMaj7th | _ kmDim5th, _ km5th},
{"M9", _ kmMaj7th | _ kmMaj9th, 0},
{"aug9", _ kmMin7th | _ kmMaj9th | _ kmAug5th, _ km5th},
{"dim3", _ kmMin3rd | _ kmDim5th, _ kmMaj3rd | _ km5th},
{"dim7", _ kmMin3rd | _ kmDim5th | _ kmDim7th, _ kmMaj3rd | _ km5th},
{"m", _ kmMin3rd, _ kmMaj3rd},
{"m#5", _ kmMin3rd | _ kmAug5th, _ kmMaj3rd | _ km5th},
{"m(maj7)", _ kmMin3rd | _ kmMaj7th, _ kmMaj3rd},
{"m(sus9)", _ kmMin3rd | _ kmMaj9th, _ kmMaj3rd},
{"m11", _ kmMin3rd | _ kmMin7th | _ kmMaj9th | _ km11th, _ kmMaj3rd},
{"m6", _ kmMin3rd | _ kmDim7th, _ kmMaj3rd},
{"m69", _ kmMin3rd | _ kmDim7th | _ kmMaj9th, _ kmMaj3rd},
{"m7", _ kmMin3rd | _ kmMin7th, _ kmMaj3rd},
{"m7b5", _ kmMin3rd | _ kmMin7th | _ kmDim5th, _ kmMaj3rd | _ km5th},
{"m7b9", _ kmMin3rd | _ kmMin7th | _ kmMin9th, _ kmMaj3rd},
{"m9", _ kmMin3rd | _ kmMin7th | _ kmMaj9th, _ kmMaj3rd},
{"m9b5", _ kmMin3rd | _ kmMin7th | _ kmMaj9th | _ kmDim5th, _ kmMaj3rd | _ km5th},
{"mM7", _ kmMin3rd | _ kmMaj7th, _ kmMaj3rd},
{"mb5", _ kmMin3rd | _ kmDim5th, _ kmMaj3rd | _ km5th},
{"sus", _ km4th, _ kmMaj3rd},
{"sus2", _ kmMaj2nd, _ kmMaj3rd},
{"sus9", _ kmMaj9th, 0},
{NULL, 0, 0}
};
bool VLChord::MMAName(std::string & name, bool useSharps, bool initial) const
{
VLFraction dur = fDuration;
int quarters = static_cast<int>(dur*4.0f+0.5f);
name = "";
if (!quarters--)
return initial;
if (fPitch == kNoPitch) {
name = initial ? 'z' : '/';
} else {
std::string base, ext;
VLNote::Name(base, useSharps);
size_t best = 0;
size_t bestBits = 32;
size_t bestScore= 0;
for (size_t i=0; kMMAModifiers[i].fName; ++i) {
uint32_t steps = (kmUnison | kmMaj3rd | km5th)
| kMMAModifiers[i].fAddSteps
&~kMMAModifiers[i].fDelSteps;
if (fSteps == steps) {
//
// Exact match
//
best = i;
break;
}
steps ^= fSteps;
size_t bits=0;
size_t score=0;
for (uint32_t b=steps; b; b &= (b-1))
++bits;
for (size_t b=0; b<32; ++b)
if (steps & (1<<b))
score += 32-b;
if (bits < bestBits || (bits==bestBits && score < bestScore)) {
best = i;
bestBits = bits;
bestScore = score;
}
}
ext = kMMAModifiers[best].fName;
name = base+ext;
if (fRootPitch != kNoPitch)
name += '/' + PitchName(fRootPitch, useSharps);
std::toupper(base[0]);
size_t mod;
while ((mod = name.find("Maj")) != std::string::npos)
name.erase(mod+1, 2);
while ((mod = name.find(kVLSharpStr)) != std::string::npos)
name.replace(mod, 3, "#", 1);
while ((mod = name.find(kVLFlatStr)) != std::string::npos)
name.replace(mod, 3, "&", 1);
}
while (quarters--)
name += " /";
return false;
}
static VLFraction MaxNote(VLFraction d)
{
if (d >= 1)
return 1;
if (d.fNum == 1 && !(d.fDenom & (d.fDenom-1))) // Power of 2
return d;
VLFraction note(1,2);
VLFraction triplet(1,3);
for (;;) {
if (d >= note)
return note;
else if (d >= triplet)
return triplet;
note /= 2;
triplet /= 2;
}
}
static void TrimNote(VLFraction at, VLFraction & d, VLFraction grid)
{
if (at < grid && d > grid-at)
d = MaxNote(grid-at);
}
void VLProperties::PartialNote(VLFraction at, VLFraction totalDuration,
bool grouped, VLFraction * noteDuration) const
{
const VLFraction kBeat(1, fTime.fDenom);
at %= fTime;
*noteDuration = MaxNote(std::min(MaxNote(totalDuration), fTime-at)); // Don't extend past measure
if (at.fDenom > kBeat.fDenom) { // Break up notes not starting on beat
// Don't extend past "middle" of measure
if (fTime.fNum & 1) // Odd timecode, round up (most 5/4 seems to be 3+2, not 2+3)
TrimNote(at, *noteDuration, VLFraction((fTime.fNum+1)/2, fTime.fDenom));
else
TrimNote(at, *noteDuration, fTime / 2);
at %= kBeat;
if (at == 2*kBeat/3)
TrimNote(0, *noteDuration, kBeat); // Allow syncopated beats in swing
else
TrimNote(at, *noteDuration, kBeat);// Don't let other notes span beats
}
if (!(noteDuration->fDenom % 3))
if (*noteDuration != totalDuration) {
if (((at+*noteDuration)%kBeat) > 0)
*noteDuration *= VLFraction(3,4); // avoid frivolous triplets
} else if (*noteDuration > VLFraction(1,4*fDivisions) && !grouped) {
if (*noteDuration == VLFraction(1,2*fDivisions))
if (at % VLFraction(1, 4*fDivisions/3) == 0)
return; // Permit larger swing notes
*noteDuration *= VLFraction(3,4); // avoid other isolated triplets
}
}
void VLProperties::VisualNote(VLFraction at, VLFraction actualDur,
bool prevTriplet,
VLFraction *visualDur, bool * triplet) const
{
bool swing= !(fDivisions % 3); // In swing mode?
VLFraction swung(3, fDivisions*8, true); // Which notes to swing
VLFraction swingGrid(2*swung); // Alignment of swing notes
if (*triplet = !(actualDur.fDenom % 3)) {
if (swing) { // Swing 8ths / 16ths are written as straight 8ths
if (actualDur == 4*swung/3 && (at % swingGrid) == 0) {
*visualDur = swung;
*triplet = false;
} else if (actualDur == 2*swung/3 && ((at+actualDur) % swingGrid) == 0 && !prevTriplet) {
*visualDur = swung;
*triplet = false;
} else {
*visualDur = 3*actualDur/2;
}
} else {
*visualDur = 3*actualDur/2;
}
} else {
*visualDur = actualDur;
}
}
VLMeasure::VLMeasure()
: fPropIdx(0)
{
}
void VLMeasure::MMANotes(std::string & notes, const VLProperties & prop,
VLFraction extra) const
{
VLFraction at(0);
VLNoteList::const_iterator i = fMelody.begin();
VLNoteList::const_iterator e = fMelody.end();
notes.clear();
VLFraction prevDur(0);
for (; i!=e; ++i) {
std::string note;
VLFraction nextDur(0);
VLFraction dur(i->fDuration);
VLNoteList::const_iterator n=i;
if (++n != e)
nextDur = n->fDuration;
else
dur += extra;
i->MMAName(note, at, dur, prevDur, nextDur, prop);
if (notes.size()>1)
notes += ' ';
if (note == "~")
notes += note;
else
notes += note+';';
at += i->fDuration;
}
if (notes == "~")
notes += "<>;";
}
void VLMeasure::MMAChords(std::string & chords, const VLProperties & prop,
bool initial) const
{
VLChordList::const_iterator i = fChords.begin();
VLChordList::const_iterator e = fChords.end();
chords.clear();
for (; i!=e; ++i) {
std::string chord;
initial = i->MMAName(chord, prop.fKey >= 0, initial);
if (chords.size())
chords += ' ';
chords += chord;
}
}
bool VLMeasure::IsEmpty() const
{
return fChords.size() == 1 && fMelody.size() == 1

View File

@ -150,7 +150,6 @@ struct VLNote {
VLNote(VLFraction dur=0, int pitch=kNoPitch);
VLNote(std::string name);
void Name(std::string & name, bool useSharps = false) const;
void MMAName(std::string & name, VLFraction at, VLFraction dur, VLFraction prevDur, VLFraction nextDur, const VLProperties & prop) const;
void MakeRepresentable();
void AlignToGrid(VLFraction at, VLFraction grid);
};
@ -209,7 +208,6 @@ struct VLChord : VLNote {
VLChord(VLFraction dur=0, int pitch=kNoPitch, int rootPitch=kNoPitch);
VLChord(std::string name);
void Name(std::string & base, std::string & ext, std::string & root, bool useSharps = false) const;
bool MMAName(std::string & name, bool useSharps, bool initial) const;
};
struct VLChordModifier {
@ -223,15 +221,6 @@ struct VLProperties {
int8_t fKey; // Circle of fifths from C, >0 sharps, <0 flats
int8_t fMode; // 1 = major -1 = minor
int8_t fDivisions; // Number of divisions per quarter note
//
// Subdivide a note and adjust for swing
//
void PartialNote(VLFraction at, VLFraction totalDuration, bool grouped, VLFraction * noteDuration) const;
//
// Determine visual representation of note head
//
void VisualNote(VLFraction at, VLFraction actualDur, bool prevTriplet, VLFraction *visualDur, bool * triplet) const;
bool operator==(const VLProperties & other)
{ return fTime == other.fTime && fKey == other.fKey && fMode == other.fMode
@ -256,9 +245,6 @@ struct VLMeasure {
VLMeasure();
void MMANotes(std::string & notes, const VLProperties & prop, VLFraction extra) const;
void MMAChords(std::string & chords, const VLProperties & prop, bool initial) const;
bool IsEmpty() const;
bool NoChords() const;