Successfully round trip double accidentals

This commit is contained in:
Matthias Neeracher 2011-08-28 20:47:25 +02:00
parent a2b1a1e991
commit ffdc41e1d7
9 changed files with 175 additions and 143 deletions

View File

@ -348,6 +348,10 @@ class MusicXMLListener
@note['visual'] = VL::WantSharp @note['visual'] = VL::WantSharp
when 'flat' when 'flat'
@note['visual'] = VL::WantFlat @note['visual'] = VL::WantFlat
when 'double-sharp'
@note['visual'] = VL::Want2Sharp
when 'flat-flat'
@note['visual'] = VL::Want2Flat
end end
when 'root-step' when 'root-step'
@note['pitch'] = PITCH[@text] @note['pitch'] = PITCH[@text]

View File

@ -9,7 +9,6 @@ require 'rexml/document'
INPUT = readPlist(INFILE) INPUT = readPlist(INFILE)
$USE_FLATS = false
$DIVISIONS = 3 $DIVISIONS = 3
def newTextElement(name, text) def newTextElement(name, text)
@ -59,7 +58,6 @@ def _part_list
end end
def _attributes(prop) def _attributes(prop)
$USE_FLATS = prop['key'] <= 0
$DIVISIONS = prop['divisions'] $DIVISIONS = prop['divisions']
attr = REXML::Element.new('attributes') attr = REXML::Element.new('attributes')
attr.add_element newTextElement('divisions', prop['divisions']) attr.add_element newTextElement('divisions', prop['divisions'])
@ -100,28 +98,23 @@ def _tempo(tempo)
return dir return dir
end end
STEPS = 'C DbD EbE F GbG AbA BbB ' STEPS = ' BC D EF G A B C '
def _pitch(name, pitch, preferFlats, prefix="") def _pitch(name, pitch, accidental, prefix="")
oct = pitch/12 - 1 pitch-= accidental
stp = 2*(pitch%12) oct = pitch/12 - 1
step = STEPS[stp] stp = (pitch%12)+2
alt = STEPS[stp+1] == ?b step = STEPS[stp]
if alt if step == 0x20
if preferFlats abort "Pitch #{pitch} not representable"
alt = -1
else
step = step == ?A ? ?G : step-1
alt = 1
end
end end
if prefix.length > 0 if prefix.length > 0
prefix += "-" prefix += "-"
end end
pitch= REXML::Element.new(name) pitch= REXML::Element.new(name)
pitch.add_element newTextElement(prefix+'step', step.chr) pitch.add_element newTextElement(prefix+'step', step.chr)
if alt if accidental != 0
pitch.add_element newTextElement(prefix+'alter', alt) pitch.add_element newTextElement(prefix+'alter', accidental)
end end
if prefix.length == 0 if prefix.length == 0
pitch.add_element newTextElement('octave', oct) pitch.add_element newTextElement('octave', oct)
@ -130,28 +123,28 @@ def _pitch(name, pitch, preferFlats, prefix="")
return pitch return pitch
end end
def _addAccidental(note, pitch, preferFlats)
stp = 2*(pitch%12)
alt = STEPS[stp+1] == ?b
if alt
note.add_element newTextElement('accidental',
preferFlats ? 'flat' : 'sharp')
end
end
TYPE = %w[whole half quarter eighth 16th 32nd] TYPE = %w[whole half quarter eighth 16th 32nd]
ACC = %w[flat-flat flat natural sharp double-sharp]
def _note(pitch, dur, visual, tied) def _note(pitch, dur, visual, tied)
preferFlats = (visual & VL::WantSharp) == 0 && accidental = nil
((visual & VL::WantFlat) != 0 || $USE_FLATS) case visual & VL::Accidentals
when VL::Want2Flat
accidental = -2
when VL::WantFlat
accidental = -1
when VL::WantNatural
accidental = 0
when VL::WantSharp
accidental = 1
when VL::Want2Sharp
accidental = 2
end
note = REXML::Element.new('note') note = REXML::Element.new('note')
if pitch == VL::NoPitch if pitch == VL::NoPitch
note.add_element(REXML::Element.new('rest')) note.add_element(REXML::Element.new('rest'))
else else
if (tied & VL::InChord) != 0 note.add_element(_pitch('pitch', pitch, accidental))
note.add_element 'chord'
end
note.add_element(_pitch('pitch', pitch, preferFlats))
end end
note.add_element newTextElement('duration', dur) note.add_element newTextElement('duration', dur)
if (tied & VL::TiedWithPrev) != 0 if (tied & VL::TiedWithPrev) != 0
@ -162,8 +155,8 @@ def _note(pitch, dur, visual, tied)
end end
note.add_element newTextElement('voice', 1) note.add_element newTextElement('voice', 1)
note.add_element newTextElement('type', TYPE[visual & 7]) note.add_element newTextElement('type', TYPE[visual & 7])
if (visual & (VL::WantSharp | VL::WantFlat)) != 0 if accidental
_addAccidental(note, pitch, preferFlats) note.add_element newTextElement('accidental', ACC[accidental+2])
end end
return note return note

View File

@ -7,9 +7,12 @@ class VL
TiedWithNext = 1 TiedWithNext = 1
TiedWithPrev = 2 TiedWithPrev = 2
WantSharp = 0x20 WantSharp = 0x10
Want2Sharp = 0x20
WantFlat = 0x40 WantFlat = 0x40
InChord = 4 Want2Flat = 0x80
WantNatural = 0x50
Accidentals = 0xF0
Unison = 1<<0 Unison = 1<<0
Min2nd = 1<<1 Min2nd = 1<<1

View File

@ -10,6 +10,7 @@
#include "VLModel.h" #include "VLModel.h"
#include "VLPitchName.h" #include "VLPitchName.h"
#include "VLPitchGrid.h"
#pragma mark class VLFraction #pragma mark class VLFraction
@ -548,6 +549,11 @@ uint8_t & LastTie(VLMeasure & measure)
// //
void VLSong::AddNote(VLLyricsNote note, size_t measure, VLFraction at) void VLSong::AddNote(VLLyricsNote note, size_t measure, VLFraction at)
{ {
//
// Sanity check on accidentals
//
note.fVisual = (note.fVisual & ~VLNote::kAccidentalsMask)
| VLPitchAccidental(note.fPitch, note.fVisual, Properties(measure).fKey);
// //
// Always keep an empty measure in reserve // Always keep an empty measure in reserve
// //
@ -771,9 +777,17 @@ static void TransposePinned(int8_t & pitch, int semi)
pitch = octave+pitchInOctave; pitch = octave+pitchInOctave;
} }
static inline void FlipAccidentals(uint16_t & visual)
{
visual = (visual & ~VLNote::kAccidentalsMask)
| ((visual & VLNote::kPreferSharps) << 2)
| ((visual & VLNote::kPreferFlats) << 2);
}
void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose) void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
{ {
VLProperties & prop = fProperties[section]; VLProperties & prop = fProperties[section];
bool flipAcc= newKey*prop.fKey < 0;
int semi = 7*(newKey-prop.fKey) % 12; int semi = 7*(newKey-prop.fKey) % 12;
prop.fKey = newKey; prop.fKey = newKey;
prop.fMode = newMode; prop.fMode = newMode;
@ -790,6 +804,10 @@ 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);
if (flipAcc) {
FlipAccidentals(i->fVisual);
FlipAccidentals(i->fRootAccidental);
}
} }
} }
for (int pass=0; pass<2 && semi;) { for (int pass=0; pass<2 && semi;) {
@ -806,6 +824,8 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
if (i->fPitch == VLNote::kNoPitch) if (i->fPitch == VLNote::kNoPitch)
continue; continue;
i->fPitch += semi; i->fPitch += semi;
if (flipAcc)
FlipAccidentals(i->fVisual);
low = std::min(low, i->fPitch); low = std::min(low, i->fPitch);
high = std::max(high, i->fPitch); high = std::max(high, i->fPitch);
} }
@ -816,6 +836,7 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
semi = -12; // Transpose an Octave down semi = -12; // Transpose an Octave down
else else
break; // Looks like we're done break; // Looks like we're done
flipAcc = false;
} }
} }

View File

@ -10,6 +10,7 @@
#import "VLPListDocument.h" #import "VLPListDocument.h"
#import "VLModel.h" #import "VLModel.h"
#import "VLPitchGrid.h"
// //
// To convert from and to complex file formats, we use ruby scripts operating // To convert from and to complex file formats, we use ruby scripts operating
@ -40,6 +41,7 @@ protected:
NSMutableArray * fChords; NSMutableArray * fChords;
bool fPerfOrder; bool fPerfOrder;
const VLSong * fSong; const VLSong * fSong;
VLVisualFilter fVisFilter;
}; };
NSArray * VLPlistVisitor::EncodeProperties(const std::vector<VLProperties> & properties) NSArray * VLPlistVisitor::EncodeProperties(const std::vector<VLProperties> & properties)
@ -79,7 +81,8 @@ void VLPlistVisitor::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
{ {
fNotes = [NSMutableArray arrayWithCapacity:1]; fNotes = [NSMutableArray arrayWithCapacity:1];
fChords= [NSMutableArray arrayWithCapacity:1]; fChords= [NSMutableArray arrayWithCapacity:1];
fVisFilter.ResetWithKey(p.fKey);
VisitNotes(meas, p, true); VisitNotes(meas, p, true);
VisitChords(meas); VisitChords(meas);
@ -137,14 +140,15 @@ void VLPlistVisitor::VisitNote(VLLyricsNote & n)
[NSNumber numberWithInt:n.fLyrics[i].fKind], @"kind", [NSNumber numberWithInt:n.fLyrics[i].fKind], @"kind",
nil] nil]
: [NSDictionary dictionary]]; : [NSDictionary dictionary]];
int grid = VLPitchToGrid(n.fPitch, n.fVisual, 0);
NSDictionary * nd = NSDictionary * nd =
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:n.fDuration.fNum], @"durNum", [NSNumber numberWithInt:n.fDuration.fNum], @"durNum",
[NSNumber numberWithInt:n.fDuration.fDenom], @"durDenom", [NSNumber numberWithInt:n.fDuration.fDenom], @"durDenom",
[NSNumber numberWithInt:n.fPitch], @"pitch", [NSNumber numberWithInt:n.fPitch], @"pitch",
[NSNumber numberWithInt:n.fTied], @"tied", [NSNumber numberWithInt:n.fTied], @"tied",
[NSNumber numberWithInt:n.fVisual], @"visual", [NSNumber numberWithInt:fVisFilter(grid, n.fVisual)], @"visual",
ly, @"lyrics", ly, @"lyrics",
nil]; nil];
[fNotes addObject:nd]; [fNotes addObject:nd];

View File

@ -80,10 +80,9 @@ static inline int8_t StepToSemi(int step)
return sSemi[step]; return sSemi[step];
} }
int VLPitchToGrid(int8_t pitch, uint16_t & visual, int key) uint16_t VLPitchAccidental(int8_t pitch, uint16_t visual, int key)
{ {
int semi = pitch % 12; int semi = pitch % 12;
int octave = (pitch/12)-5;
if ((visual &= VLNote::kAccidentalsMask)) { if ((visual &= VLNote::kAccidentalsMask)) {
// //
@ -91,62 +90,73 @@ int VLPitchToGrid(int8_t pitch, uint16_t & visual, int key)
// //
switch (visual) { switch (visual) {
case VLNote::kWantNatural: case VLNote::kWantNatural:
if (!IsBasicNote(semi)) if (IsBasicNote(semi))
break; return visual;
visual = 0; // Don't draw naturals unless needed break;
goto computePosition;
case VLNote::kWant2Flat: case VLNote::kWant2Flat:
if (IsBasicNote(semi+2)) { if (IsBasicNote(semi+2))
semi += 2; return visual;
goto computePosition; else
} return VLNote::kWantFlat;
visual = VLNote::kWantFlat;
goto flatIsPossible;
case VLNote::kWantFlat: case VLNote::kWantFlat:
if (!IsBasicNote(semi+1)) if (IsBasicNote(semi+1))
break; return visual;
flatIsPossible: break;
semi += 1;
if (key < 0 && HasFlat(semi, key))
visual = 0;
goto computePosition;
case VLNote::kWant2Sharp: case VLNote::kWant2Sharp:
if (IsBasicNote(semi-2)) { if (IsBasicNote(semi-2))
semi -= 2; return visual;
goto computePosition; else
} return VLNote::kWantSharp;
visual = VLNote::kWantSharp;
goto sharpIsPossible;
case VLNote::kWantSharp: case VLNote::kWantSharp:
if (!IsBasicNote(semi-1)) if (IsBasicNote(semi-1))
break; return visual;
sharpIsPossible: break;
semi -= 1; default:
if (key > 0 && HasSharp(semi, key)) break;
visual = 0;
goto computePosition;
} }
} }
// //
// No visuals, or no match // No visuals, or no match
// //
visual = 0;
if (IsBasicNote(semi)) { if (IsBasicNote(semi)) {
if (key < 0 ? HasFlat(semi, key) : key > 0 && HasSharp(semi, key)) return VLNote::kWantNatural;
visual = VLNote::kWantNatural; } else if (key <= 0) {
} else if (key < 0) { return VLNote::kWantFlat;
semi += 1;
if (!HasFlat(semi, key))
visual = VLNote::kWantFlat;
} else if (key > 0) {
semi -= 1;
if (!HasSharp(semi, key))
visual = VLNote::kWantSharp;
} else { } else {
semi += 1; return VLNote::kWantSharp;
visual = VLNote::kWantFlat; }
}
int VLPitchToGrid(int8_t pitch, uint16_t visual, int key)
{
int semi = pitch % 12;
int octave = (pitch/12)-5;
switch (visual & VLNote::kAccidentalsMask) {
case VLNote::kWantNatural:
break;
case VLNote::kWant2Flat:
semi += 2;
break;
case VLNote::kWantFlat:
semi += 1;
break;
case VLNote::kWant2Sharp:
semi -= 2;
break;
case VLNote::kWantSharp:
semi -= 1;
break;
default:
if (IsBasicNote(semi)) {
;
} else if (key <= 0) {
semi += 1;
} else {
semi -= 1;
}
break;
} }
computePosition:
return SemiToStep(semi)+7*octave; return SemiToStep(semi)+7*octave;
} }
@ -192,56 +202,52 @@ int8_t VLGridToPitch(int gridPos, uint16_t visual, int key)
return octave+semi+accidental; return octave+semi+accidental;
} }
VLVisualFilter::VLVisualFilter(int key) void VLVisualFilter::ResetWithKey(int key)
{ {
memset(&fKeyState[0], 0, 7*sizeof(fKeyState[0])); memset(&fState[0], 0, 7*sizeof(fState[0]));
switch (key) { // Almost every state falls through switch (key) { // Almost every state falls through
case -6: case -6:
fKeyState[0] = VLNote::kWantFlat; fState[0] = VLNote::kWantFlat;
case -5: case -5:
fKeyState[5] = VLNote::kWantFlat; fState[5] = VLNote::kWantFlat;
case -4: case -4:
fKeyState[1] = VLNote::kWantFlat; fState[1] = VLNote::kWantFlat;
case -3: case -3:
fKeyState[4] = VLNote::kWantFlat; fState[4] = VLNote::kWantFlat;
case -2: case -2:
fKeyState[2] = VLNote::kWantFlat; fState[2] = VLNote::kWantFlat;
case -1: case -1:
fKeyState[6] = VLNote::kWantFlat; fState[6] = VLNote::kWantFlat;
case 0: case 0:
break; break;
case 6: case 6:
fKeyState[2] = VLNote::kWantSharp; fState[2] = VLNote::kWantSharp;
case 5: case 5:
fKeyState[5] = VLNote::kWantSharp; fState[5] = VLNote::kWantSharp;
case 4: case 4:
fKeyState[1] = VLNote::kWantSharp; fState[1] = VLNote::kWantSharp;
case 3: case 3:
fKeyState[4] = VLNote::kWantSharp; fState[4] = VLNote::kWantSharp;
case 2: case 2:
fKeyState[0] = VLNote::kWantSharp; fState[0] = VLNote::kWantSharp;
case 1: case 1:
fKeyState[3] = VLNote::kWantSharp; fState[3] = VLNote::kWantSharp;
default: default:
break; break;
} }
memcpy(fState, fKeyState, 7*sizeof(fKeyState[0]));
} }
uint16_t VLVisualFilter::operator()(int gridPos, uint16_t visual) uint16_t VLVisualFilter::operator()(int gridPos, uint16_t visual)
{ {
gridPos %= 12; gridPos = (gridPos+60) % 12;
if (!visual) if (visual == VLNote::kWantNatural)
visual = fKeyState[gridPos];
if (visual != fState[gridPos])
if (!fState[gridPos] && visual == VLNote::kWantNatural) {
visual = 0;
} else {
if (!visual)
visual = VLNote::kWantNatural;
fState[gridPos] = visual==VLNote::kWantNatural ? 0 : visual;
}
else
visual = 0; visual = 0;
if (visual != fState[gridPos]) {
fState[gridPos] = visual;
if (!visual)
visual = VLNote::kWantNatural;
} else {
visual = 0;
}
return visual; return visual;
} }

View File

@ -18,18 +18,19 @@ uint16_t VLVisualInKey(int8_t pitch, int key);
// //
// Grid position is defined from middle C // Grid position is defined from middle C
// //
int VLPitchToGrid(int8_t pitch, uint16_t & visual, int key); uint16_t VLPitchAccidental(int8_t pitch, uint16_t visual, int key);
int8_t VLGridToPitch(int gridPos, uint16_t visual, int key); int VLPitchToGrid(int8_t pitch, uint16_t visual, int key);
int8_t VLGridToPitch(int gridPos, uint16_t visual, int key);
// //
// Avoid repeating accidentals // Avoid repeating accidentals
// //
class VLVisualFilter { class VLVisualFilter {
public: public:
VLVisualFilter(int key); VLVisualFilter(int key=0) { ResetWithKey(key); }
void ResetWithKey(int key);
uint16_t operator()(int gridPos, uint16_t visual); uint16_t operator()(int gridPos, uint16_t visual);
private: private:
uint16_t fState[7]; uint16_t fState[7];
uint16_t fKeyState[7];
}; };

View File

@ -353,7 +353,7 @@
visual:note->fVisual visual:note->fVisual
at:NSMakePoint([self noteXInMeasure:measIdx at:at], at:NSMakePoint([self noteXInMeasure:measIdx at:at],
kSystemY)]; kSystemY)];
uint16_t visual = note->fVisual; uint16_t visual = VLPitchAccidental(note->fPitch, note->fVisual, kProp.fKey);
pos = pos =
NSMakePoint([self noteXInMeasure:measIdx at:at], NSMakePoint([self noteXInMeasure:measIdx at:at],
kSystemY+[self noteYInSection:measure.fPropIdx kSystemY+[self noteYInSection:measure.fPropIdx

View File

@ -23,7 +23,7 @@
} }
#define TestPitchToGrid(grid,visualOut,pitch,visualIn,key) \ #define TestPitchToGrid(grid,visualOut,pitch,visualIn,key) \
do { uint16_t vis = visualIn; \ do { uint16_t vis = VLPitchAccidental(pitch, visualIn, key); \
STAssertEquals(grid, VLPitchToGrid(pitch,vis,key),\ STAssertEquals(grid, VLPitchToGrid(pitch,vis,key),\
@"VLPitchToGrid(%d,%02x,%d)", pitch, visualIn, key);\ @"VLPitchToGrid(%d,%02x,%d)", pitch, visualIn, key);\
STAssertEquals((uint16_t)visualOut, vis,\ STAssertEquals((uint16_t)visualOut, vis,\
@ -32,47 +32,47 @@
- (void)testPitchToGrid - (void)testPitchToGrid
{ {
TestPitchToGrid( 0, 0, 60, 0, 0); // Middle C, C Major TestPitchToGrid( 0, VLNote::kWantNatural, 60, 0, 0); // Middle C, C Major
TestPitchToGrid( 0, VLNote::kWantNatural, 60, 0, 2); // Middle C, D Major TestPitchToGrid( 0, VLNote::kWantNatural, 60, 0, 2); // Middle C, D Major
TestPitchToGrid( 0, 0, 60, 0, -5); // Middle C, Db Major TestPitchToGrid( 0, VLNote::kWantNatural, 60, 0, -5); // Middle C, Db Major
TestPitchToGrid( 0, VLNote::kWantNatural, 60, 0, -6); // Middle C, Gb Major TestPitchToGrid( 0, VLNote::kWantNatural, 60, 0, -6); // Middle C, Gb Major
TestPitchToGrid( 0, 0, 60, VLNote::kWantNatural, 0); TestPitchToGrid( 0, VLNote::kWantNatural, 60, VLNote::kWantNatural, 0);
TestPitchToGrid( -1, VLNote::kWantSharp, 60, VLNote::kWantSharp, 0); TestPitchToGrid( -1, VLNote::kWantSharp, 60, VLNote::kWantSharp, 0);
TestPitchToGrid( 0, 0, 60, VLNote::kWantFlat, 0); TestPitchToGrid( 0, VLNote::kWantNatural, 60, VLNote::kWantFlat, 0);
TestPitchToGrid( 0, VLNote::kWantNatural, 60, VLNote::kWantFlat, 2); TestPitchToGrid( 0, VLNote::kWantNatural, 60, VLNote::kWantFlat, 2);
TestPitchToGrid( -1, VLNote::kWantSharp, 60, VLNote::kWant2Sharp, 0); TestPitchToGrid( -1, VLNote::kWantSharp, 60, VLNote::kWant2Sharp, 0);
TestPitchToGrid( 1, VLNote::kWant2Flat, 60, VLNote::kWant2Flat, 0); TestPitchToGrid( 1, VLNote::kWant2Flat, 60, VLNote::kWant2Flat, 0);
TestPitchToGrid( 1, VLNote::kWantFlat, 61, 0, 0); // D flat, C Major TestPitchToGrid( 1, VLNote::kWantFlat, 61, 0, 0); // D flat, C Major
TestPitchToGrid( 1, VLNote::kWantFlat, 61, 0, -1); // D flat, F Major TestPitchToGrid( 1, VLNote::kWantFlat, 61, 0, -1); // D flat, F Major
TestPitchToGrid( 1, 0, 61, 0, -4); // D flat, Ab Major TestPitchToGrid( 1, VLNote::kWantFlat, 61, 0, -4); // D flat, Ab Major
TestPitchToGrid( 0, VLNote::kWantSharp, 61, 0, 1); // D flat, G Major TestPitchToGrid( 0, VLNote::kWantSharp, 61, 0, 1); // D flat, G Major
TestPitchToGrid( 0, 0, 61, 0, 2); // D flat, D Major TestPitchToGrid( 0, VLNote::kWantSharp, 61, 0, 2); // D flat, D Major
TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWantNatural, 0); TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWantNatural, 0);
TestPitchToGrid( 0, VLNote::kWantSharp, 61, VLNote::kWantSharp, 0); TestPitchToGrid( 0, VLNote::kWantSharp, 61, VLNote::kWantSharp, 0);
TestPitchToGrid( 0, 0, 61, VLNote::kWantSharp, 2); TestPitchToGrid( 0, VLNote::kWantSharp, 61, VLNote::kWantSharp, 2);
TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWantFlat, 0); TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWantFlat, 0);
TestPitchToGrid( 1, 0, 61, VLNote::kWantFlat, -4); TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWantFlat, -4);
TestPitchToGrid( -1, VLNote::kWant2Sharp, 61, VLNote::kWant2Sharp, 0); TestPitchToGrid( -1, VLNote::kWant2Sharp, 61, VLNote::kWant2Sharp, 0);
TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWant2Flat, 0); TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWant2Flat, 0);
TestPitchToGrid( 1, 0, 62, 0, 0); // D, C Major TestPitchToGrid( 1, VLNote::kWantNatural, 62, 0, 0); // D, C Major
TestPitchToGrid( 1, 0, 62, VLNote::kWantNatural, 0); TestPitchToGrid( 1, VLNote::kWantNatural, 62, VLNote::kWantNatural, 0);
TestPitchToGrid( 1, 0, 62, VLNote::kWantSharp, 0); TestPitchToGrid( 1, VLNote::kWantNatural, 62, VLNote::kWantSharp, 0);
TestPitchToGrid( 1, 0, 62, VLNote::kWantFlat, 0); TestPitchToGrid( 1, VLNote::kWantNatural, 62, VLNote::kWantFlat, 0);
TestPitchToGrid( 0, VLNote::kWant2Sharp, 62, VLNote::kWant2Sharp, 0); TestPitchToGrid( 0, VLNote::kWant2Sharp, 62, VLNote::kWant2Sharp, 0);
TestPitchToGrid( 2, VLNote::kWant2Flat, 62, VLNote::kWant2Flat, 0); TestPitchToGrid( 2, VLNote::kWant2Flat, 62, VLNote::kWant2Flat, 0);
TestPitchToGrid( 6, 0, 71, 0, 0); // B, C Major TestPitchToGrid( 6, VLNote::kWantNatural, 71, 0, 0); // B, C Major
TestPitchToGrid( 6, 0, 71, VLNote::kWantNatural, 0); TestPitchToGrid( 6, VLNote::kWantNatural, 71, VLNote::kWantNatural, 0);
TestPitchToGrid( 6, 0, 71, VLNote::kWantSharp, 0); TestPitchToGrid( 6, VLNote::kWantNatural, 71, VLNote::kWantSharp, 0);
TestPitchToGrid( 7, VLNote::kWantFlat, 71, VLNote::kWantFlat, 0); TestPitchToGrid( 7, VLNote::kWantFlat, 71, VLNote::kWantFlat, 0);
TestPitchToGrid( 5, VLNote::kWant2Sharp, 71, VLNote::kWant2Sharp, 0); TestPitchToGrid( 5, VLNote::kWant2Sharp, 71, VLNote::kWant2Sharp, 0);
TestPitchToGrid( 7, VLNote::kWantFlat, 71, VLNote::kWant2Flat, 0); TestPitchToGrid( 7, VLNote::kWantFlat, 71, VLNote::kWant2Flat, 0);
TestPitchToGrid( 7, 0, 72, 0, 0); // Octaves TestPitchToGrid( 7, VLNote::kWantNatural, 72, 0, 0); // Octaves
TestPitchToGrid( 14, 0, 84, 0, 0); TestPitchToGrid( 14, VLNote::kWantNatural, 84, 0, 0);
TestPitchToGrid( -7, 0, 48, 0, 0); TestPitchToGrid( -7, VLNote::kWantNatural, 48, 0, 0);
} }
#define TestGridToPitch(pitch,grid,visualIn,key) \ #define TestGridToPitch(pitch,grid,visualIn,key) \
@ -105,12 +105,12 @@
{ {
VLVisualFilter filterBbMajor(-2); VLVisualFilter filterBbMajor(-2);
TestVisualFilter(0, 0, 0, filterBbMajor); TestVisualFilter(0, 0, VLNote::kWantNatural, filterBbMajor);
TestVisualFilter(VLNote::kWantFlat, 0, VLNote::kWantFlat, filterBbMajor); TestVisualFilter(VLNote::kWantFlat, 0, VLNote::kWantFlat, filterBbMajor);
TestVisualFilter(VLNote::kWantNatural, 0, 0, filterBbMajor); TestVisualFilter(VLNote::kWantNatural, 0, VLNote::kWantNatural, filterBbMajor);
TestVisualFilter(VLNote::kWantSharp, 0, VLNote::kWantSharp, filterBbMajor); TestVisualFilter(VLNote::kWantSharp, 0, VLNote::kWantSharp, filterBbMajor);
TestVisualFilter(0, 2, VLNote::kWantFlat, filterBbMajor); TestVisualFilter(0, 2, VLNote::kWantFlat, filterBbMajor);
TestVisualFilter(VLNote::kWantSharp, 2, VLNote::kWantSharp, filterBbMajor); TestVisualFilter(VLNote::kWantSharp, 2, VLNote::kWantSharp, filterBbMajor);
TestVisualFilter(VLNote::kWantFlat, 2, 0, filterBbMajor); TestVisualFilter(VLNote::kWantNatural, 2, VLNote::kWantNatural, filterBbMajor);
} }
@end @end