PTLib  Version 2.10.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vxml.h
Go to the documentation of this file.
1 /*
2  * vxml.h
3  *
4  * VXML engine for pwlib library
5  *
6  * Copyright (C) 2002 Equivalence Pty. Ltd.
7  *
8  * The contents of this file are subject to the Mozilla Public License
9  * Version 1.0 (the "License"); you may not use this file except in
10  * compliance with the License. You may obtain a copy of the License at
11  * http://www.mozilla.org/MPL/
12  *
13  * Software distributed under the License is distributed on an "AS IS"
14  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15  * the License for the specific language governing rights and limitations
16  * under the License.
17  *
18  * The Original Code is Portable Windows Library.
19  *
20  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
21  *
22  * Contributor(s): ______________________________________.
23  *
24  * $Revision: 26933 $
25  * $Author: rjongbloed $
26  * $Date: 2012-02-02 21:17:20 -0600 (Thu, 02 Feb 2012) $
27  */
28 
29 #ifndef PTLIB_VXML_H
30 #define PTLIB_VXML_H
31 
32 #ifdef P_USE_PRAGMA
33 #pragma interface
34 #endif
35 
36 
37 #include <ptclib/pxml.h>
38 
39 #if P_VXML
40 
41 #include <ptlib/pfactory.h>
42 #include <ptlib/pipechan.h>
43 #include <ptclib/delaychan.h>
44 #include <ptclib/pwavfile.h>
45 #include <ptclib/ptts.h>
46 #include <ptclib/url.h>
47 
48 #include <queue>
49 
50 
51 class PVXMLSession;
52 class PVXMLDialog;
53 class PVXMLSession;
54 
55 // these are the same strings as the Opal equivalents, but as this is PWLib, we can't use Opal contants
56 #define VXML_PCM16 "PCM-16"
57 #define VXML_G7231 "G.723.1"
58 #define VXML_G729 "G.729"
59 
60 
62 
63 class PVXMLGrammar : public PObject
64 {
65  PCLASSINFO(PVXMLGrammar, PObject);
66  public:
67  PVXMLGrammar(PVXMLSession & session, PXMLElement & field);
68 
69  virtual void OnUserInput(const char ch) = 0;
70  virtual void Start();
71  virtual bool Process();
72 
73  enum GrammarState {
74  Idle,
80  };
81 
82  GrammarState GetState() const { return m_state; }
83 
84  protected:
86 
93 };
94 
95 
97 
99 {
100  PCLASSINFO(PVXMLMenuGrammar, PVXMLGrammar);
101  public:
102  PVXMLMenuGrammar(PVXMLSession & session, PXMLElement & field);
103  virtual void OnUserInput(const char ch);
104  virtual bool Process();
105 };
106 
107 
109 
111 {
112  PCLASSINFO(PVXMLDigitsGrammar, PVXMLGrammar);
113  public:
115  PVXMLSession & session,
116  PXMLElement & field,
117  PINDEX minDigits,
118  PINDEX maxDigits,
119  PString terminators
120  );
121 
122  virtual void OnUserInput(const char ch);
123 
124  protected:
125  PINDEX m_minDigits;
126  PINDEX m_maxDigits;
128 };
129 
130 
132 
133 class PVXMLCache : public PMutex
134 {
135  public:
137 
138  PFilePath CreateFilename(const PString & prefix, const PString & key, const PString & fileType);
139 
140  void Put(const PString & prefix,
141  const PString & key,
142  const PString & fileType,
143  const PString & contentType,
144  const PFilePath & fn,
145  PFilePath & dataFn);
146 
147  PBoolean Get(const PString & prefix,
148  const PString & key,
149  const PString & fileType,
150  PString & contentType,
151  PFilePath & fn);
152 
154  { return directory; }
155 
156  PFilePath GetRandomFilename(const PString & prefix, const PString & fileType);
157 
158  static PVXMLCache & GetResourceCache();
159 
160  protected:
162 };
163 
165 
166 class PVXMLChannel;
167 
169 {
170  PCLASSINFO(PVXMLSession, PIndirectChannel);
171  public:
172  PVXMLSession(PTextToSpeech * tts = NULL, PBoolean autoDelete = false);
173  virtual ~PVXMLSession();
174 
175  // new functions
176  PTextToSpeech * SetTextToSpeech(PTextToSpeech * tts, PBoolean autoDelete = false);
177  PTextToSpeech * SetTextToSpeech(const PString & ttsName);
178  PTextToSpeech * GetTextToSpeech() const { return m_textToSpeech; }
179 
180  virtual PBoolean Load(const PString & source);
181  virtual PBoolean LoadFile(const PFilePath & file, const PString & firstForm = PString::Empty());
182  virtual PBoolean LoadURL(const PURL & url);
183  virtual PBoolean LoadVXML(const PString & xml, const PString & firstForm = PString::Empty());
184  virtual PBoolean IsLoaded() const { return m_xml.IsLoaded(); }
185 
186  virtual PBoolean Open(const PString & mediaFormat);
187  virtual PBoolean Close();
188 
189  virtual PBoolean Execute();
190 
192  void UnLockVXMLChannel() { m_sessionMutex.Signal(); }
194 
195  virtual PBoolean LoadGrammar(PVXMLGrammar * grammar);
196 
197  virtual PBoolean PlayText(const PString & text, PTextToSpeech::TextType type = PTextToSpeech::Default, PINDEX repeat = 1, PINDEX delay = 0);
198  PBoolean ConvertTextToFilenameList(const PString & text, PTextToSpeech::TextType type, PStringArray & list, PBoolean useCacheing);
199 
200  virtual PBoolean PlayFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
201  virtual PBoolean PlayData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
202  virtual PBoolean PlayCommand(const PString & data, PINDEX repeat = 1, PINDEX delay = 0);
203  virtual PBoolean PlayResource(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
204  virtual PBoolean PlayTone(const PString & toneSpec, PINDEX repeat = 1, PINDEX delay = 0);
205  virtual PBoolean PlayElement(PXMLElement & element);
206 
207  //virtual PBoolean PlayMedia(const PURL & url, PINDEX repeat = 1, PINDEX delay = 0);
208  virtual PBoolean PlaySilence(PINDEX msecs = 0);
209  virtual PBoolean PlaySilence(const PTimeInterval & timeout);
210 
211  virtual PBoolean PlayStop();
212 
213  virtual void SetPause(PBoolean pause);
214  virtual void GetBeepData(PBYTEArray & data, unsigned ms);
215 
216  virtual PBoolean StartRecording(const PFilePath & fn, PBoolean recordDTMFTerm, const PTimeInterval & recordMaxTime, const PTimeInterval & recordFinalSilence);
217  virtual PBoolean EndRecording();
218 
219  virtual void OnUserInput(const PString & str);
220 
221  PString GetXMLError() const;
222 
223  virtual void OnEndDialog();
224  virtual void OnEndSession();
225 
230  };
231  virtual bool OnTransfer(const PString & /*destination*/, TransferType /*type*/) { return false; }
232  void SetTransferComplete(bool state);
233 
235  virtual PCaselessString GetVar(const PString & str) const;
236  virtual void SetVar(const PString & ostr, const PString & val);
237  virtual PString EvaluateExpr(const PString & oexpr);
238 
239  static PTimeInterval StringToTime(const PString & str);
240 
241  virtual PBoolean RetreiveResource(const PURL & url, PString & contentType, PFilePath & fn, PBoolean useCache = true);
242 
243  PDECLARE_NOTIFIER(PThread, PVXMLSession, VXMLExecute);
244 
245  bool SetCurrentForm(const PString & id, bool fullURI);
246  bool GoToEventHandler(PXMLElement & element, const PString & eventName);
247 
248  // overrides from VXMLChannelInterface
249  virtual void OnEndRecording();
250  virtual void Trigger();
251 
252 
253  virtual PBoolean TraverseAudio(PXMLElement & element);
254  virtual PBoolean TraverseBreak(PXMLElement & element);
255  virtual PBoolean TraverseValue(PXMLElement & element);
256  virtual PBoolean TraverseSayAs(PXMLElement & element);
257  virtual PBoolean TraverseGoto(PXMLElement & element);
258  virtual PBoolean TraverseGrammar(PXMLElement & element);
259  virtual PBoolean TraverseRecord(PXMLElement & element);
260  virtual PBoolean TraversedRecord(PXMLElement & element);
261  virtual PBoolean TraverseIf(PXMLElement & element);
262  virtual PBoolean TraverseExit(PXMLElement & element);
263  virtual PBoolean TraverseVar(PXMLElement & element);
264  virtual PBoolean TraverseSubmit(PXMLElement & element);
265  virtual PBoolean TraverseMenu(PXMLElement & element);
266  virtual PBoolean TraversedMenu(PXMLElement & element);
267  virtual PBoolean TraverseChoice(PXMLElement & element);
268  virtual PBoolean TraverseProperty(PXMLElement & element);
269  virtual PBoolean TraverseDisconnect(PXMLElement & element);
270  virtual PBoolean TraverseForm(PXMLElement & element);
271  virtual PBoolean TraversedForm(PXMLElement & element);
272  virtual PBoolean TraversePrompt(PXMLElement & element);
273  virtual PBoolean TraverseField(PXMLElement & element);
274  virtual PBoolean TraversedField(PXMLElement & element);
275  virtual PBoolean TraverseFilled(PXMLElement & element);
276  virtual PBoolean TraverseNoInput(PXMLElement & element);
277  virtual PBoolean TraverseNoMatch(PXMLElement & element);
278  virtual PBoolean TraverseError(PXMLElement & element);
279  virtual PBoolean TraverseCatch(PXMLElement & element);
280  virtual PBoolean TraverseTransfer(PXMLElement & element);
281  virtual PBoolean TraversedTransfer(PXMLElement & element);
282 
283  __inline PVXMLChannel * GetVXMLChannel() const { return (PVXMLChannel *)readChannel; }
284 
285  protected:
286  virtual bool ProcessNode();
287  virtual bool ProcessEvents();
288  virtual bool ProcessGrammar();
289  virtual bool NextNode(bool skipChildren);
290 
291  void SayAs(const PString & className, const PString & text);
292  void SayAs(const PString & className, const PString & text, const PString & voice);
293 
294  PURL NormaliseResourceName(const PString & src);
295 
297 
300 
301  PTextToSpeech * m_textToSpeech;
303 
310 
313 
316 
317  std::queue<char> m_userInputQueue;
319 
320  enum {
326 
327  enum {
334 };
335 
336 
338 
339 class PVXMLRecordable : public PObject
340 {
341  PCLASSINFO(PVXMLRecordable, PObject);
342  public:
343  PVXMLRecordable();
344 
345  virtual PBoolean Open(const PString & arg) = 0;
346 
347  virtual bool OnStart(PVXMLChannel & incomingChannel) = 0;
348  virtual void OnStop() { }
349 
350  virtual PBoolean OnFrame(PBoolean /*isSilence*/) { return false; }
351 
352  void SetFinalSilence(unsigned v)
353  { m_finalSilence = v > 0 ? v : 60000; }
354 
355  unsigned GetFinalSilence()
356  { return m_finalSilence; }
357 
358  void SetMaxDuration(unsigned v)
359  { m_maxDuration = v > 0 ? v : 86400000; }
360 
361  unsigned GetMaxDuration()
362  { return m_maxDuration; }
363 
364  protected:
367  unsigned m_finalSilence;
368  unsigned m_maxDuration;
369 };
370 
372 
374 {
376  public:
377  PBoolean Open(const PString & arg);
378  bool OnStart(PVXMLChannel & incomingChannel);
379  PBoolean OnFrame(PBoolean isSilence);
380 
381  protected:
383 };
384 
386 
387 class PVXMLPlayable : public PObject
388 {
389  PCLASSINFO(PVXMLPlayable, PObject);
390  public:
391  PVXMLPlayable();
392 
393  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
394 
395  virtual bool OnStart() = 0;
396  virtual bool OnRepeat();
397  virtual bool OnDelay();
398  virtual void OnStop();
399 
400  virtual void SetRepeat(PINDEX v)
401  { m_repeat = v; }
402 
403  virtual PINDEX GetRepeat() const
404  { return m_repeat; }
405 
406  virtual PINDEX GetDelay() const
407  { return m_delay; }
408 
409  void SetFormat(const PString & fmt)
410  { m_format = fmt; }
411 
412  void SetSampleFrequency(unsigned rate)
413  { m_sampleFrequency = rate; }
414 
415  friend class PVXMLChannel;
416 
417  protected:
420  PINDEX m_repeat;
421  PINDEX m_delay;
425  bool m_delayDone; // very tacky flag used to indicate when the post-play delay has been done
426 };
427 
429 
431 {
432  PCLASSINFO(PVXMLPlayableStop, PVXMLPlayable);
433  public:
434  virtual bool OnStart();
435 };
436 
438 
440 {
441  PCLASSINFO(PVXMLPlayableURL, PVXMLPlayable);
442  public:
443  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
444  virtual bool OnStart();
445  protected:
447 };
448 
450 
452 {
453  PCLASSINFO(PVXMLPlayableData, PVXMLPlayable);
454  public:
455  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
456  void SetData(const PBYTEArray & data);
457  virtual bool OnStart();
458  virtual bool OnRepeat();
459  protected:
461 };
462 
464 
465 #include <ptclib/dtmf.h>
466 
468 {
470  public:
471  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
472  protected:
474 };
475 
477 
479 {
480  PCLASSINFO(PVXMLPlayableCommand, PVXMLPlayable);
481  public:
482  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
483  virtual bool OnStart();
484  virtual void OnStop();
485 
486  protected:
488 };
489 
491 
493 {
494  PCLASSINFO(PVXMLPlayableFile, PVXMLPlayable);
495  public:
496  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
497  virtual bool OnStart();
498  virtual bool OnRepeat();
499  virtual void OnStop();
500  protected:
502 };
503 
505 
507 {
509  public:
511  virtual PBoolean Open(PVXMLChannel & chan, const PString & arg, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
512  virtual PBoolean Open(PVXMLChannel & chan, const PStringArray & filenames, PINDEX delay, PINDEX repeat, PBoolean autoDelete);
513  virtual bool OnStart();
514  virtual bool OnRepeat();
515  virtual void OnStop();
516  protected:
519 };
520 
522 
523 PQUEUE(PVXMLQueue, PVXMLPlayable);
524 
526 
528 {
529  PCLASSINFO(PVXMLChannel, PDelayChannel);
530  public:
531  PVXMLChannel(unsigned frameDelay, PINDEX frameSize);
532  ~PVXMLChannel();
533 
534  virtual PBoolean Open(PVXMLSession * session);
535 
536  // overrides from PIndirectChannel
537  virtual PBoolean IsOpen() const;
538  virtual PBoolean Close();
539  virtual PBoolean Read(void * buffer, PINDEX amount);
540  virtual PBoolean Write(const void * buf, PINDEX len);
541 
542  // new functions
543  virtual PWAVFile * CreateWAVFile(const PFilePath & fn, PBoolean recording = false);
544 
545  const PString & GetMediaFormat() const { return mediaFormat; }
546  PBoolean IsMediaPCM() const { return mediaFormat == "PCM-16"; }
547  virtual PString AdjustWavFilename(const PString & fn);
548 
549  // Incoming channel functions
550  virtual PBoolean WriteFrame(const void * buf, PINDEX len) = 0;
551  virtual PBoolean IsSilenceFrame(const void * buf, PINDEX len) const = 0;
552 
553  virtual PBoolean QueueRecordable(PVXMLRecordable * newItem);
554 
555  PBoolean StartRecording(const PFilePath & fn, unsigned finalSilence = 3000, unsigned maxDuration = 30000);
557  PBoolean IsRecording() const { return m_recordable != NULL; }
558 
559  // Outgoing channel functions
560  virtual PBoolean ReadFrame(void * buffer, PINDEX amount) = 0;
561  virtual PINDEX CreateSilenceFrame(void * buffer, PINDEX amount) = 0;
562  virtual void GetBeepData(PBYTEArray &, unsigned) { }
563 
564  virtual PBoolean QueueResource(const PURL & url, PINDEX repeat= 1, PINDEX delay = 0);
565 
566  virtual PBoolean QueuePlayable(const PString & type, const PString & str, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false);
567  virtual PBoolean QueuePlayable(PVXMLPlayable * newItem);
568  virtual PBoolean QueueData(const PBYTEArray & data, PINDEX repeat = 1, PINDEX delay = 0);
569 
570  virtual PBoolean QueueFile(const PString & fn, PINDEX repeat = 1, PINDEX delay = 0, PBoolean autoDelete = false)
571  { return QueuePlayable("File", fn, repeat, delay, autoDelete); }
572 
573  virtual PBoolean QueueCommand(const PString & cmd, PINDEX repeat = 1, PINDEX delay = 0)
574  { return QueuePlayable("Command", cmd, repeat, delay, true); }
575 
576  virtual void FlushQueue();
577  virtual PBoolean IsPlaying() const { return m_currentPlayItem != NULL || m_playQueue.GetSize() > 0; }
578 
579  void SetPause(PBoolean pause) { m_paused = pause; }
580 
581  unsigned GetSampleFrequency() const { return m_sampleFrequency; }
582 
583  void SetSilence(unsigned msecs);
584 
585  protected:
587 
591 
594  bool m_closed;
595  bool m_paused;
596  PINDEX m_totalData;
597 
598  // Incoming audio variables
600  unsigned m_finalSilence;
601  unsigned m_silenceRun;
602 
603  // Outgoing audio variables
604  PVXMLQueue m_playQueue;
607 };
608 
609 
611 
612 class PVXMLNodeHandler : public PObject
613 {
614  PCLASSINFO(PVXMLNodeHandler, PObject);
615  public:
616  // Return true for process node, false to skip and move to next sibling
617  virtual bool Start(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
618 
619  // Return true to move to next sibling, false to stay at this node.
620  virtual bool Finish(PVXMLSession & /*session*/, PXMLElement & /*node*/) const { return true; }
621 };
622 
623 
625 
626 
627 #endif // P_VXML
628 
629 #endif // PTLIB_VXML_H
630 
631 
632 // End of file ////////////////////////////////////////////////////////////////