List<VoiceDef> CreateBar1()
        {
            List<VoiceDef> bar = new List<VoiceDef>();

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

            InputVoiceDef inputVoiceDef = new InputVoiceDef();
            VoiceDef bottomOutputVoice = bar[0];

            foreach(IUniqueDef iud in bottomOutputVoice.UniqueDefs)
            {
                MidiChordDef mcd = iud as MidiChordDef;
                RestDef rd = iud as RestDef;
                if(mcd != null)
                {
                    List<IUniqueDef> iuds = new List<IUniqueDef>() { (IUniqueDef)mcd };

                    // Note that the msPosition of the trkDef is trkDef.StartMsPosition (= iuds[0].msPosition),
                    // which may be greater than the InputChordDef's msPosition
                    TrkDef trkDef = new TrkDef(bottomOutputVoice.MidiChannel, iuds);

                    // If non-null, arg2 overrides the inputControls attached to the InputNote or InputChord.
                    TrkOn trkRef = new TrkOn(trkDef, null);
                    List<TrkOn> trkRefs = new List<TrkOn>() { trkRef };
                    TrkOns trkOns = new TrkOns(trkRefs, null);

                    byte displayPitch = (byte)(mcd.NotatedMidiPitches[0] + 36);
                    Pressure pressure = new Pressure(0, null);
                    Pressures pressures = new Pressures(new List<Pressure>() {pressure}, null);
                    TrkOff trkOff = new TrkOff(trkRef.TrkMidiChannel, mcd.MsPosition, null);
                    List<TrkOff> noteOffTrkOffs = new List<TrkOff>() { trkOff };
                    TrkOffs trkOffs = new TrkOffs(noteOffTrkOffs, null);

                    InputNoteDef inputNoteDef = new InputNoteDef(displayPitch,
                                                                    trkOns, null,
                                                                    pressures,
                                                                    null, trkOffs,
                                                                    null);

                    List<InputNoteDef> inputNoteDefs = new List<InputNoteDef>() { inputNoteDef };

                    // The InputChordDef's msPosition must be <= the msPosition of any of the contained trkRefs
                    InputChordDef icd = new InputChordDef(mcd.MsPosition, mcd.MsDuration, inputNoteDefs);

                    inputVoiceDef.UniqueDefs.Add(icd);
                }
                else if(rd != null)
                {
                    RestDef newRest = new RestDef(rd.MsPosition, rd.MsDuration);
                    inputVoiceDef.UniqueDefs.Add(newRest);
                }
            }

            #region set cascading inputControls on the first InputChordDef  (for testing)
            InputChordDef inputChordDef1 = inputVoiceDef.UniqueDefs[0] as InputChordDef; // no need to check for null here.

            InputControls chordInputControls = new InputControls();

            chordInputControls.VelocityOption = VelocityOption.overridden;
            chordInputControls.MinimumVelocity = 19;
            inputChordDef1.InputControls = chordInputControls;

            InputControls noteInputControls = new InputControls();
            noteInputControls.VelocityOption = VelocityOption.scaled;
            noteInputControls.MinimumVelocity = 20;
            inputChordDef1.InputNoteDefs[0].InputControls = noteInputControls;

            #endregion

            bar.Add(inputVoiceDef);

            return bar;
        }
        /// <summary>
        /// This function creates only one bar, but with VoiceDef objects. 
        /// </summary>
        List<VoiceDef> CreateBar2(int bar2StartMsPos)
        {
            List<VoiceDef> bar = new List<VoiceDef>();

            byte channel = 0;
            List<TrkDef> trkDefs = new List<TrkDef>();
            foreach(Palette palette in _palettes)
            {
                bar.Add(new TrkDef(channel, new List<IUniqueDef>()));
                TrkDef trkDef = palette.NewTrkDef(channel);
                trkDef.SetMsDuration(6000);
                trkDefs.Add(trkDef);
                ++channel;
            }

            int msPosition = bar2StartMsPos;
            int maxBarMsPos = 0;
            int startMsDifference = 1500;
            for(int i = 0; i < trkDefs.Count; ++i)
            {
                int maxMsPos = WriteVoiceMidiDurationDefsInBar2(bar[i], trkDefs[i], msPosition, bar2StartMsPos);
                maxBarMsPos = maxBarMsPos > maxMsPos ? maxBarMsPos : maxMsPos;
                msPosition += startMsDifference;
            }

            // now add the final rest in the bar
            for(int i = 0; i < trkDefs.Count; ++i)
            {
                int mdsdEndPos = trkDefs[i].EndMsPosition;
                if(maxBarMsPos > mdsdEndPos)
                {
                    RestDef rest2Def = new RestDef(mdsdEndPos, maxBarMsPos - mdsdEndPos);
                    bar[i].UniqueDefs.Add(rest2Def);
                }
            }

            InputVoiceDef inputVoiceDef = new InputVoiceDef(maxBarMsPos - bar2StartMsPos);
            inputVoiceDef.StartMsPosition = bar2StartMsPos;
            int msPos = bar2StartMsPos;
            for(int i = 0; i < bar.Count; ++i)
            {
                TrkOn trkRef = new TrkOn((byte)i, msPos, 12, null);
                List<TrkOn> trkRefs = new List<TrkOn>() { trkRef };
                TrkOns seqDef = new TrkOns(trkRefs, null);

                InputNoteDef inputNoteDef = new InputNoteDef(64, seqDef, null, null);

                List<InputNoteDef> inputNoteDefs = new List<InputNoteDef>(){inputNoteDef};
                InputChordDef inputChordDef = new InputChordDef(msPos, startMsDifference, inputNoteDefs);
                inputVoiceDef.InsertInRest(inputChordDef);
                msPos += startMsDifference;
            }

            bar.Add(inputVoiceDef);
            return bar;
        }