示例#1
0
        public static Composition Read(string filename, Fraction?prec = null)
        {
            var reader = new StreamReader(filename);

            MelodyPartList list = new MelodyPartList(MelodyPartList.Type.Voice);

            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine();
                if (line == "")
                {
                    continue;
                }
                var values = line.Split(',');
                if (values.Length != 2)
                {
                    throw new Exception($"The line `{line}` must contain exactly two values.");
                }

                int              note     = int.Parse(values[0].Trim());
                Fraction         duration = Fraction.Parse(values[1].Trim());
                NoteWithDuration nwd      = new NoteWithDuration(60 + note, duration);
                list.Add(nwd);
            }

            Composition composition = new Composition();

            composition.millisecondsPerNote = 500; // todo: arbitrary tempo
            composition.AddVoice(list);
            return(composition);
        }
        /// <summary>
        /// Flat copy constructor
        /// </summary>
        public MelodyPartList(MelodyPartList mpl)
        {
            this.type = Type.Copy;

            foreach (var nwd in mpl.children)
            {
                children.Add(nwd);
            }
        }
示例#3
0
        public MelodyPartPointer(MelodyPartList part, int index, int lastNoteIndex)
        {
            this.part           = part;
            this.firstNoteIndex = index;
            Debug.Assert(part[index] is NoteWithDuration);

            this.lastNoteIndex = lastNoteIndex;
            Debug.Assert(part[lastNoteIndex] is NoteWithDuration);
        }
示例#4
0
        private static void UpdateLowerRecursive(MelodyPartList mpl, HashSet <MelodyPartList> mplVoices)
        {
            mpl.TotalOccurances++;
            mplVoices.Add(mpl);

            foreach (var childNode in mpl.GetChildren())
            {
                UpdateLowerRecursive(childNode, mplVoices);
            }
        }
示例#5
0
        private static void AddNote(MelodyPartList list, NoteWithDuration nwd, Fraction?prec = null, long absoluteTime = 0)
        {
            if (prec != null)
            {
                Fraction times = (nwd.Duration / prec.Value);
                if (!times.IsWhole())
                {
                    throw new Exception($"Duration of Note {nwd} not divisible by {prec.Value} at absoluteTime={absoluteTime}");
                }
            }

            list.Add(nwd);
        }
示例#6
0
        /// <summary>
        /// lastNoteIndex as far as possible
        /// </summary>
        public MelodyPartPointer(MelodyPartList part, int index)
        {
            this.part           = part;
            this.firstNoteIndex = index;
            Debug.Assert(part[index] is NoteWithDuration);

            lastNoteIndex = index + 1;
            while (lastNoteIndex < part.Count && part[lastNoteIndex] is NoteWithDuration)
            {
                lastNoteIndex++;
            }

            lastNoteIndex--;

            Debug.Assert(part[lastNoteIndex] is NoteWithDuration);
        }
示例#7
0
        public static Composition Read(string filename, Fraction?prec = null)
        {
            MidiFile    midi               = new MidiFile(filename, true);
            Composition composition        = new Composition();
            int         quarterNoteInTicks = midi.DeltaTicksPerQuarterNote;

            for (int track = 0; track < midi.Tracks; track++)
            {
                MelodyPartList list = new MelodyPartList(MelodyPartList.Type.Voice);
                foreach (MidiEvent midievent in midi.Events[track])
                {
                    if (midievent is NoteOnEvent noteonevent)
                    {
                        if (noteonevent.OffEvent != null)
                        {
                            if (noteonevent.DeltaTime > 0)
                            {
                                AddNote(list, new NoteWithDuration(new Fraction(noteonevent.DeltaTime, quarterNoteInTicks)), prec, noteonevent.AbsoluteTime);
                            }

                            AddNote(
                                list,
                                new NoteWithDuration(
                                    noteonevent.NoteNumber,
                                    Alteration.Natural,
                                    new Fraction(noteonevent.NoteLength, quarterNoteInTicks)),
                                prec,
                                noteonevent.AbsoluteTime);
                        }
                    }
                    else if (midievent is TempoEvent tempoevent)
                    {
                        if (composition.millisecondsPerNote == null)
                        {
                            composition.millisecondsPerNote = tempoevent.MicrosecondsPerQuarterNote / 1000;
                        }
                    }
                }

                if (list.Count > 0)
                {
                    composition.AddVoice(list);
                }
            }

            return(composition);
        }
示例#8
0
        public static Composition Read(string filename)
        {
            MidiFile    midi        = new MidiFile(filename, true);
            Composition composition = new Composition();

            for (int track = 0; track < midi.Tracks; track++)
            {
                MelodyPartList list = new MelodyPartList(MelodyPartList.Type.Voice);
                foreach (MidiEvent midievent in midi.Events[track])
                {
                    if (midievent is NoteOnEvent noteonevent)
                    {
                        if (noteonevent.OffEvent != null)
                        {
                            if (noteonevent.DeltaTime > 0)
                            {
                                list.Add(new NoteWithDuration(new Fraction(noteonevent.DeltaTime, 120)));
                            }

                            list.Add(
                                new NoteWithDuration(
                                    noteonevent.NoteNumber,
                                    Alteration.Natural,
                                    new Fraction(noteonevent.NoteLength, 120)));
                        }
                    }
                    else
                    {
                    }
                }

                if (list.Count > 0)
                {
                    composition.AddVoice(list);
                }
            }

            return(composition);
        }
 public MelodyPart(int offset, MelodyPartList node)
 {
     this.offset = offset;
     this.node   = node;
 }
示例#10
0
 public MelodyPartDtoC(int offset, TwelveToneSet scale, MelodyPartList node) //todo: scale should be 3rd arg
     : base(offset, node)
 {
     Debug.Assert(node.IsDiatonic);
     this.scale = scale;
 }
示例#11
0
 public bool IsIdentical(MelodyPartList node) => this.children.SequenceEqual(node.children) && this.IsDiatonic == node.IsDiatonic;
示例#12
0
 public void AddVoice(MelodyPartList mpl, Fraction offset)
 {
     mpls.Add(new Voice(mpl, offset));
 }
示例#13
0
 public void AddVoice(MelodyPartList mpl)
 {
     AddVoice(mpl, 0);
 }
示例#14
0
            //todo: instrument

            public Voice(MelodyPartList mpl, Fraction offset)
            {
                this.mpl    = mpl;
                this.offset = offset;
            }