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