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

Generated on Fri Mar 7 06:25:03 2008 for PTLib by  doxygen 1.5.1