Exemple #1
0
 public void Properties()
 {
     ChordPattern cp = new ChordPattern("a", "b", new int[] { 0, 1, 2, 3 },
         new int[] { 0, 1, 2, 3 });
     Assert.AreEqual(cp.Name, "a");
     Assert.AreEqual(cp.Abbreviation, "b");
     Assert.AreEqual(cp.Ascent.Length, 4);
     Assert.AreEqual(cp.LetterOffsets.Length, 4);
 }
Exemple #2
0
 /// <summary>
 /// Constructs a chord from its root note, pattern, and inversion.
 /// </summary>
 /// <param name="root">The root note of the chord.</param>
 /// <param name="pattern">The chord pattern.</param>
 /// <param name="inversion">The inversion, in [0..N-1] where N is the number of notes
 /// in pattern.</param>
 /// <exception cref="ArgumentNullException">pattern is null.</exception>
 /// <exception cref="ArgumentOutOfRangeException">inversion is out of range.</exception>
 public Chord(Note root, ChordPattern pattern, int inversion)
 {
     if (pattern == null)
     {
         throw new ArgumentNullException();
     }
     if (inversion < 0 || inversion >= pattern.Ascent.Length)
     {
         throw new ArgumentOutOfRangeException("inversion out of range.");
     }
     this.root      = root;
     this.pattern   = pattern;
     this.inversion = inversion;
     this.positionInOctaveToContains = new bool[12];
     Note[] uninvertedSequence = new Note[pattern.Ascent.Length];
     Build(root, pattern, this.positionInOctaveToContains,
           uninvertedSequence);
     this.noteSequence = new Note[pattern.Ascent.Length];
     RotateArrayLeft(uninvertedSequence, this.noteSequence, inversion);
 }
Exemple #3
0
        private static void Build(Note root, ChordPattern pattern,
                                  bool[] positionInOctaveToContains, Note[] noteSequence)
        {
            for (int i = 0; i < 12; ++i)
            {
                positionInOctaveToContains[i] = false;
            }
            Pitch rootPitch = root.PitchInOctave(0);

            for (int i = 0; i < pattern.Ascent.Length; ++i)
            {
                Pitch pitch  = rootPitch + pattern.Ascent[i];
                char  letter = (char)(pattern.LetterOffsets[i] + (int)(root.Letter));
                while (letter > 'G')
                {
                    letter = (char)((int)letter - 7);
                }
                noteSequence[i] = pitch.NoteWithLetter(letter);
                positionInOctaveToContains[pitch.PositionInOctave()] = true;
            }
        }
Exemple #4
0
        /// <summary>
        /// Value equality.
        /// </summary>
        public override bool Equals(System.Object obj)
        {
            ChordPattern other = obj as ChordPattern;

            if ((Object)other == null)
            {
                return(false);
            }
            if (!this.name.Equals(other.name))
            {
                return(false);
            }
            if (!this.abbreviation.Equals(other.abbreviation))
            {
                return(false);
            }
            if (this.ascent.Length != other.ascent.Length)
            {
                return(false);
            }
            for (int i = 0; i < this.ascent.Length; ++i)
            {
                if (this.ascent[i] != other.ascent[i])
                {
                    return(false);
                }
            }
            if (this.letterOffsets.Length != other.letterOffsets.Length)
            {
                return(false);
            }
            for (int i = 0; i < this.letterOffsets.Length; ++i)
            {
                if (this.letterOffsets[i] != other.letterOffsets[i])
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #5
0
 private static void Build(Note root, ChordPattern pattern,
     bool[] positionInOctaveToContains, Note[] noteSequence)
 {
     for (int i = 0; i < 12; ++i)
     {
         positionInOctaveToContains[i] = false;
     }
     Pitch rootPitch = root.PitchInOctave(0);
     for (int i = 0; i < pattern.Ascent.Length; ++i)
     {
         Pitch pitch = rootPitch + pattern.Ascent[i];
         char letter = (char)(pattern.LetterOffsets[i] + (int)(root.Letter));
         while (letter > 'G')
         {
             letter = (char)((int)letter - 7);
         }
         noteSequence[i] = pitch.NoteWithLetter(letter);
         positionInOctaveToContains[pitch.PositionInOctave()] = true;
     }
 }
Exemple #6
0
 /// <summary>
 /// Constructs a chord from its root note, pattern, and inversion.
 /// </summary>
 /// <param name="root">The root note of the chord.</param>
 /// <param name="pattern">The chord pattern.</param>
 /// <param name="inversion">The inversion, in [0..N-1] where N is the number of notes
 /// in pattern.</param>
 /// <exception cref="ArgumentNullException">pattern is null.</exception>
 /// <exception cref="ArgumentOutOfRangeException">inversion is out of range.</exception>
 public Chord(Note root, ChordPattern pattern, int inversion)
 {
     if (pattern == null)
     {
         throw new ArgumentNullException();
     }
     if (inversion < 0 || inversion >= pattern.Ascent.Length)
     {
         throw new ArgumentOutOfRangeException("inversion out of range.");
     }
     this.root = root;
     this.pattern = pattern;
     this.inversion = inversion;
     this.positionInOctaveToContains = new bool[12];
     Note[] uninvertedSequence = new Note[pattern.Ascent.Length];
     Build(root, pattern, this.positionInOctaveToContains,
         uninvertedSequence);
     this.noteSequence = new Note[pattern.Ascent.Length];
     RotateArrayLeft(uninvertedSequence, this.noteSequence, inversion);
 }
Exemple #7
0
 /// <summary>
 /// Constructs a chord from a string.
 /// </summary>
 /// <param name="name">The name to parse.  This is the same format as the Name property:
 /// a letter in ['A'..'G'], an optional series of accidentals (#'s or b's), then an
 /// optional inversion specified as a '/' followed by another note name.  If the
 /// inversion is present it must be one of the notes in the chord.</param>
 /// <exception cref="ArgumentNullException">name is null.</exception>
 /// <exception cref="ArgumentException">cannot parse a chord from name.</exception>
 public Chord(string name)
 {
     if (name == null)
     {
         throw new ArgumentNullException("name is null.");
     }
     if (name.Length == 0)
     {
         throw new ArgumentException("name is empty.");
     }
     int pos = 0;
     this.root = Note.ParseNote(name, ref pos);
     this.pattern = null;
     foreach (ChordPattern p in Chord.Patterns)
     {
         if (pos + p.Abbreviation.Length > name.Length)
         {
             continue;
         }
         if (String.Compare(name, pos, p.Abbreviation, 0, p.Abbreviation.Length) != 0)
         {
             continue;
         }
         if (pos + p.Abbreviation.Length == name.Length ||
             name[pos+p.Abbreviation.Length] == '/')
         {
             pos += p.Abbreviation.Length;
             this.pattern = p;
             break;
         }
     }
     if (this.pattern == null)
     {
         throw new ArgumentException("name does not match a known chord pattern.");
     }
     // At this point, we know the note and pattern (but not yet the inversion).  Build
     // the chord prior to inversion.
     this.positionInOctaveToContains = new bool[12];
     Note[] uninvertedSequence = new Note[pattern.Ascent.Length];
     Build(root, pattern, this.positionInOctaveToContains,
         uninvertedSequence);
     this.noteSequence = new Note[pattern.Ascent.Length];
     // Now see if there's an inversion.
     this.inversion = 0;
     if (pos < name.Length)
     {
         if (name[pos] != '/')
         {
             throw new ArgumentException(String.Format("unexpected character '{0}' in name.",
                 name[pos]));
         }
         pos++;
         Note bass = Note.ParseNote(name, ref pos);
         if (name.Length > pos)
         {
             throw new ArgumentException(String.Format("unexpected character '{0}' in name.",
                 name[pos]));
         }
         this.inversion = Array.IndexOf(uninvertedSequence, bass);
         if (inversion == -1)
         {
             throw new ArgumentException("invalid bass note for inversion.");
         }
     }
     RotateArrayLeft(uninvertedSequence, this.noteSequence, inversion);
 }