示例#1
0
        /// <summary>
        /// Creates a BasicMidiChordDef having the original base pitch,
        /// but in which the top-bottom order of the prime intervals is reversed.
        /// Velocities remain in the same order, bottom to top. They are not inverted.
        /// </summary>
        /// <returns></returns>
        public BasicMidiChordDef Inversion()
        {
            List <byte> pitches = Pitches; // default if Pitches.Count == 1

            if (Pitches.Count > 1)
            {
                List <byte> intervals = new List <byte>();

                for (int i = 1; i < Pitches.Count; ++i)
                {
                    intervals.Add((byte)(Pitches[i] - Pitches[i - 1]));
                }
                intervals.Reverse();
                pitches = new List <byte>()
                {
                    Pitches[0]
                };
                for (int i = 0; i < intervals.Count; ++i)
                {
                    byte interval = intervals[i];
                    pitches.Add((byte)(pitches[pitches.Count - 1] + interval));
                }
            }

            BasicMidiChordDef invertedBMCD = new BasicMidiChordDef(MsDuration, BankIndex, PatchIndex, HasChordOff, pitches, Velocities);

            return(invertedBMCD);
        }
示例#2
0
 public BasicMidiChordDef(BasicMidiChordDef original, int msDuration)
 {
     _msDuration = msDuration; // read-only!
     BankIndex   = original.BankIndex;
     PatchIndex  = original.PatchIndex;
     HasChordOff = original.HasChordOff;
     Pitches     = new List <byte>(original.Pitches);
     Velocities  = new List <byte>(original.Velocities);
 }
示例#3
0
 public BasicMidiChordDef(BasicMidiChordDef original, int msDuration)
 {
     _msDuration = msDuration; // read-only!
     BankIndex = original.BankIndex;
     PatchIndex = original.PatchIndex;
     HasChordOff = original.HasChordOff;
     Pitches = new List<byte>(original.Pitches);
     Velocities = new List<byte>(original.Velocities);
 }
示例#4
0
        public BasicMidiChord(int channel, MidiChord midiChord, BasicMidiChordDef bmcd, int realMsDuration)
        {
            MidiChord = midiChord;
            //MsPosition = bmcd.MsPosition;
            MsDuration = realMsDuration;

            if(bmcd.BankIndex != null)
            {
                BankControl = new BankControl(channel, (byte)bmcd.BankIndex);
            }
            if(bmcd.PatchIndex != null)
            {
                PatchControl = new PatchControl(channel, (byte)bmcd.PatchIndex);
            }

            ChordOn = new ChordOn(this);
            SetChordOn(channel, bmcd.Pitches, bmcd.Velocities);
            if(bmcd.HasChordOff)
            {
                ChordOff = new ChordOff(this);
                SetChordOff(channel, bmcd.Pitches);
            }
        }
示例#5
0
文件: Palette.cs 项目: notator/Moritz
        /// <summary>
        /// Returns either a new RestDef or a new MidiChordDef
        /// In both cases, MsPosition is set to zero, Lyric is set to null.
        /// </summary>
        private DurationDef GetDurationDef(int index)
        {
            DurationDef rval = null;
            BasicChordMidiSettings bcms = _basicChordMidiSettings;

            if(bcms.MidiPitches[index].Count == 0)
            {
                /// RestDefs are immutable, and have no MsPosition property.
                /// UniqueRestDefs are mutable RestDefs with both MsPositon and MsDuration properties.
                int restMsDuration = bcms.Durations[index];
                rval = new RestDef(0, restMsDuration);
            }
            else
            {
                /// Create a new MidiChordDef (with msPosition=0, lyric=null)
                bool hasChordOff = BoolOrDefaultValue(bcms.ChordOffs, index, M.DefaultHasChordOff); // true
                int duration = bcms.Durations[index];
                List<byte> rootMidiPitches = bcms.MidiPitches[index];
                List<byte> rootMidiVelocities = bcms.Velocities[index];

                byte? bankIndex = ByteOrNull(_bankIndices, index);
                byte? patchIndex = ByteOrNull(_patchIndices, index);
                byte pitchwheelDeviation = ByteOrDefaultValue(_pitchwheelDeviations, index, M.DefaultPitchWheelDeviation); // 2
                List<byte> pitchwheelEnvelope = ListByte(_pitchwheelEnvelopes, index);
                List<byte> panEnvelope = ListByte(_panEnvelopes, index);
                List<byte> modulationWheelEnvelope = ListByte(_modulationWheelEnvelopes, index);
                List<byte> expressionEnvelope = ListByte(_expressionEnvelopes, index);

                MidiChordSliderDefs midiChordSliderDefs =
                    new MidiChordSliderDefs(pitchwheelEnvelope,
                                            panEnvelope,
                                            modulationWheelEnvelope,
                                            expressionEnvelope);

                OrnamentSettings os = _ornamentSettings;
                List<BasicMidiChordDef> basicMidiChordDefs = new List<BasicMidiChordDef>();
                int ornamentNumber;
                if(os == null || _ornamentNumbers[index] == 0)
                {
                    ornamentNumber = 0;
                    BasicMidiChordDef bmcd = new BasicMidiChordDef(duration, bankIndex, patchIndex, hasChordOff, rootMidiPitches, rootMidiVelocities);
                    basicMidiChordDefs.Add(bmcd);
                }
                else
                {
                    ornamentNumber = _ornamentNumbers[index];
                    int ornamentMinMsDuration = IntOrDefaultValue(_ornamentMinMsDurations, index, M.DefaultOrnamentMinimumDuration); // 1

                    List<int> ornamentValues = os.OrnamentValues[_ornamentNumbers[index] - 1];

                    for(int i = 0; i < ornamentValues.Count; ++i)
                    {
                        int oIndex = ornamentValues[i] - 1;
                        bool oHasChordOff = BoolOrDefaultValue(os.BasicChordMidiSettings.ChordOffs, oIndex, M.DefaultHasChordOff);
                        int oDuration = os.BasicChordMidiSettings.Durations[oIndex];
                        List<byte> oMidiPitches = os.BasicChordMidiSettings.MidiPitches[oIndex];
                        List<byte> oVelocities = os.BasicChordMidiSettings.Velocities[oIndex];
                        byte? oBank = ByteOrNull(os.BankIndices, oIndex);
                        byte? oPatch = ByteOrNull(os.PatchIndices, oIndex);

                        BasicMidiChordDef bmcd = new BasicMidiChordDef(oDuration, oBank, oPatch, oHasChordOff, oMidiPitches, oVelocities);
                        basicMidiChordDefs.Add(bmcd);
                    }

                    // The basicMidiChordDefs currently contain the values from the ornaments form.
                    // All oBank and oPatch values will be null if the corresponding field in the ornament form was empty.
                    // The durations, pitches and velocities are relative to the main palette's values.

                    RemoveDuplicateBankAndPatchValues(basicMidiChordDefs);

                    if(basicMidiChordDefs[0].BankIndex == null)
                        basicMidiChordDefs[0].BankIndex = bankIndex; // can be null
                    if(basicMidiChordDefs[0].PatchIndex == null)
                        basicMidiChordDefs[0].PatchIndex = patchIndex;

                    Debug.Assert(basicMidiChordDefs[0].PatchIndex != null);

                    basicMidiChordDefs = Moritz.Spec.MidiChordDef.FitToDuration(basicMidiChordDefs, duration, ornamentMinMsDuration);

                    foreach(BasicMidiChordDef b in basicMidiChordDefs)
                    {
                        List<byte> combinedPitches = new List<byte>();
                        foreach(byte pitch in b.Pitches)
                        {
                            foreach(byte rootMidiPitch in rootMidiPitches)
                            {
                                combinedPitches.Add(M.MidiValue(rootMidiPitch + pitch));
                            }
                        }
                        b.Pitches = combinedPitches;

                        List<byte> combinedVelocities = new List<byte>();
                        foreach(byte velocity in b.Velocities)
                        {
                            foreach(byte rootMidiVelocity in rootMidiVelocities)
                            {
                                combinedVelocities.Add(M.MidiValue(rootMidiVelocity + velocity));
                            }
                        }
                        b.Velocities = combinedVelocities;
                    }
                }

                rval = new MidiChordDef(
                    duration,
                    pitchwheelDeviation,
                    hasChordOff,
                    rootMidiPitches,
                    rootMidiVelocities,
                    ornamentNumber,
                    midiChordSliderDefs,
                    basicMidiChordDefs);
            }
            return rval;
        }
示例#6
0
        /// <summary>
        /// Creates a BasicMidiChordDef having the original base pitch,
        /// but in which the top-bottom order of the prime intervals is reversed. 
        /// Velocities remain in the same order, bottom to top. They are not inverted. 
        /// </summary>
        /// <returns></returns>
        public BasicMidiChordDef Inversion()
        {
            List<byte> pitches = Pitches; // default if Pitches.Count == 1

            if(Pitches.Count > 1)
            {
                List<byte> intervals = new List<byte>();

                for(int i = 1; i < Pitches.Count; ++i)
                {
                    intervals.Add((byte)(Pitches[i] - Pitches[i - 1]));
                }
                intervals.Reverse();
                pitches = new List<byte>() { Pitches[0] };
                for(int i = 0; i < intervals.Count; ++i)
                {
                    byte interval = intervals[i];
                    pitches.Add((byte)(pitches[pitches.Count - 1] + interval));
                }
            }

            BasicMidiChordDef invertedBMCD = new BasicMidiChordDef(_msDuration, BankIndex, PatchIndex, HasChordOff, pitches, Velocities);

            return invertedBMCD;
        }
示例#7
0
文件: Trk.cs 项目: notator/Moritz
        /// <summary>
        /// Returns a new MidiChordDef having msDuration, whose BasicMidiChordDefs are created from the MidiChordDefs and RestDefs in the Trk.
        /// BasicMidiChordDefs created from MidiChordDefs are the MidiChordDef's BasicMidiChordDef[0].
        /// BasicMidiChordDefs created from RestDefs have a single pitch (=0) and velocity=0.
        /// The durations of the returned BasicMidiChordDefs are in proportion to the durations of the MidiChordDefs and RestDefs in the Trk. 
        /// The Trk (which must contain at least one MidiChordDef) is not changed by calling this function.
        /// </summary>
        /// <param name="msDuration">The duration of the returned MidiChordDef</param>
        public MidiChordDef ToMidiChordDef(int msDuration)
        {
            List<BasicMidiChordDef> basicMidiChordDefs = new List<BasicMidiChordDef>();
            int bmcMsDuration = 0;
            byte? bmcBank = null;
            byte? bmcPatch = null;
            bool bmcHasChordOff = true;
            List<byte> restPitch = new List<byte>() { 0 };
            List<byte> restVelocity = new List<byte>() { 0 };
            List<byte> bmcPitches = null;
            List<byte> bmcVelocities = null;
            int totalDuration = 0;
            int nMidiChordDefs = 0;
            foreach(IUniqueDef iud in UniqueDefs)
            {
                MidiChordDef mcd = iud as MidiChordDef;
                RestDef restDef = iud as RestDef;

                if(mcd != null)
                {
                    bmcBank = mcd.BasicMidiChordDefs[0].BankIndex;
                    bmcPatch = mcd.BasicMidiChordDefs[0].PatchIndex;
                    bmcHasChordOff = mcd.BasicMidiChordDefs[0].HasChordOff;
                    bmcPitches = mcd.BasicMidiChordDefs[0].Pitches;
                    bmcVelocities = mcd.BasicMidiChordDefs[0].Velocities;
                    bmcMsDuration = mcd.MsDuration;
                    nMidiChordDefs++;
                }
                else if(restDef != null)
                {
                    bmcBank = null;
                    bmcPatch = null;
                    bmcHasChordOff = false;
                    bmcPitches = restPitch;
                    bmcVelocities = restVelocity;
                    bmcMsDuration = restDef.MsDuration;
                }

                if(iud is DurationDef)
                {
                    var basicMidiChordDef = new BasicMidiChordDef(bmcMsDuration, bmcBank, bmcPatch, bmcHasChordOff, bmcPitches, bmcVelocities);
                    totalDuration += bmcMsDuration;
                    basicMidiChordDefs.Add(basicMidiChordDef);
                }
            }

            Debug.Assert(nMidiChordDefs > 0, "Error: The original Trk must contain at least one MidiChordDef.");

            const byte pitchWheelDeviation = 2;
            const bool hasChordOff = true;
            const MidiChordSliderDefs midiChordSliderDefs = null;

            List<byte> rootMidiPitches = new List<byte>(basicMidiChordDefs[0].Pitches);
            List<byte> rootMidiVelocities = new List<byte>(basicMidiChordDefs[0].Velocities);

            MidiChordDef returnMCD = new MidiChordDef(totalDuration, pitchWheelDeviation, hasChordOff, rootMidiPitches, rootMidiVelocities,
                                                        nMidiChordDefs, midiChordSliderDefs, basicMidiChordDefs);

            returnMCD.MsDuration = msDuration;

            return returnMCD;
        }
示例#8
0
        /// <summary>
        /// Sets an ornament having the shape and number of elements in the ornamentEnvelope.
        /// If ornamentEnvelope == null, BasicMidiChords[0] is set to the NotatedMidiChord.
        /// using the NotatedMidiPitches as the first chord.
        /// Uses the current Gamut.
        /// Replaces any existing ornament.
        /// Sets the OrnamentNumberSymbol to the number of BasicMidiChordDefs.
        /// </summary>
        /// <param name="ornamentEnvelope"></param>
        public void SetOrnament(Gamut gamut, Envelope ornamentEnvelope)
        {
            Debug.Assert(gamut != null);
            List<int> basicMidiChordRootPitches = gamut.PitchSequence(_notatedMidiPitches[0], ornamentEnvelope);
            // If ornamentEnvelope is null, basicMidiChordRootPitches will only contain rootNotatedpitch.

            BasicMidiChordDefs = new List<BasicMidiChordDef>();
            foreach(int rootPitch in basicMidiChordRootPitches)
            {
                BasicMidiChordDef bmcd = new BasicMidiChordDef(1000, gamut, rootPitch, _notatedMidiPitches.Count);
                BasicMidiChordDefs.Add(bmcd);
            }
            this.MsDuration = _msDuration; // resets the BasicMidiChordDef msDurations.

            if(basicMidiChordRootPitches.Count > 1)
            {
                _ornamentNumberSymbol = basicMidiChordRootPitches.Count;
            }
        }