Ejemplo n.º 1
0
        /// <summary>
        /// A Block contains a list of VoiceDefs consisting of a group of Trks possibly followed by InputVoiceDefs.
        /// This constructor creates a MainBlock consisting of the Trks in the mainSeq.
        /// The initialClefs are set to the clefs in initialClefsPerChannel.
        /// initialClefsPerChannel contains the clefs for the Trks followed by the clefs for the clefs for the InputVoiceDefs.
        /// Note that initialClefsPerChannel contains a clef for each channel, regardless of whether it is going to be printed or not. 
        /// </summary>
        /// <param name="initialClefPerChannel">The clefs to set at the start of each Trk followed by the clefs for each InputVoiceDef (if any)</param>
        /// <param name="mainSeq">A Seq containing the trks for this MainBlock.</param>
        /// <param name="barlineMsPositions">Does not contain the value 0, but must contain a barline at mainSeq.MsDuration.</param>
        public MainBlock(List<string> initialClefPerChannel, Seq mainSeq, List<int> barlineMsPositions)
            : base()
        {
            #region conditions
            Debug.Assert(initialClefPerChannel != null && mainSeq != null && mainSeq.Trks != null && barlineMsPositions != null);
            Debug.Assert(initialClefPerChannel.Count == mainSeq.Trks.Count);
            Debug.Assert(barlineMsPositions.Count > 0 && barlineMsPositions[barlineMsPositions.Count - 1] == mainSeq.MsDuration);
            #endregion conditions

            int nTrks = mainSeq.Trks.Count;
            int blockMsDuration = mainSeq.MsDuration;

            for(int i = 0; i < nTrks; ++i)
            {
                Trk trk = mainSeq.Trks[i];
                if(trk.MsDuration < blockMsDuration)
                {
                    trk.Add(new RestDef(0, blockMsDuration - trk.MsDuration));
                }
                trk.UniqueDefs.Insert(0, new ClefChangeDef(initialClefPerChannel[trk.MidiChannel], 0));
                _voiceDefs.Add(trk);
            }

            this.AddBarlines(barlineMsPositions);
        }
Ejemplo n.º 2
0
        // Neither the krystals, nor the palettes argument is used.
        public override List<List<VoiceDef>> DoAlgorithm(List<Krystal> krystals, List<Palette> palettes)
        {
            List<Trk> tracks1and6 = GetTracks1and6();
            List<Trk> tracks2and5 = GetTracks2and5();
            List<Trk> tracks3and4 = GetTracks3and4();

            // Add each Trk to trks here, in top to bottom (=channelIndex) order in the score.
            List<Trk> trks = new List<Trk>() { tracks1and6[0], tracks2and5[0], tracks3and4[0], tracks3and4[1], tracks2and5[1], tracks1and6[1] };
            Debug.Assert(trks.Count == MidiChannelIndexPerOutputVoice.Count);

            Seq seq = new Seq(0, trks, MidiChannelIndexPerOutputVoice);
            double approxBarMsDuration = ((double)seq.MsDuration / 8);
            List<int> approxBarlineMsPositions = new List<int>();
            for(int barnumber = 1; barnumber < 9; ++barnumber)
            {
                approxBarlineMsPositions.Add((int)Math.Round(approxBarMsDuration * barnumber));
            }
            Block block = new Block(seq, approxBarlineMsPositions);

            MainBlock mainBlock = new MainBlock(InitialClefPerChannel, new List<Block>() { block });

            List <List<VoiceDef>> bars = mainBlock.ConvertToBars();

            SetPatch0InAllChords(bars);

            return bars;
        }
Ejemplo n.º 3
0
        // Also called by other, specialised Block constructors
        protected void FinalizeBlock(Seq seq, IReadOnlyList<int> approxBarlineMsPositions, List<InputVoiceDef> inputVoiceDefs = null)
        {
            Debug.Assert(seq.IsNormalized);

            AbsMsPosition = seq.AbsMsPosition;

            foreach(Trk trk in seq.Trks)
            {
                trk.Container = null;
                _voiceDefs.Add(trk);
            }

            if(inputVoiceDefs != null)
            {
                foreach(InputVoiceDef ivd in inputVoiceDefs)
                {
                    ivd.Container = null;
                    _voiceDefs.Add(ivd);
                }
            }

            Blockify();

            AddBarlines(approxBarlineMsPositions);

            AssertNonEmptyBlockConsistency();
        }
Ejemplo n.º 4
0
 /// <summary>
 /// A Block contains a list of voiceDefs, that can be of both kinds: Trks and InputVoiceDefs. A Seq can only contain Trks.
 /// This constructor uses its arguments' voiceDefs directly in the Block so, if the arguments needs to be used again, pass a clone.
 /// <para>The seq's Trks and the inputVoiceDefs (if any) are cast to VoiceDefs, and then padded at the beginning and end with rests
 /// so that they all start at the beginning of the Block and have the same duration.</para>
 /// <para>The Block's AbsMsPosition is set to the seq's AbsMsPosition.</para>
 /// <para>There must be at least one MidiChordDef at the start of the Block (possibly following a ClefChangeDef), and
 /// at least one MidiChordDef ends at its end.</para>
 /// <para>If an original voiceDef is empty or contains a single restDef, it will be altered to contain a single rest having the
 /// same duration as the other voiceDefs.</para>
 /// <para>For further documentation about Block consistency, see its private AssertBlockConsistency() function.
 /// </summary>
 /// <param name="seq">Cannot be null, and must have Trks</param>
 /// <param name="inputVoiceDefs">This list can be null or empty</param>
 public Block(Seq seq, IReadOnlyList<int> approxBarlineMsPositions, List<InputVoiceDef> inputVoiceDefs = null)
 {
     FinalizeBlock(seq, approxBarlineMsPositions, inputVoiceDefs);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// A deep clone of the Block
        /// </summary>
        public Block Clone()
        {
            List<Trk> clonedTrks = new List<Trk>();
            List<int> midiChannelPerOutputVoice = new List<int>();
            foreach(Trk trk in Trks)
            {
                Trk trkClone = trk.Clone();
                clonedTrks.Add(trkClone);
                midiChannelPerOutputVoice.Add(trk.MidiChannel);
            }
            Seq clonedSeq = new Seq(this.AbsMsPosition, clonedTrks, midiChannelPerOutputVoice);
            List<InputVoiceDef> clonedInputVoiceDefs = new List<Spec.InputVoiceDef>();
            foreach(InputVoiceDef ivd in InputVoiceDefs)
            {
                clonedInputVoiceDefs.Add(ivd.Clone());
            }
            Block clone = new Block(clonedSeq, this.BarlineMsPositionsReBlock, clonedInputVoiceDefs);

            return clone;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Sets mainSeq (to the concatenation of the seqs), and approxBarlineMsPositions (re mainSeq).
        /// The approximate barlineMsPositions are made precise later, by positioning them on the nearest
        /// completion of a chord or rest, inside the MainBlock constructor. 
        /// </summary>
        /// <param name="seqs">A sequence of Seqs</param>
        /// <param name="mainSeq">An empty Seq</param>
        /// <param name="approxBarlineMsPositions">an empty List of ints</param>
        private void GetMainSeqAndApproximateBarlineMsPositions(List<Seq> seqs, Seq mainSeq, List<int> approxBarlineMsPositions)
        {
            foreach(Trk trk in mainSeq.Trks)
            {
                Debug.Assert(trk.UniqueDefs.Count == 0);
            }
            Debug.Assert(approxBarlineMsPositions != null && approxBarlineMsPositions.Count == 0);

            for(int i = 0; i < seqs.Count; ++i)
            {
                Seq seq = seqs[i];
                int seqMsDuration = seq.MsDuration;
                int mainSeqMsDuration = mainSeq.MsDuration;
                List<int> barlineMsPositionsReSeq = GetBarlineMsPositionsReSeq(seq);
                foreach(int barlineMsPositionReSeq in barlineMsPositionsReSeq)
                {
                    approxBarlineMsPositions.Add(mainSeqMsDuration + barlineMsPositionReSeq);
                }

                mainSeq.Concat(seq);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Barlines are placed at the end of each seq. If the seq is longer than maxSystemMsDuration,
        /// it is split into two bars (recursively until the bars are shorter than maxSystemMsDuration).
        /// maxSystemMsDuration is a constant that can be changed inside this function.
        /// </summary>
        /// <param name="seq"></param>
        /// <returns></returns>
        private List<int> GetBarlineMsPositionsReSeq(Seq seq)
        {
            const int maxSystemMsDuration = 20000;

            List<int> barlineMsPositionsReSeq = new List<int>();
            int seqMsDuration = seq.MsDuration;
            int barMsDuration = seqMsDuration;
            while(barMsDuration > maxSystemMsDuration)
            {
                barMsDuration /= 2;
            }
            int barMsPosition = barMsDuration;
            while(barMsPosition < seqMsDuration)
            {
                barlineMsPositionsReSeq.Add(barMsPosition);
                barMsPosition += barMsDuration;
            }
            barlineMsPositionsReSeq.Add(seqMsDuration);
            return barlineMsPositionsReSeq;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// See CompositionAlgorithm.DoAlgorithm()
        /// </summary>
        public override List<List<VoiceDef>> DoAlgorithm(List<Krystal> krystals, List<Palette> palettes)
        {
            _krystals = krystals;
            _palettes = palettes;

            #region main comment (thoughts etc.)
            /*********************************************************************************************
            Think Nancarrow.
            Think Bach, Brückner, Reich. Repeating/changing, fairly fast groups of chords with harmonic support... and ornaments...
            Think Study 1: background/foreground, depth.

            The following parameters can be controlled using the Resident Sf2 Synth:
                Commands:    preset, pitchwheel
                Controls:    volume, pan, pitchWheelDeviation, allControllersOff, allSoundOff
                Note:        velocity, pitch.

            Tombeau1 is just going to use preset 0:0 (=grandPiano), so the available parameters are:
                "tuning" -- i.e. pitchWheelDeviation and pitchWheel
                pan,
                velocity,
                pitch

            ** "Chords are colour" (Stockhausen)

            ** I want to keep the number of pitches in chords fairly low, so that they are recognisable.

            ** Using Seqs and Trks should make it possible to compose powerful, comprehensible, pregnant
               relations between these parameters at every structural level. "Harmony & counterpoint" is
               not only going to be there in the pitches (chords, envelopes...), but also in the velocities
               and the pan positions... Tuning is a parameter that could be introduced as a surprise later...

            ** Thinking about templates and the structural levels:
               First create a set of Template1: Envelopes, Durations, MidiChordDefs, Trks etc. that can be
               used as the basis for similar objects in the piece. This includes MidiChordDefs created from pallets.
               Trks in the piece may be derived fairly simply from templates, but they may also be influenced by
               their containing Seqs.
               How do notes/chords relate horizontally inside a trk? How do they relate vertically inside a seq?
               How do seqs relate to each other globally...
               Seqs can also be cloned, but I dont think there should be Seqs in Template1.

            ** Draw a map of the chords that are to be used, showing the way they relate to each other.
               Use this drawing to create a data structure, containing the chords, that can be used when composing.
               Positions in this structure can probably be assigned to krystal values somehow...

            ** The following functions could be written:
               -- MidiChordDef.Gliss(toMidiChordDef)
                  This would create both a pitchwheel gliss from the pitchwheel setting of the original chord to the pitchwheel
                  setting of the argument chord, and a transformation in the basicMidiChordDefs to the first basicMidiChordDef
                  in the toMidiChordDef.
               -- List<MidiChordDef> MidiChordDef.ToMidiChordDefList()
                  Returns the midiChordDef's basicMidiChordDefs as a list of simple midiChordDefs. The msDurations of the
                  returned midiChordDefs are those of the original basicMidiChorddefs, so the msDuration of the list is the
                  msDuration of the original midiChordDef. The original midiChordDef can therefore be replaced by the list in
                  a host Trk.
               -- MidiChordDef = trk.ToMidiChordDef(msDuration) or MidiChordDef = new MidiChordDef(trk, msDuration);
                  Converts the trk's MidiChordDefs (just their NotatedPitches and NotatedVelocities) to BasicMidiChords in a
                  single, ornamented MidiChordDef.
               -- Seq.AlignTrk(alignmentMsPosReSeq, trkIndex, trkUniqueDefIndex)
                  Shifts the trk horizontally in the seq until the indexed UniqueDef is at alignmentMsPosReSeq. The relative
                  positions of the UniqueDefs in the trk do not change.

            ** Representing velocity using coloured noteheads and extenders:
               There is a new pop-up menu in the Assistant Composer's main form for setting the output chord symbol type.
               This has two values: "standard black" and "coloured velocities". This value is saved in .mkss files.
               (Input chord symbols have no midi velocity, so their noteheads and extenders are never coloured anything but black.)
               If "coloured velocities" is selected, (output) noteheads and extenders are coloured according to the velocities
               constructed either from the density and vertical velocity parameters in a palette or by passing velocities directly
               to a MidiChordDef constructor. The densities and velocities of BasicChordDefs depend on ornament definitions,
               so are independent of the notated values.
               The colours themselves are defined in MoritzStatics.cs:
                   public static readonly Dictionary<M.Dynamic, string> NoteheadColors

            ** The concept of InputChords is still a bit hazy. Why should they ever have more than one notehead?...
               But I can compose Tombeau 1(that doesn't have inputChords) before worrying about that...
               Also, *annotations* that are instructions to performers (hairpins spring to mind).
               Conventional dynamic symbols are, I think, meant for *performers*, so should only be attached to inputChords...
               The info in *outputChords* is the info that could go in a MIDI file, and vice versa.

            ****************************************************************************/
            #endregion main comment (thoughts etc.)
            #region MoritzStatics functions
            /***************************************************************************
            public static Moritz.Statics functions relating to pitch hierarchies and velocities:
                GetAbsolutePitchHierarchy(int relativePitchHierarchyIndex, int rootPitch)
            ***************************************************************************/
            #endregion MoritzStatics functions
            #region Envelope functions
            /***************************************************************************
            public Envelope functions that have been implemented:
                constructors:
                Envelope(List<byte> inputValues, int inputDomain, int domain, int count)
                Envelope(List<int> inputValues, int inputDomain, int domain, int count)

                Clone()

                SetCount(int count)
                WarpVertically(int finalDomain)

                ValueList<T>(List<T> availableValues) // Uses the values in envelope.Original as indices in the availableValues list to create and return a list of values of type T.
                TimeWarp(List<int> originalMsPositions, double distortion)
                GetValuePerMsPosition(List<int> msPositions) // Returns a dictionary in which: Key is one of the positions in msPositions, Value is the envelope value at that msPosition.
            ***************************************************************************/
            #endregion Envelope functions
            #region Gamut functions
            /***************************************************************************
            public Gamut functions and properties that have been implemented:
                (Gamut is immutable)
                constructor:
                Gamut(List<int> absolutePitchHierarchy, int nPitchesPerOctave)

                Clone()
                Conjugate()

                Contains(byte pitch)
                ContainsAllPitches(List<byte> pitches)

                PitchSequence(int pitch1OctaveIndex, int pitch1pitchInOctaveIndex, Envelope envelope)
                GetChord(int rootPitch, int nPitches)

                GetVelocityPerAbsolutePitch(int minimumVelocity)

                Gamut[i] { get; }
                IndexOf(int pitch)
                NPitchesPerOctave { get; }
                AbsolutePitchHierarchy  { get; } // a copy of the private list.
                List {get;} // a copy of the private list.
                Count {get;}
            ***************************************************************************/
            #endregion Gamut functions
            #region MidiChordDef functions
            /***************************************************************************
            public MidiChordDef functions that have been implemented and are especially relevant to this project:
                constructors:
                SIMPLE MidiChordDefs (containing a single BasicMidiChordDef):
                    MidiChordDef(List<byte> pitches, List<byte> velocities, int msDuration, bool hasChordOff)
                ORNAMENTS
                    MidiChordDef(int msDuration, Gamut gamut, int rootNotatedPitch, int nPitchesPerChord, Envelope ornamentEnvelope = null)
                PALETTE MidiChordDefs (MidiChordDefs created from palettes):
                    MidiChordDef(int msDuration, byte pitchWheelDeviation, bool hasChordOff, List<byte> rootMidiPitches, List<byte> rootMidiVelocities, int ornamentNumberSymbol, MidiChordSliderDefs midiChordSliderDefs, List<BasicMidiChordDef> basicMidiChordDefs)

                Clone()
                Conjugate() // requires MidiChordDef.Gamut to be set.

                TimeWarp(Envelope envelope, double distortion) // Changes the msPositions of the BasicMidiChordDefs without changing the length of the MidiChordDef.
                MsDuration {get; set;} // set changes the durations of contained BasicMidiChordDefs
                AdjustMsDuration(double factor) // Multiplies the MsDuration by the given factor.

                SetVerticalDensity(int newDensity)
                GetNoteCombination(MidiChordDef mcd1, MidiChordDef mcd2, MidiChordPitchOperator midiChordPitchOperator) // a static function

                Invert(int nPitchesToShift) // shifts the lower pitches up one octave. The pitches stay in the Gamut, if any.
                Transpose(int interval) // sets Gamut to null
                Transpose(Gamut gamut, int steps)

                SetVelocityPerAbsolutePitch(List<int> velocityPerAbsolutePitch)
                SetVerticalVelocityGradient(byte rootVelocity, byte topVelocity)
                AdjustVelocities(double factor) // Multiplies the velocities in NotatedMidiVelocities, and all BasicMidiChordDef.Velocities by the argument factor.

                SetPitchWheelEnvelope(Envelope envelope)
                SetPanEnvelope(Envelope envelope)
                SetModulationWheelEnvelope(Envelope envelope)
                SetExpressionEnvelope(Envelope envelope)
                AdjustPitchWheel(double factor)
                PanMsbs {get; set;}
                AdjustModulationWheel(double factor)
                AdjustExpression(double factor)

                Gamut {get; set;} // The Gamut can only be set (or changed) if all the pitches in the MidiChordDef are in the new Gamut.
            ***************************************************************************/
            #endregion MidiChordDef functions
            #region Trk functions
            /***************************************************************************
            public Trk functions that have been implemented and are especially relevant to this project:
            constructors:
                Trk(int midiChannel, int msPositionReContainer, List<IUniqueDef> iuds)
                Trk(int midiChannel)

                Clone()

                this[i] { get; set; } // indexer (set sets MsPositionsReFirstUD in whole Trk
                uniqueDefs // enumerator

                **** Changing the trk without changing its duration ****
                // clefs, lyrics
                InsertClefChange(int index, string clefType)
                SetLyricsToIndex()
                // alignment changers
                TimeWarp(Envelope envelope, double distortion)
                FindIndexAtMsPositionReFirstIUD(int msPositionReFirstIUD) // Returns the index of the IUniqueDef which starts at or is otherwise current at msPosition.
                AlignObjectAtIndex(int anchor1Index, int indexToAlign, int anchor2Index, int toMsPositionReFirstIUD)
                // sorting and permutation
                SortRootNotatedPitchAscending()
                SortRootNotatedPitchDescending()
                SortVelocityIncreasing()
                SortVelocityDecreasing()
                Permute(int axisNumber, int contourNumber) // permutes recursively
                PermutePartitions(int axisNumber, int contourNumber, List<int> partitionSizes)
                // rests
                Erase(int startMsPosition, int endMsPosition) // Replace all the IUniqueDefs from startMsPosition to (not including) endMsPosition by a single rest.
                InsertInRest(Trk trk) // An attempt is made to insert the argument trk in a rest in the host trk.
                InsertInRest(MidiChordDef midiChordDef) // Creates a new TrkDef the midiChordDef, then calls the other InsertInRest() function.
                // replace and translate
                Replace(int index, IUniqueDef replacementIUnique) // Removes the iUniqueDef at index from the list, and then inserts the replacement at the same index.
                Translate(int fromIndex, int nUniqueDefs, int toIndex) // Extracts nUniqueDefs from the uniqueDefs, and then inserts them again at the toIndex.
                // sliders
                AdjustExpression(int beginIndex, int endIndex, double factor)
                AdjustExpression(double factor)
                SetPanGliss(int startMsPosition, int endMsPosition, int startPanValue, int endPanValue)
                SetPitchWheelSliders(Envelope envelope)
                SetPitchWheelSliders(Dictionary<int, int> pitchWheelValuesPerMsPosition) // called by Seq and Block
                SetPitchWheelDeviation(int beginIndex, int endIndex, int deviation)
                RemoveScorePitchWheelCommands(int beginIndex, int endIndex)
                AdjustPitchWheelDeviations(int startMsPosition, int endMsPosition, int startPwd, int endPwd)
                // pitch
                Transpose(int beginIndex, int endIndex, int interval)
                Transpose(int interval)
                TransposeNotation(int semitonesToTranspose)
                TransposeToDict(Dictionary<int, int> msPosTranspositionDict)
                StepwiseGliss(int beginIndex, int endIndex, int glissInterval)
                // velocity
                AdjustVelocities(int beginIndex, int endIndex, double factor)
                AdjustVelocities(double factor)
                AdjustVelocitiesHairpin(int startMsPosition, int endMsPosition, double startFactor, double endFactor)
                SetVelocityPerAbsolutePitch(List<int> velocityPerAbsolutePitch)
                SetVerticalVelocityGradient(byte rootVelocity, byte topVelocity)

                **** Functions that change trk's duration ****
                CreateAccel(int beginIndex, int endIndex, double startEndRatio) // Creates an exponential accelerando or decelerando from beginIndex to (not including) endIndex.
                Add(IUniqueDef iUniqueDef) // Appends the new IUniqueDef to the end of the trk.
                AddRange(VoiceDef trk) // Adds the argument's UniqueDefs to the end of the trk.
                Insert(int index, IUniqueDef iUniqueDef) // Inserts the iUniqueDef in the list at the given index.
                InsertRange(int index, Trk trk) // Inserts the trk's UniqueDefs in the list at the given index.
                Remove(IUniqueDef iUniqueDef) // removes the iUniqueDef from the list.
                RemoveAt(int index) // Removes the iUniqueDef at index from the list.
                RemoveRange(int index, int count) // Removes count iUniqueDefs from the list, startíng with the iUniqueDef at index.
                RemoveBetweenMsPositions(int startMsPosReFirstIUD, int endMsPosReFirstIUD) // Remove the IUniqueDefs which start between startMsPosReFirstIUD and (not including) endMsPosReFirstIUD
                RemoveRests() // Removes all the rests in this Trk
                AdjustMsDurations(int beginIndex, int endIndex, double factor, int minThreshold = 100)
                AdjustMsDurations(double factor, int minThreshold = 100)
                AdjustChordMsDurations(int beginIndex, int endIndex, double factor, int minThreshold = 100)
                AdjustChordMsDurations(double factor, int minThreshold = 100)
                AdjustRestMsDurations(int beginIndex, int endIndex, double factor, int minThreshold = 100)
                AdjustRestMsDurations(double factor, int minThreshold = 100)

                **** Properties ****
                MidiChannel  { get; set; }
                Count { get; } // The number of IUniqueDefs in this TrkDef
                DurationsCount { get; } // The number of MidiChordDefs and RestDefs in this TrkDef
                MsDuration { get; set; } // set stretches or compresses each IUniqueDef to fit the new duration
                EndMsPositionReFirstIUD  { get; set; }  // set changes the msDuration of the last IUniqueDef in the trk.
                MsPositionReContainer  { get; set; } // The trk's MsPosition wrt the containing Seq.
                AxisIndex { get; set; } // The index of the UniqueDef (in the UniqueDefs list) that will be aligned when calling Seq.AlignTrkAxes().
                MasterVolume // Algorithms must set this value in the first Trk in each midiChannel in the score. (Default is null.)

            ***************************************************************************/
            #endregion Trk functions
            #region Seq functions
            /***************************************************************************
            public Seq functions that have been implemented and are especially relevant to this project:
                constructors:
                Seq(int absSeqMsPosition, List<Trk> trks, IReadOnlyList<int> midiChannelIndexPerOutputVoice)
                Seq(int absSeqMsPosition, IReadOnlyList<int> midiChannelIndexPerOutputVoice)

                Clone()

                Concat(Seq seq2) // Concatenates seq2 to the caller (seq1). Returns a pointer to the caller.

                SetTrk(Trk trk) // replaces or updates the trk having the same channel in the Seg.

                Normalize() // Shifts the Trks so that the earliest trk.MsPositionReContainer is 0.

                // Sorting (These functions smply call the coresponding function on each trk.)
                SortVelocityIncreasing()
                SortVelocityDecreasing()
                SortRootNotatedPitchAscending()
                SortRootNotatedPitchDescending()

                AlignTrkUniqueDefs(List<int> indicesToAlign) // Aligns the Trk UniqueDefs whose indices are given in the argument.
                AlignTrkAxes()// Aligns using each trk.AxisIndex.

                ShiftTrks(List<int> msShifts) // Shifts each track by adding the corresponding millisecond argument to its MsPositionReContainer attribute.

                // Envelopes
                TimeWarp(Envelope envelope, double distortion)
                SetPitchWheelSliders(Envelope envelope)

                // Properties
                Trks { get; }
                AbsMsPosition { get; set; }
                MsDuration { get; set; } // Setting this value stretches or compresses the msDurations of all the trks and their contained UniqueDefs.
                MidiChannelIndexPerOutputVoice { get; }

            ***************************************************************************/
            #endregion Seq functions
            #region Block functions
            /***************************************************************************
            public Block functions that have been implemented and are especially relevant to this project:
                constructors:
                Block(Seq seq, List<int> rightBarlineMsPositions)
                Block(List<Block> blocks)

                Clone()

                Concat(Block block2)

                ConvertToBars()

                AddInputVoice(InputVoiceDef ivd)

                SetInitialClefs(List<string> clefs)

                // Envelopes
                TimeWarp(Envelope envelope, double distortion)
                SetPitchWheelSliders(Envelope envelope)

                // Properties
                MsDuration { get; set; } // Setting this value stretches or compresses the msDurations of all the voiceDefs and their contained UniqueDefs.
                AbsMsPosition { get; set; }
                BarlineMsPositions // public List<int>
                Trks { get; }
                InputVoiceDefs { get; }

            ***************************************************************************/
            #endregion Block functions

            /**********************************************/

            TenorGrps tenorGrps = new TenorGrps();
            SopranoGrps sopranoGrps = new SopranoGrps(tenorGrps.Grps);
            BassGrps bassGrps = new BassGrps(sopranoGrps.Grps, tenorGrps.Grps);
            AltoGrps altoGrps = new AltoGrps(sopranoGrps.Grps, tenorGrps.Grps, bassGrps.Grps);

            List<Seq> outputSeqs = new List<Seq>(); // The seqs that will be displayed (the score).
            bool composingGrps = false;
            if(composingGrps)
            {
                // add the Grps to the outputSeqs
                AddGrpsToSeqs(outputSeqs, tenorGrps.Grps, MidiChannelIndexPerOutputVoice[2]);
                //AddGrpsToSeqs(outputSeqs, sopranoGrps.Grps, MidiChannelIndexPerOutputVoice[0]);
                //AddGrpsToSeqs(seqs, bassGrps.Grps, MidiChannelIndexPerOutputVoice[3]);
                //AddGrpsToSeqs(seqs, altoGrps.Grps, MidiChannelIndexPerOutputVoice[1]);
            }
            else
            {
                // Compose the piece in the outputSeqs
                ComposeSeqs(outputSeqs, sopranoGrps.Grps, altoGrps.Grps, tenorGrps.Grps, bassGrps.Grps, MidiChannelIndexPerOutputVoice);
            }

            Seq mainSeq = new Seq(0, new List<Trk>() { new Trk(0) }, MidiChannelIndexPerOutputVoice);
            List<int> approximateBarlineMsPositions = new List<int>();
            GetMainSeqAndApproximateBarlineMsPositions(outputSeqs, mainSeq, approximateBarlineMsPositions);

            MainBlock mainBlock = new MainBlock(InitialClefPerChannel, mainSeq, approximateBarlineMsPositions);

            List<List<VoiceDef>> bars = mainBlock.ConvertToBars();

            return bars;
        }
Ejemplo n.º 9
0
        public Seq Clone()
        {
            List<Trk> trks = new List<Trk>();
            for(int i = 0; i < _trks.Count; ++i)
            {
                trks.Add(_trks[i].Clone());
            }

            Seq clone = new Seq(_absMsPosition, trks, MidiChannelIndexPerOutputVoice);

            return clone;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Concatenates seq2 to the caller (seq1). Returns a pointer to the caller.
        /// Both Seqs must be normalized before calling this function.
        /// When this function is called, seq2.AbsMsPosition is the earliest position, relative to seq1, at which it can be concatenated.
        /// When it returns, seq2's Trks will have been concatenated to Seq1, and seq1 is consistent.
        /// If Seq2 is needed after calling this function, then it should be cloned first.
        /// For example:
        /// If seq2.MsPosition==0, it will be concatenated such that there will be at least one trk concatenation without an
        /// intervening rest.
        /// If seq2.MsPosition == seq1.MsDuration, the seqs will be juxtaposed.
        /// If seq2.MsPosition > seq1.MsDuration, the seqs will be concatenated with an intervening rest.
        /// Redundant clef changes are silently removed.
        /// </summary>
        public Seq Concat(Seq seq2)
        {
            #region assertions
            Debug.Assert(_trks.Count == seq2.Trks.Count);
            Debug.Assert(this.IsNormalized);
            Debug.Assert(seq2.IsNormalized);
            AssertChannelConsistency(seq2.MidiChannelIndexPerOutputVoice);
            #endregion

            int nTrks = _trks.Count;

            #region find concatMsPos
            int absConcatMsPos = seq2.AbsMsPosition;
            if(seq2.AbsMsPosition < (AbsMsPosition + MsDuration))
            {
                for(int i = 0; i < nTrks; ++i)
                {
                    Trk trk1 = _trks[i];
                    Trk trk2 = seq2.Trks[i];
                    int earliestAbsConcatPos = trk1.MsPositionReContainer + trk1.EndMsPositionReFirstIUD - trk2.MsPositionReContainer;
                    absConcatMsPos = (earliestAbsConcatPos > absConcatMsPos) ? earliestAbsConcatPos : absConcatMsPos;
                }
            }
            #endregion

            #region concatenation
            for(int i = 0; i < nTrks; ++i)
            {
                Trk trk2 = seq2.Trks[i];
                if(trk2.UniqueDefs.Count > 0)
                {
                    Trk trk1 = _trks[i];
                    int trk1AbsEndMsPosition = AbsMsPosition + trk1.MsPositionReContainer + trk1.EndMsPositionReFirstIUD;
                    int trk2AbsStartMsPosition = absConcatMsPos + trk2.MsPositionReContainer;
                    if(trk1AbsEndMsPosition < trk2AbsStartMsPosition)
                    {
                        trk1.Add(new RestDef(trk1.EndMsPositionReFirstIUD, trk2AbsStartMsPosition - trk1AbsEndMsPosition));
                    }
                    trk1.AddRange(trk2);
                }
            }
            #endregion

            foreach(Trk trk in Trks)
            {
                trk.AgglomerateRests();
            }

            AssertSeqConsistency();

            return this;
        }
Ejemplo n.º 11
0
        private Seq CreateBar1Seq()
        {
            List<Trk> bar = new List<Trk>();

            byte channel = 0;
            foreach(Palette palette in _palettes)
            {
                Trk trk = new Trk(channel, 0, new List<IUniqueDef>());
                bar.Add(trk);
                WriteVoiceMidiDurationDefs1(trk, palette);
                channel++;
            }

            Seq seq = new Seq(0, bar, MidiChannelIndexPerOutputVoice);

            return seq;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// This function creates only one bar, using Trk objects. 
        /// </summary>
        private Seq CreateBar2Seq()
        {
            List<Trk> bar = new List<Trk>();

            byte channel = 0;
            foreach(Palette palette in _palettes)
            {
                Trk trk = palette.NewTrk(channel);
                trk.MsPositionReContainer = 0;
                trk.MsDuration = 6000; // stretches or compresses the trk duration to 6000ms
                bar.Add(trk);
                ++channel;
            }

            int maxMsPosReBar = 0;
            // insert rests at the start of the Trks
            int restMsDuration = 0;
            foreach(Trk trk in bar)
            {
                if(restMsDuration > 0)
                {
                    RestDef restDef = new RestDef(0, restMsDuration);
                    trk.Insert(0, restDef);
                }
                restMsDuration += 1500;
                maxMsPosReBar = trk.EndMsPositionReFirstIUD;
            }

            // add the final rest in the bar
            foreach(Trk trk in bar)
            {
                int trkEndMsPosReBar = trk.EndMsPositionReFirstIUD;
                if(maxMsPosReBar > trkEndMsPosReBar)
                {
                    RestDef restDef = new RestDef(trkEndMsPosReBar, maxMsPosReBar - trkEndMsPosReBar);
                    trk.Add(restDef);
                }
            }

            Seq seq = new Seq(0, bar, MidiChannelIndexPerOutputVoice);

            return seq;
        }
Ejemplo n.º 13
0
 private InputVoiceDef GetBar345InputVoiceDef(Seq bars345Seq)
 {
     InputVoiceDef ivd = GetBar2InputVoiceDef(bars345Seq);
     return ivd;
 }
Ejemplo n.º 14
0
        private InputVoiceDef GetBar2InputVoiceDef(Seq bar2Seq)
        {
            InputVoiceDef ivd = new InputVoiceDef(0, 0, new List<IUniqueDef>());
            ivd.MsPositionReContainer = bar2Seq.AbsMsPosition;

            foreach(Trk trk in bar2Seq.Trks)
            {
                MidiChordDef firstMidiChordDef = null;
                foreach(IUniqueDef iud in trk.UniqueDefs)
                {
                    firstMidiChordDef = iud as MidiChordDef;
                    if(firstMidiChordDef != null)
                    {
                        List<TrkRef> trkRefs = new List<TrkRef>();
                        trkRefs.Add(new TrkRef((byte)trk.MidiChannel, bar2Seq.AbsMsPosition + firstMidiChordDef.MsPositionReFirstUD, 12, null));
                        SeqRef seqRef = new SeqRef(trkRefs, null);
                        NoteOn noteOn = new NoteOn(seqRef);
                        List<InputNoteDef> inputNoteDefs = new List<InputNoteDef>();
                        inputNoteDefs.Add(new InputNoteDef((byte)65, noteOn, null));
                        InputChordDef icd = new InputChordDef(firstMidiChordDef.MsPositionReFirstUD, 1500, inputNoteDefs, M.Dynamic.none, null);
                        ivd.Add(icd);
                        break;
                    }
                }
            }

            return ivd;
        }
Ejemplo n.º 15
0
        private InputVoiceDef GetBar1InputVoiceDef(Seq bar1Seq)
        {
            InputVoiceDef ivd = new InputVoiceDef(0, 0, new List<IUniqueDef>());
            ivd.MsPositionReContainer = bar1Seq.AbsMsPosition;

            Trk leadTrk = null;
            foreach(Trk trk in bar1Seq.Trks)
            {
                if(trk.MidiChannel == 0)
                {
                    leadTrk = trk;
                    break;
                }

            }
            Debug.Assert(leadTrk != null);
            foreach(IUniqueDef tIud in leadTrk)
            {
                RestDef tRestDef = tIud as RestDef;
                MidiChordDef tmcd = tIud as MidiChordDef;
                if(tRestDef != null)
                {
                    RestDef iRestDef = new RestDef(tRestDef.MsPositionReFirstUD, tRestDef.MsDuration);
                    ivd.Add(iRestDef);
                }
                else if(tmcd != null)
                {
                    List<TrkRef> trkRefs = new List<TrkRef>();

                    foreach(Trk trk in bar1Seq.Trks)
                    {
                        trkRefs.Add(new TrkRef((byte)trk.MidiChannel, bar1Seq.AbsMsPosition + tmcd.MsPositionReFirstUD, 1, null));
                    }
                    SeqRef seqRef = new SeqRef(trkRefs, null);
                    NoteOn noteOn = new NoteOn(seqRef);
                    List<InputNoteDef> inputNoteDefs = new List<InputNoteDef>();
                    foreach(byte notatedMidiPitch in tmcd.NotatedMidiPitches)
                    {
                        inputNoteDefs.Add(new InputNoteDef((byte)(notatedMidiPitch + 36), noteOn, null));
                    }
                    InputChordDef icd = new InputChordDef(tIud.MsPositionReFirstUD, tIud.MsDuration, inputNoteDefs, M.Dynamic.none, null);
                    ivd.Add(icd);
                }
            }

            return ivd;
        }