Пример #1
0
        private int width_to_pair; /** The width (in pixels) to the chord pair */

        #endregion Fields

        #region Constructors

        /** Create a new stem.  The top note, bottom note, and direction are
         * needed for drawing the vertical line of the stem.  The duration is
         * needed to draw the tail of the stem.  The overlap boolean is true
         * if the notes in the chord overlap.  If the notes overlap, the
         * stem must be drawn on the right side.
         */
        public Stem(WhiteNote bottom, WhiteNote top, 
                NoteDuration duration, int direction, bool overlap)
        {
            this.top = top;
            this.bottom = bottom;
            this.duration = duration;
            this.direction = direction;
            this.notesoverlap = overlap;
            if (direction == Up || notesoverlap)
            side = RightSide;
            else
            side = LeftSide;
            end = CalculateEnd();
            pair = null;
            width_to_pair = 0;
            receiver_in_pair = false;
        }
Пример #2
0
        /** Return the time period (in pulses) the the given duration spans */
        public int DurationToTime(NoteDuration dur)
        {
            int eighth = quarternote/2;
            int sixteenth = eighth/2;

            switch (dur) {
            case NoteDuration.Whole:         return quarternote * 4;
            case NoteDuration.DottedHalf:    return quarternote * 3;
            case NoteDuration.Half:          return quarternote * 2;
            case NoteDuration.DottedQuarter: return 3*eighth;
            case NoteDuration.Quarter:       return quarternote;
            case NoteDuration.DottedEighth:  return 3*sixteenth;
            case NoteDuration.Eighth:        return eighth;
            case NoteDuration.Triplet:       return quarternote/3;
            case NoteDuration.Sixteenth:     return sixteenth;
            case NoteDuration.ThirtySecond:  return sixteenth/2;
            default:                         return 0;
               }
        }
Пример #3
0
 /** Convert a note duration into a stem duration.  Dotted durations
  * are converted into their non-dotted equivalents.
  */
 public static NoteDuration GetStemDuration(NoteDuration dur)
 {
     if (dur == NoteDuration.DottedHalf)
     return NoteDuration.Half;
     else if (dur == NoteDuration.DottedQuarter)
     return NoteDuration.Quarter;
     else if (dur == NoteDuration.DottedEighth)
     return NoteDuration.Eighth;
     else
     return dur;
 }
Пример #4
0
 public Note(float frequency, NoteDuration duration)
 {
     Frequency = frequency;
     Duration  = duration;
 }
Пример #5
0
        /** Return true if the chords can be connected, where their stems are
         * joined by a horizontal beam. In order to create the beam:
         *
         * - The chords must be in the same measure.
         * - The chord stems should not be a dotted duration.
         * - The chord stems must be the same duration, with one exception
         *   (Dotted Eighth to Sixteenth).
         * - The stems must all point in the same direction (up or down).
         * - The chord cannot already be part of a beam.
         *
         * - 6-chord beams must be 8th notes in 3/4, 6/8, or 6/4 time
         * - 3-chord beams must be either triplets, or 8th notes (12/8 time signature)
         * - 4-chord beams are ok for 2/2, 2/4 or 4/4 time, any duration
         * - 4-chord beams are ok for other times if the duration is 16th
         * - 2-chord beams are ok for any duration
         *
         * If startQuarter is true, the first note should start on a quarter note
         * (only applies to 2-chord beams).
         */
        public static bool CanCreateBeam(ChordSymbol[] chords, TimeSignature time, bool startQuarter)
        {
            int  numChords = chords.Length;
            Stem firstStem = chords[0].Stem;
            Stem lastStem  = chords[chords.Length - 1].Stem;

            if (firstStem == null || lastStem == null)
            {
                return(false);
            }
            int          measure = chords[0].StartTime / time.Measure;
            NoteDuration dur     = firstStem.Duration;
            NoteDuration dur2    = lastStem.Duration;

            bool dotted8_to_16 = false;

            if (chords.Length == 2 && dur == NoteDuration.DottedEighth &&
                dur2 == NoteDuration.Sixteenth)
            {
                dotted8_to_16 = true;
            }

            if (dur == NoteDuration.Whole || dur == NoteDuration.Half ||
                dur == NoteDuration.DottedHalf || dur == NoteDuration.Quarter ||
                dur == NoteDuration.DottedQuarter ||
                (dur == NoteDuration.DottedEighth && !dotted8_to_16))
            {
                return(false);
            }

            if (numChords == 6)
            {
                if (dur != NoteDuration.Eighth)
                {
                    return(false);
                }
                bool correctTime =
                    ((time.Numerator == 3 && time.Denominator == 4) ||
                     (time.Numerator == 6 && time.Denominator == 8) ||
                     (time.Numerator == 6 && time.Denominator == 4));

                if (!correctTime)
                {
                    return(false);
                }

                if (time.Numerator == 6 && time.Denominator == 4)
                {
                    /* first chord must start at 1st or 4th quarter note */
                    int beat = time.Quarter * 3;
                    if ((chords[0].StartTime % beat) > time.Quarter / 6)
                    {
                        return(false);
                    }
                }
            }
            else if (numChords == 4)
            {
                if (time.Numerator == 3 && time.Denominator == 8)
                {
                    return(false);
                }
                bool correctTime =
                    (time.Numerator == 2 || time.Numerator == 4 || time.Numerator == 8);
                if (!correctTime && dur != NoteDuration.Sixteenth)
                {
                    return(false);
                }

                /* chord must start on quarter note */
                int beat = time.Quarter;
                if (dur == NoteDuration.Eighth)
                {
                    /* 8th note chord must start on 1st or 3rd quarter note */
                    beat = time.Quarter * 2;
                }
                else if (dur == NoteDuration.ThirtySecond)
                {
                    /* 32nd note must start on an 8th beat */
                    beat = time.Quarter / 2;
                }

                if ((chords[0].StartTime % beat) > time.Quarter / 6)
                {
                    return(false);
                }
            }
            else if (numChords == 3)
            {
                bool valid = (dur == NoteDuration.Triplet) ||
                             (dur == NoteDuration.Eighth &&
                              time.Numerator == 12 && time.Denominator == 8);
                if (!valid)
                {
                    return(false);
                }

                /* chord must start on quarter note */
                int beat = time.Quarter;
                if (time.Numerator == 12 && time.Denominator == 8)
                {
                    /* In 12/8 time, chord must start on 3*8th beat */
                    beat = time.Quarter / 2 * 3;
                }
                if ((chords[0].StartTime % beat) > time.Quarter / 6)
                {
                    return(false);
                }
            }

            else if (numChords == 2)
            {
                if (startQuarter)
                {
                    int beat = time.Quarter;
                    if ((chords[0].StartTime % beat) > time.Quarter / 6)
                    {
                        return(false);
                    }
                }
            }

            foreach (ChordSymbol chord in chords)
            {
                if ((chord.StartTime / time.Measure) != measure)
                {
                    return(false);
                }
                if (chord.Stem == null)
                {
                    return(false);
                }
                if (chord.Stem.Duration != dur && !dotted8_to_16)
                {
                    return(false);
                }
                if (chord.Stem.isBeam)
                {
                    return(false);
                }
            }

            /* Check that all stems can point in same direction */
            bool hasTwoStems = false;
            int  direction   = Stem.Up;

            foreach (ChordSymbol chord in chords)
            {
                if (chord.HasTwoStems)
                {
                    if (hasTwoStems && chord.Stem.Direction != direction)
                    {
                        return(false);
                    }
                    hasTwoStems = true;
                    direction   = chord.Stem.Direction;
                }
            }

            /* Get the final stem direction */
            if (!hasTwoStems)
            {
                WhiteNote note1;
                WhiteNote note2;
                note1     = (firstStem.Direction == Stem.Up ? firstStem.Top : firstStem.Bottom);
                note2     = (lastStem.Direction == Stem.Up ? lastStem.Top : lastStem.Bottom);
                direction = StemDirection(note1, note2, chords[0].Clef);
            }

            /* If the notes are too far apart, don't use a beam */
            if (direction == Stem.Up)
            {
                if (Math.Abs(firstStem.Top.Dist(lastStem.Top)) >= 11)
                {
                    return(false);
                }
            }
            else
            {
                if (Math.Abs(firstStem.Bottom.Dist(lastStem.Bottom)) >= 11)
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #6
0
        /** Create a new Chord Symbol from the given list of midi notes.
         * All the midi notes will have the same start time.  Use the
         * key signature to get the white key and accidental symbol for
         * each note.  Use the time signature to calculate the duration
         * of the notes. Use the clef when drawing the chord.
         */
        public ChordSymbol(List <MidiNote> midinotes, KeySignature key, TimeSignature time, Clef c, SheetMusic sheet)
        {
            int len = midinotes.Count;
            int i;

            hastwostems = false;
            clef        = c;
            sheetmusic  = sheet;

            starttime = midinotes[0].StartTime;
            endtime   = midinotes[0].EndTime;

            // Midi Notes of the chord
            notes = new List <MidiNote>();
            for (i = 0; i < midinotes.Count; i++)
            {
                if (i > 1)
                {
                    if (midinotes[i].Number < midinotes[i - 1].Number)
                    {
                        // FAB a corriger
                        //throw new System.ArgumentException("Chord notes not in increasing order by number");
                    }
                }
                endtime = Math.Max(endtime, midinotes[i].EndTime);

                notes.Add(midinotes[i]);
            }

            // Note data of the chord
            notedata     = CreateNoteData(midinotes, key, time);
            accidsymbols = CreateAccidSymbols(notedata, clef);


            /* Find out how many stems we need (1 or 2) */
            NoteDuration dur1   = notedata[0].duration;
            NoteDuration dur2   = dur1;
            int          change = -1;

            for (i = 0; i < notedata.Length; i++)
            {
                dur2 = notedata[i].duration;
                if (dur1 != dur2)
                {
                    change = i;
                    break;
                }
            }

            if (dur1 != dur2)
            {
                /* We have notes with different durations.  So we will need
                 * two stems.  The first stem points down, and contains the
                 * bottom note up to the note with the different duration.
                 *
                 * The second stem points up, and contains the note with the
                 * different duration up to the top note.
                 */
                hastwostems = true;
                stem1       = new Stem(notedata[0].whitenote,
                                       notedata[change - 1].whitenote,
                                       dur1,
                                       Stem.Down,
                                       NotesOverlap(notedata, 0, change)
                                       );

                stem2 = new Stem(notedata[change].whitenote,
                                 notedata[notedata.Length - 1].whitenote,
                                 dur2,
                                 Stem.Up,
                                 NotesOverlap(notedata, change, notedata.Length)
                                 );
            }
            else
            {
                /* All notes have the same duration, so we only need one stem. */
                int direction = StemDirection(notedata[0].whitenote,
                                              notedata[notedata.Length - 1].whitenote,
                                              clef);

                stem1 = new Stem(notedata[0].whitenote,
                                 notedata[notedata.Length - 1].whitenote,
                                 dur1,
                                 direction,
                                 NotesOverlap(notedata, 0, notedata.Length)
                                 );
                stem2 = null;
            }

            /* For whole notes, no stem is drawn. */
            if (dur1 == NoteDuration.Whole)
            {
                stem1 = null;
            }
            if (dur2 == NoteDuration.Whole)
            {
                stem2 = null;
            }

            width = MinWidth;


            // Lync MidiNotes & NotesData
            foreach (NoteData note in notedata)
            {
                for (i = 0; i < notes.Count; i++)
                {
                    if (notes[i].Number == note.number)
                    {
                        note.midinoteindex = i;
                        break;
                    }
                }
            }
        }
Пример #7
0
        private int width; /** The width in pixels */

        #endregion Fields

        #region Constructors

        /** Create a new rest symbol with the given start time and duration */
        public RestSymbol(int start, NoteDuration dur)
        {
            starttime = start;
            duration = dur;
            width = MinWidth;
        }
Пример #8
0
        private int width;              /** The width in pixels */

        /** Create a new rest symbol with the given start time and duration */
        public RestSymbol(int start, NoteDuration dur)
        {
            starttime = start;
            duration  = dur;
            width     = MinWidth;
        }