예제 #1
0
        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);
            }
        }
예제 #2
0
        /// <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);
        }