# vxml.h

Go to the documentation of this file.

    00001 /*
    00002  * vxml.h
    00003  *
    00004  * VXML engine for pwlib library
    00005  *
    00006  * Copyright (C) 2002 Equivalence Pty. Ltd.
    00007  *
    00008  * The contents of this file are subject to the Mozilla Public License
    00009  * Version 1.0 (the "License"); you may not use this file except in
    00010  * compliance with the License. You may obtain a copy of the License at
    00011  * http://www.mozilla.org/MPL/
    00012  *
    00013  * Software distributed under the License is distributed on an "AS IS"
    00014  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00015  * the License for the specific language governing rights and limitations
    00016  * under the License.
    00017  *
    00018  * The Original Code is Portable Windows Library.
    00019  *
    00020  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
    00021  *
    00022  * Contributor(s): ______________________________________.
    00023  *
    00024  * $Revision: 29067 $
    00025  * $Author: rjongbloed $
    00026  * $Date: 2013-02-11 22:34:39 -0600 (Mon, 11 Feb 2013) $
    00027  */
    00028
    00029 #ifndef PTLIB_VXML_H
    00030 #define PTLIB_VXML_H
    00031
    00032 #ifdef P_USE_PRAGMA
    00033 #pragma interface
    00034 #endif
    00035
    00036
    00037 #include <ptclib/pxml.h>
    00038
    00039 #if P_VXML
    00040
    00041 #include <ptlib/pfactory.h>
    00042 #include <ptlib/pipechan.h>
    00043 #include <ptclib/delaychan.h>
    00044 #include <ptclib/pwavfile.h>
    00045 #include <ptclib/ptts.h>
    00046 #include <ptclib/url.h>
    00047
    00048 #include <queue>
    00049
    00050
    00051 class PVXMLSession;
    00052 class PVXMLDialog;
    00053 class PVXMLSession;
    00054
    00055 // these are the same strings as the Opal equivalents, but as this is PWLib, we can't use Opal contants
    00056 #define VXML_PCM16         "PCM-16"
    00057 #define VXML_G7231         "G.723.1"
    00058 #define VXML_G729          "G.729"
    00059
    00060
    00062
    00063 class PVXMLGrammar : public PObject
    00064 {
    00065   PCLASSINFO(PVXMLGrammar, PObject);
    00066   public:
    00067     PVXMLGrammar(PVXMLSession & session, PXMLElement & field);
    00068
    00069     virtual void OnUserInput(const char ch) = 0;
    00070     virtual void Start();
    00071     virtual bool Process();
    00072
    00073     enum GrammarState {
    00074       Idle,
    00075       Started,
    00076       Filled,
    00077       NoInput,
    00078       NoMatch,
    00079       Help
    00080     };
    00081
    00082     GrammarState GetState() const { return m_state; }
    00083
    00084     void SetTimeout(const PTimeInterval & timeout);
    00085
    00086   protected:
    00087     PDECLARE_NOTIFIER(PTimer, PVXMLGrammar, OnTimeout);
    00088
    00089     PVXMLSession & m_session;
    00090     PXMLElement  & m_field;
    00091     PString        m_value;
    00092     GrammarState   m_state;
    00093     PTimeInterval  m_timeout;
    00094     PTimer         m_timer;
    00095     PMutex         m_mutex;
    00096 };
    00097
    00098
    00100
    00101 class PVXMLMenuGrammar : public PVXMLGrammar
    00102 {
    00103   PCLASSINFO(PVXMLMenuGrammar, PVXMLGrammar);
    00104   public:
    00105     PVXMLMenuGrammar(PVXMLSession & session, PXMLElement & field);
    00106     virtual void OnUserInput(const char ch);
    00107     virtual bool Process();
    00108 };
    00109
    00110
    00112
    00113 class PVXMLDigitsGrammar : public PVXMLGrammar
    00114 {
    00115   PCLASSINFO(PVXMLDigitsGrammar, PVXMLGrammar);
    00116   public:
    00117     PVXMLDigitsGrammar(
    00118       PVXMLSession & session,
    00119       PXMLElement & field,
    00120       PINDEX minDigits,
    00121       PINDEX maxDigits,
    00122       PString terminators
    00123     );
    00124
    00125     virtual void OnUserInput(const char ch);
    00126
    00127   protected:
    00128     PINDEX  m_minDigits;
    00129     PINDEX  m_maxDigits;
    00130     PString m_terminators;
    00131 };
    00132
    00133
    00135
    00136 class PVXMLCache : public PMutex
    00137 {
    00138   public:
    00139     PVXMLCache(const PDirectory & directory);
    00140
    00141     PFilePath CreateFilename(const PString & prefix, const PString & key, const PString & fileType);
    00142
    00143     void Put(const PString & prefix,
    00144              const PString & key,
    00145              const PString & fileType,
    00146              const PString & contentType,
    00147            const PFilePath & fn,
    00148                  PFilePath & dataFn);
    00149
    00150     PBoolean Get(const PString & prefix,
    00151              const PString & key,
    00152              const PString & fileType,
    00153                    PString & contentType,
    00154                  PFilePath & fn);
    00155
    00156     PFilePath GetCacheDir() const
    00157     { return directory; }
    00158
    00159     PFilePath GetRandomFilename(const PString & prefix, const PString & fileType);
    00160
    00161     static PVXMLCache & GetResourceCache();
    00162
    00163   protected:
    00164     PDirectory directory;
    00165 };
    00166
    00168
    00169 class PVXMLChannel;
    00170
    00171 class PVXMLSession : public PIndirectChannel
    00172 {
    00173   PCLASSINFO(PVXMLSession, PIndirectChannel);
    00174   public:
    00175     PVXMLSession(PTextToSpeech * tts = NULL, PBoolean autoDelete = false);
    00176     virtual ~PVXMLSession();
    00177
    00178     // new functions
    00179     PTextToSpeech * SetTextToSpeech(PTextToSpeech * tts, PBoolean autoDelete = false);
    00180     PTextToSpeech * SetTextToSpeech(const PString & ttsName);
    00181     PTextToSpeech * GetTextToSpeech() const { return m_textToSpeech; }
    00182
    00183     virtual PBoolean Load(const PString & source);
    00184     virtual PBoolean LoadFile(const PFilePath & file, const PString & firstForm = PString::Empty());
    00185     virtual PBoolean LoadURL(const PURL & url);
    00186     virtual PBoolean LoadVXML(const PString & xml, const PString & firstForm = PString::Empty());
    00187     virtual PBoolean IsLoaded() const { return m_xml.IsLoaded(); }
    00188
    00189     virtual PBoolean Open(const PString & mediaFormat);
    00190     virtual PBoolean Close();
    00191
    00192     virtual PBoolean Execute();
    00193
    00194     PVXMLChannel * GetAndLockVXMLChannel();
    00195     void UnLockVXMLChannel() { m_sessionMutex.Signal(); }
    00196     PMutex & GetSessionMutex() { return m_sessionMutex; }
    00197
    00198     virtual PBoolean LoadGrammar(PVXMLGrammar * grammar);
    00199
    00200     virtual PBoolean PlayText(const PString & text, PTextToSpeech::TextType type = PTextToSpeech::Default, PINDEX repeat = 1, PINDEX delay = 0);
    00201     PBoolean ConvertTextToFilenameList(const PString & text, PTextToSpeech::TextType type, PStringArray & list, PBoolean useCacheing);
    00202
    00203     virtual PBoolean PlayFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
    00204     virtual PBoolean PlayData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
    00205     virtual PBoolean PlayCommand(const PString & data, PINDEX repeat = 1, PINDEX delay = 0);
    00206     virtual PBoolean PlayResource(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
    00207     virtual PBoolean PlayTone(const PString & toneSpec, PINDEX repeat = 1, PINDEX delay = 0);
    00208     virtual PBoolean PlayElement(PXMLElement & element);
    00209
    00210     //virtual PBoolean PlayMedia(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
    00211     virtual PBoolean PlaySilence(PINDEX msecs = 0);
    00212     virtual PBoolean PlaySilence(const PTimeInterval & timeout);
    00213
    00214     virtual PBoolean PlayStop();
    00215
    00216     virtual void SetPause(PBoolean pause);
    00217     virtual void GetBeepData(PBYTEArray & data, unsigned ms);
    00218
    00219     virtual PBoolean StartRecording(const PFilePath & fn, PBoolean recordDTMFTerm, const PTimeInterval & recordMaxTime, const PTimeInterval & recordFinalSilence);
    00220     virtual PBoolean EndRecording();
    00221
    00222     virtual void OnUserInput(const PString & str);
    00223
    00224     PString GetXMLError() const;
    00225
    00226     virtual void OnEndDialog();
    00227     virtual void OnEndSession();
    00228
    00229     enum TransferType {
    00230       BridgedTransfer,
    00231       BlindTransfer,
    00232       ConsultationTransfer
    00233     };
    00234     virtual bool OnTransfer(const PString & /*destination*/, TransferType /*type*/) { return false; }
    00235     void SetTransferComplete(bool state);
    00236
    00237     const PStringToString & GetVariables() { return m_variables; }
    00238     virtual PCaselessString GetVar(const PString & str) const;
    00239     virtual void SetVar(const PString & ostr, const PString & val);
    00240     virtual PString EvaluateExpr(const PString & oexpr);
    00241
    00242     static PTimeInterval StringToTime(const PString & str, int dflt = 0);
    00243
    00244     virtual PBoolean RetreiveResource(const PURL & url, PString & contentType, PFilePath & fn, PBoolean useCache = true);
    00245
    00246     PDECLARE_NOTIFIER(PThread, PVXMLSession, VXMLExecute);
    00247
    00248     bool SetCurrentForm(const PString & id, bool fullURI);
    00249     bool GoToEventHandler(PXMLElement & element, const PString & eventName);
    00250
    00251     // overrides from VXMLChannelInterface
    00252     virtual void OnEndRecording();
    00253     virtual void Trigger();
    00254
    00255
    00256     virtual PBoolean TraverseAudio(PXMLElement & element);
    00257     virtual PBoolean TraverseBreak(PXMLElement & element);
    00258     virtual PBoolean TraverseValue(PXMLElement & element);
    00259     virtual PBoolean TraverseSayAs(PXMLElement & element);
    00260     virtual PBoolean TraverseGoto(PXMLElement & element);
    00261     virtual PBoolean TraverseGrammar(PXMLElement & element);
    00262     virtual PBoolean TraverseRecord(PXMLElement & element);
    00263     virtual PBoolean TraversedRecord(PXMLElement & element);
    00264     virtual PBoolean TraverseIf(PXMLElement & element);
    00265     virtual PBoolean TraverseExit(PXMLElement & element);
    00266     virtual PBoolean TraverseVar(PXMLElement & element);
    00267     virtual PBoolean TraverseSubmit(PXMLElement & element);
    00268     virtual PBoolean TraverseMenu(PXMLElement & element);
    00269     virtual PBoolean TraversedMenu(PXMLElement & element);
    00270     virtual PBoolean TraverseChoice(PXMLElement & element);
    00271     virtual PBoolean TraverseProperty(PXMLElement & element);
    00272     virtual PBoolean TraverseDisconnect(PXMLElement & element);
    00273     virtual PBoolean TraverseForm(PXMLElement & element);
    00274     virtual PBoolean TraversedForm(PXMLElement & element);
    00275     virtual PBoolean TraversePrompt(PXMLElement & element);
    00276     virtual PBoolean TraversedPrompt(PXMLElement & element);
    00277     virtual PBoolean TraverseField(PXMLElement & element);
    00278     virtual PBoolean TraversedField(PXMLElement & element);
    00279     virtual PBoolean TraverseTransfer(PXMLElement & element);
    00280     virtual PBoolean TraversedTransfer(PXMLElement & element);
    00281
    00282     __inline PVXMLChannel * GetVXMLChannel() const { return (PVXMLChannel *)readChannel; }
    00283
    00284   protected:
    00285     virtual bool InternalLoadVXML(const PString & xml, const PString & firstForm);
    00286
    00287     virtual bool ProcessNode();
    00288     virtual bool ProcessEvents();
    00289     virtual bool ProcessGrammar();
    00290     virtual bool NextNode(bool processChildren);
    00291
    00292     void SayAs(const PString & className, const PString & text);
    00293     void SayAs(const PString & className, const PString & text, const PString & voice);
    00294
    00295     PURL NormaliseResourceName(const PString & src);
    00296
    00297     PMutex           m_sessionMutex;
    00298
    00299     PURL             m_rootURL;
    00300     PXML             m_xml;
    00301
    00302     PTextToSpeech *  m_textToSpeech;
    00303     bool             m_autoDeleteTextToSpeech;
    00304
    00305     PThread     *    m_vxmlThread;
    00306     bool             m_abortVXML;
    00307     PSyncPoint       m_waitForEvent;
    00308     PXMLObject  *    m_currentNode;
    00309     bool             m_xmlChanged;
    00310     bool             m_speakNodeData;
    00311     bool             m_bargeIn;
    00312     bool             m_bargingIn;
    00313
    00314     PVXMLGrammar *   m_grammar;
    00315     char             m_defaultMenuDTMF;
    00316
    00317     PStringToString  m_variables;
    00318     PString          m_variableScope;
    00319
    00320     std::queue<char> m_userInputQueue;
    00321     PMutex           m_userInputMutex;
    00322
    00323     enum {
    00324       NotRecording,
    00325       RecordingInProgress,
    00326       RecordingComplete
    00327     }    m_recordingStatus;
    00328     bool m_recordStopOnDTMF;
    00329
    00330     enum {
    00331       NotTransfering,
    00332       TransferInProgress,
    00333       TransferFailed,
    00334       TransferSuccessful
    00335     }     m_transferStatus;
    00336     PTime m_transferStartTime;
    00337 };
    00338
    00339
    00341
    00342 class PVXMLRecordable : public PObject
    00343 {
    00344   PCLASSINFO(PVXMLRecordable, PObject);
    00345   public:
    00346     PVXMLRecordable();
    00347
    00348     virtual PBoolean Open(const PString & arg) = 0;
    00349
    00350     virtual bool OnStart(PVXMLChannel & incomingChannel) = 0;
    00351     virtual void OnStop() { }
    00352
    00353     virtual PBoolean OnFrame(PBoolean /*isSilence*/) { return false; }
    00354
    00355     void SetFinalSilence(unsigned v)
    00356     { m_finalSilence = v > 0 ? v : 60000; }
    00357
    00358     unsigned GetFinalSilence()
    00359     { return m_finalSilence; }
    00360
    00361     void SetMaxDuration(unsigned v)
    00362     { m_maxDuration = v > 0 ? v : 86400000; }
    00363
    00364     unsigned GetMaxDuration()
    00365     { return m_maxDuration; }
    00366
    00367   protected:
    00368     PSimpleTimer m_silenceTimer;
    00369     PSimpleTimer m_recordTimer;
    00370     unsigned     m_finalSilence;
    00371     unsigned     m_maxDuration;
    00372 };
    00373
    00375
    00376 class PVXMLRecordableFilename : public PVXMLRecordable
    00377 {
    00378   PCLASSINFO(PVXMLRecordableFilename, PVXMLRecordable);
    00379   public:
    00380     PBoolean Open(const PString & arg);
    00381     bool OnStart(PVXMLChannel & incomingChannel);
    00382     PBoolean OnFrame(PBoolean isSilence);
    00383
    00384   protected:
    00385     PFilePath m_fileName;
    00386 };
    00387
    00389
    00390 class PVXMLPlayable : public PObject
    00391 {
    00392   PCLASSINFO(PVXMLPlayable, PObject);
    00393   public:
    00394     PVXMLPlayable();
    00395
    00396     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00397
    00398     virtual bool OnStart() = 0;
    00399     virtual bool OnRepeat();
    00400     virtual bool OnDelay();
    00401     virtual void OnStop();
    00402
    00403     virtual void SetRepeat(PINDEX v)
    00404     { m_repeat = v; }
    00405
    00406     virtual PINDEX GetRepeat() const
    00407     { return m_repeat; }
    00408
    00409     virtual PINDEX GetDelay() const
    00410     { return m_delay; }
    00411
    00412     void SetFormat(const PString & fmt)
    00413     { m_format = fmt; }
    00414
    00415     void SetSampleFrequency(unsigned rate)
    00416     { m_sampleFrequency = rate; }
    00417
    00418     friend class PVXMLChannel;
    00419
    00420   protected:
    00421     PVXMLChannel * m_vxmlChannel;
    00422     PChannel * m_subChannel;
    00423     PINDEX   m_repeat;
    00424     PINDEX   m_delay;
    00425     PString  m_format;
    00426     unsigned m_sampleFrequency;
    00427     bool     m_autoDelete;
    00428     bool     m_delayDone; // very tacky flag used to indicate when the post-play delay has been done
    00429 };
    00430
    00432
    00433 class PVXMLPlayableStop : public PVXMLPlayable
    00434 {
    00435   PCLASSINFO(PVXMLPlayableStop, PVXMLPlayable);
    00436   public:
    00437     virtual bool OnStart();
    00438 };
    00439
    00441
    00442 class PVXMLPlayableURL : public PVXMLPlayable
    00443 {
    00444   PCLASSINFO(PVXMLPlayableURL, PVXMLPlayable);
    00445   public:
    00446     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00447     virtual bool OnStart();
    00448   protected:
    00449     PURL m_url;
    00450 };
    00451
    00453
    00454 class PVXMLPlayableData : public PVXMLPlayable
    00455 {
    00456   PCLASSINFO(PVXMLPlayableData, PVXMLPlayable);
    00457   public:
    00458     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00459     void SetData(const PBYTEArray & data);
    00460     virtual bool OnStart();
    00461     virtual bool OnRepeat();
    00462   protected:
    00463     PBYTEArray m_data;
    00464 };
    00465
    00467
    00468 #include <ptclib/dtmf.h>
    00469
    00470 class PVXMLPlayableTone : public PVXMLPlayableData
    00471 {
    00472   PCLASSINFO(PVXMLPlayableTone, PVXMLPlayableData);
    00473   public:
    00474     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00475   protected:
    00476     PTones m_tones;
    00477 };
    00478
    00480
    00481 class PVXMLPlayableCommand : public PVXMLPlayable
    00482 {
    00483   PCLASSINFO(PVXMLPlayableCommand, PVXMLPlayable);
    00484   public:
    00485     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00486     virtual bool OnStart();
    00487     virtual void OnStop();
    00488
    00489   protected:
    00490     PString m_command;
    00491 };
    00492
    00494
    00495 class PVXMLPlayableFile : public PVXMLPlayable
    00496 {
    00497   PCLASSINFO(PVXMLPlayableFile, PVXMLPlayable);
    00498   public:
    00499     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00500     virtual bool OnStart();
    00501     virtual bool OnRepeat();
    00502     virtual void OnStop();
    00503   protected:
    00504     PFilePath m_filePath;
    00505 };
    00506
    00508
    00509 class PVXMLPlayableFileList : public PVXMLPlayableFile
    00510 {
    00511   PCLASSINFO(PVXMLPlayableFileList, PVXMLPlayableFile);
    00512   public:
    00513     PVXMLPlayableFileList();
    00514     virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00515     virtual PBoolean Open(PVXMLChannel & chan, const PStringArray & filenames, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
    00516     virtual bool OnStart();
    00517     virtual bool OnRepeat();
    00518     virtual void OnStop();
    00519   protected:
    00520     PStringArray m_fileNames;
    00521     PINDEX       m_currentIndex;
    00522 };
    00523
    00525
    00526 PQUEUE(PVXMLQueue, PVXMLPlayable);
    00527
    00529
    00530 class PVXMLChannel : public PDelayChannel
    00531 {
    00532   PCLASSINFO(PVXMLChannel, PDelayChannel);
    00533   public:
    00534     PVXMLChannel(unsigned frameDelay, PINDEX frameSize);
    00535     ~PVXMLChannel();
    00536
    00537     virtual PBoolean Open(PVXMLSession * session);
    00538
    00539     // overrides from PIndirectChannel
    00540     virtual PBoolean IsOpen() const;
    00541     virtual PBoolean Close();
    00542     virtual PBoolean Read(void * buffer, PINDEX amount);
    00543     virtual PBoolean Write(const void * buf, PINDEX len);
    00544
    00545     // new functions
    00546     virtual PWAVFile * CreateWAVFile(const PFilePath & fn, PBoolean recording = false);
    00547
    00548     const PString & GetMediaFormat() const { return mediaFormat; }
    00549     PBoolean IsMediaPCM() const { return mediaFormat == "PCM-16"; }
    00550     virtual PString AdjustWavFilename(const PString & fn);
    00551
    00552     // Incoming channel functions
    00553     virtual PBoolean WriteFrame(const void * buf, PINDEX len) = 0;
    00554     virtual PBoolean IsSilenceFrame(const void * buf, PINDEX len) const = 0;
    00555
    00556     virtual PBoolean QueueRecordable(PVXMLRecordable * newItem);
    00557
    00558     PBoolean StartRecording(const PFilePath & fn, unsigned finalSilence = 3000, unsigned maxDuration = 30000);
    00559     PBoolean EndRecording();
    00560     PBoolean IsRecording() const { return m_recordable != NULL; }
    00561
    00562     // Outgoing channel functions
    00563     virtual PBoolean ReadFrame(void * buffer, PINDEX amount) = 0;
    00564     virtual PINDEX CreateSilenceFrame(void * buffer, PINDEX amount) = 0;
    00565     virtual void GetBeepData(PBYTEArray &, unsigned) { }
    00566
    00567     virtual PBoolean QueueResource(const PURL & url, PINDEX repeat= 1, PINDEX delay = 0);
    00568
    00569     virtual PBoolean QueuePlayable(const PString & type, const PString & str, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
    00570     virtual PBoolean QueuePlayable(PVXMLPlayable * newItem);
    00571     virtual PBoolean QueueData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
    00572
    00573     virtual PBoolean QueueFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false)
    00574     { return QueuePlayable("File", fn, repeat, delay, autoDelete); }
    00575
    00576     virtual PBoolean QueueCommand(const PString & cmd, PINDEX repeat = 1, PINDEX delay = 0)
    00577     { return QueuePlayable("Command", cmd, repeat, delay, true); }
    00578
    00579     virtual void FlushQueue();
    00580     virtual PBoolean IsPlaying() const { return m_currentPlayItem != NULL || m_playQueue.GetSize() > 0; }
    00581
    00582     void SetPause(PBoolean pause) { m_paused = pause; }
    00583
    00584     unsigned GetSampleFrequency() const { return m_sampleFrequency; }
    00585
    00586     void SetSilence(unsigned msecs);
    00587
    00588   protected:
    00589     PVXMLSession * m_vxmlSession;
    00590
    00591     unsigned m_sampleFrequency;
    00592     PString mediaFormat;
    00593     PString wavFilePrefix;
    00594
    00595     PMutex   m_channelWriteMutex;
    00596     PMutex   m_channelReadMutex;
    00597     bool     m_closed;
    00598     bool     m_paused;
    00599     PINDEX   m_totalData;
    00600
    00601     // Incoming audio variables
    00602     PVXMLRecordable * m_recordable;
    00603     unsigned          m_finalSilence;
    00604     unsigned          m_silenceRun;
    00605
    00606     // Outgoing audio variables
    00607     PVXMLQueue      m_playQueue;
    00608     PVXMLPlayable * m_currentPlayItem;
    00609     PSimpleTimer    m_silenceTimer;
    00610 };
    00611
    00612
    00614
    00615 class PVXMLNodeHandler : public PObject
    00616 {
    00617     PCLASSINFO(PVXMLNodeHandler, PObject);
    00618   public:
    00619     // Return true for process node, false to skip and move to next sibling
    00620     virtual bool Start(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
    00621
    00622     // Return true to move to next sibling, false to stay at this node.
    00623     virtual bool Finish(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
    00624 };
    00625
    00626
    00627 typedef PFactory<PVXMLNodeHandler, PCaselessString> PVXMLNodeFactory;
    00628
    00629
    00630 #endif // P_VXML
    00631
    00632 #endif // PTLIB_VXML_H
    00633
    00634
    00635 // End of file ////////////////////////////////////////////////////////////////