Ejemplo n.º 1
0
        //

        public void EditNoteProperties()
        {
            NoteObjectRec selectedNote;

            if (trackViewControl.TryGetSelectedNote(out selectedNote))
            {
                if (selectedNote is NoteNoteObjectRec)
                {
                    NoteNoteObjectRec note = (NoteNoteObjectRec)selectedNote;
                    NoteNoteObjectRec copy = new NoteNoteObjectRec(note, new TrackObjectRec(new Document()));
                    using (NoteAttributeDialog noteAttributeDialog = new NoteAttributeDialog(copy))
                    {
                        DialogResult result = noteAttributeDialog.ShowDialog();
                        if (result == DialogResult.OK)
                        {
                            note.CopyFrom(copy);
                        }
                    }
                }
                else if (selectedNote is CommandNoteObjectRec)
                {
                    CommandNoteObjectRec command = (CommandNoteObjectRec)selectedNote;
                    EditCommandParameters.EditCommandAttributes(command);
                }
            }

            trackViewControl.TrackObjectAlteredAtSelection();
        }
Ejemplo n.º 2
0
            public override string GetValue(NoteNoteObjectRec note)
            {
                T   value = getValue(note);
                int i     = FindIndex(value);

                return(possibleValues[i].text);
            }
Ejemplo n.º 3
0
        /* determine if note is an integer multiple of a 64th div3 */
        public static bool IntMultOf64thDiv3(NoteFlags Opcode)
        {
            FractionRec OpcodesDuration;

            NoteNoteObjectRec.ConvertDurationFrac(Opcode, out OpcodesDuration);
            return(FractionIntMultOf64thDiv3(OpcodesDuration));
        }
Ejemplo n.º 4
0
        /* quantize the start time */
        private static void QuantizeStartTime(
            int StartTime,
            int QuarterNoteLen,
            NoteFlags QuantizedDuration,
            double QuantizedDurationAdjust,
            out FractionRec StartTimeOut,
            out double StartTimeAdjustOut,
            out double WholeNoteStartTimeAdjust)
        {
            uint        Denominator;
            double      QuantizedStartTime;
            double      OrigDuration;
            FractionRec OrigDurationFractional;

            /* start times must be a multiple of the 64th note.  see rationale */
            /* in comment at top of this file. */
            Denominator = 64;

            NoteNoteObjectRec.ConvertDurationFrac(QuantizedDuration, out OrigDurationFractional);
            OrigDuration = (4 * QuarterNoteLen) * QuantizedDurationAdjust
                           * FractionRec.Fraction2Double(OrigDurationFractional);

            /* compute start time to nearest division they allow */
            FractionRec.Double2Fraction(StartTime / (double)(QuarterNoteLen * 4), Denominator, out StartTimeOut);

            /* set start time adjust (relative to duration) */
            QuantizedStartTime       = FractionRec.Fraction2Double(StartTimeOut) * (4 * QuarterNoteLen);
            StartTimeAdjustOut       = (QuantizedStartTime - StartTime) / OrigDuration;
            WholeNoteStartTimeAdjust = (QuantizedStartTime - StartTime) / (4 * QuarterNoteLen);
        }
Ejemplo n.º 5
0
        // returns width
        // requiring Graphics passed in is a bit hacky
        public int Add(int x, NoteNoteObjectRec note, Graphics graphics)
        {
            Info one;

            info.Add(one = new Info(x, MeasureWidth(graphics, note), note));
            Invalidate2();
            return(one.width);
        }
Ejemplo n.º 6
0
            public override void SetValue(NoteNoteObjectRec note, string value)
            {
                double d;

                if (Double.TryParse(value, out d))
                {
                    setValue(note, d);
                }
            }
Ejemplo n.º 7
0
        private void SetValue(NoteNoteObjectRec note, InlineParamVis param, string value)
        {
            ValueInfo valueInfo = ValueInfo.FindInlineParamVis(param);

            valueInfo.SetValue(note, value);
            if (ValueChanged != null)
            {
                ValueChanged.Invoke(this, EventArgs.Empty);
            }
        }
Ejemplo n.º 8
0
 public override string GetValue(NoteNoteObjectRec Note)
 {
     if (-1 == Note.GetNoteMultisampleFalsePitch())
     {
         return("dflt");
     }
     else
     {
         return(SymbolicPitch.NumericPitchToString(Note.GetNoteMultisampleFalsePitch(), 0));
     }
 }
Ejemplo n.º 9
0
 public override void SetValue(NoteNoteObjectRec note, string value)
 {
     for (int i = 0; i < possibleValues.Length; i++)
     {
         if (String.Equals(value, possibleValues[i].text))
         {
             setValue(note, possibleValues[i].value);
             return;
         }
     }
     // if new value is invalid then ignore - this can happen under certain user editing scenarios
 }
Ejemplo n.º 10
0
        /* determine if fraction is an integer multiple of a 64th div3 */
        public static bool FractionIntMultOf64thDiv3(FractionRec Fraction)
        {
            FractionRec SixtyFourthDiv3;
            FractionRec SixtyFourthDiv3Reciprocal;
            FractionRec Product;

            NoteNoteObjectRec.ConvertDurationFrac(NoteFlags.e64thNote | NoteFlags.eDiv3Modifier, out SixtyFourthDiv3);
            Debug.Assert((SixtyFourthDiv3.Integer == 0) && (SixtyFourthDiv3.Fraction != 0)); // "cute problem"
            FractionRec.MakeFraction(out SixtyFourthDiv3Reciprocal, 0, (int)SixtyFourthDiv3.Denominator,
                                     (int)SixtyFourthDiv3.Fraction);                         /* reciprocal */
            FractionRec.MultFractions(Fraction, SixtyFourthDiv3Reciprocal, out Product);
            /* if fraction == 0 then it is an even multiple of the 64th note */
            return(Product.Fraction == 0);
        }
Ejemplo n.º 11
0
            public override void DoClick(NoteNoteObjectRec note, int noteIndex, IValueInfoOwner owner)
            {
                owner.SaveUndoInfo("Change Note Property");

                T   value = getValue(note);
                int i     = FindIndex(value);

                i = (i + 1) % possibleValues.Length;
                setValue(note, possibleValues[i].value);

                if (owner.FocusReturnsTo != null)
                {
                    owner.FocusReturnsTo.Focus();
                }
            }
Ejemplo n.º 12
0
 public override void SetValue(NoteNoteObjectRec Note, string value)
 {
     if (String.Equals(value, GetDefaultValue()))
     {
         Note.PutNoteMultisampleFalsePitch(-1);
     }
     else
     {
         short     pitch     = Note.GetNoteMultisampleFalsePitch();
         NoteFlags sharpFlat = Note.SharpFlat;
         SymbolicPitch.StringToNumericPitch(value, ref pitch, ref sharpFlat);
         Note.PutNoteMultisampleFalsePitch(pitch);
         Note.PutNoteFlatOrSharpStatus(sharpFlat);
     }
 }
Ejemplo n.º 13
0
        private int MeasureWidth(Graphics graphics, NoteNoteObjectRec note)
        {
            int width = 0;

            for (int i = 0; i < lines.Count; i++)
            {
                int width1 = MyTextRenderer.MeasureText(
                    graphics,
                    GetValue(note, lines[i]),
                    Font,
                    new Size(Int16.MaxValue, FontHeight),
                    Flags).Width;
                width = Math.Max(width, width1);
            }
            return(width);
        }
Ejemplo n.º 14
0
        /* add a quant-note pair */
        public static void TieMappingAddPair(
            TieMappingRec Mapping,
            QuantEventRec QuantEvent,
            NoteNoteObjectRec NoteEvent)
        {
            NodeRec NewNode;

            /* allocate */
            if (Mapping.FreeList == null)
            {
                ExpandFreeList(Mapping);
            }
            /* unlink first mapping entry */
            NewNode          = Mapping.FreeList;
            Mapping.FreeList = Mapping.FreeList.Next;
            /* fill in fields */
            NewNode.Key   = QuantEvent;
            NewNode.Value = NoteEvent;
            NewNode.Next  = Mapping.List;
            Mapping.List  = NewNode;
        }
Ejemplo n.º 15
0
        public NoteAttributeDialog(NoteNoteObjectRec note)
        {
            this.note = note;

            InitializeComponent();
            this.Icon = OutOfPhase.Properties.Resources.Icon2;

            DpiChangeHelper.ScaleFont(this, Program.Config.AdditionalUIZoom);

            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.ReleasePoint1OriginAllowedValues, NoteNoteObjectRec.ReleasePoint1Origin_EnumCategoryName))
            {
                comboBoxRelease1Origin.Items.Add(item);
            }
            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.ReleasePoint2OriginAllowedValues, NoteNoteObjectRec.ReleasePoint2Origin_EnumCategoryName))
            {
                comboBoxRelease2Origin.Items.Add(item);
            }
            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.ReleasePoint3OriginAllowedValues, NoteNoteObjectRec.ReleasePoint3Origin_EnumCategoryName))
            {
                comboBoxRelease3Origin.Items.Add(item);
            }
            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.PitchDisplacementOriginAllowedValues, NoteNoteObjectRec.PitchDisplacementOrigin_EnumCategoryName))
            {
                comboBoxPitchDisplacementOrigin.Items.Add(item);
            }
            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.PortamentoUnitsAllowedValues, NoteNoteObjectRec.PortamentoUnits_EnumCategoryName))
            {
                comboBoxPortamentoUnits.Items.Add(item);
            }
            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.DurationAdjustModeAllowedValues, NoteNoteObjectRec.DurationAdjustMode_EnumCategoryName))
            {
                comboBoxDurationAdjustMode.Items.Add(item);
            }
            foreach (string item in EnumUtility.GetDescriptions(NoteNoteObjectRec.DetuningModeAllowedValues, NoteNoteObjectRec.DetuningMode_EnumCategoryName))
            {
                comboBoxDetuningMode.Items.Add(item);
            }

            noteNoteObjectRecBindingSource.Add(this.note);
        }
Ejemplo n.º 16
0
        /* insert rests */
        private static void InsertRests(
            FractionRec Now,
            FractionRec Target,
            TrackObjectRec NoteTrack,
            OpDurRec[] OpcodeDurationTable,
            int OpcodeDurationTableLength)
        {
            while (FractionRec.FracGreaterThan(Target, Now))
            {
                FractionRec       Difference;
                NoteFlags         Opcode;
                FractionRec       OpcodesDuration;
                NoteNoteObjectRec Note;
                FrameObjectRec    Frame;

                /* how much time left */
                FractionRec.SubFractions(Target, Now, out Difference);
                /* search for appropriate opcode */
                Opcode = GetMaxDurationOpcode(Difference, out OpcodesDuration, OpcodeDurationTable, OpcodeDurationTableLength);

                /* add duration to Now */
                FractionRec.AddFractions(Now, OpcodesDuration, out Now);

                /* create the note */
                Note = new NoteNoteObjectRec(NoteTrack);
                Note.PutNoteDuration(Opcode & NoteFlags.eDurationMask);
                Note.PutNoteDurationDivision(Opcode & NoteFlags.eDivisionMask);
                Note.PutNoteDotStatus((Opcode & NoteFlags.eDotModifier) != 0);
                Note.PutNotePitch(Constants.CENTERNOTE);
                Note.PutNoteIsItARest(true);
                /* create the frame */
                Frame = new FrameObjectRec();
                Frame.Add(Note);
                NoteTrack.FrameArray.Add(Frame);
            }
        }
Ejemplo n.º 17
0
 public abstract void DoClick(NoteNoteObjectRec note, int noteIndex, IValueInfoOwner owner);
Ejemplo n.º 18
0
 public abstract string GetValue(NoteNoteObjectRec note);
Ejemplo n.º 19
0
 public abstract void SetValue(NoteNoteObjectRec note, string value);
Ejemplo n.º 20
0
        /* convert interval track into quantized track. */
        public static bool ConvertIntervalToQuantized(
            IntervalTrackRec IntervalTrack,
            QuantizedTrackRec QuantizedTrack,
            int MidiQuarterNote)
        {
            int Scan;
            int Limit;

            TimeMatchRec[] MatchingTable = new TimeMatchRec[4 /*divisions*/ * 2 /*dot*/ * 9 /*notetypes*/];
            int            MatchingTableLength;

            /* build duration matching table */
            MatchingTableLength = 0;
            for (Scan = 0; Scan < 4 /*divisions*/ * 2 /*dot*/ * 9 /*notetypes*/; Scan += 1)
            {
                double      MIDIClocks;
                NoteFlags   Descriptor;
                FractionRec DurationFraction;

                /* determine root duration and descriptor */
                switch (Scan % 9)
                {
                default:
                    Debug.Assert(false);
                    throw new InvalidOperationException();

                case 0:
                    Descriptor = NoteFlags.e64thNote;
                    break;

                case 1:
                    Descriptor = NoteFlags.e32ndNote;
                    break;

                case 2:
                    Descriptor = NoteFlags.e16thNote;
                    break;

                case 3:
                    Descriptor = NoteFlags.e8thNote;
                    break;

                case 4:
                    Descriptor = NoteFlags.e4thNote;
                    break;

                case 5:
                    Descriptor = NoteFlags.e2ndNote;
                    break;

                case 6:
                    Descriptor = NoteFlags.eWholeNote;
                    break;

                case 7:
                    Descriptor = NoteFlags.eDoubleNote;
                    break;

                case 8:
                    Descriptor = NoteFlags.eQuadNote;
                    break;
                }

                /* determine if dot is needed */
                if (((Scan / 9) % 2) != 0)
                {
                    /* dot needed */
                    Descriptor |= NoteFlags.eDotModifier;
                }

                /* determine what division is needed */
                switch (((Scan / 9) / 2) % 4)
                {
                default:
                    Debug.Assert(false);
                    throw new InvalidOperationException();

                case 0:
                    break;

                case 1:
                    Descriptor |= NoteFlags.eDiv3Modifier;
                    break;

                case 2:
                    Descriptor |= NoteFlags.eDiv5Modifier;
                    break;

                case 3:
                    Descriptor |= NoteFlags.eDiv7Modifier;
                    break;
                }

                /* how int is this note */
                NoteNoteObjectRec.ConvertDurationFrac(Descriptor, out DurationFraction); /* units of whole notes */
                MIDIClocks = MidiQuarterNote * (4 * FractionRec.Fraction2Double(DurationFraction));

                /* add to table if note can be represented in the timing scheme */
                /* AND only if note is an integer multiple of the 64th div3 (see */
                /* comment at the top of this file for the rationale) */
                if ((MIDIClocks == Math.Floor(MIDIClocks)) && (MIDIClocks >= 1) && IntMultOf64thDiv3(Descriptor))
                {
                    MatchingTable[MatchingTableLength].Ticks      = (int)MIDIClocks;
                    MatchingTable[MatchingTableLength].Descriptor = Descriptor;
                    MatchingTableLength += 1;
                }
            }

            /* quantize note events */
            Limit = GetIntervalTrackLength(IntervalTrack);
            for (Scan = 0; Scan < Limit; Scan += 1)
            {
                IntEventRec Event;

                Event = GetIntervalTrackIndexedEvent(IntervalTrack, Scan);
                switch (IntervalEventGetType(Event))
                {
                default:
                    Debug.Assert(false);
                    throw new InvalidOperationException();

                case IntEventType.eIntervalNoteEvent:
                {
                    /* input values */
                    int   StartTime;
                    int   Duration;
                    short MIDIPitch;
                    short MIDIAttackVelocity;
                    short MIDIReleaseVelocity;
                    /* output values */
                    NoteFlags   QuantizedDuration;
                    double      QuantizedDurationAdjust;
                    int         WholeNoteOverflow;
                    FractionRec QuantizedStartTime;
                    double      QuantizedStartTimeAdjust;
                    double      WholeNoteStartTimeAdjust;    /* auxiliary value */
                    /* stuff */
                    QuantEventRec QuantEvent;

                    /* get the information */
                    GetIntervalNoteEventInfo(Event, out StartTime, out Duration, out MIDIPitch,
                                             out MIDIAttackVelocity, out MIDIReleaseVelocity);

                    /* quantize duration */
                    QuantizeDuration(Duration, MidiQuarterNote, MatchingTable,
                                     MatchingTableLength, out QuantizedDuration, out QuantizedDurationAdjust,
                                     out WholeNoteOverflow);
                    Debug.Assert(IntMultOf64thDiv3(QuantizedDuration));         // non-64div3 duration quantization?

                    /* quantize start time */
                    QuantizeStartTime(StartTime, MidiQuarterNote, QuantizedDuration,
                                      QuantizedDurationAdjust, out QuantizedStartTime, out QuantizedStartTimeAdjust,
                                      out WholeNoteStartTimeAdjust);
                    Debug.Assert(FractionIntMultOf64thDiv3(QuantizedStartTime));         // non-64div3 start time quantization?

                    /* bump start time to end of whole note chain */
                    QuantizedStartTime.Integer += (uint)WholeNoteOverflow;

                    /* create new event & insert into track */
                    QuantEvent = NewQuantizedNoteEvent(QuantizedStartTime,
                                                       QuantizedStartTimeAdjust, QuantizedDuration, QuantizedDurationAdjust,
                                                       MIDIPitch, MIDIAttackVelocity, MIDIReleaseVelocity);
                    QuantizedTrackInsertEventSorted(QuantizedTrack, QuantEvent);

                    /* insert whole notes behind the last note in reverse order */
                    while (WholeNoteOverflow > 0)
                    {
                        QuantEventRec Predecessor;

                        /* create preceding whole note */
                        QuantizedStartTime.Integer -= 1;
                        Predecessor = NewQuantizedNoteEvent(QuantizedStartTime,
                                                            WholeNoteStartTimeAdjust, NoteFlags.eWholeNote, 1, MIDIPitch,
                                                            MIDIAttackVelocity, MIDIReleaseVelocity);
                        QuantizedTrackInsertEventSorted(QuantizedTrack, Predecessor);
                        /* set tie */
                        PutQuantizedEventTieTarget(Predecessor, QuantEvent);
                        QuantEvent = Predecessor;
                        /* step */
                        WholeNoteOverflow -= 1;
                    }
                }
                break;

                case IntEventType.eIntervalCommentEvent:
                {
                    QuantEventRec QuantEvent;
                    /* input values */
                    int    StartTime;
                    string OriginalString;
                    /* output values */
                    FractionRec QuantizedStartTime;

                    /* get the information */
                    GetIntervalCommentEventInfo(Event, out StartTime, out OriginalString);

                    /* compute start time to nearest 64th div3 */
                    FractionRec.Double2Fraction(StartTime / (double)MidiQuarterNote,
                                                64 * 3, out QuantizedStartTime);
                    Debug.Assert(FractionIntMultOf64thDiv3(QuantizedStartTime));         //non-64div3 start time quantization?

                    /* create new event & insert into track */
                    QuantEvent = NewQuantizedCommentEvent(QuantizedStartTime, 0, OriginalString);
                    QuantizedTrackInsertEventSorted(QuantizedTrack, QuantEvent);
                }
                break;
                }
            }

            return(true);
        }
Ejemplo n.º 21
0
 public override void DoClick(NoteNoteObjectRec note, int noteIndex, IValueInfoOwner owner)
 {
     owner.BeginFieldEdit(this, noteIndex, GetValue(note));
 }
Ejemplo n.º 22
0
 public Info(int x, int width, NoteNoteObjectRec note)
 {
     this.x     = x;
     this.width = width;
     this.note  = note;
 }
Ejemplo n.º 23
0
        private string GetValue(NoteNoteObjectRec note, InlineParamVis param)
        {
            ValueInfo valueInfo = ValueInfo.FindInlineParamVis(param);

            return(valueInfo.GetValue(note));
        }
Ejemplo n.º 24
0
        /* construct a new oscillator bank state object based on the note.  the note is */
        /* assumed to start "now" in terms of the parameters in the ParameterUpdator.  */
        /* the ScanningGapWidth is the number of envelope clock ticks in the current scanning */
        /* gap.  this is used to determine how far later than "now" in terms of the back */
        /* edge of the scanning gap (different from above) the osc bank should start playing. */
        /* *WhenToStartPlayingOut returns the number of envelope ticks after the back edge */
        /* of the scanning gap that the note should be started. */
        /*     <already played>       |    <scanning gap>     |    <not yet analyzed> */
        /*   time ---.    time ---.    time ---.    time ---.    time ---.   time ---. */
        /*                            ^A                      ^B     */
        /* point A is the back edge of the scanning gap.  as this edge moves forward in time, */
        /*   oscillator bank state objects are removed from the queue and playback is commenced */
        /*   for them. */
        /* point B is the front edge of the scanning gap.  as this edge moves forward in time, */
        /*   notes are extracted from the track and state bank objects are created for them. */
        /*   ParameterUpdator always reflects parameters at this point in time. */
        public static SynthErrorCodes NewOscBankState(
            OscBankTemplateRec Template,
            out int WhenToStartPlayingOut,
            NoteNoteObjectRec Note,
            double EnvelopeTicksPerDurationTick,
            short PitchIndexAdjust,
            PlayTrackInfoRec TrackInfo,
            SynthParamRec SynthParams,
            out OscStateBankRec StateOut)
        {
            int ThisPreOriginTime;
            int StartPointAdjust;

            WhenToStartPlayingOut = 0;
            StateOut = null;

            int MaxOscillatorPreOriginTime = 0;

            OscStateBankRec State = New(ref SynthParams.freelists.oscStateBankFreeList);

            // all fields must be assigned: State

            State.PortamentoHertz      = false;
            State.TotalPortamentoTicks = 0;
            State.InitialFrequency     = 0;
            State.FinalFrequency       = 0;

            State.BankTemplate = Template;

            /* freeze the parameters */
            FrozenNoteRec FrozenNote = new FrozenNoteRec();

            FixNoteParameters(
                Template.ParamUpdator,
                Note,
                out StartPointAdjust,
                EnvelopeTicksPerDurationTick,
                PitchIndexAdjust,
                ref FrozenNote,
                SynthParams);


            /* this calculates the differential values for periodic pitch displacements */
            State.PitchLFO = NewLFOGenerator(
                Template.PitchLFOTemplate,
                out ThisPreOriginTime,
                ref FrozenNote.Accents,
                FrozenNote.NominalFrequency,
                FrozenNote.HurryUpFactor,
                FrozenNote.PitchDisplacementDepthLimit,
                FrozenNote.PitchDisplacementRateLimit,
                FrozenNote.MultisampleFrequency,
                _PlayTrackParamGetter,
                TrackInfo,
                SynthParams);
            if (ThisPreOriginTime > MaxOscillatorPreOriginTime)
            {
                MaxOscillatorPreOriginTime = ThisPreOriginTime;
            }

            /* list of oscillators that this oscillator bank is comprised of */
            State.OscillatorList = null;
            for (int i = 0; i < Template.NumOscillatorsInBank; i++)
            {
                OscStateRec OneState = New(ref SynthParams.freelists.oscStateFreeList);

                // all fields must be assigned: OneState

                /* link it in */
                OneState.Next        = State.OscillatorList;
                State.OscillatorList = OneState;

                /* copy over the function vectors */
                OneState.Template = Template.TemplateArray[i];

                /* create the oscillator */
                SynthErrorCodes Result = OneState.Template.TemplateReference.NewState(
                    FrozenNote.MultisampleFrequency,
                    ref FrozenNote.Accents,
                    FrozenNote.LoudnessAdjust * Template.InstrOverallLoudness,
                    FrozenNote.HurryUpFactor,
                    out ThisPreOriginTime,
                    FrozenNote.StereoPosition,
                    FrozenNote.NominalFrequency,
                    FrozenNote.PitchDisplacementDepthLimit,
                    FrozenNote.PitchDisplacementRateLimit,
                    FrozenNote.PitchDisplacementStartPoint,
                    TrackInfo,
                    SynthParams,
                    out OneState.StateReference);
                if (Result != SynthErrorCodes.eSynthDone)
                {
                    return(Result);
                }
                if (ThisPreOriginTime > MaxOscillatorPreOriginTime)
                {
                    MaxOscillatorPreOriginTime = ThisPreOriginTime;
                }
            }

            State.CombinedOscEffectGenerator = null;
            if ((Template.CombinedOscillatorEffects != null) && (GetEffectSpecListLength(Template.CombinedOscillatorEffects) > 0))
            {
                SynthErrorCodes Result = NewOscEffectGenerator(
                    Template.CombinedOscillatorEffects,
                    ref FrozenNote.Accents,
                    FrozenNote.HurryUpFactor,
                    FrozenNote.NominalFrequency,
                    FrozenNote.MultisampleFrequency,
                    out ThisPreOriginTime,
                    TrackInfo,
                    SynthParams,
                    out State.CombinedOscEffectGenerator);
                if (Result != SynthErrorCodes.eSynthDone)
                {
                    return(Result);
                }
                if (ThisPreOriginTime > MaxOscillatorPreOriginTime)
                {
                    MaxOscillatorPreOriginTime = ThisPreOriginTime;
                }
            }
            /* else no combined oscillator effects, State.CombinedOscEffectGenerator is null */

            /* if this object ties to a note, then this is the note */
            /* to tie to.  this is used for finding existing oscillators */
            /* for tie continuations. */
            State.TieToNote = Note._Tie;

            /* portamento control parameters */
            State.PortamentoCounter = 0;
            State.CurrentFrequency  = FrozenNote.NominalFrequency;


            /* fix up pre-origin times */
            OscStateRec StateScan = State.OscillatorList;

            while (StateScan != null)
            {
                StateScan.StateReference.FixUpPreOrigin(
                    MaxOscillatorPreOriginTime);
                StateScan = StateScan.Next;
            }
            LFOGeneratorFixEnvelopeOrigins(
                State.PitchLFO,
                MaxOscillatorPreOriginTime);
            if (State.CombinedOscEffectGenerator != null)
            {
                FixUpOscEffectGeneratorPreOrigin(
                    State.CombinedOscEffectGenerator,
                    MaxOscillatorPreOriginTime);
            }

            /* various counters (in terms of envelope ticks) */
            if (State.TieToNote == null)
            {
                State.Release1Countdown = FrozenNote.ReleasePoint1 + MaxOscillatorPreOriginTime;
                State.Release2Countdown = FrozenNote.ReleasePoint2 + MaxOscillatorPreOriginTime;
                State.Release3Countdown = FrozenNote.ReleasePoint3 + MaxOscillatorPreOriginTime;
            }
            else
            {
                /* for ties, only honor releases from start */
                if (FrozenNote.Release1FromStart)
                {
                    State.Release1Countdown = FrozenNote.ReleasePoint1 + MaxOscillatorPreOriginTime;
                }
                else
                {
                    State.Release1Countdown = -1;
                }
                if (FrozenNote.Release2FromStart)
                {
                    State.Release2Countdown = FrozenNote.ReleasePoint2 + MaxOscillatorPreOriginTime;
                }
                else
                {
                    State.Release2Countdown = -1;
                }
                if (FrozenNote.Release3FromStart)
                {
                    State.Release3Countdown = FrozenNote.ReleasePoint3 + MaxOscillatorPreOriginTime;
                }
                else
                {
                    State.Release3Countdown = -1;
                }
            }
            State.PitchLFOStartCountdown = FrozenNote.PitchDisplacementStartPoint
                                           /*+ MaxOscillatorPreOriginTime*/;
            /* pre origin relationship must be preserved for */
            /* pitch LFO trigger */

            /* done */
            WhenToStartPlayingOut = StartPointAdjust - MaxOscillatorPreOriginTime;
            StateOut = State;
            return(SynthErrorCodes.eSynthDone);
        }
Ejemplo n.º 25
0
        /* fill in opcode table and sort for largest-duration first */
        private static void InitializeOpcodeDurationTable(
            OpDurRec[] Table, // [4/*divisions*/ * 2/*dot*/ * 9/*notetypes*/]
            out int TableLengthOut)
        {
            Debug.Assert(Table.Length == 4 /*divisions*/ * 2 /*dot*/ * 9 /*notetypes*/);
            /* scan all possible notes */
            TableLengthOut = 0;
            for (int Scan = 0; Scan < 4 /*divisions*/ * 2 /*dot*/ * 9 /*notetypes*/; Scan += 1)
            {
                NoteFlags   Descriptor;
                FractionRec DurationFraction;
                int         InsertScan;
                int         EndScan;

                /* determine root duration and descriptor */
                switch (Scan % 9)
                {
                default:
                    Debug.Assert(false);
                    throw new InvalidOperationException();

                case 0:
                    Descriptor = NoteFlags.e64thNote;
                    break;

                case 1:
                    Descriptor = NoteFlags.e32ndNote;
                    break;

                case 2:
                    Descriptor = NoteFlags.e16thNote;
                    break;

                case 3:
                    Descriptor = NoteFlags.e8thNote;
                    break;

                case 4:
                    Descriptor = NoteFlags.e4thNote;
                    break;

                case 5:
                    Descriptor = NoteFlags.e2ndNote;
                    break;

                case 6:
                    Descriptor = NoteFlags.eWholeNote;
                    break;

                case 7:
                    Descriptor = NoteFlags.eDoubleNote;
                    break;

                case 8:
                    Descriptor = NoteFlags.eQuadNote;
                    break;
                }

                /* determine if dot is needed */
                if (((Scan / 9) % 2) != 0)
                {
                    /* dot needed */
                    Descriptor |= NoteFlags.eDotModifier;
                }

                /* determine what division is needed */
                switch (((Scan / 9) / 2) % 4)
                {
                default:
                    Debug.Assert(false);
                    throw new InvalidOperationException();

                case 0:
                    break;

                case 1:
                    Descriptor |= NoteFlags.eDiv3Modifier;
                    break;

                case 2:
                    Descriptor |= NoteFlags.eDiv5Modifier;
                    break;

                case 3:
                    Descriptor |= NoteFlags.eDiv7Modifier;
                    break;
                }

                /* don't use ugly rests, except we need the 64th div3 (see below) */
                if (!(((Descriptor & NoteFlags.eDivisionMask) == NoteFlags.eDiv5Modifier) ||
                      ((Descriptor & NoteFlags.eDivisionMask) == NoteFlags.eDiv7Modifier) ||
                      ((Descriptor & NoteFlags.eDotModifier) != 0) ||
                      (((Descriptor & NoteFlags.eDivisionMask) == NoteFlags.eDiv3Modifier) &&
                       ((Descriptor & NoteFlags.eDurationMask) != NoteFlags.e64thNote))))
                {
                    /* don't use things that aren't multiples of a 64th div3 note.  see the */
                    /* comment at the top of ConvertIntToQuant for the rationale. */
                    if (IntMultOf64thDiv3(Descriptor))
                    {
                        /* get duration, units of whole notes */
                        NoteNoteObjectRec.ConvertDurationFrac(Descriptor, out DurationFraction);

                        /* add duration to table */
                        InsertScan = 0;
                        while (InsertScan < TableLengthOut)
                        {
                            if (FractionRec.FracGreaterThan(DurationFraction, Table[InsertScan].Duration))
                            {
                                /* insert here */
                                goto InsertNowPoint;
                            }
                            else if (FractionRec.FractionsEqual(DurationFraction, Table[InsertScan].Duration))
                            {
                                /* redundant */
                                goto DoneInsertingPoint;
                            }
                            else
                            {
                                /* try the next one */
                                InsertScan += 1;
                            }
                        }
                        /* this gets executed to insert a new value before Table[InsertScan] */
InsertNowPoint:
                        for (EndScan = TableLengthOut - 1; EndScan >= InsertScan; EndScan -= 1)
                        {
                            Table[EndScan + 1] = Table[EndScan];
                        }
                        Table[InsertScan].Opcode   = Descriptor;
                        Table[InsertScan].Duration = DurationFraction;
                        TableLengthOut++;

DoneInsertingPoint:
                        ;
                    }
                }
            }

            /* verify sort order */
#if DEBUG
            for (int Scan = 0; Scan < TableLengthOut - 1; Scan += 1)
            {
                if (!FractionRec.FracGreaterThan(Table[Scan].Duration, Table[Scan + 1].Duration))
                {
                    // sort failure
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }
            }
#endif
        }
Ejemplo n.º 26
0
        /* convert quantized track into native track */
        public static void ConvertQuantToNote(
            QuantizedTrackRec QuantizedTrack,
            TrackObjectRec NoteTrack)
        {
            FractionRec          CurrentTime;
            int                  Index;
            int                  Limit;
            List <QuantEventRec> FrameArray;
            TieMappingRec        TieMapping;
            int                  OpcodeDurationTableLength;

            OpDurRec[] OpcodeDurationTable = new OpDurRec[4 /*divisions*/ * 2 /*dot*/ * 9 /*notetypes*/];

            /* initialize variables */
            InitializeOpcodeDurationTable(OpcodeDurationTable, out OpcodeDurationTableLength);
            CurrentTime.Integer     = 0;
            CurrentTime.Fraction    = 0;
            CurrentTime.Denominator = 1;
            FrameArray = new List <QuantEventRec>();
            TieMapping = NewTieMapping();
            Limit      = GetQuantizedTrackLength(QuantizedTrack);
            Index      = 0;

            /* iterate over variables */
            while (Index < Limit)
            {
                FractionRec   NextTime;
                QuantEventRec QuantEvent;
                bool          Continue;
                int           InspectScan;

                /* reset frame array */
                FrameArray.Clear();

                /* get the start time of the next available event */
                QuantEvent = GetQuantizedTrackIndexedEvent(QuantizedTrack, Index);
                NextTime   = GetQuantizedEventTime(QuantEvent);
                Debug.Assert(FractionIntMultOf64thDiv3(NextTime)); // non-64div3 start time quantization?

                /* sanity check */
                Debug.Assert(!FractionRec.FracGreaterThan(CurrentTime, NextTime)); // next time inconsistency

                /* get all events starting at this time into FrameArray */
                Continue = true;
                while (Continue && (Index < Limit))
                {
                    FractionRec EventTime;

                    /* get the event */
                    QuantEvent = GetQuantizedTrackIndexedEvent(QuantizedTrack, Index);
                    EventTime  = GetQuantizedEventTime(QuantEvent);
                    Debug.Assert(FractionIntMultOf64thDiv3(EventTime)); // non-64div3 start time quantization?
                    if (FractionRec.FractionsEqual(EventTime, NextTime))
                    {
                        /* add event to the list */
                        FrameArray.Add(QuantEvent);
                        /* go past this event */
                        Index += 1;
                    }
                    else
                    {
                        /* end hit so stop */
                        Continue = false;
                    }
                }

                /* insert rests to bring current time up to next time */
                InsertRests(CurrentTime, NextTime, NoteTrack, OpcodeDurationTable, OpcodeDurationTableLength);

                /* remove command events from list */
                InspectScan = 0;
                while (InspectScan < FrameArray.Count)
                {
                    /* get the event */
                    QuantEvent = FrameArray[InspectScan];
                    /* determine if event is a command */
                    if (QuantizedEventGetType(QuantEvent) == QuantEventType.eQuantizedNoteEvent)
                    {
                        /* note events should be skipped */
                        InspectScan += 1;
                    }
                    else
                    {
                        /* command events should be handled */
                        switch (QuantizedEventGetType(QuantEvent))
                        {
                        default:
                            Debug.Assert(false);
                            throw new InvalidOperationException();

                        case QuantEventType.eQuantizedCommentEvent:
                        {
                            string CommentString;
                            CommandNoteObjectRec Note;
                            FrameObjectRec       Frame;
                            FractionRec          unusedf;
                            double unusedd;

                            GetQuantizedCommentEventInfo(QuantEvent, out unusedf, out unusedd, out CommentString);
                            Note = new CommandNoteObjectRec(NoteTrack);
                            Note.PutCommandStringArg1(CommentString);
                            Note.PutCommandOpcode(NoteCommands.eCmdMarker);
                            Frame = new FrameObjectRec();
                            Frame.Add(Note);
                            NoteTrack.FrameArray.Add(Frame);
                        }
                        break;
                        }
                        /* delete event from array */
                        FrameArray.RemoveAt(InspectScan);
                        /* don't increment InspectScan */
                    }
                }

                /* process remaining notes in FrameArray, computing minimum duration */
                /* and updating CurrentTime with minimum duration. */
                if (FrameArray.Count != 0)
                {
                    NoteFlags      DurationOpcode;
                    FrameObjectRec Frame;
                    int            Scan;
                    int            FrameLimit;
                    FractionRec    MinimumDuration;
                    FractionRec    unusedf;
                    double         unusedd;
                    short          unuseds;

                    /* initialize minimum duration */
                    QuantEvent = FrameArray[0];
                    GetQuantizedNoteEventInfo(QuantEvent, out unusedf, out unusedd, out DurationOpcode,
                                              out unusedd, out unuseds, out unuseds, out unuseds);
                    NoteNoteObjectRec.ConvertDurationFrac(DurationOpcode, out MinimumDuration);
                    Debug.Assert(FractionIntMultOf64thDiv3(MinimumDuration)); // non-64div3 duration quantization?

                    /* allocate frame */
                    Frame = new FrameObjectRec();

                    /* process notes in frame */
                    FrameLimit = FrameArray.Count;
                    for (Scan = 0; Scan < FrameLimit; Scan += 1)
                    {
                        FractionRec       StartTime;
                        double            StartTimeAdjust;
                        NoteFlags         Duration;
                        double            DurationAdjust;
                        short             MIDIPitch;
                        short             MIDIAttackVelocity;
                        short             MIDIReleaseVelocity;
                        NoteNoteObjectRec Note;
                        FractionRec       FracDuration;

                        /* get the note */
                        QuantEvent = FrameArray[Scan];
                        Debug.Assert(QuantizedEventGetType(QuantEvent) == QuantEventType.eQuantizedNoteEvent); // non-note in frame array
                        /* get attributes */
                        GetQuantizedNoteEventInfo(QuantEvent, out StartTime, out StartTimeAdjust,
                                                  out Duration, out DurationAdjust, out MIDIPitch, out MIDIAttackVelocity,
                                                  out MIDIReleaseVelocity);
                        Debug.Assert(IntMultOf64thDiv3(Duration));                        // non-64div3 duration quantization?
                        Debug.Assert(FractionRec.FractionsEqual(StartTime, CurrentTime)); // start time inconsistency
                        /* create note */
                        Note = new NoteNoteObjectRec(NoteTrack);
                        Frame.Add(Note);
                        TieMappingAddPair(TieMapping, QuantEvent, Note);
                        /* set note attributes */
                        Note.PutNoteDuration(Duration & NoteFlags.eDurationMask);
                        Note.PutNoteDurationDivision(Duration & NoteFlags.eDivisionMask);
                        Note.PutNoteDotStatus((Duration & NoteFlags.eDotModifier) != 0);
                        Note.EarlyLateAdjust    = StartTimeAdjust;
                        Note.DurationAdjust     = DurationAdjust;
                        Note.DurationAdjustMode = NoteFlags.eDurationAdjustMultiplicative;
                        Note.PutNotePitch((short)(MIDIPitch - MIDIC + Constants.CENTERNOTE));
                        Note.Accent1 = (MIDIAttackVelocity > 0)
                            ? -Math.Log(MIDIAttackVelocity) / Constants.LOG2 + LN127OVERLN2 : 7;
                        Note.Accent2 = (MIDIReleaseVelocity > 0)
                            ? -Math.Log(MIDIReleaseVelocity) / Constants.LOG2 + LN127OVERLN2 : 7;
                        switch ((MIDIPitch - MIDIC + ((MIDIC / 12 + 1) * 12)) % 12)
                        {
                        default:
                            // midi sharp/flat problem
                            Debug.Assert(false);
                            throw new InvalidOperationException();

                        case 0:     /* C */
                        case 2:     /* D */
                        case 4:     /* E */
                        case 5:     /* F */
                        case 7:     /* G */
                        case 9:     /* A */
                        case 11:    /* B */
                            break;

                        case 1:     /* C# */
                        case 3:     /* D# */
                        case 6:     /* F# */
                        case 8:     /* G# */
                        case 10:    /* A# */
                            Note.PutNoteFlatOrSharpStatus(NoteFlags.eSharpModifier);
                            break;
                        }
                        /* do the minimum duration thing */
                        NoteNoteObjectRec.ConvertDurationFrac(Duration, out FracDuration);
                        Debug.Assert(FractionIntMultOf64thDiv3(FracDuration)); // non-64div3 duration quantization?
                        if (FractionRec.FracGreaterThan(MinimumDuration, FracDuration))
                        {
                            MinimumDuration = FracDuration;
                        }
                    }

                    /* add frame to track */
                    NoteTrack.FrameArray.Add(Frame);

                    /* if minimum duration is greater than time to next event, then */
                    /* add rests (one to this frame) to fill in the gap */
                    if (Index < Limit)
                    {
                        FractionRec NextEventTime;
                        FractionRec Difference;

                        /* get the start time of the next available event */
                        QuantEvent    = GetQuantizedTrackIndexedEvent(QuantizedTrack, Index);
                        NextEventTime = GetQuantizedEventTime(QuantEvent);
                        Debug.Assert(FractionIntMultOf64thDiv3(NextEventTime)); // non-64div3 start time quantization?
                        FractionRec.SubFractions(NextEventTime, CurrentTime, out Difference);
                        if (FractionRec.FracGreaterThan(MinimumDuration, Difference))
                        {
                            NoteNoteObjectRec Note;
                            NoteFlags         RestOpcode;
                            FractionRec       OpcodesDuration;

                            /* insert first rest into frame */
                            RestOpcode = GetMaxDurationOpcode(Difference, out OpcodesDuration,
                                                              OpcodeDurationTable, OpcodeDurationTableLength);
                            Debug.Assert(IntMultOf64thDiv3(RestOpcode)); // non-64div3 duration quantization
                            Note = new NoteNoteObjectRec(NoteTrack);
                            Note.PutNoteDuration(RestOpcode & NoteFlags.eDurationMask);
                            Note.PutNoteDurationDivision(RestOpcode & NoteFlags.eDivisionMask);
                            Note.PutNoteDotStatus((RestOpcode & NoteFlags.eDotModifier) != 0);
                            Note.PutNotePitch(Constants.CENTERNOTE);
                            Note.PutNoteIsItARest(true);
                            Frame.Add(Note);
                            /* put new minimum duration in to reflect new rest we added */
                            NoteNoteObjectRec.ConvertDurationFrac(RestOpcode, out MinimumDuration);
                        }
                    }

                    /* advance thing by minimum duration */
                    FractionRec.AddFractions(MinimumDuration, CurrentTime, out CurrentTime);
                    Debug.Assert(FractionIntMultOf64thDiv3(CurrentTime)); // non-64div3 start time quantization?
                }
            }

            /* patch up ties */
            for (Index = 0; Index < Limit; Index += 1)
            {
                QuantEventRec QuantEvent;

                /* get potential event */
                QuantEvent = GetQuantizedTrackIndexedEvent(QuantizedTrack, Index);
                /* see if it ties somewhere */
                if ((QuantEventType.eQuantizedNoteEvent == QuantizedEventGetType(QuantEvent)) &&
                    (GetQuantizedEventTieTarget(QuantEvent) != null))
                {
                    QuantEventRec     TieTarget;
                    NoteNoteObjectRec Source;
                    NoteNoteObjectRec Target;

                    /* get tie target */
                    TieTarget = GetQuantizedEventTieTarget(QuantEvent);
                    /* look up source and target note events */
                    Source = TieMappingLookup(TieMapping, QuantEvent);
                    Target = TieMappingLookup(TieMapping, TieTarget);
                    /* establish tie */
                    Source.PutNoteTieTarget(Target);
                }
            }

            /* look for track name comment */
            for (Index = 0; Index < Limit; Index += 1)
            {
                QuantEventRec QuantEvent;

                /* get potential event */
                QuantEvent = GetQuantizedTrackIndexedEvent(QuantizedTrack, Index);
                /* see if it ties somewhere */
                if (QuantEventType.eQuantizedCommentEvent == QuantizedEventGetType(QuantEvent))
                {
                    string      CommentString;
                    FractionRec unusedf;
                    double      unusedd;

                    GetQuantizedCommentEventInfo(QuantEvent, out unusedf, out unusedd, out CommentString);
                    /* check for track name */
                    if ((CommentString.Length > 11 /*Prefix*/ + Environment.NewLine.Length) &&
                        CommentString.StartsWith("Track Name" + Environment.NewLine))
                    {
                        string NameString = CommentString.Substring(11, CommentString.Length - (11 + 1));
                        NoteTrack.Name = NameString;
                        goto FinishedSettingTrackName;
                    }
                }
            }
            /* if no track name was found, then use the first comment string */
            for (Index = 0; Index < Limit; Index += 1)
            {
                QuantEventRec QuantEvent;

                /* get potential event */
                QuantEvent = GetQuantizedTrackIndexedEvent(QuantizedTrack, Index);
                /* see if it ties somewhere */
                if (QuantEventType.eQuantizedCommentEvent == QuantizedEventGetType(QuantEvent))
                {
                    string      CommentString;
                    FractionRec unusedf;
                    double      unusedd;

                    GetQuantizedCommentEventInfo(QuantEvent, out unusedf, out unusedd, out CommentString);
                    /* check for track name */
                    if ((CommentString.Length > 8 /*Prefix*/ + Environment.NewLine.Length) &&
                        CommentString.StartsWith("Comment" + Environment.NewLine))
                    {
                        string NameString;

                        NameString     = CommentString.Substring(8, CommentString.Length - (8 + 1));
                        NoteTrack.Name = NameString;
                        goto FinishedSettingTrackName;
                    }
                }
            }
FinishedSettingTrackName:
            ;
        }
Ejemplo n.º 27
0
 public override string GetValue(NoteNoteObjectRec note)
 {
     return(getValue(note).ToString());
 }
        /* build a new note object with all parameters determined.  *StartAdjustOut */
        /* indicates how many ticks before (negative) or after (positive) now that */
        /* the key-down should occur.  this is added to the scanning gap size and envelope */
        /* origins to figure out how to schedule the note */
        public static void FixNoteParameters(
            IncrParamUpdateRec GlobalParamSource,
            NoteNoteObjectRec Note,
            out int StartAdjustOut,
            double EnvelopeTicksPerDurationTick,
            short PitchIndexAdjust,
            ref FrozenNoteRec FrozenNote,
            SynthParamRec SynthParams)
        {
            // must assign all fields

            /* reference to the note that defines this note. */
            FrozenNote.OriginalNote = Note;

            /* frequency determined by pitch index + detuning, in Hertz */
            double NominalFrequency;
            {
                int i = Note._Pitch
                        + GlobalParamSource.TransposeHalfsteps
                        + PitchIndexAdjust;
                if (i < 0)
                {
                    i = 0;
                }
                else if (i > Constants.NUMNOTES - 1)
                {
                    i = Constants.NUMNOTES - 1;
                }
                /* compute frequency from index */
#if DEBUG
                if ((Constants.CENTERNOTE % 12) != 0)
                {
                    // CENTERNOTE multiple of 12
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
#endif
                double d = GlobalParamSource.FrequencyTable[i % 12].nd.Current;
                i = (i / 12) - (Constants.CENTERNOTE / 12);
                d = d * Math.Exp(i * Constants.LOG2) * Constants.MIDDLEC;
                /* apply detuning */
                double e;
                switch (Note.Flags & NoteFlags.eDetuningModeMask)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NoteFlags.eDetuningModeDefault:
                    e = (double)Note._Detuning * GlobalParamSource.Detune.nd.Current;
                    if (GlobalParamSource.DetuneHertz)
                    {
                        goto DetuneHertzPoint;
                    }
                    else
                    {
                        goto DetuneHalfStepsPoint;
                    }

                case NoteFlags.eDetuningModeHalfSteps:
                    e = (double)(Note._Detuning) + GlobalParamSource.Detune.nd.Current;
DetuneHalfStepsPoint:
                    NominalFrequency = d * Math.Exp((e / 12) * Constants.LOG2);
                    break;

                case NoteFlags.eDetuningModeHertz:
                    e = (double)Note._Detuning + GlobalParamSource.Detune.nd.Current;
DetuneHertzPoint:
                    NominalFrequency = d + e;
                    break;
                }
            }
            FrozenNote.NominalFrequency = NominalFrequency;

            /* frequency used for doing multisampling, in Hertz */
            if (Note._MultisamplePitchAsIf != -1)
            {
                /* compute frequency from index */
                int i = Note._MultisamplePitchAsIf;
#if DEBUG
                if ((Constants.CENTERNOTE % 12) != 0)
                {
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
#endif
                double d = GlobalParamSource.FrequencyTable[i % 12].nd.Current;
                i = (i / 12) - (Constants.CENTERNOTE / 12);
                d = d * Math.Exp(i * Constants.LOG2) * Constants.MIDDLEC;
                FrozenNote.MultisampleFrequency = d;
            }
            else
            {
                FrozenNote.MultisampleFrequency = NominalFrequency;
            }

            /* acceleration of envelopes */
            FrozenNote.HurryUpFactor = (double)Note._HurryUpFactor * GlobalParamSource.HurryUp.nd.Current;

            /* duration, in envelope ticks */
            int Duration;
            {
                int i;
                switch (Note.Flags & NoteFlags.eDurationMask)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NoteFlags.e64thNote:
                    i = DURATIONUPDATECLOCKRESOLUTION / 64;
                    break;

                case NoteFlags.e32ndNote:
                    i = DURATIONUPDATECLOCKRESOLUTION / 32;
                    break;

                case NoteFlags.e16thNote:
                    i = DURATIONUPDATECLOCKRESOLUTION / 16;
                    break;

                case NoteFlags.e8thNote:
                    i = DURATIONUPDATECLOCKRESOLUTION / 8;
                    break;

                case NoteFlags.e4thNote:
                    i = DURATIONUPDATECLOCKRESOLUTION / 4;
                    break;

                case NoteFlags.e2ndNote:
                    i = DURATIONUPDATECLOCKRESOLUTION / 2;
                    break;

                case NoteFlags.eWholeNote:
                    i = DURATIONUPDATECLOCKRESOLUTION;
                    break;

                case NoteFlags.eDoubleNote:
                    i = DURATIONUPDATECLOCKRESOLUTION * 2;
                    break;

                case NoteFlags.eQuadNote:
                    i = DURATIONUPDATECLOCKRESOLUTION * 4;
                    break;
                }
                switch (Note.Flags & NoteFlags.eDivisionMask)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NoteFlags.eDiv1Modifier:
                    break;

                case NoteFlags.eDiv3Modifier:
                    i = i / 3;
                    break;

                case NoteFlags.eDiv5Modifier:
                    i = i / 5;
                    break;

                case NoteFlags.eDiv7Modifier:
                    i = i / 7;
                    break;
                }
                if ((Note.Flags & NoteFlags.eDotModifier) != 0)
                {
                    i = (i * 3) / 2;
                }
                double d = i;
                switch (Note.Flags & NoteFlags.eDurationAdjustMask)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NoteFlags.eDurationAdjustDefault:
                    if (GlobalParamSource.DurationAdjustAdditive)
                    {
                        goto DurationAdjustAddPoint;
                    }
                    else
                    {
                        goto DurationAdjustMultPoint;
                    }

                case NoteFlags.eDurationAdjustAdditive:
DurationAdjustAddPoint:
                    d = d + (double)Note._DurationAdjust * (DURATIONUPDATECLOCKRESOLUTION / 4);
                    break;

                case NoteFlags.eDurationAdjustMultiplicative:
DurationAdjustMultPoint:
                    d = d * (double)Note._DurationAdjust;
                    break;
                }
                if (GlobalParamSource.DurationAdjustAdditive)
                {
                    d = d + GlobalParamSource.DurationAdjust.nd.Current * (DURATIONUPDATECLOCKRESOLUTION / 4);
                }
                else
                {
                    d = d * GlobalParamSource.DurationAdjust.nd.Current;
                }
                /* this line is what converts from duration update ticks to envelope ticks */
                Duration = (int)(d * EnvelopeTicksPerDurationTick);
            }
            FrozenNote.Duration = Duration;

            /* portamento duration, in envelope ticks */
            FrozenNote.PortamentoDuration = (int)(((double)Note._PortamentoDuration + GlobalParamSource.Portamento.nd.Current)
                                                  * (DURATIONUPDATECLOCKRESOLUTION / 4) * EnvelopeTicksPerDurationTick);

            /* see if portamento occurs before note retrigger */
            FrozenNote.PortamentoBeforeNote = ((Note.Flags & NoteFlags.ePortamentoLeadsNote) != 0);

            /* first release point, in envelope ticks after start of note */
            switch (Note.Flags & NoteFlags.eRelease1OriginMask)
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case NoteFlags.eRelease1FromStart:
                FrozenNote.ReleasePoint1     = (int)((double)Note._ReleasePoint1 * Duration);
                FrozenNote.Release1FromStart = true;
                break;

            case NoteFlags.eRelease1FromEnd:
                FrozenNote.ReleasePoint1     = (int)((1 - (double)Note._ReleasePoint1) * Duration);
                FrozenNote.Release1FromStart = false;
                break;

            case NoteFlags.eRelease1FromDefault:
                if (GlobalParamSource.ReleasePoint1FromStart)
                {
                    FrozenNote.ReleasePoint1 = (int)(((double)Note._ReleasePoint1
                                                      + GlobalParamSource.ReleasePoint1.nd.Current)
                                                     * Duration);
                    FrozenNote.Release1FromStart = true;
                }
                else
                {
                    FrozenNote.ReleasePoint1 = (int)((1 - ((double)Note._ReleasePoint1
                                                           + GlobalParamSource.ReleasePoint1.nd.Current))
                                                     * Duration);
                    FrozenNote.Release1FromStart = false;
                }
                break;
            }

            /* second release point, in envelope ticks after start of note */
            switch (Note.Flags & NoteFlags.eRelease2OriginMask)
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case NoteFlags.eRelease2FromStart:
                FrozenNote.ReleasePoint2     = (int)((double)Note._ReleasePoint2 * Duration);
                FrozenNote.Release2FromStart = true;
                break;

            case NoteFlags.eRelease2FromEnd:
                FrozenNote.ReleasePoint2     = (int)((1 - (double)Note._ReleasePoint2) * Duration);
                FrozenNote.Release2FromStart = false;
                break;

            case NoteFlags.eRelease2FromDefault:
                if (GlobalParamSource.ReleasePoint2FromStart)
                {
                    FrozenNote.ReleasePoint2 = (int)(((double)Note._ReleasePoint2
                                                      + GlobalParamSource.ReleasePoint2.nd.Current)
                                                     * Duration);
                    FrozenNote.Release2FromStart = true;
                }
                else
                {
                    FrozenNote.ReleasePoint2 = (int)((1 - ((double)Note._ReleasePoint2
                                                           + GlobalParamSource.ReleasePoint2.nd.Current))
                                                     * Duration);
                    FrozenNote.Release2FromStart = false;
                }
                break;
            }

            /* third release point, in envelope ticks after start of note */
            if ((Note.Flags & NoteFlags.eRelease3FromStartNotEnd) != 0)
            {
                FrozenNote.ReleasePoint3     = 0;
                FrozenNote.Release3FromStart = true;
            }
            else
            {
                FrozenNote.ReleasePoint3     = Duration;
                FrozenNote.Release3FromStart = false;
            }

            /* overall loudness adjustment for envelopes, including global volume scaling */
            FrozenNote.LoudnessAdjust = (double)Note._OverallLoudnessAdjustment * GlobalParamSource.Volume.nd.Current;

            /* stereo positioning for note */
            {
                double d = (double)Note._StereoPositionAdjustment + GlobalParamSource.StereoPosition.nd.Current;
                if (d < -1)
                {
                    d = -1;
                }
                else if (d > 1)
                {
                    d = 1;
                }
                FrozenNote.StereoPosition = d;
            }

            /* accent values for controlling envelopes */
            InitializeAccent(
                ref FrozenNote.Accents,
                (double)Note._Accent1 + GlobalParamSource.Accent1.nd.Current,
                (double)Note._Accent2 + GlobalParamSource.Accent2.nd.Current,
                (double)Note._Accent3 + GlobalParamSource.Accent3.nd.Current,
                (double)Note._Accent4 + GlobalParamSource.Accent4.nd.Current,
                (double)Note._Accent5 + GlobalParamSource.Accent5.nd.Current,
                (double)Note._Accent6 + GlobalParamSource.Accent6.nd.Current,
                (double)Note._Accent7 + GlobalParamSource.Accent7.nd.Current,
                (double)Note._Accent8 + GlobalParamSource.Accent8.nd.Current);

            /* pitch displacement maximum depth, in tonal Hertz */
            FrozenNote.PitchDisplacementDepthLimit = (double)Note._PitchDisplacementDepthAdjustment
                                                     * GlobalParamSource.PitchDisplacementDepthLimit.nd.Current;

            /* pitch displacement maximum rate, in LFO Hertz */
            FrozenNote.PitchDisplacementRateLimit = (double)Note._PitchDisplacementRateAdjustment
                                                    * GlobalParamSource.PitchDisplacementRateLimit.nd.Current;

            /* pitch displacement start point, in envelope clocks after start of note */
            switch (Note.Flags & NoteFlags.ePitchDisplacementStartOriginMask)
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case NoteFlags.ePitchDisplacementStartFromStart:
                FrozenNote.PitchDisplacementStartPoint = (int)(Duration
                                                               * (double)Note._PitchDisplacementStartPoint);
                break;

            case NoteFlags.ePitchDisplacementStartFromEnd:
                FrozenNote.PitchDisplacementStartPoint = (int)(Duration
                                                               * (1 - (double)Note._PitchDisplacementStartPoint));
                break;

            case NoteFlags.ePitchDisplacementStartFromDefault:
                if (GlobalParamSource.PitchDisplacementStartPointFromStart)
                {
                    FrozenNote.PitchDisplacementStartPoint = (int)(Duration
                                                                   * ((double)Note._PitchDisplacementStartPoint
                                                                      + GlobalParamSource.PitchDisplacementStartPoint.nd.Current));
                }
                else
                {
                    FrozenNote.PitchDisplacementStartPoint = (int)(Duration
                                                                   * (1 - ((double)Note._PitchDisplacementStartPoint
                                                                           + GlobalParamSource.PitchDisplacementStartPoint.nd.Current)));
                }
                break;
            }

            StartAdjustOut = (int)(((double)Note._EarlyLateAdjust
                                    + GlobalParamSource.EarlyLateAdjust.nd.Current) * Duration);
        }