public Voice[] GetAvailableVoices()
        {
            if (cachedAvailableVoices != null)
            {
                return(cachedAvailableVoices);
            }

            List <Voice> voices = new List <Voice>();

            if (config.EnabledModules.Contains(Module.Windows))
            {
                Voice[] arr = new Voice[0];

                string err = WindowsTTS.GetVoices(ref arr);

                if (err != null)
                {
                    OnError(err);
                    return(null);
                }
                else
                {
                    voices.AddRange(arr);
                }
            }

            if (config.EnabledModules.Contains(Module.Azure))
            {
                Voice[] arr = new Voice[0];

                string err = AzureTTS.GetVoices(ref arr, config.AzureAPI);

                if (err != null)
                {
                    OnError(err);
                    return(null);
                }
                else
                {
                    voices.AddRange(arr);
                }
            }

            if (config.EnabledModules.Contains(Module.Google))
            {
                Voice[] arr = new Voice[0];

                string err = GoogleTTS.GetVoices(ref arr);

                if (err != null)
                {
                    OnError(err);
                    return(null);
                }
                else
                {
                    voices.AddRange(arr);
                }
            }

            if (config.EnabledModules.Contains(Module.AWS))
            {
                Voice[] arr = new Voice[0];

                string err = AwsTTS.GetVoices(ref arr, config.AwsAPI);

                if (err != null)
                {
                    OnError(err);
                    return(null);
                }
                else
                {
                    voices.AddRange(arr);
                }
            }

            cachedAvailableVoices = voices.ToArray();             // cache list

            return(cachedAvailableVoices);
        }