Beispiel #1
0
        /// <summary>
        /// The palette has created new values for all the arguments, so this 
        /// constructor simply transfers those values to the new MidiChordDef.
        /// msPosition is set to 0, lyric is set to null.
        /// </summary>
        public MidiChordDef(
            int msDuration, // the total duration (this should be the sum of the durations of the basicMidiChordDefs)
            byte pitchWheelDeviation, // default is M.DefaultPitchWheelDeviation (=2)
            bool hasChordOff, // default is M.DefaultHasChordOff (=true)
            List<byte> midiPitches, // the pitches that are displayed in the score
            int ornamentNumberSymbol, // is 0 when there is no ornament
            MidiChordSliderDefs midiChordSliderDefs, // can contain empty lists
            List<BasicMidiChordDef> basicMidiChordDefs)
            : base(msDuration)
        {
            foreach(byte pitch in midiPitches)
                Debug.Assert(pitch == M.MidiValue((int)pitch), "Pitch out of range.");

            _msPosition = 0;
            _msDuration = msDuration;
            _pitchWheelDeviation = pitchWheelDeviation;
            _hasChordOff = hasChordOff;
            _displayedMidiPitches = midiPitches;
            // midiVelocities are handled via the basicMidiChordDefs
            _lyric = null;
            _ornamentNumberSymbol = ornamentNumberSymbol;
            _lyric = null;

            MidiChordSliderDefs = midiChordSliderDefs;
            BasicMidiChordDefs = basicMidiChordDefs;

            CheckTotalDuration();
        }
Beispiel #2
0
        /// <summary>
        /// The palette has created new values for all the arguments, so this
        /// constructor simply transfers those values to the new MidiChordDef.
        /// msPosition is set to 0, lyric is set to null.
        /// </summary>
        public MidiChordDef(
            int msDuration,                          // the total duration (this should be the sum of the durations of the basicMidiChordDefs)
            byte pitchWheelDeviation,                // default is M.DefaultPitchWheelDeviation (=2)
            bool hasChordOff,                        // default is M.DefaultHasChordOff (=true)
            List <byte> midiPitches,                 // the pitches that are displayed in the score
            int ornamentNumberSymbol,                // is 0 when there is no ornament
            MidiChordSliderDefs midiChordSliderDefs, // can contain empty lists
            List <BasicMidiChordDef> basicMidiChordDefs)
            : base(msDuration)
        {
            foreach (byte pitch in midiPitches)
            {
                Debug.Assert(pitch == M.MidiValue((int)pitch), "Pitch out of range.");
            }

            _msPosition           = 0;
            _msDuration           = msDuration;
            _pitchWheelDeviation  = pitchWheelDeviation;
            _hasChordOff          = hasChordOff;
            _displayedMidiPitches = midiPitches;
            // midiVelocities are handled via the basicMidiChordDefs
            _lyric = null;
            _ornamentNumberSymbol = ornamentNumberSymbol;
            _lyric = null;

            MidiChordSliderDefs = midiChordSliderDefs;
            BasicMidiChordDefs  = basicMidiChordDefs;

            CheckTotalDuration();
        }
Beispiel #3
0
        public override IUniqueDef DeepClone()
        {
            MidiChordDef rval = new MidiChordDef();

            rval.MsPosition = this.MsPosition;
            // rval.MsDuration must be set after setting BasicMidiChordDefs See below.
            rval.Bank  = this.Bank;
            rval.Patch = this.Patch;
            rval.PitchWheelDeviation = this.PitchWheelDeviation;
            rval.HasChordOff         = this.HasChordOff;
            rval.Lyric = this.Lyric;
            rval.MinimumBasicMidiChordMsDuration = this.MinimumBasicMidiChordMsDuration; // required when changing a midiChord's duration
            rval.NotatedMidiPitches = new List <byte>(this.NotatedMidiPitches);          // the displayed noteheads
            // rval.MidiVelocity must be set after setting BasicMidiChordDefs See below.
            rval.OrnamentNumberSymbol = this.OrnamentNumberSymbol;                       // the displayed ornament number

            MidiChordSliderDefs m = this.MidiChordSliderDefs;
            List <byte>         pitchWheelMsbs      = NewListByteOrNull(m.PitchWheelMsbs);
            List <byte>         panMsbs             = NewListByteOrNull(m.PanMsbs);
            List <byte>         modulationWheelMsbs = NewListByteOrNull(m.ModulationWheelMsbs);
            List <byte>         expressionMsbs      = NewListByteOrNull(m.ExpressionMsbs);

            if (pitchWheelMsbs != null || panMsbs != null || modulationWheelMsbs != null || expressionMsbs != null)
            {
                rval.MidiChordSliderDefs = new MidiChordSliderDefs(pitchWheelMsbs, panMsbs, modulationWheelMsbs, expressionMsbs);
            }
            else
            {
                rval.MidiChordSliderDefs = null;
            }

            List <BasicMidiChordDef> newBs = new List <BasicMidiChordDef>();

            foreach (BasicMidiChordDef b in this.BasicMidiChordDefs)
            {
                List <byte> pitches    = new List <byte>(b.Pitches);
                List <byte> velocities = new List <byte>(b.Velocities);
                newBs.Add(new BasicMidiChordDef(b.MsDuration, b.BankIndex, b.PatchIndex, b.HasChordOff, pitches, velocities));
            }
            rval.BasicMidiChordDefs = newBs;

            rval.MsDuration   = this.MsDuration;
            rval.MidiVelocity = this.MidiVelocity; // needed for displaying dynamics (must be set *after* setting BasicMidiChordDefs)

            return(rval);
        }
Beispiel #4
0
        /// <summary>
        /// Note that, unlike Rests, MidiChordDefs do not have a msDuration attribute.
        /// Their msDuration is deduced from the contained BasicMidiChords.
        /// Patch indices already set in the BasicMidiChordDefs take priority over those set in the main MidiChordDef.
        /// However, if BasicMidiChordDefs[0].PatchIndex is null, and this.Patch is set, BasicMidiChordDefs[0].PatchIndex is set to Patch.
        /// The same is true for Bank settings.
        /// The AssistantPerformer therefore only needs to look at BasicMidiChordDefs to find Bank and Patch changes.
        /// While constructing Tracks, the AssistantPerformer should monitor the current Bank and/or Patch, so that it can decide
        /// whether or not to actually construct and send bank and/or patch change messages.
        /// </summary>
        public void WriteSvg(SvgWriter w)
        {
            w.WriteStartElement("score", "midiChord", null);

            Debug.Assert(BasicMidiChordDefs != null && BasicMidiChordDefs.Count > 0);

            if (BasicMidiChordDefs[0].BankIndex == null && Bank != null)
            {
                BasicMidiChordDefs[0].BankIndex = Bank;
            }
            if (BasicMidiChordDefs[0].PatchIndex == null && Patch != null)
            {
                BasicMidiChordDefs[0].PatchIndex = Patch;
            }
            if (HasChordOff == false)
            {
                w.WriteAttributeString("hasChordOff", "0");
            }
            if (PitchWheelDeviation != null && PitchWheelDeviation != M.DefaultPitchWheelDeviation)
            {
                w.WriteAttributeString("pitchWheelDeviation", PitchWheelDeviation.ToString());
            }
            if (MinimumBasicMidiChordMsDuration != M.DefaultMinimumBasicMidiChordMsDuration)
            {
                w.WriteAttributeString("minBasicChordMsDuration", MinimumBasicMidiChordMsDuration.ToString());
            }

            w.WriteStartElement("basicChords");
            foreach (BasicMidiChordDef basicMidiChord in BasicMidiChordDefs) // containing basic <midiChord> elements
            {
                basicMidiChord.WriteSVG(w);
            }
            w.WriteEndElement();

            if (MidiChordSliderDefs != null)
            {
                MidiChordSliderDefs.WriteSVG(w); // writes sliders element
            }
            w.WriteEndElement();                 // score:midiChord
        }
Beispiel #5
0
        /// <summary>
        /// This constructor creates a MidiChordDef at msPosition 0, lyric = null, containing a single BasicMidiChordDef and no sliders.
        /// </summary>
        public MidiChordDef(List<byte> pitches, List<byte> velocities, int msPosition, int msDuration, bool hasChordOff)
            : base(msDuration)
        {
            foreach(byte pitch in pitches)
                Debug.Assert(pitch == M.MidiValue((int)pitch), "Pitch out of range.");

            _msPosition = msPosition;
            _hasChordOff = hasChordOff;
            _minimumBasicMidiChordMsDuration = 1; // not used (this is not an ornament)

            _displayedMidiPitches = pitches;
            // midiVelocity is handled via the BasicMidiChordDefs
            _ornamentNumberSymbol = 0;

            MidiChordSliderDefs = null;

            byte? bank = null;
            byte? patch = null;

            BasicMidiChordDefs.Add(new BasicMidiChordDef(msDuration, bank, patch, hasChordOff, pitches, velocities));

            CheckTotalDuration();
        }
Beispiel #6
0
        /// <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;
        }
Beispiel #7
0
 private void CreateSliders(int channel, MidiChordSliderDefs sliderDefs, int msDuration)
 {
     if(sliderDefs.ModulationWheelMsbs != null && sliderDefs.ModulationWheelMsbs.Count > 0)
         this._modulationWheelSlider = new MidiModulationWheelSlider(sliderDefs.ModulationWheelMsbs, channel, msDuration);
     if(sliderDefs.PanMsbs != null && sliderDefs.PanMsbs.Count > 0)
         this._panSlider = new MidiPanSlider(sliderDefs.PanMsbs, channel, msDuration);
     if(sliderDefs.PitchWheelMsbs != null && sliderDefs.PitchWheelMsbs.Count > 0)
         this._pitchWheelSlider = new MidiPitchWheelSlider(sliderDefs.PitchWheelMsbs, channel, msDuration);
     if(sliderDefs.ExpressionMsbs != null && sliderDefs.ExpressionMsbs.Count > 0)
         this._expressionSlider = new MidiExpressionSlider(sliderDefs.ExpressionMsbs, channel, msDuration);
 }
Beispiel #8
0
        /// <summary>
        /// Constructor used when creating a list of DurationDef templates from a Palette.
        /// The palette has created new values for all the arguments, so this constructor simply transfers
        /// those values to the new MidiChordDef. MsPositionReFirstIUD is set to 0, lyric is set to null.
        /// </summary>
        public MidiChordDef(
            int msDuration, // the total duration (this should be the sum of the durations of the basicMidiChordDefs)
            byte pitchWheelDeviation, // default is M.DefaultPitchWheelDeviation (=2)
            bool hasChordOff, // default is M.DefaultHasChordOff (=true)
            List<byte> rootMidiPitches, // the pitches defined in the root chord settings (displayed, by default, in the score).
            List<byte> rootMidiVelocities, // the velocities defined in the root chord settings (displayed, by default, in the score).
            int ornamentNumberSymbol, // is 0 when there is no ornament
            MidiChordSliderDefs midiChordSliderDefs, // can be null or contain empty lists
            List<BasicMidiChordDef> basicMidiChordDefs)
            : base(msDuration)
        {
            Debug.Assert(rootMidiPitches.Count <= rootMidiVelocities.Count);
            foreach(byte pitch in rootMidiPitches)
            {
                AssertIsMidiValue(pitch);
            }

            _msPositionReFirstIUD = 0;
            _msDuration = msDuration;
            _pitchWheelDeviation = pitchWheelDeviation;
            _hasChordOff = hasChordOff;
            _notatedMidiPitches = rootMidiPitches;
            _notatedMidiVelocities = rootMidiVelocities;

            _ornamentNumberSymbol = ornamentNumberSymbol;

            MidiChordSliderDefs = midiChordSliderDefs;
            BasicMidiChordDefs = basicMidiChordDefs;

            CheckTotalDuration();
        }
Beispiel #9
0
        private void SetSliderEnvelope(int domain, List<byte> pitchWheelBytes, List<byte> panBytes, List<byte> modulationBytes, List<byte> expressionBytes)
        {
            #region condition
            if(domain != 127)
            {
                throw new ArgumentException($"{nameof(domain)} must be 127.");
            }
            #endregion condition

            if(MidiChordSliderDefs == null)
            {
                MidiChordSliderDefs = new MidiChordSliderDefs(null, null, null, null);
            }
            if(pitchWheelBytes != null)
            {
                MidiChordSliderDefs.PitchWheelMsbs = pitchWheelBytes;
            }
            else
            if(panBytes != null)
            {
                MidiChordSliderDefs.PanMsbs = panBytes;
            }
            else
            if(modulationBytes != null)
            {
                MidiChordSliderDefs.ModulationWheelMsbs = modulationBytes;
            }
            else
            if(expressionBytes != null)
            {
                MidiChordSliderDefs.ExpressionMsbs = expressionBytes;
            }
        }