/* insert a new phase at the specified position. Values are undefined */ public static void EnvelopeInsertPhase( EnvelopeRec Envelope, int Index) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.NumPhases++; Array.Resize(ref Envelope.PhaseArray, Envelope.NumPhases); Array.Copy(Envelope.PhaseArray, Index, Envelope.PhaseArray, Index + 1, Envelope.NumPhases - Index - 1); Envelope.PhaseArray[Index] = new EnvStepRec(); //Envelope.PhaseArray[Index].Duration = 0; //Envelope.PhaseArray[Index].EndPoint = 0; Envelope.PhaseArray[Index].TransitionType = EnvTransTypes.eEnvelopeLinearInAmplitude; Envelope.PhaseArray[Index].TargetType = EnvTargetTypes.eEnvelopeTargetAbsolute; //InitializeAccentZero(out Envelope.PhaseArray[Index].AccentAmp); //Envelope.PhaseArray[Index].FrequencyAmpRolloff = 0; Envelope.PhaseArray[Index].FrequencyAmpNormalization = Constants.MIDDLEC; //InitializeAccentZero(out Envelope.PhaseArray[Index].AccentRate); //Envelope.PhaseArray[Index].FrequencyRateRolloff = 0; Envelope.PhaseArray[Index].FrequencyRateNormalization = Constants.MIDDLEC; }
/* set the constant shortcut value */ public static void EnvelopeSetConstantShortcut( EnvelopeRec Envelope, double Value) { Envelope.ConstantShortcut = true; Envelope.ConstantShortcutValue = Value; }
/* get value for constant shortcut */ public static double GetEnvelopeConstantShortcutValue(EnvelopeRec Envelope) { if (!Envelope.ConstantShortcut) { // GetEnvelopeConstantShortcutValue: constant shortcut not enabled Debug.Assert(false); throw new ArgumentException(); } return(Envelope.ConstantShortcutValue); }
/* specify a formula for the envelope generator. */ public static void EnvelopeSetFormula( EnvelopeRec Envelope, PcodeRec Formula) { if (Envelope.Formula != null) { // EnvelopeSetFormula: formula has already been specified Debug.Assert(false); throw new ArgumentException(); } Envelope.Formula = Formula; }
public static PcodeRec GetEnvelopePhaseFinalValueFormula( EnvelopeRec Envelope, int Index) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif return(Envelope.PhaseArray[Index].EndPointFunction); }
/* get the target type for a phase */ public static EnvTargetTypes GetEnvelopePhaseTargetType( EnvelopeRec Envelope, int Index) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif return(Envelope.PhaseArray[Index].TargetType); }
/* set a new value for the specified phase's duration */ public static void EnvelopeSetPhaseDuration( EnvelopeRec Envelope, int Index, double Duration) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.PhaseArray[Index].Duration = Duration; }
/* set a new value for the specified phase's ultimate value */ public static void EnvelopeSetPhaseFinalValue( EnvelopeRec Envelope, int Index, double FinalValue) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.PhaseArray[Index].EndPoint = FinalValue; }
public static void EnvelopeSetPhaseFinalValueFormula( EnvelopeRec Envelope, int Index, PcodeRec FinalValueFunction) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.PhaseArray[Index].EndPointFunction = FinalValueFunction; }
/* set the value for a phase's target type */ public static void EnvelopeSetPhaseTargetType( EnvelopeRec Envelope, int Index, EnvTargetTypes TargetType) { #if DEBUG if ((Index < 0) || (Index > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.PhaseArray[Index].TargetType = TargetType; }
public static void EnvelopeSetFreqRateNormalization( EnvelopeRec Envelope, double Val, int Phase) { #if DEBUG if ((Phase < 0) || (Phase >= Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.PhaseArray[Phase].FrequencyRateNormalization = Val; }
public static void EnvelopeSetAccentRate( EnvelopeRec Envelope, double Val, int Phase, int AccentNumber) { #if DEBUG if ((Phase < 0) || (Phase >= Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } #endif SetAccentMemberValue(ref Envelope.PhaseArray[Phase].AccentRate, AccentNumber, Val); }
public static bool EnvelopeContainsFormula(EnvelopeRec Envelope) { if (Envelope.containsFormula == EnvelopeContainsFormulaType.NotInitialized) { Envelope.containsFormula = EnvelopeContainsFormulaType.No; if (Envelope.Formula != null) { Envelope.containsFormula = EnvelopeContainsFormulaType.Yes; } for (int i = 0; i < Envelope.PhaseArray.Length; i++) { if ((Envelope.PhaseArray[i].DurationFunction != null) || (Envelope.PhaseArray[i].EndPointFunction != null)) { Envelope.containsFormula = EnvelopeContainsFormulaType.Yes; break; } } } return(Envelope.containsFormula != EnvelopeContainsFormulaType.No); }
/* create a new envelope record with nothing in it */ public static EnvelopeRec NewEnvelope() { EnvelopeRec Envelope = new EnvelopeRec(); Envelope.PhaseArray = new EnvStepRec[0]; Envelope.SustainPhase1 = -1; Envelope.SustainPhase2 = -1; Envelope.SustainPhase3 = -1; Envelope.SustainPhase1Type = SustainTypes.eEnvelopeReleasePointNoSkip; Envelope.SustainPhase2Type = SustainTypes.eEnvelopeReleasePointNoSkip; Envelope.SustainPhase3Type = SustainTypes.eEnvelopeReleasePointNoSkip; //Envelope.Origin = 0; //Envelope.NumPhases = 0; //Envelope.GlobalPitchRateRolloff = 0; Envelope.GlobalPitchRateNormalization = Constants.MIDDLEC; Envelope.OverallScalingFactor = 1; //Envelope.Formula = null; Envelope.ConstantShortcut = false; return(Envelope); }
/* set a release point. -1 means this release point is ignored */ public static void EnvelopeSetReleasePoint3( EnvelopeRec Envelope, int Release, SustainTypes ReleaseType) { #if DEBUG if ((Release < -1) || (Release > Envelope.NumPhases)) { Debug.Assert(false); throw new ArgumentException(); } if ((ReleaseType != SustainTypes.eEnvelopeSustainPointSkip) && (ReleaseType != SustainTypes.eEnvelopeReleasePointSkip) && (ReleaseType != SustainTypes.eEnvelopeSustainPointNoSkip) && (ReleaseType != SustainTypes.eEnvelopeReleasePointNoSkip)) { Debug.Assert(false); throw new ArgumentException(); } #endif Envelope.SustainPhase3 = Release; Envelope.SustainPhase3Type = ReleaseType; }
/* get the formula for the envelope generator. returns NIL if none specified. */ public static PcodeRec GetEnvelopeFormula(EnvelopeRec Envelope) { return(Envelope.Formula); }
/* get the release point type */ public static SustainTypes GetEnvelopeReleaseType3(EnvelopeRec Envelope) { return(Envelope.SustainPhase3Type); }
/* set the origin of the envelope */ public static void EnvelopeSetOrigin( EnvelopeRec Envelope, int Origin) { Envelope.Origin = Origin; }
/* get the origin from the envelope */ public static int GetEnvelopeOrigin(EnvelopeRec Envelope) { return(Envelope.Origin); }
/* get the global pitch rate rolloff factor */ public static double GetGlobalEnvelopePitchRateRolloff(EnvelopeRec Envelope) { return(Envelope.GlobalPitchRateRolloff); }
/* get the global pitch rate normalization factor */ public static double GetGlobalEnvelopePitchRateNormalization(EnvelopeRec Envelope) { return(Envelope.GlobalPitchRateNormalization); }
/* change the global pitch rate rolloff factor */ public static void PutGlobalEnvelopePitchRateRolloff( EnvelopeRec Envelope, double NewGlobalPitchRateRolloff) { Envelope.GlobalPitchRateRolloff = NewGlobalPitchRateRolloff; }
/* change the global pitch rate normalization factor */ public static void PutGlobalEnvelopePitchRateNormalization( EnvelopeRec Envelope, double NewGlobalPitchRateNormalization) { Envelope.GlobalPitchRateNormalization = NewGlobalPitchRateNormalization; }
/* find out how many frames there are in the envelope */ public static int GetEnvelopeNumFrames(EnvelopeRec Envelope) { return(Envelope.NumPhases); }
/* get the value of a release point */ public static int GetEnvelopeReleasePoint3(EnvelopeRec Envelope) { return(Envelope.SustainPhase3); }
/* is shortcut constant specified? */ public static bool GetEnvelopeUseConstantShortcut(EnvelopeRec Envelope) { return(Envelope.ConstantShortcut); }
/* set the overall amplitude scaling factor */ public static void EnvelopeSetOverallAmplitude( EnvelopeRec Envelope, double OverallAmplitude) { Envelope.OverallScalingFactor = OverallAmplitude; }
/* get the overall amplitude */ public static double GetEnvelopeOverallAmplitude(EnvelopeRec Envelope) { return(Envelope.OverallScalingFactor); }
/* create a new envelope state record. Accent factors have no effect with a value */ /* of 1, attenuate at smaller values, and amplify at larger values. */ public static EvalEnvelopeRec NewEnvelopeStateRecord( EnvelopeRec Template, ref AccentRec Accents, double FrequencyHertz, double Loudness, double HurryUp, out int PreOriginTime, ParamGetterMethod ParamGetter, object ParamGetterContext, SynthParamRec SynthParams) { EvalEnvelopeRec State = New(ref SynthParams.freelists.envelopeStateFreeList); // must assign all fields: State, State.PhaseVector State.NumPhases = Template.NumPhases; State.PhaseVector = New(ref SynthParams.freelists.envelopeOnePhaseFreeList, Template.NumPhases); // cleared #if DEBUG if ((Template.NumPhases != 0) && Template.ConstantShortcut) { // shouldn't specify shortcut and phase list at the same time Debug.Assert(false); throw new ArgumentException(); } #endif State.Template = Template; State.CurrentPhase = -1; State.SustainPhase1 = Template.SustainPhase1; State.OriginalSustainPhase1 = Template.SustainPhase1; State.SustainPhase1Type = Template.SustainPhase1Type; State.SustainPhase2 = Template.SustainPhase2; State.OriginalSustainPhase2 = Template.SustainPhase2; State.SustainPhase2Type = Template.SustainPhase2Type; State.SustainPhase3 = Template.SustainPhase3; State.OriginalSustainPhase3 = Template.SustainPhase3; State.SustainPhase3Type = Template.SustainPhase3Type; State.Origin = Template.Origin; State.ParamGetter = ParamGetter; State.ParamGetterContext = ParamGetterContext; State.LastOutputtedValue = 0; State.PreOriginTime = 0; State.FrozenNoteAccentDifferential = new AccentRec(); /* build initial delay transition */ ResetLinearTransition( ref State.LinearTransition, 0, 0, 1); State.LinearTransitionCounter = 0; State.LinearTransitionTotalDuration = 0; State.EnvelopeUpdate = _EnvUpdateLinearAbsolute; State.EnvelopeHasFinished = false; State.PerformGlobalPitchScaling = (0 != Template.GlobalPitchRateRolloff); // A note about accents to follow: // - The "Accents" parameter to this function comes from the FrozenNote - so they are the accent values in effect // at the time the note was "frozen" (i.e. the accent defaults added to the individual note's adjustments). // - The "LiveAccents" parameter is the current accent defaults at time t (which should be equal to "Accents", at the // the a note is initiated, but not necessarily before or after), since this event is occurring at time t. // - The "LiveTrackAccents" parameter is the current track effect accent values. // There is some redundancy here, but it is not being changed in case this is wrong and there are legacy // interactions that need to be preserved. AccentRec LiveAccents; AccentRec LiveTrackAccents; #if DEBUG bool liveAccentInit = false; #endif if (EnvelopeContainsFormula(Template)) // an optimization { /* get current live accents that do not contain any info from the note */ ParamGetter( ParamGetterContext, out LiveAccents, out LiveTrackAccents); #if DEBUG liveAccentInit = true; #endif } else { LiveAccents = new AccentRec(); LiveTrackAccents = new AccentRec(); } /* build list of nodes */ if (Template.ConstantShortcut) { State.NumPhases = 0; /* make sure */ State.CurrentPhase = 0; State.LastOutputtedValue = Template.ConstantShortcutValue; State.EnvelopeUpdate = _EnvUpdateSustain; State.EnvelopeHasFinished = false; } else { State.LastOutputtedValue = 0; double accumulatedError = 0; OneEnvPhaseRec[] PhaseVector = State.PhaseVector; if (unchecked ((uint)State.NumPhases > (uint)PhaseVector.Length)) { throw new IndexOutOfRangeException(); } EnvStepRec[] TemplatePhaseArray = Template.PhaseArray; if (unchecked ((uint)State.NumPhases > (uint)TemplatePhaseArray.Length)) { throw new IndexOutOfRangeException(); } for (int i = 0; i < State.NumPhases; i++) { Debug.Assert(PhaseVector[i].Equals(new OneEnvPhaseRec())); // verify cleared PhaseVector[i].TransitionType = TemplatePhaseArray[i].TransitionType; PhaseVector[i].TargetType = TemplatePhaseArray[i].TargetType; /* calculate the total duration. the effect of accents is this: */ /* - the accent is the base-2 log of a multiplier for the rate. a value of 0 */ /* does not change the rate. -1 halves the rate, and 1 doubles the rate. */ /* - the accent scaling factor is the base-2 log for scaling the accent. */ /* a value of 0 eliminates the effect of the accent, a value of 1 does not */ /* scale the accent. */ /* - pitch has two factors: normalization point and rolloff. rolloff */ /* determines how much the signal will decrease with each octave. 0 */ /* removes effect, 1 halfs signal with each octave. normalization point */ /* determines what pitch will be the invariant point. */ double Temp; if (TemplatePhaseArray[i].DurationFunction == null) { Temp = TemplatePhaseArray[i].Duration; } else { #if DEBUG Debug.Assert(liveAccentInit); #endif SynthErrorCodes error = EnvelopeInitParamEval( TemplatePhaseArray[i].DurationFunction, ref Accents, ref LiveTrackAccents, SynthParams, out Temp); if (error != SynthErrorCodes.eSynthDone) { // TODO: } } double preciseDuration = SynthParams.dEnvelopeRate * HurryUp * Temp * Math.Pow(2, -(AccentProduct(ref Accents, ref TemplatePhaseArray[i].AccentRate) + (Math.Log(FrequencyHertz / TemplatePhaseArray[i].FrequencyRateNormalization) * Constants.INVLOG2) * TemplatePhaseArray[i].FrequencyRateRolloff)) + accumulatedError; PhaseVector[i].Duration = (int)Math.Round(preciseDuration); accumulatedError = preciseDuration - PhaseVector[i].Duration; /* the final amplitude scaling values are computed similarly to the rate */ /* scaling values. */ if (TemplatePhaseArray[i].EndPointFunction == null) { Temp = TemplatePhaseArray[i].EndPoint; } else { #if DEBUG Debug.Assert(liveAccentInit); #endif SynthErrorCodes error = EnvelopeInitParamEval( TemplatePhaseArray[i].EndPointFunction, ref Accents, ref LiveTrackAccents, SynthParams, out Temp); if (error != SynthErrorCodes.eSynthDone) { // TODO: } } PhaseVector[i].FinalAmplitude = Temp * Template.OverallScalingFactor * Loudness * Math.Pow(2, -(AccentProduct(ref Accents, ref TemplatePhaseArray[i].AccentAmp) + (Math.Log(FrequencyHertz / TemplatePhaseArray[i].FrequencyAmpNormalization) * Constants.INVLOG2) * TemplatePhaseArray[i].FrequencyAmpRolloff)); /* adjust initial countdown */ if (i < Template.Origin) { /* this occurs before the origin, so add it in */ State.PreOriginTime += PhaseVector[i].Duration; } } } PreOriginTime = State.PreOriginTime; /* compute accent differentials */ if (State.Template.Formula != null) { #if DEBUG Debug.Assert(liveAccentInit); #endif /* subtract composite accents ("Accents") from current live accents */ AccentAdd( -1, ref Accents, ref LiveAccents, ref State.FrozenNoteAccentDifferential); } return(State); }
public PluggableEvaluableOscParam(EnvelopeRec envelope, LFOListSpecRec lfo) { this.ParamEnvelope = envelope; this.ParamLFO = lfo; }