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  * $Log: vxml.h,v $
00025  * Revision 1.44  2005/12/15 21:14:33  dsandras
00026  * Fixed from Alexander Larsson <alexl _AT__ redhat.com> for gcc 4.1 compilation. Thanks!
00027  *
00028  * Revision 1.43  2005/11/30 12:47:37  csoutheren
00029  * Removed tabs, reformatted some code, and changed tags for Doxygen
00030  *
00031  * Revision 1.42  2005/10/30 23:25:51  csoutheren
00032  * Fixed formatting
00033  * Removed throw() declarations (PWLib does not do exceptions)
00034  * Removed duplicate destructor declarations and definitions
00035  *
00036  * Revision 1.41  2005/10/30 19:41:53  dominance
00037  * fixed most of the warnings occuring during compilation
00038  *
00039  * Revision 1.40  2005/05/12 13:40:45  csoutheren
00040  * Fixed locking problems with currentPLayItem optimisation
00041  *
00042  * Revision 1.39  2005/05/12 05:28:35  csoutheren
00043  * Optimised read loop and fixed problems with playing repeated continuous tones
00044  *
00045  * Revision 1.38  2005/04/21 05:27:58  csoutheren
00046  * Changed default value for OnFrame
00047  *
00048  * Revision 1.37  2005/03/19 02:52:53  csoutheren
00049  * Fix warnings from gcc 4.1-20050313 shapshot
00050  *
00051  * Revision 1.36  2004/12/08 00:52:06  csoutheren
00052  * Added GetSampleFrequency function
00053  *
00054  * Revision 1.35  2004/11/11 07:34:50  csoutheren
00055  * Added #include <ptlib.h>
00056  *
00057  * Revision 1.34  2004/08/09 11:10:34  csoutheren
00058  * Changed SetTextToSpeech to return ptr to new engine
00059  *
00060  * Revision 1.33  2004/07/26 00:40:41  csoutheren
00061  * Fixed thread starvation problem under Linux by splitting channelMutex
00062  * into seperate read and write mutexes
00063  *
00064  * Revision 1.32  2004/07/23 00:59:26  csoutheren
00065  * Check in latest changes
00066  *
00067  * Revision 1.31  2004/07/15 03:12:41  csoutheren
00068  * Migrated changes from crs_vxnml_devel branch into main trunk
00069  *
00070  * Revision 1.30.2.7  2004/07/13 08:13:05  csoutheren
00071  * Lots of implementation of factory-based PWAVFile
00072  *
00073  * Revision 1.30.2.6  2004/07/12 08:30:16  csoutheren
00074  * More fixes for abstract factory implementation of PWAVFile
00075  *
00076  * Revision 1.30.2.5  2004/07/08 04:58:11  csoutheren
00077  * Exposed VXML playable classes to allow descendants
00078  *
00079  * Revision 1.30.2.4  2004/07/07 07:07:41  csoutheren
00080  * Changed PWAVFile to use abstract factories (extensively)
00081  * Removed redundant blocking/unblocking when using G.723.1
00082  * More support for call transfer
00083  *
00084  * Revision 1.30.2.3  2004/07/06 01:38:57  csoutheren
00085  * Changed PVXMLChannel to use PDelayChannel
00086  * Fixed bug where played files were deleted after playing
00087  *
00088  * Revision 1.30.2.2  2004/07/02 07:22:37  csoutheren
00089  * Updated for latest factory changes
00090  *
00091  * Revision 1.30.2.1  2004/06/20 11:18:03  csoutheren
00092  * Rewrite of resource cacheing to cache text-to-speech output
00093  *
00094  * Revision 1.30  2004/06/19 07:21:08  csoutheren
00095  * Change TTS engine registration to use abstract factory code
00096  * Started disentanglement of PVXMLChannel from PVXMLSession
00097  * Fixed problem with VXML session closing if played data file is not exact frame size multiple
00098  * Allowed PVXMLSession to be used without a VXML script
00099  * Changed PVXMLChannel to handle "file:" URLs
00100  * Numerous other small improvements and optimisations
00101  *
00102  * Revision 1.29  2004/06/02 08:29:28  csoutheren
00103  * Added new code from Andreas Sikkema to implement various VXML features
00104  *
00105  * Revision 1.28  2004/06/02 06:17:21  csoutheren
00106  * Removed unnecessary buffer copying and removed potential busy loop
00107  *
00108  * Revision 1.27  2004/03/23 04:48:42  csoutheren
00109  * Improved ability to start VXML scripts as needed
00110  *
00111  * Revision 1.26  2003/04/23 11:55:13  craigs
00112  * Added ability to record audio
00113  *
00114  * Revision 1.25  2003/04/08 05:09:41  craigs
00115  * Added ability to use commands as an audio source
00116  *
00117  * Revision 1.24  2003/03/18 00:45:36  robertj
00118  * Fixed missing return in previous patch.
00119  *
00120  * Revision 1.23  2003/03/18 00:40:28  robertj
00121  * Added back the IsMediaPCM() function for backward compatibility.
00122  *
00123  * Revision 1.22  2003/03/17 08:02:54  robertj
00124  * Combined to the separate incoming and outgoing substream classes into
00125  *   a single class to make it easier to produce codec aware descendents.
00126  * Added G.729 substream class.
00127  *
00128  * Revision 1.21  2002/11/08 03:38:34  craigs
00129  * Fixed problem with G.723.1 files
00130  *
00131  * Revision 1.20  2002/09/18 06:37:13  robertj
00132  * Added functions to load vxml directly, via file or URL. Old function
00133  *   intelligently picks which one to use.
00134  *
00135  * Revision 1.19  2002/09/16 01:08:59  robertj
00136  * Added #define so can select if #pragma interface/implementation is used on
00137  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00138  *
00139  * Revision 1.18  2002/09/03 04:11:14  craigs
00140  * More VXML changes
00141  *
00142  * Revision 1.17  2002/08/30 05:06:13  craigs
00143  * Added changes for PVXMLGrammar
00144  *
00145  * Revision 1.16  2002/08/28 08:04:31  craigs
00146  * Reorganised VXMLSession class as per contributed code
00147  *
00148  * Revision 1.15  2002/08/28 05:10:27  craigs
00149  * Added ability to load resources via URI
00150  * Added cache
00151  *
00152  * Revision 1.14  2002/08/27 02:19:13  craigs
00153  * Added <break> command in prompt blocks
00154  * Fixed potential deadlock
00155  *
00156  * Revision 1.13  2002/08/15 04:11:16  robertj
00157  * Fixed shutdown problems with closing vxml session, leaks a thread.
00158  * Fixed potential problems with indirect channel Close() function.
00159  *
00160  * Revision 1.12  2002/08/08 01:03:19  craigs
00161  * Added function to re-enable automatic call clearing on script end
00162  *
00163  * Revision 1.11  2002/08/06 07:44:56  craigs
00164  * Added lots of stuff from OpalVXML
00165  *
00166  * Revision 1.10  2002/07/29 15:08:34  craigs
00167  * Added autodelete option to PlayFile
00168  *
00169  * Revision 1.9  2002/07/29 15:03:58  craigs
00170  * Added access to queue functions
00171  * Added autodelete option to AddFile
00172  *
00173  * Revision 1.8  2002/07/29 14:15:47  craigs
00174  * Added asynchronous VXML execution
00175  *
00176  * Revision 1.7  2002/07/17 08:34:12  craigs
00177  * Fixed deadlock problems
00178  *
00179  * Revision 1.6  2002/07/17 06:08:43  craigs
00180  * Added additional "sayas" classes
00181  *
00182  * Revision 1.5  2002/07/10 13:14:55  craigs
00183  * Moved some VXML classes from Opal back into PTCLib
00184  *
00185  * Revision 1.4  2002/07/05 06:27:26  craigs
00186  * Removed unused member variables
00187  * Added OnEmptyAction callback
00188  *
00189  * Revision 1.3  2002/07/02 06:23:51  craigs
00190  * Added recording functions
00191  *
00192  * Revision 1.2  2002/06/27 05:39:18  craigs
00193  * Fixed Linux warning
00194  *
00195  * Revision 1.1  2002/06/27 05:28:17  craigs
00196  * Initial version
00197  *
00198  *
00199  */
00200 
00201 #ifndef _VXML_H
00202 #define _VXML_H
00203 
00204 #ifdef P_USE_PRAGMA
00205 #pragma interface
00206 #endif
00207 
00208 #include <ptlib/pipechan.h>
00209 
00210 #include <ptclib/pxml.h>
00211 #include <ptclib/delaychan.h>
00212 #include <ptclib/pwavfile.h>
00213 #include <ptclib/ptts.h>
00214 #include <ptclib/url.h>
00215 
00216 #include <queue>
00217 
00218 
00219 class PVXMLSession;
00220 class PVXMLDialog;
00221 class PVXMLSession;
00222 
00223 class PVXMLTransferOptions;
00224 class PVXMLTransferResult;
00225 
00226 // these are the same strings as the Opal equivalents, but as this is PWLib, we can't use Opal contants
00227 #define VXML_PCM16         "PCM-16"
00228 #define VXML_G7231         "G.723.1"
00229 #define VXML_G729          "G.729"
00230 
00231 #define PVXML_HAS_FACTORY   1
00232 
00233 class PVXMLGrammar : public PObject
00234 {
00235   PCLASSINFO(PVXMLGrammar, PObject);
00236   public:
00237     PVXMLGrammar(PXMLElement * field);
00238     virtual BOOL OnUserInput(const char /*ch*/) { return TRUE; }
00239     virtual void Stop() { }
00240 
00241     PString GetValue() const { return value; }
00242     PXMLElement * GetField() { return field; }
00243 
00244     enum GrammarState { 
00245       FILLED,       
00246       NOINPUT,      
00247       NOMATCH,      
00248       HELP };       
00249 
00250     GrammarState GetState() const { return state; }
00251 
00252   protected:
00253     PXMLElement * field;
00254     PString value;
00255     GrammarState state;
00256 };
00257 
00258 
00260 
00261 class PVXMLMenuGrammar : public PVXMLGrammar
00262 {
00263   PCLASSINFO(PVXMLMenuGrammar, PVXMLGrammar);
00264   public:
00265     PVXMLMenuGrammar(PXMLElement * field);
00266 };
00267 
00268 
00270 
00271 class PVXMLDigitsGrammar : public PVXMLGrammar
00272 {
00273   PCLASSINFO(PVXMLDigitsGrammar, PVXMLGrammar);
00274   public:
00275     PVXMLDigitsGrammar(PXMLElement * field, PINDEX minDigits, PINDEX maxDigits, PString terminators);
00276     BOOL OnUserInput(const char ch);
00277     virtual void Stop();
00278 
00279   protected:
00280     PINDEX minDigits;
00281     PINDEX maxDigits;
00282     PString terminators;
00283 };
00284 
00285 
00287 
00288 class PVXMLCache : public PMutex
00289 {
00290   public:
00291     PVXMLCache(const PDirectory & _directory);
00292 
00293     PFilePath CreateFilename(const PString & prefix, const PString & key, const PString & fileType);
00294 
00295     void Put(const PString & prefix,
00296              const PString & key, 
00297              const PString & fileType, 
00298              const PString & contentType,       
00299            const PFilePath & fn, 
00300                  PFilePath & dataFn);
00301 
00302     BOOL Get(const PString & prefix,
00303              const PString & key, 
00304              const PString & fileType, 
00305                    PString & contentType,       
00306                  PFilePath & fn);
00307 
00308     PFilePath GetCacheDir() const
00309     { return directory; }
00310 
00311     PFilePath GetRandomFilename(const PString & prefix, const PString & fileType);
00312 
00313     static PVXMLCache & GetResourceCache();
00314 
00315   protected:
00316     PDirectory directory;
00317 };
00318 
00320 
00321 class PVXMLChannel;
00322 
00323 class PVXMLChannelInterface {
00324   public:
00325     virtual ~PVXMLChannelInterface() { }
00326     virtual PWAVFile * CreateWAVFile(const PFilePath & fn, PFile::OpenMode mode, int opts, unsigned fmt) = 0;
00327     virtual void RecordEnd() = 0;
00328     virtual void OnEndRecording(const PString & channelName) = 0;
00329     virtual void Trigger() = 0;
00330 };
00331 
00333 
00334 class PVXMLSession : public PIndirectChannel, public PVXMLChannelInterface
00335 {
00336   PCLASSINFO(PVXMLSession, PIndirectChannel);
00337   public:
00338     PVXMLSession(PTextToSpeech * tts = NULL, BOOL autoDelete = FALSE);
00339     virtual ~PVXMLSession();
00340 
00341     void SetFinishWhenEmpty(BOOL v)
00342     { finishWhenEmpty = v; }
00343 
00344     // new functions
00345     PTextToSpeech * SetTextToSpeech(PTextToSpeech * _tts, BOOL autoDelete = FALSE);
00346     PTextToSpeech * SetTextToSpeech(const PString & ttsName);
00347     PTextToSpeech * GetTextToSpeech() { return textToSpeech; }
00348 
00349     virtual BOOL Load(const PString & source);
00350     virtual BOOL LoadFile(const PFilePath & file);
00351     virtual BOOL LoadURL(const PURL & url);
00352     virtual BOOL LoadVXML(const PString & xml);
00353     virtual BOOL IsLoaded() const { return loaded; }
00354 
00355     virtual BOOL Open(BOOL isPCM); // For backward compatibility FALSE=G.723.1
00356     virtual BOOL Open(const PString & mediaFormat);
00357     virtual BOOL Close();
00358 
00359     BOOL Execute();
00360 
00361     PVXMLChannel * GetAndLockVXMLChannel() 
00362     { 
00363       sessionMutex.Wait(); 
00364       if (vxmlChannel != NULL) 
00365         return vxmlChannel; 
00366       sessionMutex.Signal();
00367       return NULL;
00368     }
00369     void UnLockVXMLChannel() { sessionMutex.Signal(); }
00370     PMutex & GetSessionMutex() { return sessionMutex; }
00371 
00372     BOOL LoadGrammar(PVXMLGrammar * grammar);
00373 
00374     virtual BOOL PlayText(const PString & text, PTextToSpeech::TextType type = PTextToSpeech::Default, PINDEX repeat = 1, PINDEX delay = 0);
00375     BOOL ConvertTextToFilenameList(const PString & _text, PTextToSpeech::TextType type, PStringArray & list, BOOL useCacheing);
00376 
00377     virtual BOOL PlayFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, BOOL autoDelete = FALSE);
00378     virtual BOOL PlayData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
00379     virtual BOOL PlayCommand(const PString & data, PINDEX repeat = 1, PINDEX delay = 0);
00380     virtual BOOL PlayResource(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
00381 
00382     //virtual BOOL PlayMedia(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
00383     virtual BOOL PlaySilence(PINDEX msecs = 0);
00384     virtual BOOL PlaySilence(const PTimeInterval & timeout);
00385 
00386     virtual void SetPause(BOOL pause);
00387     virtual void GetBeepData(PBYTEArray & data, unsigned ms);
00388 
00389     virtual BOOL StartRecording(const PFilePath & fn, BOOL recordDTMFTerm, const PTimeInterval & recordMaxTime, const PTimeInterval & recordFinalSilence);
00390     virtual BOOL EndRecording();
00391     virtual BOOL IsPlaying() const;
00392     virtual BOOL IsRecording() const;
00393 
00394     virtual BOOL OnUserInput(const PString & str);
00395 
00396     PString GetXMLError() const;
00397 
00398     virtual void OnEndSession()         { }
00399 
00400     virtual PString GetVar(const PString & str) const;
00401     virtual void SetVar(const PString & ostr, const PString & val);
00402     virtual PString EvaluateExpr(const PString & oexpr);
00403 
00404     virtual BOOL RetreiveResource(const PURL & url, PString & contentType, PFilePath & fn, BOOL useCache = TRUE);
00405 
00406     PDECLARE_NOTIFIER(PThread, PVXMLSession, VXMLExecute);
00407 
00408     virtual BOOL DoTransfer(const PVXMLTransferOptions &) { return TRUE; }
00409     virtual void OnTransfer(const PVXMLTransferResult &);
00410 
00411     void SetCallingToken( PString& token ) { callingCallToken = token; }
00412 
00413     PXMLElement * FindHandler(const PString & event);
00414 
00415     // overrides from VXMLChannelInterface
00416     PWAVFile * CreateWAVFile(const PFilePath & fn, PFile::OpenMode mode, int opts, unsigned fmt);
00417     void OnEndRecording(const PString & channelName);
00418     void RecordEnd();
00419     void Trigger();
00420 
00421   protected:
00422     void Initialise();
00423 
00424     void AllowClearCall();
00425     void ProcessUserInput();
00426     void ProcessNode();
00427     void ProcessGrammar();
00428 
00429     BOOL TraverseAudio();
00430     BOOL TraverseGoto();
00431     BOOL TraverseGrammar();
00432     BOOL TraverseRecord();
00433 
00434     BOOL TraverseIf();
00435     BOOL TraverseExit();
00436     BOOL TraverseVar();
00437     BOOL TraverseSubmit();
00438     BOOL TraverseMenu();
00439     BOOL TraverseChoice(const PString & grammarResult);
00440     BOOL TraverseProperty();
00441 
00442     void SayAs(const PString & className, const PString & text);
00443     static PTimeInterval StringToTime(const PString & str);
00444 
00445     PURL NormaliseResourceName(const PString & src);
00446 
00447     PXMLElement * FindForm(const PString & id);
00448 
00449     virtual BOOL TraverseTransfer();
00450 
00451     //friend class PVXMLChannel;
00452 
00453     PSyncPoint waitForEvent;
00454 
00455     PMutex sessionMutex;
00456 
00457     PXML xmlFile;
00458 
00459     PVXMLGrammar * activeGrammar;
00460     BOOL listening;                 // TRUE if waiting for recognition events
00461     int timeout;                    // timeout in msecs for the current recognition
00462 
00463     PStringToString sessionVars;
00464     PStringToString documentVars;
00465 
00466     PMutex userInputMutex;
00467     std::queue<char> userInputQueue;
00468 
00469     BOOL recording;
00470     PFilePath recordFn;
00471     BOOL recordDTMFTerm;
00472     PTimeInterval recordMaxTime;
00473     PTimeInterval recordFinalSilence;
00474     PSyncPoint    recordSync;
00475 
00476     BOOL loaded;
00477     BOOL finishWhenEmpty;
00478     BOOL allowFinish;
00479     PURL rootURL;
00480     BOOL emptyAction;
00481 
00482     PThread * vxmlThread;
00483     BOOL threadRunning;
00484     BOOL forceEnd;
00485 
00486     PString mediaFormat;
00487     PVXMLChannel * vxmlChannel;
00488 
00489     PTextToSpeech * textToSpeech;
00490     BOOL autoDeleteTextToSpeech;
00491 
00492     PXMLElement * currentForm;
00493     PXMLElement * currentField;
00494     PXMLObject  * currentNode;
00495 
00496   private:
00497     void      ExecuteDialog();
00498 
00499     PString       callingCallToken;
00500     PSyncPoint    transferSync;
00501     PSyncPoint    answerSync;
00502     PString       grammarResult;
00503     PString       eventName;
00504     PINDEX        defaultDTMF;
00505 };
00506 
00507 
00509 
00510 class PVXMLRecordable : public PObject
00511 {
00512   PCLASSINFO(PVXMLRecordable, PObject);
00513   public:
00514     PVXMLRecordable()
00515     { consecutiveSilence = 0; finalSilence = 3000; maxDuration = 30000; }
00516 
00517     virtual BOOL Open(const PString & _arg) = 0;
00518 
00519     virtual void Record(PVXMLChannel & incomingChannel) = 0;
00520 
00521     virtual void OnStart() { }
00522 
00523     virtual BOOL OnFrame(BOOL /*isSilence*/) { return FALSE; }
00524 
00525     virtual void OnStop() { }
00526 
00527     void SetFinalSilence(unsigned v)
00528     { finalSilence = v; }
00529 
00530     unsigned GetFinalSilence()
00531     { return finalSilence; }
00532 
00533     void SetMaxDuration(unsigned v)
00534     { maxDuration = v; }
00535 
00536     unsigned GetMaxDuration()
00537     { return maxDuration; }
00538 
00539   protected:
00540     PTime silenceStart;
00541     PTime recordStart;
00542     unsigned finalSilence;
00543     unsigned maxDuration;
00544     unsigned consecutiveSilence;
00545 };
00546 
00548 
00549 class PVXMLPlayable : public PObject
00550 {
00551   PCLASSINFO(PVXMLPlayable, PObject);
00552   public:
00553     PVXMLPlayable()
00554     { repeat = 1; delay = 0; sampleFrequency = 8000; autoDelete = FALSE; delayDone = FALSE; }
00555 
00556     virtual BOOL Open(PVXMLChannel & /*chan*/, PINDEX _delay, PINDEX _repeat, BOOL _autoDelete)
00557     { delay = _delay; repeat = _repeat; autoDelete = _autoDelete; return TRUE; }
00558 
00559     virtual BOOL Open(PVXMLChannel & chan, const PString & _arg, PINDEX _delay, PINDEX _repeat, BOOL v)
00560     { arg = _arg; return Open(chan, _delay, _repeat, v); }
00561 
00562     virtual void Play(PVXMLChannel & outgoingChannel) = 0;
00563 
00564     virtual void OnRepeat(PVXMLChannel & /*outgoingChannel*/)
00565     { }
00566 
00567     virtual void OnStart() { }
00568 
00569     virtual void OnStop() { }
00570 
00571     virtual void SetRepeat(PINDEX v) 
00572     { repeat = v; }
00573 
00574     virtual PINDEX GetRepeat() const
00575     { return repeat; }
00576 
00577     virtual PINDEX GetDelay() const
00578     { return delay; }
00579 
00580     void SetFormat(const PString & _fmt)
00581     { format = _fmt; }
00582 
00583     void SetSampleFrequency(unsigned _rate)
00584     { sampleFrequency = _rate; }
00585 
00586     virtual BOOL ReadFrame(PVXMLChannel & channel, void * buf, PINDEX len);
00587 
00588     virtual BOOL Rewind(PChannel *) 
00589     { return FALSE; }
00590 
00591     friend class PVXMLChannel;
00592 
00593   protected:
00594     PString arg;
00595     PINDEX repeat;
00596     PINDEX delay;
00597     PString format;
00598     unsigned sampleFrequency;
00599     BOOL autoDelete;
00600     BOOL delayDone; // very tacky flag used to indicate when the post-play delay has been done
00601 };
00602 
00604 
00605 class PVXMLPlayableURL : public PVXMLPlayable
00606 {
00607   PCLASSINFO(PVXMLPlayableURL, PVXMLPlayable);
00608   public:
00609     BOOL Open(PVXMLChannel & chan, const PString & _url, PINDEX _delay, PINDEX _repeat, BOOL v);
00610     void Play(PVXMLChannel & outgoingChannel);
00611   protected:
00612     PURL url;
00613 };
00614 
00616 
00617 class PVXMLPlayableData : public PVXMLPlayable
00618 {
00619   PCLASSINFO(PVXMLPlayableData, PVXMLPlayable);
00620   public:
00621     BOOL Open(PVXMLChannel & chan, const PString & /*_fn*/, PINDEX _delay, PINDEX _repeat, BOOL v);
00622     void SetData(const PBYTEArray & _data);
00623     void Play(PVXMLChannel & outgoingChannel);
00624     BOOL Rewind(PChannel * chan);
00625   protected:
00626     PBYTEArray data;
00627 };
00628 
00630 
00631 class PVXMLPlayableCommand : public PVXMLPlayable
00632 {
00633   PCLASSINFO(PVXMLPlayableCommand, PVXMLPlayable);
00634   public:
00635     PVXMLPlayableCommand();
00636     void Play(PVXMLChannel & outgoingChannel);
00637     void OnStop();
00638 
00639   protected:
00640     PPipeChannel * pipeCmd;
00641 };
00642 
00644 
00645 class PVXMLPlayableFilename : public PVXMLPlayable
00646 {
00647   PCLASSINFO(PVXMLPlayableFilename, PVXMLPlayable);
00648   public:
00649     BOOL Open(PVXMLChannel & chan, const PString & _fn, PINDEX _delay, PINDEX _repeat, BOOL _autoDelete);
00650     void Play(PVXMLChannel & outgoingChannel);
00651     void OnStop();
00652     virtual BOOL Rewind(PChannel * chan);
00653   protected:
00654     PFilePath fn;
00655 };
00656 
00658 
00659 class PVXMLPlayableFilenameList : public PVXMLPlayable
00660 {
00661   PCLASSINFO(PVXMLPlayableFilenameList, PVXMLPlayable);
00662   public:
00663     BOOL Open(PVXMLChannel & chan, const PStringArray & _filenames, PINDEX _delay, PINDEX _repeat, BOOL _autoDelete);
00664     void Play(PVXMLChannel & outgoingChannel)
00665     { OnRepeat(outgoingChannel); }
00666     void OnRepeat(PVXMLChannel & outgoingChannel);
00667     void OnStop();
00668   protected:
00669     PINDEX currentIndex;
00670     PStringArray filenames;
00671 };
00672 
00674 
00675 class PVXMLRecordableFilename : public PVXMLRecordable
00676 {
00677   PCLASSINFO(PVXMLRecordableFilename, PVXMLRecordable);
00678   public:
00679     BOOL Open(const PString & _arg);
00680     void Record(PVXMLChannel & incomingChannel);
00681     BOOL OnFrame(BOOL isSilence);
00682 
00683   protected:
00684     PFilePath fn;
00685 };
00686 
00688 
00689 PQUEUE(PVXMLQueue, PVXMLPlayable);
00690 
00692 
00693 class PVXMLChannel : public PDelayChannel
00694 {
00695   PCLASSINFO(PVXMLChannel, PDelayChannel);
00696   public:
00697     PVXMLChannel(unsigned frameDelay, PINDEX frameSize);
00698     ~PVXMLChannel();
00699 
00700     virtual BOOL Open(PVXMLChannelInterface * _vxml);
00701 
00702     // overrides from PIndirectChannel
00703     virtual BOOL IsOpen() const;
00704     virtual BOOL Close();
00705     virtual BOOL Read(void * buffer, PINDEX amount);
00706     virtual BOOL Write(const void * buf, PINDEX len);
00707 
00708     // new functions
00709     virtual PWAVFile * CreateWAVFile(const PFilePath & fn, BOOL recording = FALSE);
00710 
00711     const PString & GetMediaFormat() const { return mediaFormat; }
00712     BOOL IsMediaPCM() const { return mediaFormat == "PCM-16"; }
00713     virtual PString AdjustWavFilename(const PString & fn);
00714 
00715     // Incoming channel functions
00716     virtual BOOL WriteFrame(const void * buf, PINDEX len) = 0;
00717     virtual BOOL IsSilenceFrame(const void * buf, PINDEX len) const = 0;
00718 
00719     virtual BOOL QueueRecordable(PVXMLRecordable * newItem);
00720 
00721     BOOL StartRecording(const PFilePath & fn, unsigned finalSilence = 3000, unsigned maxDuration = 30000);
00722     BOOL EndRecording();
00723     BOOL IsRecording() const { return recording; }
00724 
00725     // Outgoing channel functions
00726     virtual BOOL ReadFrame(void * buffer, PINDEX amount) = 0;
00727     virtual PINDEX CreateSilenceFrame(void * buffer, PINDEX amount) = 0;
00728     virtual void GetBeepData(PBYTEArray &, unsigned) { }
00729 
00730     virtual BOOL QueueResource(const PURL & url, PINDEX repeat= 1, PINDEX delay = 0);
00731 
00732     virtual BOOL QueuePlayable(const PString & type, const PString & str, PINDEX repeat = 1, PINDEX delay = 0, BOOL autoDelete = FALSE);
00733     virtual BOOL QueuePlayable(PVXMLPlayable * newItem);
00734     virtual BOOL QueueData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
00735 
00736     virtual BOOL QueueFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, BOOL autoDelete = FALSE)
00737     { return QueuePlayable("File", fn, repeat, delay, autoDelete); }
00738 
00739     virtual BOOL QueueCommand(const PString & cmd, PINDEX repeat = 1, PINDEX delay = 0)
00740     { return QueuePlayable("Command", cmd, repeat, delay, TRUE); }
00741 
00742     virtual void FlushQueue();
00743     virtual BOOL IsPlaying() const   { return (playQueue.GetSize() > 0) || playing ; }
00744 
00745     void SetPause(BOOL _pause) { paused = _pause; }
00746 
00747     void SetName(const PString & name) { channelName = name; }
00748 
00749     unsigned GetSampleFrequency() const
00750     { return sampleFrequency; }
00751 
00752   protected:
00753     PVXMLChannelInterface * vxmlInterface;
00754 
00755     unsigned sampleFrequency;
00756     PString mediaFormat;
00757     PString wavFilePrefix;
00758 
00759     PMutex channelWriteMutex;
00760     PMutex channelReadMutex;
00761     BOOL closed;
00762 
00763     // Incoming audio variables
00764     BOOL recording;
00765     PVXMLRecordable * recordable;
00766     unsigned finalSilence;
00767     unsigned silenceRun;
00768 
00769     // Outgoing audio variables
00770     BOOL playing;
00771     PMutex queueMutex;
00772     PVXMLQueue playQueue;
00773     PVXMLPlayable * currentPlayItem;
00774 
00775     BOOL paused;
00776     int silentCount;
00777     int totalData;
00778     PTimer delayTimer;
00779 
00780     // "channelname" (which is the name of the <record> tag) so
00781     // results can be saved in vxml session variable
00782     PString channelName;
00783 };
00784 
00785 
00787 
00788 class PVXMLTransferOptions : public PObject
00789 {
00790   PCLASSINFO(PVXMLTransferOptions, PObject);
00791   public:
00792     PVXMLTransferOptions() { }
00793 
00794     void SetCallingToken(const PString & calling) { callingToken = calling; }
00795     PString GetCallingToken() const               { return callingToken; }
00796     
00797     void SetCalledToken(const PString & called)   { calledToken = called; }
00798     PString GetCalledToken( ) const               { return calledToken; }
00799 
00800     void SetSourceDNR(const PString & src)        { source = src; }
00801     PString GetSourceDNR() const                  { return source; }
00802 
00803     void SetDestinationDNR(const PString & dest ) { destination = dest; }
00804     PString GetDestinationDNR() const             { return destination; }
00805 
00806     void SetTimeout(unsigned int time)            { timeout = time; }
00807     unsigned int GetTimeout() const               { return timeout; }
00808 
00809     void SetBridge(BOOL brdg)                     { bridge = brdg; }
00810     BOOL GetBridge() const                        { return bridge; }
00811 
00812   private:
00813     PString callingToken;
00814     PString calledToken;
00815     PString destination;
00816     PString source;
00817     unsigned int timeout;
00818     BOOL bridge;
00819 };
00820 
00821 class PVXMLTransferResult : public PString
00822 {
00823   PCLASSINFO(PVXMLTransferResult, PString);
00824   public:
00825     PVXMLTransferResult()
00826     { }
00827 
00828     PVXMLTransferResult(char * cstr) 
00829       : PString( cstr ) 
00830     { }
00831 
00832     PVXMLTransferResult(const PString & str )
00833       : PString(str)
00834     {}
00835 
00836     void SetName(const PString & n) 
00837     { name = n; }
00838 
00839     PString GetName() const         
00840     { return name; } 
00841 
00842   private:
00843     PString name;
00844 };
00845 
00846 #endif
00847 
00848 
00849 // End of file ////////////////////////////////////////////////////////////////

Generated on Fri Sep 21 14:40:12 2007 for PWLib by  doxygen 1.5.3