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

View File

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

View File

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