/* create a new convolver */ public static SynthErrorCodes NewConvolver( ConvolverSpecRec Template, SynthParamRec SynthParams, out ConvolverRec ConvolverOut) { ConvolverOut = null; ConvolverRec Convolver = new ConvolverRec(); Convolver.Type = ConvolverSpecGetSourceType(Template); ConvRuleRec[] RuleArray; switch (Convolver.Type) { default: Debug.Assert(false); throw new ArgumentException(); case ConvolveSrcType.eConvolveMono: RuleArray = ConvMonoRule; break; case ConvolveSrcType.eConvolveStereo: RuleArray = ConvStereoRule; break; case ConvolveSrcType.eConvolveBiStereo: RuleArray = ConvBiStereoRule; break; } int?Latency = null; if (ConvolverSpecGetLatencySpecified(Template)) { Latency = (int)(ConvolverSpecGetLatency(Template) * SynthParams.dSamplingRate); if (Latency.Value < 0) { Latency = 0; } } // validation pass int maximumImpulseResponseLength = 0; float[][] Data = new float[RuleArray.Length][]; int[] Frames = new int[RuleArray.Length]; for (int i = 0; i < RuleArray.Length; i += 1) { NumChannelsType NumChannels; int SamplingRate; int unusedInt; double unusedDouble; bool unusedBool; string ImpulseResponseName = RuleArray[i].ConvolverSpecGetImpulseResponse(Template); if (!WaveSampDictGetSampleInfo( SynthParams.Dictionary, ImpulseResponseName, out Data[i], out Frames[i], out NumChannels, out unusedInt, out unusedInt, out unusedInt, out unusedInt, out unusedInt, out unusedInt, out unusedInt, out unusedDouble, out SamplingRate, out unusedBool, out unusedBool, out unusedBool)) { // should never be provided with name of non-existent sample data Debug.Assert(false); throw new ArgumentException(); } if (SamplingRate * SynthParams.iOversampling != SynthParams.iSamplingRate) { SynthParams.ErrorInfo.ErrorEx = SynthErrorSubCodes.eSynthErrorExConvolverBadSamplingRate; SynthParams.ErrorInfo.SampleName = ImpulseResponseName; return(SynthErrorCodes.eSynthErrorEx); } if (NumChannels != NumChannelsType.eSampleMono) { SynthParams.ErrorInfo.ErrorEx = SynthErrorSubCodes.eSynthErrorExConvolverBadNumChannels; SynthParams.ErrorInfo.SampleName = ImpulseResponseName; return(SynthErrorCodes.eSynthErrorEx); } maximumImpulseResponseLength = Math.Max(maximumImpulseResponseLength, Frames[i]); } if (!Latency.HasValue) { Latency = maximumImpulseResponseLength * SynthParams.iOversampling; } for (int i = 0; i < RuleArray.Length; i += 1) { IConvolution ConvStream; SynthErrorCodes result = ConvolveStreamFactory.NewConvStream( Data[i], Frames[i], ConvolverSpecGetLatencySpecified(Template), Latency.Value, SynthParams.iOversampling, SynthParams.ErrorInfo, out ConvStream); if (result != SynthErrorCodes.eSynthDone) { return(result); } switch (i) { default: Debug.Assert(false); throw new InvalidOperationException(); case 0: Convolver.ConvStream0 = ConvStream; break; case 1: Convolver.ConvStream1 = ConvStream; break; case 2: Convolver.ConvStream2 = ConvStream; break; case 3: Convolver.ConvStream3 = ConvStream; break; } } ConvolverSpecGetDirectGain( Template, out Convolver.DirectGain); ConvolverSpecGetProcessedGain( Template, out Convolver.ProcessedGain); /* done successfully */ ConvolverOut = Convolver; return(SynthErrorCodes.eSynthDone); }
/* create a new track effect generator */ public static SynthErrorCodes NewTrackEffectGenerator( EffectSpecListRec SpecList, SynthParamRec SynthParams, out TrackEffectGenRec GeneratorOut) { GeneratorOut = null; TrackEffectGenRec Generator = new TrackEffectGenRec(); Generator.Enable = true; Generator.AutoQuiescence = EffectSpecListIsAutoQuiescenceEnabled(SpecList); if (Generator.AutoQuiescence) { Generator.Enable = false; /* start with it off in this case */ Generator.GateLevel = (float)(Math.Pow( 2, EffectSpecListGetAutoQuiescenceDecibels(SpecList) * (1 / -6.0205999132796239)) / SynthParams.fOverallVolumeScaling); Generator.WindowDuration = (int)(SynthParams.dEnvelopeRate * EffectSpecListGetAutoQuiescenceWindowDuration(SpecList)); Generator.CurrentWindowDuration = 0; } /* this is the current envelope update index for removing things from the */ /* scanning gap list (i.e. the back edge of the scanning gap) */ /* by setting this negative, we cause the scanning gap to open. */ Generator.ExecutionIndex = -SynthParams.iScanningGapWidthInEnvelopeTicks; /* initialize accent trackers */ InitAccentTracker(ref Generator.Accents0); InitAccentTracker(ref Generator.Accents1); InitAccentTracker(ref Generator.Accents2); InitAccentTracker(ref Generator.Accents3); InitAccentTracker(ref Generator.Accents4); InitAccentTracker(ref Generator.Accents5); InitAccentTracker(ref Generator.Accents6); InitAccentTracker(ref Generator.Accents7); /* build list of thingers */ OneEffectRec Appender = null; int l = GetEffectSpecListLength(SpecList); for (int i = 0; i < l; i += 1) { /* see if effect is enabled */ if (IsEffectFromEffectSpecListEnabled(SpecList, i)) { OneEffectRec Effect = new OneEffectRec(); /* link */ Effect.Next = null; if (Appender == null) { Generator.List = Effect; } else { Appender.Next = Effect; } Appender = Effect; /* fill in fields */ EffectTypes Type = GetEffectSpecListElementType(SpecList, i); switch (Type) { default: Debug.Assert(false); throw new ArgumentException(); case EffectTypes.eDelayEffect: Effect.u = DelayUnifiedRec.NewTrackDelayLineProcessor( GetDelayEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eNLProcEffect: Effect.u = NLProcUnifiedRec.NewTrackNLProcProcessor( GetNLProcEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eFilterEffect: Effect.u = FilterArrayRec.NewTrackFilterArrayProcessor( GetFilterEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eAnalyzerEffect: Effect.u = AnalyzerRec.NewAnalyzer( GetAnalyzerEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eHistogramEffect: Effect.u = HistogramRec.NewHistogram( GetHistogramEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eResamplerEffect: Effect.u = ResamplerRec.NewResampler( GetResamplerEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eCompressorEffect: Effect.u = CompressorRec.NewTrackCompressor( GetCompressorEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eVocoderEffect: Effect.u = VocoderRec.NewTrackVocoder( GetVocoderEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eIdealLowpassEffect: Effect.u = IdealLPRec.NewIdealLP( GetIdealLPEffectFromEffectSpecList(SpecList, i), SynthParams); break; case EffectTypes.eConvolverEffect: { ConvolverRec ConvolverEffect; SynthErrorCodes Result = ConvolverRec.NewConvolver( GetConvolverEffectFromEffectSpecList(SpecList, i), SynthParams, out ConvolverEffect); if (Result != SynthErrorCodes.eSynthDone) { return(Result); } Effect.u = ConvolverEffect; } break; case EffectTypes.eUserEffect: { UserEffectProcRec userEffect; SynthErrorCodes error = UserEffectProcRec.NewTrackUserEffectProc( GetUserEffectFromEffectSpecList(SpecList, i), SynthParams, out userEffect); if (error != SynthErrorCodes.eSynthDone) { return(error); } Effect.u = userEffect; } break; case EffectTypes.ePluggableEffect: { PluggableSpec Spec = GetPluggableEffectFromEffectSpecList(SpecList, i); Debug.Assert(Spec is PluggableTrackSpec); PluggableTrackEffectTemplate Template = new PluggableTrackEffectTemplate( (PluggableTrackSpec)Spec, SynthParams); ITrackEffect effect; SynthErrorCodes error = Template.Create( SynthParams, out effect); if (error != SynthErrorCodes.eSynthDone) { return(error); } Effect.u = effect; } break; } } } GeneratorOut = Generator; return(SynthErrorCodes.eSynthDone); }