Refactor pitch/chord naming code

This commit is contained in:
Matthias Neeracher 2011-08-28 00:12:32 +02:00
parent f47c7d725d
commit d6ce6acd27
9 changed files with 149 additions and 328 deletions

View File

@ -249,7 +249,7 @@ static std::string EscapeSyllable(std::string syll)
static bool PreferSharps(bool globalSharps, int noteAccidentals) static bool PreferSharps(bool globalSharps, int noteAccidentals)
{ {
return (noteAccidentals & VLNote::kAccidentals) return (noteAccidentals & VLNote::kAccidentalsMask)
? (noteAccidentals & VLNote::kWantSharp) ? (noteAccidentals & VLNote::kWantSharp)
: globalSharps; : globalSharps;
} }
@ -277,10 +277,10 @@ void VLLilypondWriter::VisitNote(VLLyricsNote & n)
strcpy(duration, "."); strcpy(duration, ".");
else if (n.fVisual & VLNote::kTriplet) else if (n.fVisual & VLNote::kTriplet)
sprintf(duration, "%s\\times 2/3 { %s%d%s }", 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 else
sprintf(duration, "%s%s%d%s", 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; fAccum += duration;
fPrevNote= n; fPrevNote= n;

View File

@ -9,7 +9,9 @@
// //
#include "VLModel.h" #include "VLModel.h"
#include <ctype.h> #include "VLPitchName.h"
#pragma mark class VLFraction
VLFraction & VLFraction::Normalize() VLFraction & VLFraction::Normalize()
{ {
@ -75,75 +77,40 @@ VLFraction & VLFraction::operator%=(VLFraction other)
return *this *= other; return *this *= other;
} }
static const char kScale[] = "c d ef g a b"; #pragma mark -
#pragma mark class VLNote
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);
}
VLNote::VLNote(std::string name) VLNote::VLNote(std::string name)
{ {
// fPitch = VLParsePitch(name, 0, &fVisual);
// 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;
failed: if (!name.empty()) { // Failed to parse completely
fPitch = kNoPitch; // Failed to parse completely fPitch = kNoPitch;
fVisual= 0;
}
} }
VLNote::VLNote(VLFraction dur, int pitch) VLNote::VLNote(VLFraction dur, int pitch, uint16_t visual)
: fDuration(dur), fPitch(pitch), fTied(0), fVisual(0) : 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) if (uint16_t acc = (fVisual & kAccidentalsMask))
useSharps = true; if (acc == kWantNatural)
else if (fVisual & kWantFlat) accidental |= acc;
useSharps = false; else
accidental = acc;
name = PitchName(fPitch, useSharps); return VLPitchName(fPitch, accidental);
} }
void VLNote::MakeRepresentable() void VLNote::MakeRepresentable()
{ {
if (fDuration > 1) if (fDuration > 1)
fDuration = 1; fDuration = 1;
fVisual = kWhole | (fVisual & kAccidentals); fVisual = kWhole | (fVisual & kAccidentalsMask);
VLFraction part(1,1); VLFraction part(1,1);
VLFraction triplet(2,3); VLFraction triplet(2,3);
// //
@ -168,26 +135,6 @@ void VLNote::MakeRepresentable()
abort(); 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) void VLNote::AlignToGrid(VLFraction at, VLFraction grid)
{ {
if (at+fDuration > grid) { if (at+fDuration > grid) {
@ -201,43 +148,13 @@ VLLyricsNote::VLLyricsNote(const VLNote & note)
{ {
} }
VLLyricsNote::VLLyricsNote(VLFraction dur, int pitch) VLLyricsNote::VLLyricsNote(VLFraction dur, int pitch, uint16_t visual)
: VLNote(dur, pitch) : VLNote(dur, pitch, visual)
{ {
} }
#define _ VLChord:: #pragma mark -
#pragma mark class 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}
};
VLChord::VLChord(VLFraction dur, int pitch, int rootPitch) VLChord::VLChord(VLFraction dur, int pitch, int rootPitch)
: VLNote(dur, pitch), fSteps(0), fRootPitch(kNoPitch) : VLNote(dur, pitch), fSteps(0), fRootPitch(kNoPitch)
@ -246,172 +163,40 @@ VLChord::VLChord(VLFraction dur, int pitch, int rootPitch)
VLChord::VLChord(std::string name) VLChord::VLChord(std::string name)
{ {
size_t root; fPitch = VLParseChord(name, &fVisual, &fSteps, &fRootPitch, &fRootAccidental);
//
// Determine key if (fPitch < 0)
// fPitch = kNoPitch;
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;
} }
static const char * kStepNames[] = { void VLChord::Name(std::string & base, std::string & ext, std::string & root, uint16_t accidental) const
"", "", "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
{ {
if (fVisual & kWantSharp) uint16_t pitchAccidental;
useSharps = true; uint16_t rootAccidental;
else if (fVisual & kWantFlat) uint16_t acc;
useSharps = false;
if ((acc = (fVisual & kAccidentalsMask)))
base = PitchName(fPitch, useSharps); if (acc == kWantNatural)
ext = ""; pitchAccidental = accidental | acc;
root = ""; else
pitchAccidental = acc;
uint32_t steps = fSteps; else
// pitchAccidental = accidental;
// m / dim if ((acc = fRootAccidental))
// if (acc == kWantNatural)
if (steps & kmMin3rd) rootAccidental = accidental | acc;
if (steps & (kmDim5th|kmDim7th) else
&& !(steps & (km5th|kmMin7th|kmMaj7th|kmMin9th|kmMaj9th|km11th|kmAug11th|kmMin13th|kmMaj13th)) rootAccidental = acc;
) { else
ext += "dim"; rootAccidental = accidental;
steps|= (steps & kmDim7th) << 1;
steps&= ~(kmMin3rd|kmDim5th|kmDim7th); VLChordName(fPitch, pitchAccidental, fSteps, fRootPitch, rootAccidental,
} else { base, ext, root);
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);
} }
#pragma mark -
#pragma mark class VLMeasure
VLMeasure::VLMeasure() VLMeasure::VLMeasure()
: fBreak(0), fPropIdx(0) : fBreak(0), fPropIdx(0)
{ {
@ -574,7 +359,7 @@ void VLMeasure::DecomposeNotes(const VLProperties & prop, VLNoteList & decompose
} }
haveDuration: haveDuration:
if (p.fVisual & VLNote::kTriplet) if (p.fVisual & VLNote::kTriplet)
if (prevTriplets = (prevTriplets+1)%3) { if ((prevTriplets = (prevTriplets+1)%3)) {
prevTripDur = p.fDuration; prevTripDur = p.fDuration;
prevVisual = p.fVisual; 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) VLSong::VLSong(bool initialize)
{ {
if (!initialize) if (!initialize)
@ -765,8 +553,6 @@ void VLSong::AddNote(VLLyricsNote note, size_t measure, VLFraction at)
// //
while (measure+1 >= fMeasures.size()) while (measure+1 >= fMeasures.size())
AddMeasure(); AddMeasure();
note.AdjustAccidentals();
VLNoteList::iterator i = fMeasures[measure].fMelody.begin(); VLNoteList::iterator i = fMeasures[measure].fMelody.begin();
VLFraction t(0); VLFraction t(0);
@ -1004,7 +790,6 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
for (; i!=e; ++i) { for (; i!=e; ++i) {
TransposePinned(i->fPitch, semi); TransposePinned(i->fPitch, semi);
TransposePinned(i->fRootPitch, semi); TransposePinned(i->fRootPitch, semi);
i->AdjustAccidentals();
} }
} }
for (int pass=0; pass<2 && semi;) { 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; i->fPitch += semi;
low = std::min(low, i->fPitch); low = std::min(low, i->fPitch);
high = std::max(high, i->fPitch); high = std::max(high, i->fPitch);
i->AdjustAccidentals();
} }
} }
if (low < VLNote::kMiddleC-6 && high < VLNote::kMiddleC+7) if (low < VLNote::kMiddleC-6 && high < VLNote::kMiddleC+7)

View File

@ -13,6 +13,8 @@
#include <string> #include <string>
#include <inttypes.h> #include <inttypes.h>
#pragma mark -
#pragma mark class VLFraction
struct VLFract { struct VLFract {
uint16_t fNum; // Numerator uint16_t fNum; // Numerator
@ -93,23 +95,9 @@ inline bool operator>=(VLFraction one, VLFraction other)
return one.fNum*other.fDenom >= other.fNum*one.fDenom; 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 { struct VLNote {
VLFraction fDuration; VLFraction fDuration;
int8_t fPitch; // Semitones int8_t fPitch; // Semitones
@ -155,16 +143,48 @@ struct VLNote {
kAccidentalsMask= 0x00F0, kAccidentalsMask= 0x00F0,
kTriplet = 0x300, kTriplet = 0x300,
kTupletMask = 0x0F00 kTupletMask = 0x0F00
}; };
VLNote(VLFraction dur=0, int pitch=kNoPitch); VLNote(VLFraction dur=0, int pitch=kNoPitch, uint16_t visual=0);
VLNote(std::string name); VLNote(std::string name);
void Name(std::string & name, bool useSharps = false) const; std::string Name(uint16_t accidentals=0) const;
void MakeRepresentable(); void MakeRepresentable();
void AdjustAccidentals();
void AlignToGrid(VLFraction at, VLFraction grid); 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 { struct VLChord : VLNote {
uint32_t fSteps; // Notes in chord, listed in semitones uint32_t fSteps; // Notes in chord, listed in semitones
enum { enum {
@ -215,40 +235,42 @@ struct VLChord : VLNote {
kmMaj13th = (1 << kMaj13th) kmMaj13th = (1 << kMaj13th)
}; };
int8_t fRootPitch; // kNoPitch == no root int8_t fRootPitch; // kNoPitch == no root
uint16_t fRootAccidental;
VLChord(VLFraction dur=0, int pitch=kNoPitch, int rootPitch=kNoPitch); VLChord(VLFraction dur=0, int pitch=kNoPitch, int rootPitch=kNoPitch);
VLChord(std::string name); 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 { struct VLChordModifier {
const char * fName; const char * fName;
uint32_t fAddSteps; uint32_t fAddSteps;
uint32_t fDelSteps; uint32_t fDelSteps;
}; };
#pragma mark -
#pragma mark class VLProperties
struct VLProperties { struct VLProperties {
VLFraction fTime; // Time (non-normalized) VLFraction fTime; // Time (non-normalized)
int8_t fKey; // Circle of fifths from C, >0 sharps, <0 flats int8_t fKey; // Circle of fifths from C, >0 sharps, <0 flats
int8_t fMode; // 1 = major -1 = minor int8_t fMode; // 1 = major -1 = minor
int8_t fDivisions; // Number of divisions per quarter note int8_t fDivisions; // Number of divisions per quarter note
std::string fGroove; // MMA Groove std::string fGroove; // MMA Groove
bool operator==(const VLProperties & other) bool operator==(const VLProperties & other)
{ return fTime == other.fTime && fKey == other.fKey && fMode == other.fMode { 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 { typedef std::vector<VLProperties> VLPropertyList;
VLLyricsNote(const VLNote & note);
VLLyricsNote(VLFraction dur=0, int pitch = kNoPitch);
std::vector<VLSyllable> fLyrics; #pragma mark class VLMeasure
};
typedef std::list<VLChord> VLChordList;
typedef std::list<VLLyricsNote> VLNoteList;
struct VLMeasure { struct VLMeasure {
enum { enum {
@ -268,6 +290,10 @@ struct VLMeasure {
void DecomposeNotes(const VLProperties & prop, VLNoteList & decomposed) const; void DecomposeNotes(const VLProperties & prop, VLNoteList & decomposed) const;
}; };
typedef std::vector<VLMeasure> VLMeasureList;
#pragma mark class VLRepeat
struct VLRepeat { struct VLRepeat {
int8_t fTimes; int8_t fTimes;
@ -281,10 +307,11 @@ struct VLRepeat {
std::vector<Ending> fEndings; std::vector<Ending> fEndings;
}; };
typedef std::vector<VLProperties> VLPropertyList;
typedef std::vector<VLMeasure> VLMeasureList;
typedef std::vector<VLRepeat> VLRepeatList; typedef std::vector<VLRepeat> VLRepeatList;
#pragma mark -
#pragma mark class VLSong
class VLSong { class VLSong {
public: public:
VLSong(bool initialize = true); VLSong(bool initialize = true);
@ -400,6 +427,8 @@ private:
void AddMeasure(); void AddMeasure();
}; };
#pragma mark class VLSongVisitor
class VLSongVisitor { class VLSongVisitor {
public: public:
virtual ~VLSongVisitor(); virtual ~VLSongVisitor();

View File

@ -245,7 +245,7 @@ enum {
true); true);
note.fPitch = [[ndict objectForKey:@"pitch"] intValue]; note.fPitch = [[ndict objectForKey:@"pitch"] intValue];
note.fVisual |= [[ndict objectForKey:@"visual"] intValue] note.fVisual |= [[ndict objectForKey:@"visual"] intValue]
& VLNote::kAccidentals; & VLNote::kAccidentalsMask;
note.fTied = 0; note.fTied = 0;
if ([[ndict objectForKey:@"tied"] intValue] & VLNote::kTiedWithPrev) { if ([[ndict objectForKey:@"tied"] intValue] & VLNote::kTiedWithPrev) {

View File

@ -5,11 +5,11 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2006-2007 Matthias Neeracher // Copyright © 2006-2011 Matthias Neeracher
// //
#import "VLPitchTransformer.h" #import "VLPitchTransformer.h"
#import "VLModel.h" #import "VLPitchName.h"
@implementation VLPitchTransformer @implementation VLPitchTransformer

View File

@ -179,7 +179,7 @@ VLMusicElement sSemi2Accidental[13][12] = {
{ {
int semi = pitch % 12; int semi = pitch % 12;
int key = [self song]->fProperties[section].fKey; int key = [self song]->fProperties[section].fKey;
bool useSharps = (visual & VLNote::kAccidentals) bool useSharps = (visual & VLNote::kAccidentalsMask)
? (visual & VLNote::kWantSharp) : (key > 0); ? (visual & VLNote::kWantSharp) : (key > 0);
return sSemi2Pitch[useSharps][semi]; return sSemi2Pitch[useSharps][semi];
@ -525,7 +525,7 @@ const char * sBreak[3] = {"", "\xE2\xA4\xBE", "\xE2\x8E\x98"};
NSArray * colors = [NSColor controlAlternatingRowBackgroundColors]; NSArray * colors = [NSColor controlAlternatingRowBackgroundColors];
NSColor * color= [colors objectAtIndex:1]; NSColor * color= [colors objectAtIndex:1];
if (kAltColors) { if (kAltColors) {
float hue, saturation, brightness, alpha; CGFloat hue, saturation, brightness, alpha;
[[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getHue:&hue saturation:&saturation [[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getHue:&hue saturation:&saturation
brightness:&brightness alpha:&alpha]; brightness:&brightness alpha:&alpha];

View File

@ -26,16 +26,6 @@ std::string NormalizeName(NSString* rawName)
for (;;) { for (;;) {
size_t found; 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); found = chordName.find(" ", 0, 1);
if (found != std::string::npos) { if (found != std::string::npos) {
chordName.erase(found); chordName.erase(found);

View File

@ -185,7 +185,7 @@
// Draw note head // Draw note head
// //
NSImage * head; NSImage * head;
switch (visual & VLNote::kNoteHead) { switch (visual & VLNote::kNoteHeadMask) {
case VLNote::kWhole: case VLNote::kWhole:
head = [self musicElement:kMusicWholeNote]; head = [self musicElement:kMusicWholeNote];
break; break;
@ -341,11 +341,11 @@
const VLSong * song = [self song]; const VLSong * song = [self song];
const VLProperties & kProp = song->Properties(kFirstMeas); const VLProperties & kProp = song->Properties(kFirstMeas);
const VLSystemLayout & kLayout = (*fLayout)[system]; const VLSystemLayout & kLayout = (*fLayout)[system];
const float kSystemY = [self systemY:system]; const CGFloat kSystemY = [self systemY:system];
float tripletStartX; float tripletStartX;
float tripletEndX; float tripletEndX;
float tripletY; CGFloat tripletY;
bool hasTriplets = false; bool hasTriplets = false;
for (int m = 0; m<kLayout.NumMeasures(); ++m) { for (int m = 0; m<kLayout.NumMeasures(); ++m) {
@ -388,7 +388,7 @@
acc = kProp.fKey < 0 ? kMusicFlat : kMusicSharp; acc = kProp.fKey < 0 ? kMusicFlat : kMusicSharp;
else else
acc = kMusicNatural; acc = kMusicNatural;
[self drawNote:note->fVisual & VLNote::kNoteHead [self drawNote:note->fVisual & VLNote::kNoteHeadMask
at: pos at: pos
accidental: acc accidental: acc
tied:tied]; tied:tied];
@ -399,7 +399,7 @@
kSystemY+[self noteYInSection:measure.fPropIdx kSystemY+[self noteYInSection:measure.fPropIdx
withPitch:65 visual:0 withPitch:65 visual:0
accidental:&accidental]); accidental:&accidental]);
[self drawRest:note->fVisual & VLNote::kNoteHead at: pos]; [self drawRest:note->fVisual & VLNote::kNoteHeadMask at: pos];
} }
if (note->fVisual & VLNote::kTriplet) { if (note->fVisual & VLNote::kTriplet) {
tripletEndX = pos.x+kNoteW*0.5f; tripletEndX = pos.x+kNoteW*0.5f;

View File

@ -71,6 +71,11 @@
95A1C3860AF2ACE20076597D /* VLSheetWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */; }; 95A1C3860AF2ACE20076597D /* VLSheetWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */; };
95A55C540BD5E5770068A203 /* VLPDFDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A55C530BD5E5770068A203 /* VLPDFDocument.mm */; }; 95A55C540BD5E5770068A203 /* VLPDFDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A55C530BD5E5770068A203 /* VLPDFDocument.mm */; };
95AC700014094108007EA050 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC6FFF14094107007EA050 /* Cocoa.framework */; }; 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 */; }; 95B3E1A70960E58B000E9C0D /* Music in Resources */ = {isa = PBXBuildFile; fileRef = 95B3E1980960E58B000E9C0D /* Music */; };
95B66658096BCA1F00FE18C9 /* VLSheetViewNotes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */; }; 95B66658096BCA1F00FE18C9 /* VLSheetViewNotes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */; };
95BDA15909540BF1009F9D65 /* VLSheetView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95BDA15809540BF1009F9D65 /* VLSheetView.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>"; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( 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; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -445,6 +459,10 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
95AC6FFF14094107007EA050 /* Cocoa.framework */, 95AC6FFF14094107007EA050 /* Cocoa.framework */,
95AC70081409A291007EA050 /* Carbon.framework */,
95AC700214099C64007EA050 /* AudioToolbox.framework */,
95AC700314099C64007EA050 /* AudioUnit.framework */,
95AC700614099CF0007EA050 /* Quartz.framework */,
95CFA8481409291500D0DB0D /* SenTestingKit.framework */, 95CFA8481409291500D0DB0D /* SenTestingKit.framework */,
); );
name = Frameworks; name = Frameworks;