mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 03:04:00 +00:00
Successfully round trip double accidentals
This commit is contained in:
parent
a2b1a1e991
commit
ffdc41e1d7
|
@ -348,6 +348,10 @@ class MusicXMLListener
|
|||
@note['visual'] = VL::WantSharp
|
||||
when 'flat'
|
||||
@note['visual'] = VL::WantFlat
|
||||
when 'double-sharp'
|
||||
@note['visual'] = VL::Want2Sharp
|
||||
when 'flat-flat'
|
||||
@note['visual'] = VL::Want2Flat
|
||||
end
|
||||
when 'root-step'
|
||||
@note['pitch'] = PITCH[@text]
|
||||
|
|
|
@ -9,7 +9,6 @@ require 'rexml/document'
|
|||
|
||||
INPUT = readPlist(INFILE)
|
||||
|
||||
$USE_FLATS = false
|
||||
$DIVISIONS = 3
|
||||
|
||||
def newTextElement(name, text)
|
||||
|
@ -59,7 +58,6 @@ def _part_list
|
|||
end
|
||||
|
||||
def _attributes(prop)
|
||||
$USE_FLATS = prop['key'] <= 0
|
||||
$DIVISIONS = prop['divisions']
|
||||
attr = REXML::Element.new('attributes')
|
||||
attr.add_element newTextElement('divisions', prop['divisions'])
|
||||
|
@ -100,28 +98,23 @@ def _tempo(tempo)
|
|||
return dir
|
||||
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="")
|
||||
pitch-= accidental
|
||||
oct = pitch/12 - 1
|
||||
stp = 2*(pitch%12)
|
||||
stp = (pitch%12)+2
|
||||
step = STEPS[stp]
|
||||
alt = STEPS[stp+1] == ?b
|
||||
if alt
|
||||
if preferFlats
|
||||
alt = -1
|
||||
else
|
||||
step = step == ?A ? ?G : step-1
|
||||
alt = 1
|
||||
end
|
||||
if step == 0x20
|
||||
abort "Pitch #{pitch} not representable"
|
||||
end
|
||||
if prefix.length > 0
|
||||
prefix += "-"
|
||||
end
|
||||
pitch= REXML::Element.new(name)
|
||||
pitch.add_element newTextElement(prefix+'step', step.chr)
|
||||
if alt
|
||||
pitch.add_element newTextElement(prefix+'alter', alt)
|
||||
if accidental != 0
|
||||
pitch.add_element newTextElement(prefix+'alter', accidental)
|
||||
end
|
||||
if prefix.length == 0
|
||||
pitch.add_element newTextElement('octave', oct)
|
||||
|
@ -130,28 +123,28 @@ def _pitch(name, pitch, preferFlats, prefix="")
|
|||
return pitch
|
||||
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]
|
||||
ACC = %w[flat-flat flat natural sharp double-sharp]
|
||||
|
||||
def _note(pitch, dur, visual, tied)
|
||||
preferFlats = (visual & VL::WantSharp) == 0 &&
|
||||
((visual & VL::WantFlat) != 0 || $USE_FLATS)
|
||||
accidental = nil
|
||||
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')
|
||||
if pitch == VL::NoPitch
|
||||
note.add_element(REXML::Element.new('rest'))
|
||||
else
|
||||
if (tied & VL::InChord) != 0
|
||||
note.add_element 'chord'
|
||||
end
|
||||
note.add_element(_pitch('pitch', pitch, preferFlats))
|
||||
note.add_element(_pitch('pitch', pitch, accidental))
|
||||
end
|
||||
note.add_element newTextElement('duration', dur)
|
||||
if (tied & VL::TiedWithPrev) != 0
|
||||
|
@ -162,8 +155,8 @@ def _note(pitch, dur, visual, tied)
|
|||
end
|
||||
note.add_element newTextElement('voice', 1)
|
||||
note.add_element newTextElement('type', TYPE[visual & 7])
|
||||
if (visual & (VL::WantSharp | VL::WantFlat)) != 0
|
||||
_addAccidental(note, pitch, preferFlats)
|
||||
if accidental
|
||||
note.add_element newTextElement('accidental', ACC[accidental+2])
|
||||
end
|
||||
|
||||
return note
|
||||
|
|
|
@ -7,9 +7,12 @@ class VL
|
|||
|
||||
TiedWithNext = 1
|
||||
TiedWithPrev = 2
|
||||
WantSharp = 0x20
|
||||
WantSharp = 0x10
|
||||
Want2Sharp = 0x20
|
||||
WantFlat = 0x40
|
||||
InChord = 4
|
||||
Want2Flat = 0x80
|
||||
WantNatural = 0x50
|
||||
Accidentals = 0xF0
|
||||
|
||||
Unison = 1<<0
|
||||
Min2nd = 1<<1
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "VLModel.h"
|
||||
#include "VLPitchName.h"
|
||||
#include "VLPitchGrid.h"
|
||||
|
||||
#pragma mark class VLFraction
|
||||
|
||||
|
@ -548,6 +549,11 @@ uint8_t & LastTie(VLMeasure & measure)
|
|||
//
|
||||
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
|
||||
//
|
||||
|
@ -771,9 +777,17 @@ static void TransposePinned(int8_t & pitch, int semi)
|
|||
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)
|
||||
{
|
||||
VLProperties & prop = fProperties[section];
|
||||
bool flipAcc= newKey*prop.fKey < 0;
|
||||
int semi = 7*(newKey-prop.fKey) % 12;
|
||||
prop.fKey = newKey;
|
||||
prop.fMode = newMode;
|
||||
|
@ -790,6 +804,10 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
|
|||
for (; i!=e; ++i) {
|
||||
TransposePinned(i->fPitch, semi);
|
||||
TransposePinned(i->fRootPitch, semi);
|
||||
if (flipAcc) {
|
||||
FlipAccidentals(i->fVisual);
|
||||
FlipAccidentals(i->fRootAccidental);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
continue;
|
||||
i->fPitch += semi;
|
||||
if (flipAcc)
|
||||
FlipAccidentals(i->fVisual);
|
||||
low = std::min(low, 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
|
||||
else
|
||||
break; // Looks like we're done
|
||||
flipAcc = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#import "VLPListDocument.h"
|
||||
#import "VLModel.h"
|
||||
#import "VLPitchGrid.h"
|
||||
|
||||
//
|
||||
// To convert from and to complex file formats, we use ruby scripts operating
|
||||
|
@ -40,6 +41,7 @@ protected:
|
|||
NSMutableArray * fChords;
|
||||
bool fPerfOrder;
|
||||
const VLSong * fSong;
|
||||
VLVisualFilter fVisFilter;
|
||||
};
|
||||
|
||||
NSArray * VLPlistVisitor::EncodeProperties(const std::vector<VLProperties> & properties)
|
||||
|
@ -80,6 +82,7 @@ void VLPlistVisitor::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
|
|||
fNotes = [NSMutableArray arrayWithCapacity:1];
|
||||
fChords= [NSMutableArray arrayWithCapacity:1];
|
||||
|
||||
fVisFilter.ResetWithKey(p.fKey);
|
||||
VisitNotes(meas, p, true);
|
||||
VisitChords(meas);
|
||||
|
||||
|
@ -138,13 +141,14 @@ void VLPlistVisitor::VisitNote(VLLyricsNote & n)
|
|||
nil]
|
||||
: [NSDictionary dictionary]];
|
||||
|
||||
int grid = VLPitchToGrid(n.fPitch, n.fVisual, 0);
|
||||
NSDictionary * nd =
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:n.fDuration.fNum], @"durNum",
|
||||
[NSNumber numberWithInt:n.fDuration.fDenom], @"durDenom",
|
||||
[NSNumber numberWithInt:n.fPitch], @"pitch",
|
||||
[NSNumber numberWithInt:n.fTied], @"tied",
|
||||
[NSNumber numberWithInt:n.fVisual], @"visual",
|
||||
[NSNumber numberWithInt:fVisFilter(grid, n.fVisual)], @"visual",
|
||||
ly, @"lyrics",
|
||||
nil];
|
||||
[fNotes addObject:nd];
|
||||
|
|
|
@ -80,10 +80,9 @@ static inline int8_t StepToSemi(int 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 octave = (pitch/12)-5;
|
||||
|
||||
if ((visual &= VLNote::kAccidentalsMask)) {
|
||||
//
|
||||
|
@ -91,62 +90,73 @@ int VLPitchToGrid(int8_t pitch, uint16_t & visual, int key)
|
|||
//
|
||||
switch (visual) {
|
||||
case VLNote::kWantNatural:
|
||||
if (!IsBasicNote(semi))
|
||||
if (IsBasicNote(semi))
|
||||
return visual;
|
||||
break;
|
||||
visual = 0; // Don't draw naturals unless needed
|
||||
goto computePosition;
|
||||
case VLNote::kWant2Flat:
|
||||
if (IsBasicNote(semi+2)) {
|
||||
semi += 2;
|
||||
goto computePosition;
|
||||
}
|
||||
visual = VLNote::kWantFlat;
|
||||
goto flatIsPossible;
|
||||
if (IsBasicNote(semi+2))
|
||||
return visual;
|
||||
else
|
||||
return VLNote::kWantFlat;
|
||||
case VLNote::kWantFlat:
|
||||
if (!IsBasicNote(semi+1))
|
||||
if (IsBasicNote(semi+1))
|
||||
return visual;
|
||||
break;
|
||||
flatIsPossible:
|
||||
semi += 1;
|
||||
if (key < 0 && HasFlat(semi, key))
|
||||
visual = 0;
|
||||
goto computePosition;
|
||||
case VLNote::kWant2Sharp:
|
||||
if (IsBasicNote(semi-2)) {
|
||||
semi -= 2;
|
||||
goto computePosition;
|
||||
}
|
||||
visual = VLNote::kWantSharp;
|
||||
goto sharpIsPossible;
|
||||
if (IsBasicNote(semi-2))
|
||||
return visual;
|
||||
else
|
||||
return VLNote::kWantSharp;
|
||||
case VLNote::kWantSharp:
|
||||
if (!IsBasicNote(semi-1))
|
||||
if (IsBasicNote(semi-1))
|
||||
return visual;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
sharpIsPossible:
|
||||
semi -= 1;
|
||||
if (key > 0 && HasSharp(semi, key))
|
||||
visual = 0;
|
||||
goto computePosition;
|
||||
}
|
||||
}
|
||||
//
|
||||
// No visuals, or no match
|
||||
//
|
||||
visual = 0;
|
||||
if (IsBasicNote(semi)) {
|
||||
if (key < 0 ? HasFlat(semi, key) : key > 0 && HasSharp(semi, key))
|
||||
visual = VLNote::kWantNatural;
|
||||
} else if (key < 0) {
|
||||
semi += 1;
|
||||
if (!HasFlat(semi, key))
|
||||
visual = VLNote::kWantFlat;
|
||||
} else if (key > 0) {
|
||||
semi -= 1;
|
||||
if (!HasSharp(semi, key))
|
||||
visual = VLNote::kWantSharp;
|
||||
return VLNote::kWantNatural;
|
||||
} else if (key <= 0) {
|
||||
return VLNote::kWantFlat;
|
||||
} else {
|
||||
semi += 1;
|
||||
visual = VLNote::kWantFlat;
|
||||
return VLNote::kWantSharp;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -192,56 +202,52 @@ int8_t VLGridToPitch(int gridPos, uint16_t visual, int key)
|
|||
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
|
||||
case -6:
|
||||
fKeyState[0] = VLNote::kWantFlat;
|
||||
fState[0] = VLNote::kWantFlat;
|
||||
case -5:
|
||||
fKeyState[5] = VLNote::kWantFlat;
|
||||
fState[5] = VLNote::kWantFlat;
|
||||
case -4:
|
||||
fKeyState[1] = VLNote::kWantFlat;
|
||||
fState[1] = VLNote::kWantFlat;
|
||||
case -3:
|
||||
fKeyState[4] = VLNote::kWantFlat;
|
||||
fState[4] = VLNote::kWantFlat;
|
||||
case -2:
|
||||
fKeyState[2] = VLNote::kWantFlat;
|
||||
fState[2] = VLNote::kWantFlat;
|
||||
case -1:
|
||||
fKeyState[6] = VLNote::kWantFlat;
|
||||
fState[6] = VLNote::kWantFlat;
|
||||
case 0:
|
||||
break;
|
||||
case 6:
|
||||
fKeyState[2] = VLNote::kWantSharp;
|
||||
fState[2] = VLNote::kWantSharp;
|
||||
case 5:
|
||||
fKeyState[5] = VLNote::kWantSharp;
|
||||
fState[5] = VLNote::kWantSharp;
|
||||
case 4:
|
||||
fKeyState[1] = VLNote::kWantSharp;
|
||||
fState[1] = VLNote::kWantSharp;
|
||||
case 3:
|
||||
fKeyState[4] = VLNote::kWantSharp;
|
||||
fState[4] = VLNote::kWantSharp;
|
||||
case 2:
|
||||
fKeyState[0] = VLNote::kWantSharp;
|
||||
fState[0] = VLNote::kWantSharp;
|
||||
case 1:
|
||||
fKeyState[3] = VLNote::kWantSharp;
|
||||
fState[3] = VLNote::kWantSharp;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memcpy(fState, fKeyState, 7*sizeof(fKeyState[0]));
|
||||
}
|
||||
|
||||
uint16_t VLVisualFilter::operator()(int gridPos, uint16_t visual)
|
||||
{
|
||||
gridPos %= 12;
|
||||
if (!visual)
|
||||
visual = fKeyState[gridPos];
|
||||
if (visual != fState[gridPos])
|
||||
if (!fState[gridPos] && visual == VLNote::kWantNatural) {
|
||||
gridPos = (gridPos+60) % 12;
|
||||
if (visual == VLNote::kWantNatural)
|
||||
visual = 0;
|
||||
} else {
|
||||
if (visual != fState[gridPos]) {
|
||||
fState[gridPos] = visual;
|
||||
if (!visual)
|
||||
visual = VLNote::kWantNatural;
|
||||
fState[gridPos] = visual==VLNote::kWantNatural ? 0 : visual;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
visual = 0;
|
||||
}
|
||||
return visual;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ uint16_t VLVisualInKey(int8_t pitch, int key);
|
|||
//
|
||||
// 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);
|
||||
int VLPitchToGrid(int8_t pitch, uint16_t visual, int key);
|
||||
int8_t VLGridToPitch(int gridPos, uint16_t visual, int key);
|
||||
|
||||
//
|
||||
|
@ -26,10 +27,10 @@ int8_t VLGridToPitch(int gridPos, uint16_t visual, int key);
|
|||
//
|
||||
class VLVisualFilter {
|
||||
public:
|
||||
VLVisualFilter(int key);
|
||||
VLVisualFilter(int key=0) { ResetWithKey(key); }
|
||||
|
||||
void ResetWithKey(int key);
|
||||
uint16_t operator()(int gridPos, uint16_t visual);
|
||||
private:
|
||||
uint16_t fState[7];
|
||||
uint16_t fKeyState[7];
|
||||
};
|
|
@ -353,7 +353,7 @@
|
|||
visual:note->fVisual
|
||||
at:NSMakePoint([self noteXInMeasure:measIdx at:at],
|
||||
kSystemY)];
|
||||
uint16_t visual = note->fVisual;
|
||||
uint16_t visual = VLPitchAccidental(note->fPitch, note->fVisual, kProp.fKey);
|
||||
pos =
|
||||
NSMakePoint([self noteXInMeasure:measIdx at:at],
|
||||
kSystemY+[self noteYInSection:measure.fPropIdx
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
|
||||
#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),\
|
||||
@"VLPitchToGrid(%d,%02x,%d)", pitch, visualIn, key);\
|
||||
STAssertEquals((uint16_t)visualOut, vis,\
|
||||
|
@ -32,47 +32,47 @@
|
|||
|
||||
- (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, 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, 0, 60, VLNote::kWantNatural, 0);
|
||||
TestPitchToGrid( 0, VLNote::kWantNatural, 60, VLNote::kWantNatural, 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( -1, VLNote::kWantSharp, 60, VLNote::kWant2Sharp, 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, -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, 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( 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, 0, 61, VLNote::kWantFlat, -4);
|
||||
TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWantFlat, -4);
|
||||
TestPitchToGrid( -1, VLNote::kWant2Sharp, 61, VLNote::kWant2Sharp, 0);
|
||||
TestPitchToGrid( 1, VLNote::kWantFlat, 61, VLNote::kWant2Flat, 0);
|
||||
|
||||
TestPitchToGrid( 1, 0, 62, 0, 0); // D, C Major
|
||||
TestPitchToGrid( 1, 0, 62, VLNote::kWantNatural, 0);
|
||||
TestPitchToGrid( 1, 0, 62, VLNote::kWantSharp, 0);
|
||||
TestPitchToGrid( 1, 0, 62, VLNote::kWantFlat, 0);
|
||||
TestPitchToGrid( 1, VLNote::kWantNatural, 62, 0, 0); // D, C Major
|
||||
TestPitchToGrid( 1, VLNote::kWantNatural, 62, VLNote::kWantNatural, 0);
|
||||
TestPitchToGrid( 1, VLNote::kWantNatural, 62, VLNote::kWantSharp, 0);
|
||||
TestPitchToGrid( 1, VLNote::kWantNatural, 62, VLNote::kWantFlat, 0);
|
||||
TestPitchToGrid( 0, VLNote::kWant2Sharp, 62, VLNote::kWant2Sharp, 0);
|
||||
TestPitchToGrid( 2, VLNote::kWant2Flat, 62, VLNote::kWant2Flat, 0);
|
||||
|
||||
TestPitchToGrid( 6, 0, 71, 0, 0); // B, C Major
|
||||
TestPitchToGrid( 6, 0, 71, VLNote::kWantNatural, 0);
|
||||
TestPitchToGrid( 6, 0, 71, VLNote::kWantSharp, 0);
|
||||
TestPitchToGrid( 6, VLNote::kWantNatural, 71, 0, 0); // B, C Major
|
||||
TestPitchToGrid( 6, VLNote::kWantNatural, 71, VLNote::kWantNatural, 0);
|
||||
TestPitchToGrid( 6, VLNote::kWantNatural, 71, VLNote::kWantSharp, 0);
|
||||
TestPitchToGrid( 7, VLNote::kWantFlat, 71, VLNote::kWantFlat, 0);
|
||||
TestPitchToGrid( 5, VLNote::kWant2Sharp, 71, VLNote::kWant2Sharp, 0);
|
||||
TestPitchToGrid( 7, VLNote::kWantFlat, 71, VLNote::kWant2Flat, 0);
|
||||
|
||||
TestPitchToGrid( 7, 0, 72, 0, 0); // Octaves
|
||||
TestPitchToGrid( 14, 0, 84, 0, 0);
|
||||
TestPitchToGrid( -7, 0, 48, 0, 0);
|
||||
TestPitchToGrid( 7, VLNote::kWantNatural, 72, 0, 0); // Octaves
|
||||
TestPitchToGrid( 14, VLNote::kWantNatural, 84, 0, 0);
|
||||
TestPitchToGrid( -7, VLNote::kWantNatural, 48, 0, 0);
|
||||
}
|
||||
|
||||
#define TestGridToPitch(pitch,grid,visualIn,key) \
|
||||
|
@ -105,12 +105,12 @@
|
|||
{
|
||||
VLVisualFilter filterBbMajor(-2);
|
||||
|
||||
TestVisualFilter(0, 0, 0, filterBbMajor);
|
||||
TestVisualFilter(0, 0, VLNote::kWantNatural, 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(0, 2, VLNote::kWantFlat, filterBbMajor);
|
||||
TestVisualFilter(VLNote::kWantSharp, 2, VLNote::kWantSharp, filterBbMajor);
|
||||
TestVisualFilter(VLNote::kWantFlat, 2, 0, filterBbMajor);
|
||||
TestVisualFilter(VLNote::kWantNatural, 2, VLNote::kWantNatural, filterBbMajor);
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue
Block a user