/* check fm network */
        public static SynthErrorCodes CheckFMNetworkForUnreferencedSamples(
            FMSynthSpecRec FMSynthSpec,
            CheckUnrefParamRec Param)
        {
            int c = FMSynthGetNumStatements(FMSynthSpec);

            for (int i = 0; i < c; i += 1)
            {
                SynthErrorCodes Error;
                switch (FMSynthGetStatementType(FMSynthSpec, i))
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case FMSynthStmtType.eFMSynthWave:
                    Error = CheckWaveTableSelectorForUnreferencedSamples(
                        FMSynthWaveStmtGetSampleIntervalList(
                            FMSynthGetWaveStatement(FMSynthSpec, i)),
                        Param);
                    if (Error != SynthErrorCodes.eSynthDone)
                    {
                        return(Error);
                    }
                    break;

                case FMSynthStmtType.eFMSynthMuladd:
                    break;

                case FMSynthStmtType.eFMSynthEnvelope:
                    Error = CheckEnvelopeForUnreferencedSamples(
                        FMSynthEnvelopeStmtGetEnvelope(
                            FMSynthGetEnvelopeStatement(FMSynthSpec, i)),
                        Param);
                    if (Error != SynthErrorCodes.eSynthDone)
                    {
                        return(Error);
                    }
                    Error = CheckLFOListForUnreferencedSamples(
                        FMSynthEnvelopeStmtGetLFOList(
                            FMSynthGetEnvelopeStatement(FMSynthSpec, i)),
                        Param);
                    if (Error != SynthErrorCodes.eSynthDone)
                    {
                        return(Error);
                    }
                    break;
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
        /* check list of LFOs */
        public static SynthErrorCodes CheckLFOListForUnreferencedSamples(
            LFOListSpecRec LFOList,
            CheckUnrefParamRec Param)
        {
            int Limit = LFOListSpecGetNumElements(LFOList);

            for (int Scan = 0; Scan < Limit; Scan += 1)
            {
                SynthErrorCodes Error = CheckLFOForUnreferencedSamples(
                    LFOListSpecGetLFOSpec(LFOList, Scan),
                    Param);
                if (Error != SynthErrorCodes.eSynthDone)
                {
                    return(Error);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
        /* check list of oscillators */
        public static SynthErrorCodes CheckOscillatorListForUnreferencedSamples(
            OscillatorListRec OscillatorList,
            CheckUnrefParamRec Param)
        {
            int Limit = GetOscillatorListLength(OscillatorList);

            for (int Scan = 0; Scan < Limit; Scan += 1)
            {
                SynthErrorCodes Error = CheckOscillatorForUnreferencedSamples(
                    GetOscillatorFromList(OscillatorList, Scan),
                    Param);
                if (Error != SynthErrorCodes.eSynthDone)
                {
                    return(Error);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
        /* check wave table selector */
        public static SynthErrorCodes CheckWaveTableSelectorForUnreferencedSamples(
            SampleSelectorRec WaveTableSelector,
            CheckUnrefParamRec Param)
        {
            int Limit = GetSampleSelectorListLength(WaveTableSelector);

            for (int Scan = 0; Scan < Limit; Scan += 1)
            {
                string Name = GetSampleListEntryName(WaveTableSelector, Scan);
                if (!WaveSampDictDoesWaveTableExist(
                        Param.Dictionary,
                        Name))
                {
                    Param.ErrorInfo.ErrorEx       = SynthErrorSubCodes.eSynthErrorExUndefinedWaveTable;
                    Param.ErrorInfo.WaveTableName = Name;
                    return(SynthErrorCodes.eSynthErrorEx);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
        public static SynthErrorCodes CheckConvolverEffectForUnreferencedSamples(
            ConvolverSpecRec ConvolverEffect,
            CheckUnrefParamRec Param)
        {
            ConvolverCheckRec[] RuleArray;

            switch (ConvolverSpecGetSourceType(ConvolverEffect))
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case ConvolveSrcType.eConvolveMono:
                RuleArray = ConvolverCheckMono;
                break;

            case ConvolveSrcType.eConvolveStereo:
                RuleArray = ConvolverCheckStereo;
                break;

            case ConvolveSrcType.eConvolveBiStereo:
                RuleArray = ConvolverCheckBiStereo;
                break;
            }

            for (int i = 0; i < RuleArray.Length; i += 1)
            {
                string ImpulseResponse = RuleArray[i].ConvolverSpecGetImpulseResponse(ConvolverEffect);
                if (!WaveSampDictDoesSampleExist(
                        Param.Dictionary,
                        ImpulseResponse))
                {
                    Param.ErrorInfo.ErrorEx    = SynthErrorSubCodes.eSynthErrorExUndefinedSample;
                    Param.ErrorInfo.SampleName = ImpulseResponse;
                    return(SynthErrorCodes.eSynthErrorEx);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
        /* check oscillator */
        public static SynthErrorCodes CheckOscillatorForUnreferencedSamples(
            OscillatorRec Oscillator,
            CheckUnrefParamRec Param)
        {
            SynthErrorCodes Error = SynthErrorCodes.eSynthDone;

            switch (OscillatorGetWhatKindItIs(Oscillator))
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case OscillatorTypes.eOscillatorSampled:
                Error = CheckSampleSelectorForUnreferencedSamples(
                    OscillatorGetSampleIntervalList(Oscillator),
                    Param);
                break;

            case OscillatorTypes.eOscillatorWaveTable:
            case OscillatorTypes.eOscillatorFOF:
                Error = CheckWaveTableSelectorForUnreferencedSamples(
                    OscillatorGetSampleIntervalList(Oscillator),
                    Param);
                break;

            case OscillatorTypes.eOscillatorAlgorithm:
                break;

            case OscillatorTypes.eOscillatorFMSynth:
                Error = CheckFMNetworkForUnreferencedSamples(
                    OscillatorGetFMSynthSpec(Oscillator),
                    Param);
                break;

            case OscillatorTypes.eOscillatorPluggable:
                IPluggableProcessorTemplate pluggable = GetOscillatorPluggableSpec(Oscillator).PluggableTemplate;
                Error = pluggable.CheckUnreferencedObjects(
                    GetOscillatorPluggableSpec(Oscillator).GetStaticStrings(),
                    Param);
                break;
            }
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckEnvelopeForUnreferencedSamples(
                OscillatorGetLoudnessEnvelope(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckLFOListForUnreferencedSamples(
                OscillatorGetLoudnessLFOList(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckEnvelopeForUnreferencedSamples(
                OscillatorGetExcitationEnvelope(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckLFOListForUnreferencedSamples(
                OscillatorGetExcitationLFOList(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckLFOListForUnreferencedSamples(
                GetOscillatorFrequencyLFOList(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckEffectListForUnreferencedSamples(
                GetOscillatorEffectList(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckEnvelopeForUnreferencedSamples(
                OscillatorGetFOFRateEnvelope(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            Error = CheckLFOListForUnreferencedSamples(
                OscillatorGetFOFRateLFOList(Oscillator),
                Param);
            if (Error != SynthErrorCodes.eSynthDone)
            {
                return(Error);
            }

            return(SynthErrorCodes.eSynthDone);
        }
        /* check list of effects */
        public static SynthErrorCodes CheckEffectListForUnreferencedSamples(
            EffectSpecListRec EffectList,
            CheckUnrefParamRec Param)
        {
            int Limit = GetEffectSpecListLength(EffectList);

            for (int Scan = 0; Scan < Limit; Scan += 1)
            {
                SynthErrorCodes Error = SynthErrorCodes.eSynthDone;
                switch (GetEffectSpecListElementType(EffectList, Scan))
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case EffectTypes.eDelayEffect:
                    Error = CheckDelayEffectForUnreferencedSamples(
                        GetDelayEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eNLProcEffect:
                    Error = CheckNonlinearEffectForUnreferencedSamples(
                        GetNLProcEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eFilterEffect:
                    Error = CheckFilterEffectForUnreferencedSamples(
                        GetFilterEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eAnalyzerEffect:
                    Error = CheckAnalyzerEffectForUnreferencedSamples(
                        GetAnalyzerEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eHistogramEffect:
                    Error = CheckHistogramEffectForUnreferencedSamples(
                        GetHistogramEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eResamplerEffect:
                    Error = CheckResamplerEffectForUnreferencedSamples(
                        GetResamplerEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eCompressorEffect:
                    Error = CheckCompressorEffectForUnreferencedSamples(
                        GetCompressorEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eVocoderEffect:
                    Error = CheckVocoderEffectForUnreferencedSamples(
                        GetVocoderEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eIdealLowpassEffect:
                    Error = CheckIdealLowpassEffectForUnreferencedSamples(
                        GetIdealLPEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eConvolverEffect:
                    Error = CheckConvolverEffectForUnreferencedSamples(
                        GetConvolverEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.eUserEffect:
                    Error = CheckUserEffectForUnreferencedSamples(
                        GetUserEffectFromEffectSpecList(EffectList, Scan),
                        Param);
                    break;

                case EffectTypes.ePluggableEffect:
                    PluggableSpec PluggableEffect = GetPluggableEffectFromEffectSpecList(EffectList, Scan);
                    Error = PluggableEffect.PluggableTemplate.CheckUnreferencedObjects(
                        PluggableEffect.GetStaticStrings(),
                        Param);
                    break;
                }

                if (Error != SynthErrorCodes.eSynthDone)
                {
                    return(Error);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
 /* check envelope */
 public static SynthErrorCodes CheckEnvelopeForUnreferencedSamples(
     EnvelopeRec Envelope,
     CheckUnrefParamRec Param)
 {
     return(SynthErrorCodes.eSynthDone);
 }
        /* check user effect */
        public static SynthErrorCodes CheckUserEffectForUnreferencedSamples(
            UserEffectSpecRec UserEffect,
            CheckUnrefParamRec Param)
        {
            /* init func */
            {
                string FuncName = GetUserEffectSpecInitFuncName(UserEffect);
                if (FuncName != null) /* optional */
                {
                    FuncCodeRec FuncCode = Param.CodeCenter.ObtainFunctionHandle(FuncName);
                    if (FuncCode == null)
                    {
                        Param.ErrorInfo.ErrorEx      = SynthErrorSubCodes.eSynthErrorExUndefinedFunction;
                        Param.ErrorInfo.FunctionName = FuncName;
                        return(SynthErrorCodes.eSynthErrorEx);
                    }

                    DataTypes[] argsTypes;
                    DataTypes   returnType;
                    UserEffectGetInitSignature(UserEffect, out argsTypes, out returnType);
                    FunctionSignature expectedSignature = new FunctionSignature(argsTypes, returnType);
                    FunctionSignature actualSignature   = new FunctionSignature(
                        FuncCode.GetFunctionParameterTypeList(),
                        FuncCode.GetFunctionReturnType());
                    if (!FunctionSignature.Equals(expectedSignature, actualSignature))
                    {
                        Param.ErrorInfo.ErrorEx      = SynthErrorSubCodes.eSynthErrorExTypeMismatchFunction;
                        Param.ErrorInfo.FunctionName = FuncName;
                        Param.ErrorInfo.ExtraInfo    = String.Format(
                            "{0}{0}Expected:{0}{1}{0}{0}Actual:{0}{2}",
                            Environment.NewLine,
                            expectedSignature,
                            actualSignature);
                        return(SynthErrorCodes.eSynthErrorEx);
                    }
                }
            }

            /* data func */
            {
                DataTypes[] argsTypes;
                DataTypes   returnType;
                UserEffectGetDataSignature(UserEffect, out argsTypes, out returnType);
                FunctionSignature expectedSignature = new FunctionSignature(argsTypes, returnType);

                bool matched = false;
                List <KeyValuePair <string, FunctionSignature> > actualSignatures = new List <KeyValuePair <string, FunctionSignature> >();
                foreach (string FuncName in GetUserEffectSpecProcessDataFuncNames(UserEffect))
                {
                    FuncCodeRec FuncCode = Param.CodeCenter.ObtainFunctionHandle(FuncName);
                    if (FuncCode == null)
                    {
                        Param.ErrorInfo.ErrorEx      = SynthErrorSubCodes.eSynthErrorExUndefinedFunction;
                        Param.ErrorInfo.FunctionName = FuncName;
                        return(SynthErrorCodes.eSynthErrorEx);
                    }

                    FunctionSignature actualSignature = new FunctionSignature(
                        FuncCode.GetFunctionParameterTypeList(),
                        FuncCode.GetFunctionReturnType());
                    actualSignatures.Add(new KeyValuePair <string, FunctionSignature>(FuncName, actualSignature));
                    if (FunctionSignature.Equals(expectedSignature, actualSignature))
                    {
                        matched = true;
                        break;
                    }
                }
                if (!matched)
                {
                    StringBuilder extraInfo = new StringBuilder();
                    extraInfo.AppendLine();
                    extraInfo.AppendLine();
                    extraInfo.AppendLine(String.Format("Expected - {0}", expectedSignature));
                    foreach (KeyValuePair <string, FunctionSignature> actualSignature in actualSignatures)
                    {
                        extraInfo.AppendLine();
                        extraInfo.AppendLine(String.Format("Actual - {0}{1}", actualSignature.Key, actualSignature.Value));
                    }
                    Param.ErrorInfo.ErrorEx   = SynthErrorSubCodes.eSynthErrorExTypeMismatchFunctionMultiple;
                    Param.ErrorInfo.ExtraInfo = extraInfo.ToString();
                    return(SynthErrorCodes.eSynthErrorEx);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }