// 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(); }
public override string GetValue(NoteNoteObjectRec note) { T value = getValue(note); int i = FindIndex(value); return(possibleValues[i].text); }
/* 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)); }
/* 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); }
// 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); }
public override void SetValue(NoteNoteObjectRec note, string value) { double d; if (Double.TryParse(value, out d)) { setValue(note, d); } }
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); } }
public override string GetValue(NoteNoteObjectRec Note) { if (-1 == Note.GetNoteMultisampleFalsePitch()) { return("dflt"); } else { return(SymbolicPitch.NumericPitchToString(Note.GetNoteMultisampleFalsePitch(), 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 }
/* 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); }
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(); } }
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); } }
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); }
/* 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; }
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); }
/* 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); } }
public abstract void DoClick(NoteNoteObjectRec note, int noteIndex, IValueInfoOwner owner);
public abstract string GetValue(NoteNoteObjectRec note);
public abstract void SetValue(NoteNoteObjectRec note, string value);
/* 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); }
public override void DoClick(NoteNoteObjectRec note, int noteIndex, IValueInfoOwner owner) { owner.BeginFieldEdit(this, noteIndex, GetValue(note)); }
public Info(int x, int width, NoteNoteObjectRec note) { this.x = x; this.width = width; this.note = note; }
private string GetValue(NoteNoteObjectRec note, InlineParamVis param) { ValueInfo valueInfo = ValueInfo.FindInlineParamVis(param); return(valueInfo.GetValue(note)); }
/* 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); }
/* 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 }
/* 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: ; }
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); }