mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Successfully round trip accidentals in chords
This commit is contained in:
parent
ffdc41e1d7
commit
f27dc9ee8f
|
@ -305,6 +305,7 @@ class MusicXMLListener
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ACC = [VL::Want2Flat, VL::WantFlat, 0, VL::WantSharp, VL::Want2Sharp]
|
||||||
def tag_end(tag)
|
def tag_end(tag)
|
||||||
#
|
#
|
||||||
# Interesting text nodes have @kind set
|
# Interesting text nodes have @kind set
|
||||||
|
@ -331,8 +332,13 @@ class MusicXMLListener
|
||||||
@prop['mode'] = @text == 'minor' ? -1 : 1
|
@prop['mode'] = @text == 'minor' ? -1 : 1
|
||||||
when 'step'
|
when 'step'
|
||||||
@note['pitch'] += PITCH[@text]
|
@note['pitch'] += PITCH[@text]
|
||||||
when 'alter', 'root-alter'
|
when 'alter'
|
||||||
|
@note['pitch'] += @text.to_i
|
||||||
|
when 'root-alter'
|
||||||
@note['pitch'] += @text.to_i
|
@note['pitch'] += @text.to_i
|
||||||
|
if @text.to_i != 0
|
||||||
|
@note['visual'] = ACC[@text.to_i+2]
|
||||||
|
end
|
||||||
when 'octave'
|
when 'octave'
|
||||||
@note['pitch'] += (@text.to_i+1)*12
|
@note['pitch'] += (@text.to_i+1)*12
|
||||||
when 'duration'
|
when 'duration'
|
||||||
|
@ -359,6 +365,9 @@ class MusicXMLListener
|
||||||
@note['root'] = PITCH[@text]
|
@note['root'] = PITCH[@text]
|
||||||
when 'bass-alter'
|
when 'bass-alter'
|
||||||
@note['root'] += @text.to_i
|
@note['root'] += @text.to_i
|
||||||
|
if @text.to_i != 0
|
||||||
|
@note['rootvisual'] = ACC[@text.to_i+2]
|
||||||
|
end
|
||||||
when 'kind'
|
when 'kind'
|
||||||
@note['steps'] = CHORD[@text]
|
@note['steps'] = CHORD[@text]
|
||||||
when 'degree-value'
|
when 'degree-value'
|
||||||
|
|
|
@ -101,7 +101,7 @@ end
|
||||||
STEPS = ' BC D EF G A B C '
|
STEPS = ' BC D EF G A B C '
|
||||||
|
|
||||||
def _pitch(name, pitch, accidental, prefix="")
|
def _pitch(name, pitch, accidental, prefix="")
|
||||||
pitch-= accidental
|
pitch-= accidental ? accidental : 0
|
||||||
oct = pitch/12 - 1
|
oct = pitch/12 - 1
|
||||||
stp = (pitch%12)+2
|
stp = (pitch%12)+2
|
||||||
step = STEPS[stp]
|
step = STEPS[stp]
|
||||||
|
@ -126,7 +126,7 @@ 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]
|
ACC = %w[flat-flat flat natural sharp double-sharp]
|
||||||
|
|
||||||
def _note(pitch, dur, visual, tied)
|
def _accidental(visual)
|
||||||
accidental = nil
|
accidental = nil
|
||||||
case visual & VL::Accidentals
|
case visual & VL::Accidentals
|
||||||
when VL::Want2Flat
|
when VL::Want2Flat
|
||||||
|
@ -140,6 +140,11 @@ def _note(pitch, dur, visual, tied)
|
||||||
when VL::Want2Sharp
|
when VL::Want2Sharp
|
||||||
accidental = 2
|
accidental = 2
|
||||||
end
|
end
|
||||||
|
accidental
|
||||||
|
end
|
||||||
|
|
||||||
|
def _note(pitch, dur, visual, tied)
|
||||||
|
accidental = _accidental(visual)
|
||||||
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'))
|
||||||
|
@ -235,9 +240,7 @@ DEGREE = [
|
||||||
[VL::Dim13th+VL::Min13th+VL::Maj13th, VL::Maj13th]
|
[VL::Dim13th+VL::Min13th+VL::Maj13th, VL::Maj13th]
|
||||||
];
|
];
|
||||||
|
|
||||||
def _chord(pitch, visual, steps, root)
|
def _chord(pitch, visual, steps, root, rootVisual)
|
||||||
preferFlats = (visual & VL::WantSharp) == 0 &&
|
|
||||||
((visual & VL::WantFlat) != 0 || $USE_FLATS)
|
|
||||||
#
|
#
|
||||||
# Pick kind. sus takes precedence
|
# Pick kind. sus takes precedence
|
||||||
#
|
#
|
||||||
|
@ -272,10 +275,10 @@ def _chord(pitch, visual, steps, root)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
harm = REXML::Element.new('harmony')
|
harm = REXML::Element.new('harmony')
|
||||||
harm.add_element(_pitch('root', pitch, visual, 'root'))
|
harm.add_element(_pitch('root', pitch, _accidental(visual), 'root'))
|
||||||
harm.add_element newTextElement('kind', kind)
|
harm.add_element newTextElement('kind', kind)
|
||||||
if root != VL::NoPitch
|
if root != VL::NoPitch
|
||||||
harm.add_element(_pitch('bass', root, visual, 'bass'))
|
harm.add_element(_pitch('bass', root, _accidental(rootVisual), 'bass'))
|
||||||
end
|
end
|
||||||
needSteps = steps & ~CHORD[kind]
|
needSteps = steps & ~CHORD[kind]
|
||||||
extraSteps= CHORD[kind] & ~steps
|
extraSteps= CHORD[kind] & ~steps
|
||||||
|
@ -398,7 +401,7 @@ def _melody
|
||||||
m.add_element(fw)
|
m.add_element(fw)
|
||||||
tempAt = chordAt
|
tempAt = chordAt
|
||||||
end
|
end
|
||||||
m.add_element(_chord(chord['pitch'], chord['visual'], chord['steps'], chord['root']))
|
m.add_element(_chord(chord['pitch'], chord['visual'], chord['steps'], chord['root'], chord['rootvisual']))
|
||||||
end
|
end
|
||||||
chordAt += (chord['durNum'] * $DIVISIONS * 4) / chord['durDenom']
|
chordAt += (chord['durNum'] * $DIVISIONS * 4) / chord['durDenom']
|
||||||
chordIx += 1
|
chordIx += 1
|
||||||
|
|
|
@ -156,14 +156,19 @@ void VLPlistVisitor::VisitNote(VLLyricsNote & n)
|
||||||
|
|
||||||
void VLPlistVisitor::VisitChord(VLChord & c)
|
void VLPlistVisitor::VisitChord(VLChord & c)
|
||||||
{
|
{
|
||||||
|
int pitchGrid = VLPitchToGrid(c.fPitch, c.fVisual, 0);
|
||||||
|
VLVisualFilter pitchFilter(0);
|
||||||
|
int rootGrid = VLPitchToGrid(c.fRootPitch, c.fRootAccidental, 0);
|
||||||
|
VLVisualFilter rootFilter(0);
|
||||||
NSDictionary * cd =
|
NSDictionary * cd =
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInt:c.fDuration.fNum], @"durNum",
|
[NSNumber numberWithInt:c.fDuration.fNum], @"durNum",
|
||||||
[NSNumber numberWithInt:c.fDuration.fDenom], @"durDenom",
|
[NSNumber numberWithInt:c.fDuration.fDenom], @"durDenom",
|
||||||
[NSNumber numberWithInt:c.fPitch], @"pitch",
|
[NSNumber numberWithInt:c.fPitch], @"pitch",
|
||||||
[NSNumber numberWithInt:c.fVisual], @"visual",
|
[NSNumber numberWithInt:pitchFilter(pitchGrid, c.fVisual)], @"visual",
|
||||||
[NSNumber numberWithInt:c.fSteps], @"steps",
|
[NSNumber numberWithInt:c.fSteps], @"steps",
|
||||||
[NSNumber numberWithInt:c.fRootPitch], @"root",
|
[NSNumber numberWithInt:c.fRootPitch], @"root",
|
||||||
|
[NSNumber numberWithInt:rootFilter(rootGrid, c.fRootAccidental)], @"rootvisual",
|
||||||
nil];
|
nil];
|
||||||
[fChords addObject: cd];
|
[fChords addObject: cd];
|
||||||
}
|
}
|
||||||
|
@ -336,7 +341,9 @@ advanceAt:
|
||||||
[[cdict objectForKey:@"durDenom"] intValue],
|
[[cdict objectForKey:@"durDenom"] intValue],
|
||||||
true);
|
true);
|
||||||
chord.fPitch = [[cdict objectForKey:@"pitch"] intValue];
|
chord.fPitch = [[cdict objectForKey:@"pitch"] intValue];
|
||||||
|
chord.fVisual = [[cdict objectForKey:@"visual"] intValue];
|
||||||
chord.fRootPitch = [[cdict objectForKey:@"root"] intValue];
|
chord.fRootPitch = [[cdict objectForKey:@"root"] intValue];
|
||||||
|
chord.fRootAccidental = [[cdict objectForKey:@"rootvisual"] intValue];
|
||||||
chord.fSteps = [[cdict objectForKey:@"steps"] intValue];
|
chord.fSteps = [[cdict objectForKey:@"steps"] intValue];
|
||||||
|
|
||||||
song->AddChord(chord, measNo, at);
|
song->AddChord(chord, measNo, at);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user