public void Init(bool defaultmode, AudioQueue qu,
                         string caption, Icon ic,
                         string defpath,
                         bool waitcomplete,
                         AudioQueue.Priority prio,
                         string startname, string endname,
                         string volume,
                         Variables ef)
        {
            comboBoxCustomPriority.Items.AddRange(Enum.GetNames(typeof(AudioQueue.Priority)));

            queue = qu;

            var enumlist = new Enum[] { CFIDs.WaveConfigureDialog, CFIDs.WaveConfigureDialog_buttonExtDevice, CFIDs.WaveConfigureDialog_labelStartTrigger, CFIDs.WaveConfigureDialog_labelEndTrigger, CFIDs.WaveConfigureDialog_labelTitle, CFIDs.WaveConfigureDialog_buttonExtBrowse, CFIDs.WaveConfigureDialog_checkBoxCustomComplete, CFIDs.WaveConfigureDialog_buttonExtEffects, CFIDs.WaveConfigureDialog_buttonExtTest, CFIDs.WaveConfigureDialog_checkBoxCustomV, CFIDs.WaveConfigureDialog_labelVolume };

            BaseUtils.Translator.Instance.TranslateControls(this, enumlist);

            if (caption != null)
            {
                this.Text = caption;
            }

            this.Icon = ic;
            textBoxBorderText.Text = defpath;

            if (defaultmode)
            {
                checkBoxCustomComplete.Visible        = comboBoxCustomPriority.Visible =
                    textBoxBorderStartTrigger.Visible = textBoxBorderEndTrigger.Visible = checkBoxCustomV.Visible = labelStartTrigger.Visible = labelEndTrigger.Visible = false;
            }
            else
            {
                checkBoxCustomComplete.Checked      = waitcomplete;
                comboBoxCustomPriority.SelectedItem = prio.ToString();
                textBoxBorderStartTrigger.Text      = startname;
                textBoxBorderEndTrigger.Text        = endname;
                buttonExtDevice.Visible             = false;
            }

            int i;

            if (!defaultmode && volume.Equals("Default", StringComparison.InvariantCultureIgnoreCase))
            {
                checkBoxCustomV.Checked = false;
                trackBarVolume.Enabled  = false;
            }
            else
            {
                checkBoxCustomV.Checked = true;
                if (volume.InvariantParse(out i))
                {
                    trackBarVolume.Value = i;
                }
            }

            effects = ef;

            ExtendedControls.Theme.Current?.ApplyDialog(this);
        }
Esempio n. 2
0
        public void Init(AudioQueue qu,
                         bool defaultmode,
                         string title, string caption, Icon ic,
                         string defpath,
                         bool waitcomplete,
                         AudioQueue.Priority prio,
                         string startname, string endname,
                         string volume,
                         Variables ef)
        {
            comboBoxCustomPriority.Items.AddRange(Enum.GetNames(typeof(AudioQueue.Priority)));

            queue                  = qu;
            this.Text              = caption;
            labelTitle.Text        = title;
            this.Icon              = ic;
            textBoxBorderText.Text = defpath;

            if (defaultmode)
            {
                checkBoxCustomComplete.Visible        = comboBoxCustomPriority.Visible =
                    textBoxBorderStartTrigger.Visible = textBoxBorderEndTrigger.Visible = checkBoxCustomV.Visible = labelStartTrigger.Visible = labelEndTrigger.Visible = false;
            }
            else
            {
                checkBoxCustomComplete.Checked      = waitcomplete;
                comboBoxCustomPriority.SelectedItem = prio.ToString();
                textBoxBorderStartTrigger.Text      = startname;
                textBoxBorderEndTrigger.Text        = endname;
                buttonExtDevice.Visible             = false;
            }

            int i;

            if (!defaultmode && volume.Equals("Default", StringComparison.InvariantCultureIgnoreCase))
            {
                checkBoxCustomV.Checked = false;
                trackBarVolume.Enabled  = false;
            }
            else
            {
                checkBoxCustomV.Checked = true;
                if (volume.InvariantParse(out i))
                {
                    trackBarVolume.Value = i;
                }
            }

            effects = ef;

            ExtendedControls.ThemeableFormsInstance.Instance?.ApplyDialog(this);
        }
Esempio n. 3
0
        public override bool ExecuteAction(ActionProgramRun ap)
        {
            string             say;
            ConditionVariables statementvars;

            if (FromString(userdata, out say, out statementvars))
            {
                string             errlist = null;
                ConditionVariables vars    = statementvars.ExpandAll(ap.functions, statementvars, out errlist);

                if (errlist == null)
                {
                    bool wait = vars.GetInt(waitname, 0) != 0;
                    AudioQueue.Priority priority = AudioQueue.GetPriority(vars.GetString(priorityname, "Normal"));
                    string start  = vars.GetString(startname, checklen: true);
                    string finish = vars.GetString(finishname, checklen: true);
                    string voice  = (vars.Exists(voicename) && vars[voicename].Length > 0)? vars[voicename] : (ap.VarExist(globalvarspeechvoice) ? ap[globalvarspeechvoice] : "Default");

                    int vol = vars.GetInt(volumename, -999);
                    if (vol == -999)
                    {
                        vol = ap.variables.GetInt(globalvarspeechvolume, 60);
                    }

                    int rate = vars.GetInt(ratename, -999);
                    if (rate == -999)
                    {
                        rate = ap.variables.GetInt(globalvarspeechrate, 0);
                    }

                    int queuelimitms = vars.GetInt(queuelimit, 0);

                    string culture = (vars.Exists(culturename) && vars[culturename].Length > 0) ? vars[culturename] : (ap.VarExist(globalvarspeechculture) ? ap[globalvarspeechculture] : "Default");

                    bool literal   = vars.GetInt(literalname, 0) != 0;
                    bool dontspeak = vars.GetInt(dontspeakname, 0) != 0;

                    string prefixsoundpath  = vars.GetString(prefixsound, checklen: true);
                    string postfixsoundpath = vars.GetString(postfixsound, checklen: true);
                    string mixsoundpath     = vars.GetString(mixsound, checklen: true);

                    SoundEffectSettings ses = new SoundEffectSettings(vars);                  // use the rest of the vars to place effects

                    if (!ses.Any && !ses.OverrideNone && ap.VarExist(globalvarspeecheffects)) // if can't see any, and override none if off, and we have a global, use that
                    {
                        vars = new ConditionVariables(ap[globalvarspeecheffects], ConditionVariables.FromMode.MultiEntryComma);
                    }

                    if (queuelimitms > 0)
                    {
                        int queue = ap.actioncontroller.AudioQueueSpeech.InQueuems();

                        if (queue >= queuelimitms)
                        {
                            ap["SaySaid"] = "!LIMIT";
                            System.Diagnostics.Debug.WriteLine("Abort say due to queue being at " + queue);
                            return(true);
                        }
                    }

                    string expsay;
                    if (ap.functions.ExpandString(say, out expsay) != ConditionFunctions.ExpandResult.Failed)
                    {
                        if (!literal)
                        {
                            expsay = expsay.PickOneOfGroups(rnd);       // expand grouping if not literal
                        }
                        ap["SaySaid"] = expsay;

                        if ((ap.VarExist("SpeechDebug") && ap["SpeechDebug"].Contains("Print")))
                        {
                            ap.actioncontroller.LogLine("Say: " + expsay);
                            expsay = "";
                        }


                        if (dontspeak)
                        {
                            expsay = "";
                        }

                        System.IO.MemoryStream ms = ap.actioncontroller.SpeechSynthesizer.Speak(expsay, culture, voice, rate);

                        if (ms != null)
                        {
                            AudioQueue.AudioSample audio = ap.actioncontroller.AudioQueueSpeech.Generate(ms, vars, true);

                            if (audio == null)
                            {
                                ap.ReportError("Say could not create audio, check Effects settings");
                                return(true);
                            }

                            if (mixsoundpath != null)
                            {
                                AudioQueue.AudioSample mix = ap.actioncontroller.AudioQueueSpeech.Generate(mixsoundpath, new ConditionVariables());

                                if (audio == null)
                                {
                                    ap.ReportError("Say could not create mix audio, check audio file format is supported and effects settings");
                                    return(true);
                                }

                                audio = ap.actioncontroller.AudioQueueSpeech.Mix(audio, mix);     // audio in MIX format
                            }

                            if (prefixsoundpath != null)
                            {
                                AudioQueue.AudioSample p = ap.actioncontroller.AudioQueueSpeech.Generate(prefixsoundpath, new ConditionVariables());

                                if (p == null)
                                {
                                    ap.ReportError("Say could not create prefix audio, check audio file format is supported and effects settings");
                                    return(true);
                                }

                                audio = ap.actioncontroller.AudioQueueSpeech.Append(p, audio);        // audio in AUDIO format.
                            }

                            if (postfixsoundpath != null)
                            {
                                AudioQueue.AudioSample p = ap.actioncontroller.AudioQueueSpeech.Generate(postfixsoundpath, new ConditionVariables());

                                if (p == null)
                                {
                                    ap.ReportError("Say could not create postfix audio, check audio file format is supported and effects settings");
                                    return(true);
                                }

                                audio = ap.actioncontroller.AudioQueueSpeech.Append(audio, p);         // Audio in P format
                            }

                            if (start != null)
                            {
                                audio.sampleStartTag = new AudioEvent {
                                    apr = ap, eventname = start, triggername = "onSayStarted"
                                };
                                audio.sampleStartEvent += Audio_sampleEvent;
                            }

                            if (wait || finish != null)        // if waiting, or finish call
                            {
                                audio.sampleOverTag = new AudioEvent()
                                {
                                    apr = ap, wait = wait, eventname = finish, triggername = "onSayFinished"
                                };
                                audio.sampleOverEvent += Audio_sampleEvent;
                            }

                            ap.actioncontroller.AudioQueueSpeech.Submit(audio, vol, priority);

                            return(!wait);       //False if wait, meaning terminate and wait for it to complete, true otherwise, continue
                        }
                    }
                    else
                    {
                        ap.ReportError(expsay);
                    }
                }
                else
                {
                    ap.ReportError(errlist);
                }
            }
            else
            {
                ap.ReportError("Say command line not in correct format");
            }


            return(true);
        }
Esempio n. 4
0
        public override bool ExecuteAction(ActionProgramRun ap)
        {
            string    say;
            Variables statementvars;

            if (FromString(userdata, out say, out statementvars))
            {
                string ctrl = ap.VarExist("SpeechDebug") ? ap["SpeechDebug"] : "";

                string    errlist = null;
                Variables vars    = ap.functions.ExpandVars(statementvars, out errlist);

                if (ctrl.Contains("SayLine"))
                {
                    ap.actioncontroller.LogLine("Say Command: " + userdata);
                    ap.actioncontroller.LogLine("Say Vars: " + vars.ToString(separ: Environment.NewLine));
                    System.Diagnostics.Debug.WriteLine("Say Vars: " + vars.ToString(separ: Environment.NewLine));
                }

                if (errlist == null)
                {
                    bool wait = vars.GetInt(waitname, 0) != 0;

                    string prior = (vars.Exists(priorityname) && vars[priorityname].Length > 0) ? vars[priorityname] : (ap.VarExist(globalvarspeechpriority) ? ap[globalvarspeechpriority] : "Normal");
                    AudioQueue.Priority priority = AudioQueue.GetPriority(prior);

                    string start  = vars.GetString(startname, checklen: true);
                    string finish = vars.GetString(finishname, checklen: true);
                    string voice  = (vars.Exists(voicename) && vars[voicename].Length > 0) ? vars[voicename] : (ap.VarExist(globalvarspeechvoice) ? ap[globalvarspeechvoice] : "Default");

                    int vol = vars.GetInt(volumename, -999);
                    if (vol == -999)
                    {
                        vol = ap.variables.GetInt(globalvarspeechvolume, 60);
                    }

                    int rate = vars.GetInt(ratename, -999);
                    if (rate == -999)
                    {
                        rate = ap.variables.GetInt(globalvarspeechrate, 0);
                    }

                    int queuelimitms = vars.GetInt(queuelimit, 0);

                    string culture = (vars.Exists(culturename) && vars[culturename].Length > 0) ? vars[culturename] : (ap.VarExist(globalvarspeechculture) ? ap[globalvarspeechculture] : "Default");

                    bool literal   = vars.GetInt(literalname, 0) != 0;
                    bool dontspeak = vars.Exists(dontspeakname) ? (vars.GetInt(dontspeakname, 0) != 0) : (ap.VarExist(globalvarspeechdisable) ? ap[globalvarspeechdisable].InvariantParseInt(0) != 0 : false);

                    string prefixsoundpath  = vars.GetString(prefixsound, checklen: true);
                    string postfixsoundpath = vars.GetString(postfixsound, checklen: true);
                    string mixsoundpath     = vars.GetString(mixsound, checklen: true);

                    Variables           globalsettings = ap.VarExist(globalvarspeecheffects) ? new Variables(ap[globalvarspeecheffects], Variables.FromMode.MultiEntryComma) : null;
                    SoundEffectSettings ses            = SoundEffectSettings.Set(globalsettings, vars); // work out the settings

                    if (queuelimitms > 0)
                    {
                        int queue = ap.actioncontroller.AudioQueueSpeech.InQueuems();

                        if (queue >= queuelimitms)
                        {
                            ap["SaySaid"] = "!LIMIT";
                            System.Diagnostics.Debug.WriteLine("Abort say due to queue being at " + queue);
                            return(true);
                        }
                    }

                    string expsay;
                    if (ap.functions.ExpandString(say, out expsay) != Functions.ExpandResult.Failed)
                    {
                        System.Diagnostics.Debug.WriteLine("Say wait {0}, vol {1}, rate {2}, queue {3}, priority {4}, culture {5}, literal {6}, dontspeak {7} , prefix {8}, postfix {9}, mix {10} starte {11}, finishe {12} , voice {13}, text {14}",
                                                           wait, vol, rate, queuelimitms, priority, culture, literal, dontspeak, prefixsoundpath, postfixsoundpath, mixsoundpath, start, finish, voice, expsay);

                        Random rnd = FunctionHandlers.GetRandom();

                        if (!literal)
                        {
                            expsay = expsay.PickOneOfGroups(rnd);       // expand grouping if not literal
                        }

                        ap["SaySaid"] = expsay;

                        if (ctrl.Contains("Global"))
                        {
                            ap.actioncontroller.SetPeristentGlobal("GlobalSaySaid", expsay);
                        }

                        if (ctrl.Contains("Print"))
                        {
                            ap.actioncontroller.LogLine("Say: " + expsay);
                        }

                        if (ctrl.Contains("Mute"))
                        {
                            return(true);
                        }

                        if (ctrl.Contains("DontSpeak"))
                        {
                            expsay = "";
                        }

                        if (dontspeak)
                        {
                            expsay = "";
                        }

                        AudioQueue.AudioSample mix = null, prefix = null, postfix = null;

                        if (mixsoundpath != null)
                        {
                            mix = ap.actioncontroller.AudioQueueSpeech.Generate(mixsoundpath);

                            if (mix == null)
                            {
                                ap.ReportError("Say could not create mix audio, check audio file format is supported and effects settings");
                                return(true);
                            }
                        }

                        if (prefixsoundpath != null)
                        {
                            prefix = ap.actioncontroller.AudioQueueSpeech.Generate(prefixsoundpath);

                            if (prefix == null)
                            {
                                ap.ReportError("Say could not create prefix audio, check audio file format is supported and effects settings");
                                return(true);
                            }
                        }

                        if (postfixsoundpath != null)
                        {
                            postfix = ap.actioncontroller.AudioQueueSpeech.Generate(postfixsoundpath);

                            if (postfix == null)
                            {
                                ap.ReportError("Say could not create postfix audio, check audio file format is supported and effects settings");
                                return(true);
                            }
                        }

                        // we entrust it to a Speach Queue (New Dec 20) as the synth takes an inordinate time to generate speech, it then calls back

                        ap.actioncontroller.SpeechSynthesizer.SpeakQueue(expsay, culture, voice, rate, (memstream) =>
                        {
                            // in a thread, invoke on UI thread to complete action, since these objects are owned by that thread

                            ap.actioncontroller.Form.Invoke((MethodInvoker) delegate
                            {
                                System.Diagnostics.Debug.Assert(Application.MessageLoop);       // double check!

                                AudioQueue.AudioSample audio = ap.actioncontroller.AudioQueueSpeech.Generate(memstream, ses, true);

                                if (audio != null)
                                {
                                    if (mix != null)
                                    {
                                        audio = ap.actioncontroller.AudioQueueSpeech.Mix(audio, mix);     // audio in MIX format
                                    }
                                    if (prefix != null)
                                    {
                                        audio = ap.actioncontroller.AudioQueueSpeech.Append(prefix, audio);        // audio in AUDIO format.
                                    }
                                    if (postfix != null)
                                    {
                                        audio = ap.actioncontroller.AudioQueueSpeech.Append(audio, postfix);         // Audio in P format
                                    }
                                    if (start != null)
                                    {
                                        audio.sampleStartTag = new AudioEvent {
                                            apr = ap, eventname = start, ev = ActionEvent.onSayStarted
                                        };
                                        audio.sampleStartEvent += Audio_sampleEvent;
                                    }

                                    if (wait || finish != null)       // if waiting, or finish call
                                    {
                                        audio.sampleOverTag = new AudioEvent()
                                        {
                                            apr = ap, wait = wait, eventname = finish, ev = ActionEvent.onSayFinished
                                        };
                                        audio.sampleOverEvent += Audio_sampleEvent;
                                    }

                                    ap.actioncontroller.AudioQueueSpeech.Submit(audio, vol, priority);
                                }
                            });
                        });

                        return(!wait);
                    }
                    else
                    {
                        ap.ReportError(expsay);
                    }
                }
                else
                {
                    ap.ReportError(errlist);
                }
            }
            else
            {
                ap.ReportError("Say command line not in correct format");
            }

            return(true);
        }
Esempio n. 5
0
        public override bool ExecuteAction(ActionProgramRun ap)
        {
            string             pathunexpanded;
            ConditionVariables statementvars;

            if (FromString(userdata, out pathunexpanded, out statementvars))
            {
                string             errlist = null;
                ConditionVariables vars    = statementvars.ExpandAll(ap.functions, statementvars, out errlist);

                if (errlist == null)
                {
                    string path;
                    if (ap.functions.ExpandString(pathunexpanded, out path) != ConditionFunctions.ExpandResult.Failed)
                    {
                        if (System.IO.File.Exists(path))
                        {
                            bool wait = vars.GetInt(waitname, 0) != 0;
                            AudioQueue.Priority priority = AudioQueue.GetPriority(vars.GetString(priorityname, "Normal"));
                            string start  = vars.GetString(startname);
                            string finish = vars.GetString(finishname);

                            int vol = vars.GetInt(volumename, -999);
                            if (vol == -999)
                            {
                                vol = ap.variables.GetInt(globalvarplayvolume, 60);
                            }

                            SoundEffectSettings ses = new SoundEffectSettings(vars);                // use the rest of the vars to place effects

                            if (!ses.Any && !ses.OverrideNone && ap.VarExist(globalvarplayeffects)) // if can't see any, and override none if off, and we have a global, use that
                            {
                                vars = new ConditionVariables(ap[globalvarplayeffects], ConditionVariables.FromMode.MultiEntryComma);
                            }

                            AudioQueue.AudioSample audio = ap.actioncontroller.AudioQueueWave.Generate(path, vars);

                            if (audio != null)
                            {
                                if (start != null && start.Length > 0)
                                {
                                    audio.sampleStartTag = new AudioEvent {
                                        apr = ap, eventname = start, triggername = "onPlayStarted"
                                    };
                                    audio.sampleStartEvent += Audio_sampleEvent;
                                }
                                if (wait || (finish != null && finish.Length > 0))       // if waiting, or finish call
                                {
                                    audio.sampleOverTag = new AudioEvent()
                                    {
                                        apr = ap, wait = wait, eventname = finish, triggername = "onPlayFinished"
                                    };
                                    audio.sampleOverEvent += Audio_sampleEvent;
                                }

                                ap.actioncontroller.AudioQueueWave.Submit(audio, vol, priority);
                                return(!wait);       //False if wait, meaning terminate and wait for it to complete, true otherwise, continue
                            }
                            else
                            {
                                ap.ReportError("Play could not create audio, check audio file format is supported and effects settings");
                            }
                        }
                        else
                        {
                            ap.ReportError("Play could not find file " + path);
                        }
                    }
                    else
                    {
                        ap.ReportError(path);
                    }
                }
                else
                {
                    ap.ReportError(errlist);
                }
            }
            else
            {
                ap.ReportError("Play command line not in correct format");
            }

            return(true);
        }
        public void Init(AudioQueue qu, SpeechSynthesizer syn,
                         string title, string caption, Icon ic,
                         String text,             // if null, no text box or wait complete
                         bool waitcomplete, bool literal,
                         AudioQueue.Priority prio,
                         string startname, string endname,
                         string voicename,
                         string volume,
                         string rate,
                         Variables ef)        // effects can also contain other vars, it will ignore
        {
            comboBoxCustomPriority.Items.AddRange(Enum.GetNames(typeof(AudioQueue.Priority)));

            queue                  = qu;
            synth                  = syn;
            this.Text              = caption;
            Title.Text             = title;
            this.Icon              = ic;
            textBoxBorderTest.Text = "The quick brown fox jumped over the lazy dog";

            bool defaultmode = (text == null);

            if (defaultmode)
            {
                textBoxBorderText.Visible         = checkBoxCustomComplete.Visible = comboBoxCustomPriority.Visible = labelStartTrigger.Visible = labelEndTrigger.Visible =
                    checkBoxCustomLiteral.Visible = textBoxBorderStartTrigger.Visible = checkBoxCustomV.Visible = checkBoxCustomR.Visible = textBoxBorderEndTrigger.Visible = false;

                int offset = comboBoxCustomVoice.Top - textBoxBorderText.Top;
                foreach (Control c in panelOuter.Controls)
                {
                    if (!c.Name.Equals("Title"))
                    {
                        c.Location = new Point(c.Left, c.Top - offset);
                    }
                }

                this.Height -= offset;
            }
            else
            {
                textBoxBorderText.Text              = text;
                checkBoxCustomComplete.Checked      = waitcomplete;
                checkBoxCustomLiteral.Checked       = literal;
                comboBoxCustomPriority.SelectedItem = prio.ToString();
                textBoxBorderStartTrigger.Text      = startname;
                textBoxBorderEndTrigger.Text        = endname;
                buttonExtDevice.Visible             = false;
            }

            comboBoxCustomVoice.Items.Add("Default");
            comboBoxCustomVoice.Items.Add("Female");
            comboBoxCustomVoice.Items.Add("Male");
            comboBoxCustomVoice.Items.AddRange(synth.GetVoiceNames());
            if (comboBoxCustomVoice.Items.Contains(voicename))
            {
                comboBoxCustomVoice.SelectedItem = voicename;
            }
            else
            {
                comboBoxCustomVoice.SelectedIndex = 0;
            }

            int i;

            if (!defaultmode && volume.Equals("Default", StringComparison.InvariantCultureIgnoreCase))
            {
                checkBoxCustomV.Checked = false;
                trackBarVolume.Enabled  = false;
            }
            else
            {
                checkBoxCustomV.Checked = true;
                if (volume.InvariantParse(out i))
                {
                    trackBarVolume.Value = i;
                }
            }

            if (!defaultmode && rate.Equals("Default", StringComparison.InvariantCultureIgnoreCase))
            {
                checkBoxCustomR.Checked = false;
                trackBarRate.Enabled    = false;
            }
            else
            {
                checkBoxCustomR.Checked = true;
                if (rate.InvariantParse(out i))
                {
                    trackBarRate.Value = i;
                }
            }

            effects = ef;

            ExtendedControls.ThemeableFormsInstance.Instance?.ApplyToForm(this, System.Drawing.SystemFonts.DefaultFont);
        }
Esempio n. 7
0
        public override bool ExecuteAction(ActionProgramRun ap)
        {
            string    pathunexpanded;
            Variables statementvars;

            if (FromString(userdata, out pathunexpanded, out statementvars))
            {
                string    errlist = null;
                Variables vars    = ap.Functions.ExpandVars(statementvars, out errlist);

                if (errlist == null)
                {
                    string path;
                    if (ap.Functions.ExpandString(pathunexpanded, out path) != Functions.ExpandResult.Failed)
                    {
                        if (path == tonekey || System.IO.File.Exists(path))
                        {
                            bool wait = vars.GetInt(waitname, 0) != 0;
                            AudioQueue.Priority priority = AudioQueue.GetPriority(vars.GetString(priorityname, "Normal"));
                            string start  = vars.GetString(startname);
                            string finish = vars.GetString(finishname);

                            int vol = vars.GetInt(volumename, -999);
                            if (vol == -999)
                            {
                                vol = ap.variables.GetInt(globalvarplayvolume, 60);
                            }

                            Variables           globalsettings = ap.VarExist(globalvarplayeffects) ? new Variables(ap[globalvarplayeffects], Variables.FromMode.MultiEntryComma) : null;
                            SoundEffectSettings ses            = SoundEffectSettings.Set(globalsettings, vars); // work out the settings

                            AudioQueue.AudioSample audio = null;

                            if (path == tonekey)
                            {
                                double freq     = vars.GetDouble(tonefrequency, 512);
                                double lengthms = vars.GetDouble(toneduration, 1000);
                                audio = ap.ActionController.AudioQueueWave.Tone(freq, 100.0, lengthms);
                            }
                            else
                            {
                                audio = ap.ActionController.AudioQueueWave.Generate(path, ses);
                            }

                            double attack = vars.GetDouble(envelopeattack, -1);
                            if (attack >= 0 && audio != null)
                            {
                                double decay   = vars.GetDouble(envelopedecay, 0);
                                double sustain = vars.GetDouble(envelopesustain, 1E12);
                                double release = vars.GetDouble(enveloperelease, 1000);
                                double svolume = vars.GetDouble(sustainvolume, decay == 0 ? 100 : 50);

                                // System.Diagnostics.Debug.WriteLine($"ADSR {attack} {decay} {sustain} {release} {svolume}");
                                audio = ap.ActionController.AudioQueueWave.Envelope(audio, attack, decay, sustain, release, 100.0, svolume);
                            }

                            if (audio != null)
                            {
                                if (start != null && start.Length > 0)
                                {
                                    audio.sampleStartTag = new AudioEvent {
                                        apr = ap, eventname = start, ev = ActionEvent.onPlayStarted
                                    };
                                    audio.sampleStartEvent += Audio_sampleEvent;
                                }
                                if (wait || (finish != null && finish.Length > 0))       // if waiting, or finish call
                                {
                                    audio.sampleOverTag = new AudioEvent()
                                    {
                                        apr = ap, wait = wait, eventname = finish, ev = ActionEvent.onPlayFinished
                                    };
                                    audio.sampleOverEvent += Audio_sampleEvent;
                                }

                                ap.ActionController.AudioQueueWave.Submit(audio, vol, priority);
                                return(!wait);       //False if wait, meaning terminate and wait for it to complete, true otherwise, continue
                            }
                            else
                            {
                                ap.ReportError("Play could not create audio, check audio file format is supported and effects settings");
                            }
                        }
                        else
                        {
                            ap.ReportError("Play could not find file " + path);
                        }
                    }
                    else
                    {
                        ap.ReportError(path);
                    }
                }
                else
                {
                    ap.ReportError(errlist);
                }
            }
            else
            {
                ap.ReportError("Play command line not in correct format");
            }

            return(true);
        }