private void InitializeSignature() { // Count the # of sharps in the key signature (a negative # means flats.) int sharps = key.Fifths; // Add 3 flats for minor. if (key.Mode == KeyMode.Minor) { sharps -= 3; } int count = Math.Abs(sharps); pitchClasses = new ArrayList(count); // Find the starting accidental: F# for sharps or Bb for flats. PitchClass pc; Pitch tmpPitch; if (sharps > 0) { pc = new PitchClass(3, Accidental.Sharp); } else { pc = new PitchClass(6, Accidental.Flat); } // Move up or down the line of fifths to generate new accidentals. PitchInterval fifth = new PitchInterval(7); for (int i = 0; i < count; i++) { // Add the current pitchclass to the list. pitchClasses.Add(pc); // Convert the pitch class to a real pitch for processing. tmpPitch = new Pitch(pc.COffset, pc.Accidental); // Move by a fifth. if (sharps > 0) { tmpPitch += fifth; } else { tmpPitch -= fifth; } // Pick the right enharmonic version: don't use accidentals like B# on white keys until the 6th accidental. tmpPitch.FlipEnharmonic(i < 4, sharps > 0); // Convert back to a pitch class. pc = new PitchClass(tmpPitch.Number % 7, tmpPitch.Accidental); } }
/// <summary> /// Returns an example Pitch in the given key on the given scale degree, in the given octave. /// </summary> /// <param name="degree">The scale degree to create.</param> /// <param name="octave">The c-based octave in which to create the Pitch instance.</param> /// <returns>The example pitch on the requested scale degree.</returns> public Pitch GetScaleDegreePitch(ScaleDegree degree, int octave) { int numFifths; bool progressUp; PitchInterval fifth; PitchInterval degreeInterval; numFifths = Math.Abs(Fifths); progressUp = (Fifths > 0); fifth = new PitchInterval(7); // First, find the tonic of the key. // Start on middle C and loop through the circle of fifths. Pitch tonic = new Pitch(35, Accidental.Natural); for (int i = 0; i < numFifths; i++) { if (progressUp) { tonic += fifth; tonic.FlipEnharmonic(true, true); // The first argument is true because B# and E# are not allowed. } else { tonic -= fifth; tonic.FlipEnharmonic(i < 6, false); // The first argument is used because Cb is allowed (fifths = -7; i=6); } } // Second, add the scale degree to the tonic note. // Convert the scale degree to a pitch interval. degreeInterval = new PitchInterval(); switch ((degree.Number - 1) % 7) { case 0: degreeInterval.Interval = 0; break; case 1: degreeInterval.Interval = 2; break; case 2: degreeInterval.Interval = 4; break; case 3: degreeInterval.Interval = 5; break; case 4: degreeInterval.Interval = 7; break; case 5: degreeInterval.Interval = 9; break; case 6: degreeInterval.Interval = 11; break; } // Add back in the # octaves. degreeInterval += new PitchInterval(12 * ((degree.Number - 1) / 7)); Pitch result = tonic + degreeInterval; // Pick the correct enharmonic version (assuming no alterations). We use sharps if we are going up on the circle of fifths. // Natural notes like B are used instead of Cb until we have 6 accidentals. This is a special mixed case where we need to // use one normal "white key" and one sharp "white key": both B natural and E# are in the key signature in F# major. Similarly, // in Gb major both Cb and F natural are in the key signature. // Once we have 7 accidentals, we don't use any natural white keys. if (numFifths < 6) { result.FlipEnharmonic(true, progressUp); } else if (numFifths > 6) { result.FlipEnharmonic(false, progressUp); } else if (fifths == 6) // F# Major. { if (degree.Number == 4) // B natural special case. { result.FlipEnharmonic(true, true); } else { result.FlipEnharmonic(false, true); } } else // Gb Major. { if (degree.Number == 7) // F natural special case. { result.FlipEnharmonic(true, false); } else { result.FlipEnharmonic(false, false); } } // Set the alteration (this function picks the right enharmonic version if the pitch is already set right for the no alteration case.) result.ApplyAlteration(degree.Alteration); // Finally, set the octave. result.Octave = octave; return(result); }