mirror of
https://github.com/microtherion/VocalEasel.git
synced 2025-01-12 21:23:59 +00:00
Refactor pitch/chord naming code
This commit is contained in:
parent
f47c7d725d
commit
d6ce6acd27
|
@ -249,7 +249,7 @@ static std::string EscapeSyllable(std::string syll)
|
|||
|
||||
static bool PreferSharps(bool globalSharps, int noteAccidentals)
|
||||
{
|
||||
return (noteAccidentals & VLNote::kAccidentals)
|
||||
return (noteAccidentals & VLNote::kAccidentalsMask)
|
||||
? (noteAccidentals & VLNote::kWantSharp)
|
||||
: globalSharps;
|
||||
}
|
||||
|
@ -277,10 +277,10 @@ void VLLilypondWriter::VisitNote(VLLyricsNote & n)
|
|||
strcpy(duration, ".");
|
||||
else if (n.fVisual & VLNote::kTriplet)
|
||||
sprintf(duration, "%s\\times 2/3 { %s%d%s }",
|
||||
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHead], tie);
|
||||
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHeadMask], tie);
|
||||
else
|
||||
sprintf(duration, "%s%s%d%s",
|
||||
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHead], tie);
|
||||
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHeadMask], tie);
|
||||
|
||||
fAccum += duration;
|
||||
fPrevNote= n;
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
//
|
||||
|
||||
#include "VLModel.h"
|
||||
#include <ctype.h>
|
||||
#include "VLPitchName.h"
|
||||
|
||||
#pragma mark class VLFraction
|
||||
|
||||
VLFraction & VLFraction::Normalize()
|
||||
{
|
||||
|
@ -75,75 +77,40 @@ VLFraction & VLFraction::operator%=(VLFraction other)
|
|||
return *this *= other;
|
||||
}
|
||||
|
||||
static const char kScale[] = "c d ef g a b";
|
||||
|
||||
static std::string PitchName(int8_t pitch, bool useSharps)
|
||||
{
|
||||
if (pitch == VLNote::kNoPitch)
|
||||
return "r";
|
||||
pitch %= 12;
|
||||
if (kScale[pitch] != ' ')
|
||||
return static_cast<char>(std::toupper(kScale[pitch])) + std::string();
|
||||
else if (useSharps)
|
||||
return static_cast<char>(std::toupper(kScale[pitch-1]))
|
||||
+ std::string(kVLSharpStr);
|
||||
else
|
||||
return static_cast<char>(std::toupper(kScale[pitch+1]))
|
||||
+ std::string(kVLFlatStr);
|
||||
}
|
||||
#pragma mark -
|
||||
#pragma mark class VLNote
|
||||
|
||||
VLNote::VLNote(std::string name)
|
||||
{
|
||||
//
|
||||
// Determine key
|
||||
//
|
||||
if (const char * key = strchr(kScale, name[0]))
|
||||
fPitch = key-kScale+kMiddleC;
|
||||
else
|
||||
goto failed;
|
||||
name.erase(0, 1);
|
||||
//
|
||||
// Look for sharp / flat
|
||||
//
|
||||
fVisual = 0;
|
||||
if (name.size())
|
||||
if (name[0] == '#') {
|
||||
++fPitch;
|
||||
fVisual |= kWantSharp;
|
||||
name.erase(0);
|
||||
} else if (name[0] == 'b') {
|
||||
--fPitch;
|
||||
fVisual |= kWantFlat;
|
||||
name.erase(0, 1);
|
||||
}
|
||||
AdjustAccidentals();
|
||||
if (name == "")
|
||||
return;
|
||||
fPitch = VLParsePitch(name, 0, &fVisual);
|
||||
|
||||
failed:
|
||||
fPitch = kNoPitch; // Failed to parse completely
|
||||
if (!name.empty()) { // Failed to parse completely
|
||||
fPitch = kNoPitch;
|
||||
fVisual= 0;
|
||||
}
|
||||
}
|
||||
|
||||
VLNote::VLNote(VLFraction dur, int pitch)
|
||||
: fDuration(dur), fPitch(pitch), fTied(0), fVisual(0)
|
||||
VLNote::VLNote(VLFraction dur, int pitch, uint16_t visual)
|
||||
: fDuration(dur), fPitch(pitch), fTied(0), fVisual(visual)
|
||||
{
|
||||
}
|
||||
|
||||
void VLNote::Name(std::string & name, bool useSharps) const
|
||||
std::string VLNote::Name(uint16_t accidental) const
|
||||
{
|
||||
if (fVisual & kWantSharp)
|
||||
useSharps = true;
|
||||
else if (fVisual & kWantFlat)
|
||||
useSharps = false;
|
||||
if (uint16_t acc = (fVisual & kAccidentalsMask))
|
||||
if (acc == kWantNatural)
|
||||
accidental |= acc;
|
||||
else
|
||||
accidental = acc;
|
||||
|
||||
name = PitchName(fPitch, useSharps);
|
||||
return VLPitchName(fPitch, accidental);
|
||||
}
|
||||
|
||||
void VLNote::MakeRepresentable()
|
||||
{
|
||||
if (fDuration > 1)
|
||||
fDuration = 1;
|
||||
fVisual = kWhole | (fVisual & kAccidentals);
|
||||
fVisual = kWhole | (fVisual & kAccidentalsMask);
|
||||
VLFraction part(1,1);
|
||||
VLFraction triplet(2,3);
|
||||
//
|
||||
|
@ -168,26 +135,6 @@ void VLNote::MakeRepresentable()
|
|||
abort();
|
||||
}
|
||||
|
||||
void VLNote::AdjustAccidentals()
|
||||
{
|
||||
//
|
||||
// Don't store accidental preferences for whole notes:
|
||||
// There is no way to represent these in MusicXML, so saving and
|
||||
// reloading would change behavior.
|
||||
//
|
||||
enum {
|
||||
kC = 1<<0,
|
||||
kD = 1<<2,
|
||||
kE = 1<<4,
|
||||
kF = 1<<5,
|
||||
kG = 1<<7,
|
||||
kA = 1<<9,
|
||||
kB = 1<<11
|
||||
};
|
||||
if ((1 << (fPitch % 12)) & (kC | kD | kE | kF | kG | kA | kB))
|
||||
fVisual &= ~kAccidentals;
|
||||
}
|
||||
|
||||
void VLNote::AlignToGrid(VLFraction at, VLFraction grid)
|
||||
{
|
||||
if (at+fDuration > grid) {
|
||||
|
@ -201,43 +148,13 @@ VLLyricsNote::VLLyricsNote(const VLNote & note)
|
|||
{
|
||||
}
|
||||
|
||||
VLLyricsNote::VLLyricsNote(VLFraction dur, int pitch)
|
||||
: VLNote(dur, pitch)
|
||||
VLLyricsNote::VLLyricsNote(VLFraction dur, int pitch, uint16_t visual)
|
||||
: VLNote(dur, pitch, visual)
|
||||
{
|
||||
}
|
||||
|
||||
#define _ VLChord::
|
||||
|
||||
static const VLChordModifier kModifiers[] = {
|
||||
{"b13", _ kmMin13th, 0},
|
||||
{"add13", _ kmMaj13th, 0},
|
||||
{"13", _ kmMin7th | _ kmMaj9th | _ km11th | _ kmMaj13th, 0},
|
||||
{"#11", _ kmAug11th, 0},
|
||||
{"add11", _ km11th, 0},
|
||||
{"11", _ kmMin7th | _ kmMaj9th | _ km11th, 0},
|
||||
{"#9", _ kmAug9th, _ kmMaj9th},
|
||||
{"+9", _ kmAug9th, _ kmMaj9th},
|
||||
{"b9", _ kmMin9th, _ kmMaj9th},
|
||||
{"-9", _ kmMin9th, _ kmMaj9th},
|
||||
{"69", _ kmDim7th | _ kmMaj9th, 0},
|
||||
{"add9", _ kmMaj9th, 0},
|
||||
{"9", _ kmMin7th | _ kmMaj9th, 0},
|
||||
{"7", _ kmMin7th, 0},
|
||||
{"maj", _ kmMaj7th, _ kmMin7th},
|
||||
{"6", _ kmDim7th, 0},
|
||||
{"#5", _ kmAug5th, _ km5th},
|
||||
{"+5", _ kmAug5th, _ km5th},
|
||||
{"aug", _ kmAug5th, _ km5th},
|
||||
{"+", _ kmAug5th, _ km5th},
|
||||
{"b5", _ kmDim5th, _ km5th},
|
||||
{"-5", _ kmDim5th, _ km5th},
|
||||
{"sus4", _ km4th, _ kmMaj3rd},
|
||||
{"sus2", _ kmMaj2nd, _ kmMaj3rd},
|
||||
{"sus", _ km4th, _ kmMaj3rd},
|
||||
{"4", _ km4th, _ kmMaj3rd},
|
||||
{"2", _ kmMaj2nd, _ kmMaj3rd},
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
#pragma mark -
|
||||
#pragma mark class VLChord
|
||||
|
||||
VLChord::VLChord(VLFraction dur, int pitch, int rootPitch)
|
||||
: VLNote(dur, pitch), fSteps(0), fRootPitch(kNoPitch)
|
||||
|
@ -246,172 +163,40 @@ VLChord::VLChord(VLFraction dur, int pitch, int rootPitch)
|
|||
|
||||
VLChord::VLChord(std::string name)
|
||||
{
|
||||
size_t root;
|
||||
//
|
||||
// Determine key
|
||||
//
|
||||
if (const char * key = strchr(kScale, name[0]))
|
||||
fPitch = key-kScale+kMiddleC;
|
||||
else
|
||||
goto failed;
|
||||
name.erase(0, 1);
|
||||
//
|
||||
// Look for sharp / flat
|
||||
//
|
||||
if (name.size())
|
||||
if (name[0] == '#') {
|
||||
++fPitch;
|
||||
fVisual |= kWantSharp;
|
||||
name.erase(0, 1);
|
||||
} else if (name[0] == 'b') {
|
||||
--fPitch;
|
||||
fVisual |= kWantFlat;
|
||||
name.erase(0, 1);
|
||||
}
|
||||
AdjustAccidentals();
|
||||
//
|
||||
// Root
|
||||
//
|
||||
fRootPitch = kNoPitch;
|
||||
if ((root = name.find('/')) != std::string::npos) {
|
||||
if (root+1 >= name.size())
|
||||
goto failed;
|
||||
if (const char * key = strchr(kScale, name[root+1]))
|
||||
fRootPitch = key-kScale+kMiddleC-12;
|
||||
else
|
||||
goto failed;
|
||||
if (root+2 < name.size()) {
|
||||
switch (name[root+2]) {
|
||||
case 'b':
|
||||
--fRootPitch;
|
||||
break;
|
||||
case '#':
|
||||
++fRootPitch;
|
||||
break;
|
||||
default:
|
||||
goto failed;
|
||||
}
|
||||
name.erase(root, 3);
|
||||
} else
|
||||
name.erase(root, 2);
|
||||
}
|
||||
|
||||
//
|
||||
// Apply modifiers
|
||||
//
|
||||
fSteps = kmUnison | kmMaj3rd | km5th;
|
||||
|
||||
for (const VLChordModifier * mod = kModifiers; mod->fName && name.size() && name != "dim" && name != "m" && name != "-"; ++mod) {
|
||||
size_t pos = name.find(mod->fName);
|
||||
if (pos != std::string::npos) {
|
||||
name.erase(pos, strlen(mod->fName));
|
||||
fSteps &= ~mod->fDelSteps;
|
||||
fSteps |= mod->fAddSteps;
|
||||
}
|
||||
}
|
||||
if (name == "m" || name == "-") {
|
||||
fSteps = (fSteps & ~kmMaj3rd) | kmMin3rd;
|
||||
name.erase(0, 1);
|
||||
} else if (name == "dim") {
|
||||
uint32_t steps = fSteps & (kmMaj3rd | km5th | kmMin7th);
|
||||
fSteps ^= steps;
|
||||
fSteps |= steps >> 1; // Diminish 3rd, 5th, and 7th, if present
|
||||
name.erase(0, 3);
|
||||
}
|
||||
if (name == "")
|
||||
return; // Success
|
||||
failed:
|
||||
fPitch = kNoPitch;
|
||||
fPitch = VLParseChord(name, &fVisual, &fSteps, &fRootPitch, &fRootAccidental);
|
||||
|
||||
if (fPitch < 0)
|
||||
fPitch = kNoPitch;
|
||||
}
|
||||
|
||||
static const char * kStepNames[] = {
|
||||
"", "", "sus2", "", "", "sus", kVLFlatStr "5", "", kVLSharpStr "5", "6",
|
||||
"7", kVLSharpStr "7", "", kVLFlatStr "9", "9", kVLSharpStr "9", "",
|
||||
"11", kVLSharpStr "11", "", kVLFlatStr "13", "13"
|
||||
};
|
||||
|
||||
void VLChord::Name(std::string & base, std::string & ext, std::string & root, bool useSharps) const
|
||||
void VLChord::Name(std::string & base, std::string & ext, std::string & root, uint16_t accidental) const
|
||||
{
|
||||
if (fVisual & kWantSharp)
|
||||
useSharps = true;
|
||||
else if (fVisual & kWantFlat)
|
||||
useSharps = false;
|
||||
|
||||
base = PitchName(fPitch, useSharps);
|
||||
ext = "";
|
||||
root = "";
|
||||
|
||||
uint32_t steps = fSteps;
|
||||
//
|
||||
// m / dim
|
||||
//
|
||||
if (steps & kmMin3rd)
|
||||
if (steps & (kmDim5th|kmDim7th)
|
||||
&& !(steps & (km5th|kmMin7th|kmMaj7th|kmMin9th|kmMaj9th|km11th|kmAug11th|kmMin13th|kmMaj13th))
|
||||
) {
|
||||
ext += "dim";
|
||||
steps|= (steps & kmDim7th) << 1;
|
||||
steps&= ~(kmMin3rd|kmDim5th|kmDim7th);
|
||||
} else {
|
||||
base += "m";
|
||||
steps&= ~kmMin3rd;
|
||||
}
|
||||
//
|
||||
// +
|
||||
//
|
||||
steps &= ~(kmUnison | kmMaj3rd | km5th);
|
||||
if (steps == kmAug5th) {
|
||||
ext += "+";
|
||||
steps= 0;
|
||||
}
|
||||
//
|
||||
// Maj
|
||||
//
|
||||
if (steps & kmMaj7th) {
|
||||
ext += "Maj";
|
||||
steps&= ~kmMaj7th;
|
||||
steps|= kmMin7th; // Write out the 7 for clarification
|
||||
}
|
||||
//
|
||||
// 6/9
|
||||
//
|
||||
if ((steps & (kmDim7th|kmMaj9th)) == (kmDim7th|kmMaj9th)) {
|
||||
ext += "69";
|
||||
steps&= ~(kmDim7th|kmMaj9th);
|
||||
}
|
||||
//
|
||||
// Other extensions. Only the highest unaltered extension is listed.
|
||||
//
|
||||
bool has7th = steps & (kmMin7th|kmMaj7th);
|
||||
bool has9th = steps & (kmMin9th|kmMaj9th|kmAug9th);
|
||||
if ((steps & kmMaj13th) && has7th && has9th ) {
|
||||
ext += kStepNames[kMaj13th];
|
||||
steps &= ~(kmMin7th | kmMaj9th | km11th | kmMaj13th);
|
||||
} else if ((steps & km11th) && has7th && has9th) {
|
||||
ext += kStepNames[k11th];
|
||||
steps &= ~(kmMin7th | kmMaj9th | km11th);
|
||||
} else if ((steps & kmMaj9th) && has7th) {
|
||||
ext += kStepNames[kMaj9th];
|
||||
steps &= ~(kmMin7th | kmMaj9th);
|
||||
} else if (steps & kmMin7th) {
|
||||
ext += kStepNames[kMin7th];
|
||||
steps &= ~(kmMin7th);
|
||||
}
|
||||
|
||||
for (int step = kMin2nd; steps; ++step)
|
||||
if (steps & (1 << step)) {
|
||||
if ((1 << step) & (kmMaj9th|km11th|kmMaj13th))
|
||||
ext += "add";
|
||||
ext += kStepNames[step];
|
||||
steps &= ~(1 << step);
|
||||
}
|
||||
//
|
||||
// Root
|
||||
//
|
||||
if (fRootPitch != kNoPitch)
|
||||
root = PitchName(fRootPitch, useSharps);
|
||||
uint16_t pitchAccidental;
|
||||
uint16_t rootAccidental;
|
||||
uint16_t acc;
|
||||
|
||||
if ((acc = (fVisual & kAccidentalsMask)))
|
||||
if (acc == kWantNatural)
|
||||
pitchAccidental = accidental | acc;
|
||||
else
|
||||
pitchAccidental = acc;
|
||||
else
|
||||
pitchAccidental = accidental;
|
||||
if ((acc = fRootAccidental))
|
||||
if (acc == kWantNatural)
|
||||
rootAccidental = accidental | acc;
|
||||
else
|
||||
rootAccidental = acc;
|
||||
else
|
||||
rootAccidental = accidental;
|
||||
|
||||
VLChordName(fPitch, pitchAccidental, fSteps, fRootPitch, rootAccidental,
|
||||
base, ext, root);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark class VLMeasure
|
||||
|
||||
VLMeasure::VLMeasure()
|
||||
: fBreak(0), fPropIdx(0)
|
||||
{
|
||||
|
@ -574,7 +359,7 @@ void VLMeasure::DecomposeNotes(const VLProperties & prop, VLNoteList & decompose
|
|||
}
|
||||
haveDuration:
|
||||
if (p.fVisual & VLNote::kTriplet)
|
||||
if (prevTriplets = (prevTriplets+1)%3) {
|
||||
if ((prevTriplets = (prevTriplets+1)%3)) {
|
||||
prevTripDur = p.fDuration;
|
||||
prevVisual = p.fVisual;
|
||||
}
|
||||
|
@ -596,6 +381,9 @@ void VLMeasure::DecomposeNotes(const VLProperties & prop, VLNoteList & decompose
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark class VLSong
|
||||
|
||||
VLSong::VLSong(bool initialize)
|
||||
{
|
||||
if (!initialize)
|
||||
|
@ -765,8 +553,6 @@ void VLSong::AddNote(VLLyricsNote note, size_t measure, VLFraction at)
|
|||
//
|
||||
while (measure+1 >= fMeasures.size())
|
||||
AddMeasure();
|
||||
|
||||
note.AdjustAccidentals();
|
||||
|
||||
VLNoteList::iterator i = fMeasures[measure].fMelody.begin();
|
||||
VLFraction t(0);
|
||||
|
@ -1004,7 +790,6 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
|
|||
for (; i!=e; ++i) {
|
||||
TransposePinned(i->fPitch, semi);
|
||||
TransposePinned(i->fRootPitch, semi);
|
||||
i->AdjustAccidentals();
|
||||
}
|
||||
}
|
||||
for (int pass=0; pass<2 && semi;) {
|
||||
|
@ -1023,7 +808,6 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
|
|||
i->fPitch += semi;
|
||||
low = std::min(low, i->fPitch);
|
||||
high = std::max(high, i->fPitch);
|
||||
i->AdjustAccidentals();
|
||||
}
|
||||
}
|
||||
if (low < VLNote::kMiddleC-6 && high < VLNote::kMiddleC+7)
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <string>
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark class VLFraction
|
||||
|
||||
struct VLFract {
|
||||
uint16_t fNum; // Numerator
|
||||
|
@ -93,23 +95,9 @@ inline bool operator>=(VLFraction one, VLFraction other)
|
|||
return one.fNum*other.fDenom >= other.fNum*one.fDenom;
|
||||
}
|
||||
|
||||
class VLProperties;
|
||||
#pragma mark -
|
||||
#pragma mark class VLNote
|
||||
|
||||
struct VLSyllable {
|
||||
std::string fText; // Syllable text
|
||||
uint8_t fKind; // Adjacency information
|
||||
enum {
|
||||
kSingle = 0,
|
||||
kBegin = 1,
|
||||
kEnd = 2,
|
||||
kMiddle = 3,
|
||||
kHasNext = 1,
|
||||
kHasPrev = 2
|
||||
};
|
||||
|
||||
operator bool() const { return fText.size() > 0; }
|
||||
};
|
||||
|
||||
struct VLNote {
|
||||
VLFraction fDuration;
|
||||
int8_t fPitch; // Semitones
|
||||
|
@ -155,16 +143,48 @@ struct VLNote {
|
|||
kAccidentalsMask= 0x00F0,
|
||||
|
||||
kTriplet = 0x300,
|
||||
|
||||
kTupletMask = 0x0F00
|
||||
};
|
||||
VLNote(VLFraction dur=0, int pitch=kNoPitch);
|
||||
VLNote(VLFraction dur=0, int pitch=kNoPitch, uint16_t visual=0);
|
||||
VLNote(std::string name);
|
||||
void Name(std::string & name, bool useSharps = false) const;
|
||||
std::string Name(uint16_t accidentals=0) const;
|
||||
void MakeRepresentable();
|
||||
void AdjustAccidentals();
|
||||
void AlignToGrid(VLFraction at, VLFraction grid);
|
||||
};
|
||||
|
||||
#pragma mark class VLSyllable
|
||||
|
||||
struct VLSyllable {
|
||||
std::string fText; // Syllable text
|
||||
uint8_t fKind; // Adjacency information
|
||||
enum {
|
||||
kSingle = 0,
|
||||
kBegin = 1,
|
||||
kEnd = 2,
|
||||
kMiddle = 3,
|
||||
kHasNext = 1,
|
||||
kHasPrev = 2
|
||||
};
|
||||
|
||||
operator bool() const { return fText.size() > 0; }
|
||||
};
|
||||
|
||||
#pragma mark class VLLyricsNote
|
||||
|
||||
struct VLLyricsNote : VLNote {
|
||||
VLLyricsNote(const VLNote & note);
|
||||
VLLyricsNote(VLFraction dur=0, int pitch = kNoPitch, uint16_t visual=0);
|
||||
|
||||
std::vector<VLSyllable> fLyrics;
|
||||
};
|
||||
|
||||
|
||||
typedef std::list<VLLyricsNote> VLNoteList;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark VLChord
|
||||
|
||||
struct VLChord : VLNote {
|
||||
uint32_t fSteps; // Notes in chord, listed in semitones
|
||||
enum {
|
||||
|
@ -215,40 +235,42 @@ struct VLChord : VLNote {
|
|||
kmMaj13th = (1 << kMaj13th)
|
||||
};
|
||||
int8_t fRootPitch; // kNoPitch == no root
|
||||
uint16_t fRootAccidental;
|
||||
|
||||
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;
|
||||
void Name(std::string & base, std::string & ext, std::string & root, uint16_t accidental=0) const;
|
||||
};
|
||||
|
||||
typedef std::list<VLChord> VLChordList;
|
||||
|
||||
#pragma mark class VLChordModifier
|
||||
|
||||
struct VLChordModifier {
|
||||
const char * fName;
|
||||
uint32_t fAddSteps;
|
||||
uint32_t fDelSteps;
|
||||
};
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark class VLProperties
|
||||
|
||||
struct VLProperties {
|
||||
VLFraction fTime; // Time (non-normalized)
|
||||
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
|
||||
std::string fGroove; // MMA Groove
|
||||
|
||||
|
||||
bool operator==(const VLProperties & other)
|
||||
{ return fTime == other.fTime && fKey == other.fKey && fMode == other.fMode
|
||||
&& fDivisions == other.fDivisions && fGroove == other.fGroove;
|
||||
&& fDivisions == other.fDivisions && fGroove == other.fGroove;
|
||||
}
|
||||
};
|
||||
|
||||
struct VLLyricsNote : VLNote {
|
||||
VLLyricsNote(const VLNote & note);
|
||||
VLLyricsNote(VLFraction dur=0, int pitch = kNoPitch);
|
||||
typedef std::vector<VLProperties> VLPropertyList;
|
||||
|
||||
std::vector<VLSyllable> fLyrics;
|
||||
};
|
||||
|
||||
typedef std::list<VLChord> VLChordList;
|
||||
typedef std::list<VLLyricsNote> VLNoteList;
|
||||
#pragma mark class VLMeasure
|
||||
|
||||
struct VLMeasure {
|
||||
enum {
|
||||
|
@ -268,6 +290,10 @@ struct VLMeasure {
|
|||
void DecomposeNotes(const VLProperties & prop, VLNoteList & decomposed) const;
|
||||
};
|
||||
|
||||
typedef std::vector<VLMeasure> VLMeasureList;
|
||||
|
||||
#pragma mark class VLRepeat
|
||||
|
||||
struct VLRepeat {
|
||||
int8_t fTimes;
|
||||
|
||||
|
@ -281,10 +307,11 @@ struct VLRepeat {
|
|||
std::vector<Ending> fEndings;
|
||||
};
|
||||
|
||||
typedef std::vector<VLProperties> VLPropertyList;
|
||||
typedef std::vector<VLMeasure> VLMeasureList;
|
||||
typedef std::vector<VLRepeat> VLRepeatList;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark class VLSong
|
||||
|
||||
class VLSong {
|
||||
public:
|
||||
VLSong(bool initialize = true);
|
||||
|
@ -400,6 +427,8 @@ private:
|
|||
void AddMeasure();
|
||||
};
|
||||
|
||||
#pragma mark class VLSongVisitor
|
||||
|
||||
class VLSongVisitor {
|
||||
public:
|
||||
virtual ~VLSongVisitor();
|
||||
|
|
|
@ -245,7 +245,7 @@ enum {
|
|||
true);
|
||||
note.fPitch = [[ndict objectForKey:@"pitch"] intValue];
|
||||
note.fVisual |= [[ndict objectForKey:@"visual"] intValue]
|
||||
& VLNote::kAccidentals;
|
||||
& VLNote::kAccidentalsMask;
|
||||
note.fTied = 0;
|
||||
|
||||
if ([[ndict objectForKey:@"tied"] intValue] & VLNote::kTiedWithPrev) {
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2006-2007 Matthias Neeracher
|
||||
// Copyright © 2006-2011 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import "VLPitchTransformer.h"
|
||||
#import "VLModel.h"
|
||||
#import "VLPitchName.h"
|
||||
|
||||
@implementation VLPitchTransformer
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ VLMusicElement sSemi2Accidental[13][12] = {
|
|||
{
|
||||
int semi = pitch % 12;
|
||||
int key = [self song]->fProperties[section].fKey;
|
||||
bool useSharps = (visual & VLNote::kAccidentals)
|
||||
bool useSharps = (visual & VLNote::kAccidentalsMask)
|
||||
? (visual & VLNote::kWantSharp) : (key > 0);
|
||||
|
||||
return sSemi2Pitch[useSharps][semi];
|
||||
|
@ -525,7 +525,7 @@ const char * sBreak[3] = {"", "\xE2\xA4\xBE", "\xE2\x8E\x98"};
|
|||
NSArray * colors = [NSColor controlAlternatingRowBackgroundColors];
|
||||
NSColor * color= [colors objectAtIndex:1];
|
||||
if (kAltColors) {
|
||||
float hue, saturation, brightness, alpha;
|
||||
CGFloat hue, saturation, brightness, alpha;
|
||||
|
||||
[[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getHue:&hue saturation:&saturation
|
||||
brightness:&brightness alpha:&alpha];
|
||||
|
|
|
@ -26,16 +26,6 @@ std::string NormalizeName(NSString* rawName)
|
|||
for (;;) {
|
||||
size_t found;
|
||||
|
||||
found = chordName.find(kVLSharpStr, 0, 3);
|
||||
if (found != std::string::npos) {
|
||||
chordName.replace(found, 3, 1, '#');
|
||||
continue;
|
||||
}
|
||||
found = chordName.find(kVLFlatStr, 0, 3);
|
||||
if (found != std::string::npos) {
|
||||
chordName.replace(found, 3, 1, 'b');
|
||||
continue;
|
||||
}
|
||||
found = chordName.find(" ", 0, 1);
|
||||
if (found != std::string::npos) {
|
||||
chordName.erase(found);
|
||||
|
|
|
@ -185,7 +185,7 @@
|
|||
// Draw note head
|
||||
//
|
||||
NSImage * head;
|
||||
switch (visual & VLNote::kNoteHead) {
|
||||
switch (visual & VLNote::kNoteHeadMask) {
|
||||
case VLNote::kWhole:
|
||||
head = [self musicElement:kMusicWholeNote];
|
||||
break;
|
||||
|
@ -341,11 +341,11 @@
|
|||
const VLSong * song = [self song];
|
||||
const VLProperties & kProp = song->Properties(kFirstMeas);
|
||||
const VLSystemLayout & kLayout = (*fLayout)[system];
|
||||
const float kSystemY = [self systemY:system];
|
||||
const CGFloat kSystemY = [self systemY:system];
|
||||
|
||||
float tripletStartX;
|
||||
float tripletEndX;
|
||||
float tripletY;
|
||||
CGFloat tripletY;
|
||||
bool hasTriplets = false;
|
||||
|
||||
for (int m = 0; m<kLayout.NumMeasures(); ++m) {
|
||||
|
@ -388,7 +388,7 @@
|
|||
acc = kProp.fKey < 0 ? kMusicFlat : kMusicSharp;
|
||||
else
|
||||
acc = kMusicNatural;
|
||||
[self drawNote:note->fVisual & VLNote::kNoteHead
|
||||
[self drawNote:note->fVisual & VLNote::kNoteHeadMask
|
||||
at: pos
|
||||
accidental: acc
|
||||
tied:tied];
|
||||
|
@ -399,7 +399,7 @@
|
|||
kSystemY+[self noteYInSection:measure.fPropIdx
|
||||
withPitch:65 visual:0
|
||||
accidental:&accidental]);
|
||||
[self drawRest:note->fVisual & VLNote::kNoteHead at: pos];
|
||||
[self drawRest:note->fVisual & VLNote::kNoteHeadMask at: pos];
|
||||
}
|
||||
if (note->fVisual & VLNote::kTriplet) {
|
||||
tripletEndX = pos.x+kNoteW*0.5f;
|
||||
|
|
|
@ -71,6 +71,11 @@
|
|||
95A1C3860AF2ACE20076597D /* VLSheetWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */; };
|
||||
95A55C540BD5E5770068A203 /* VLPDFDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A55C530BD5E5770068A203 /* VLPDFDocument.mm */; };
|
||||
95AC700014094108007EA050 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC6FFF14094107007EA050 /* Cocoa.framework */; };
|
||||
95AC700114099A60007EA050 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC6FFF14094107007EA050 /* Cocoa.framework */; };
|
||||
95AC700414099C64007EA050 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC700214099C64007EA050 /* AudioToolbox.framework */; };
|
||||
95AC700514099C64007EA050 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC700314099C64007EA050 /* AudioUnit.framework */; };
|
||||
95AC700714099CF0007EA050 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC700614099CF0007EA050 /* Quartz.framework */; };
|
||||
95AC70091409A291007EA050 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC70081409A291007EA050 /* Carbon.framework */; };
|
||||
95B3E1A70960E58B000E9C0D /* Music in Resources */ = {isa = PBXBuildFile; fileRef = 95B3E1980960E58B000E9C0D /* Music */; };
|
||||
95B66658096BCA1F00FE18C9 /* VLSheetViewNotes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */; };
|
||||
95BDA15909540BF1009F9D65 /* VLSheetView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95BDA15809540BF1009F9D65 /* VLSheetView.mm */; };
|
||||
|
@ -251,6 +256,10 @@
|
|||
95A55C520BD5E5760068A203 /* VLPDFDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLPDFDocument.h; path = Sources/VLPDFDocument.h; sourceTree = "<group>"; };
|
||||
95A55C530BD5E5770068A203 /* VLPDFDocument.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLPDFDocument.mm; path = Sources/VLPDFDocument.mm; sourceTree = "<group>"; };
|
||||
95AC6FFF14094107007EA050 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
|
||||
95AC700214099C64007EA050 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; };
|
||||
95AC700314099C64007EA050 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/AudioUnit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
95AC700614099CF0007EA050 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Quartz.framework; sourceTree = DEVELOPER_DIR; };
|
||||
95AC70081409A291007EA050 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; };
|
||||
95B3E1980960E58B000E9C0D /* Music */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Music; path = Resources/Music; sourceTree = "<group>"; };
|
||||
95B66653096BC6A100FE18C9 /* VLSheetViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSheetViewInternal.h; path = Sources/VLSheetViewInternal.h; sourceTree = "<group>"; };
|
||||
95B66656096BCA1F00FE18C9 /* VLSheetViewNotes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLSheetViewNotes.h; path = Sources/VLSheetViewNotes.h; sourceTree = "<group>"; };
|
||||
|
@ -310,6 +319,11 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
95AC70091409A291007EA050 /* Carbon.framework in Frameworks */,
|
||||
95AC700714099CF0007EA050 /* Quartz.framework in Frameworks */,
|
||||
95AC700414099C64007EA050 /* AudioToolbox.framework in Frameworks */,
|
||||
95AC700514099C64007EA050 /* AudioUnit.framework in Frameworks */,
|
||||
95AC700114099A60007EA050 /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -445,6 +459,10 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
95AC6FFF14094107007EA050 /* Cocoa.framework */,
|
||||
95AC70081409A291007EA050 /* Carbon.framework */,
|
||||
95AC700214099C64007EA050 /* AudioToolbox.framework */,
|
||||
95AC700314099C64007EA050 /* AudioUnit.framework */,
|
||||
95AC700614099CF0007EA050 /* Quartz.framework */,
|
||||
95CFA8481409291500D0DB0D /* SenTestingKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
|
|
Loading…
Reference in New Issue
Block a user