Successfully round trip accidentals in chords

This commit is contained in:
Matthias Neeracher 2011-08-28 21:54:20 +02:00
parent ffdc41e1d7
commit f27dc9ee8f
3 changed files with 29 additions and 10 deletions

View File

@ -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'

View File

@ -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

View File

@ -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);