1/***************************************************** vim:set ts=4 sw=4 sts=4:
2 KSpeech
3
4 The KDE Text-to-Speech API.
5 ------------------------------
6 Copyright:
7 (C) 2006 by Gary Cramblitt <garycramblitt@comcast.net>
8 (C) 2009 by Jeremy Whiting <jpwhiting@kde.org>
9 -------------------
10 Original author: Gary Cramblitt <garycramblitt@comcast.net>
11
12 This library is free software; you can redistribute it and/or
13 modify it under the terms of the GNU Lesser General Public
14 License as published by the Free Software Foundation; either
15 version 2 of the License, or (at your option) any later version.
16
17 This library is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 Lesser General Public License for more details.
21
22 You should have received a copy of the GNU Lesser General Public
23 License along with this library; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 ******************************************************************************/
26
27#ifndef KSPEECH_H
28#define KSPEECH_H
29
30#include "kspeech_export.h"
31
32// Qt includes
33#include <QtCore/QObject>
34#include <QtCore/QString>
35#include <QtCore/QStringList>
36#include <QtCore/QByteArray>
37
38class KSpeechPrivate;
39
40/**
41* KSpeech -- the KDE Text-to-Speech API.
42*
43* Note: Applications do not use this class directly. Instead,
44* use the @ref KSpeechInterface object as described in
45* @ref programming.
46*
47* See also @ref kspeech_intro
48*/
49class KSPEECH_EXPORT KSpeech : public QObject
50{
51Q_OBJECT
52
53public:
54 /**
55 * @enum JobPriority
56 * Determines the priority of jobs submitted by @ref say.
57 * maps directly to SPDPriority
58 */
59 enum JobPriority
60 {
61 jpAll = 0, /**< All priorities. Used for information retrieval only. */
62 jpScreenReaderOutput = 1, /**< Screen Reader job. SPD_IMPORTANT */
63 jpWarning = 2, /**< Warning job. SPD_NOTIFICATION */
64 jpMessage = 3, /**< Message job.SPD_MESSAGE */
65 jpText = 4, /**< Text job. SPD_TEXT */
66 jpProgress = 5 /**< Progress report. SPD_PROGRESS added KDE 4.4 */
67 };
68
69 /**
70 * @enum JobState
71 * Job states returned by method @ref getJobState.
72 */
73 enum JobState
74 {
75 jsQueued = 0, /**< Job has been queued but is not yet speakable. */
76 jsFiltering = 1, /**< Job is being filtered. */
77 jsSpeakable = 2, /**< Job is speakable, but is not speaking. */
78 jsSpeaking = 3, /**< Job is currently speaking. */
79 jsPaused = 4, /**< Job is paused. */
80 jsInterrupted = 5, /**< Job is paused because it has been interrupted by another job. */
81 jsFinished = 6, /**< Job is finished and is deleteable. */
82 jsDeleted = 7 /**< Job is deleted from the queue. */
83 };
84
85 /**
86 * @enum SayOptions
87 * Hints about text content when sending via @ref say.
88 */
89 enum SayOptions
90 {
91 soNone = 0x0000, /**< No options specified. Autodetected. */
92 soPlainText = 0x0001, /**< The text contains plain text. */
93 soHtml = 0x0002, /**< The text contains HTML markup. */
94 soSsml = 0x0004, /**< The text contains SSML markup. */
95 soChar = 0x0008, /**< The text should be spoken as individual characters. */
96 soKey = 0x0010, /**< The text contains a keyboard symbolic key name. */
97 soSoundIcon = 0x0020 /**< The text is the name of a sound icon. */
98 };
99
100 /**
101 * @enum TalkerCapabilities1
102 * Flags for synthesizer/talker capabilities.
103 * All items marked FALSE are hard-coded off at this time.
104 */
105 enum TalkerCapabilities1
106 {
107 tcCanListVoices = 0x00000001,
108 tcCanSetVoiceByProperties = 0x00000002,
109 tcCanGetCurrentVoice = 0x00000004,
110 tcCanSetRateRelative = 0x00000008, /**< FALSE */
111 tcCanSetRateAbsolute = 0x00000010,
112 tcCanGetRateDefault = 0x00000020,
113 tcCanSetPitchRelative = 0x00000040, /**< FALSE */
114 tcCanSetPitchAbsolute = 0x00000080,
115 tcCanGetPitchDefault = 0x00000100,
116 tcCanSetPitchRangeRelative = 0x00000200, /**< FALSE */
117 tcCanSetPitchRangeAbsolute = 0x00000400, /**< FALSE */
118 tcCanGetPitchRangeDefault = 0x00000800, /**< FALSE */
119 tcCanSetVolumeRelative = 0x00001000, /**< FALSE */
120 tcCanSetVolumeAbsolute = 0x00002000,
121 tcCanGetVolumeDefault = 0x00004000,
122 tcCanSetPunctuationModeAll = 0x00008000, /**< FALSE */
123 tcCanSetPunctuationModeNone = 0x00010000, /**< FALSE */
124 tcCanSetPunctuationModeSome = 0x00020000, /**< FALSE */
125 tcCanSetPunctuationDetail = 0x00040000, /**< FALSE */
126 tcCanSetCapitalLettersModeSpelling = 0x00080000, /**< FALSE */
127 tcCanSetCapitalLettersModeIcon = 0x00100000, /**< FALSE */
128 tcCanSetCapitalLettersModePitch = 0x00200000, /**< FALSE */
129 tcCanSetNumberGrouping = 0x00400000, /**< FALSE */
130 tcCanSayTextFromPosition = 0x00800000, /**< FALSE */
131 tcCanSayChar = 0x01000000, /**< FALSE */
132 tcCanSayKey = 0x02000000, /**< FALSE */
133 tcCanSayIcon = 0x04000000, /**< FALSE */
134 tcCanSetDictionary = 0x08000000, /**< FALSE */
135 tcCanRetrieveAudio = 0x10000000, /**< FALSE */
136 tcCanPlayAudio = 0x20000000 /**< FALSE */
137 };
138
139 /**
140 * @enum TalkerCapabilities2
141 * All items marked FALSE are hard-coded off at this time.
142 */
143 enum TalkerCapabilities2
144 {
145 tcCanReportEventsBySentences = 0x00000001,
146 tcCanReportEventsByWords = 0x00000002, /**< FALSE */
147 tcCanReportCustomIndexMarks = 0x00000004, /**< FALSE */
148 tcHonorsPerformanceGuidelines1 = 0x00000008, /**< FALSE */
149 tcHonorsPerformanceGuidelines2 = 0x00000010, /**< FALSE */
150 tcHonorsPerformanceGuidelines = 0x00000018, /**< FALSE */
151 tcCanDeferMessage = 0x00000020, /**< FALSE */
152 tcCanParseSsml = 0x00000040,
153 tcSupportsMultilingualUtterances = 0x00000080, /**< FALSE */
154 tcCanParseHtml = 0x00000100
155 };
156
157 /**
158 * @enum MarkerType
159 * Types of markers emitted by @ref marker signal.
160 */
161 enum MarkerType
162 {
163 mtSentenceBegin = 0,
164 mtSentenceEnd = 1,
165 mtWordBegin = 2,
166 mtPhonemeBegin = 3,
167 mtCustom = 4
168 };
169
170 /**
171 * Constructor.
172 * Note: Applications do not create instances of KSpeech.
173 * Instead create KSpeechInterface object. See @ref programming.
174 */
175 KSpeech(QObject *parent=0);
176
177 /**
178 * Destructor.
179 */
180 ~KSpeech();
181
182public: // PROPERTIES
183 Q_PROPERTY(bool isSpeaking READ isSpeaking)
184 Q_PROPERTY(QString version READ version)
185
186public Q_SLOTS: // METHODS
187 /**
188 * Returns true if KTTSD is currently speaking.
189 * @return True if currently speaking.
190 */
191 bool isSpeaking() const;
192
193 /**
194 * Returns the version number of KTTSD.
195 * @return Version number string.
196 */
197 QString version() const;
198
199 /**
200 * Returns the friendly display name for the application.
201 * @return Application display name.
202 *
203 * If application has not provided a friendly name, the DBUS connection name is returned.
204 */
205 QString applicationName();
206
207 /**
208 * Sets a friendly display name for the application.
209 * @param applicationName Friendly name for the application.
210 */
211 void setApplicationName(const QString &applicationName);
212
213 /**
214 * Returns the default talker for the application.
215 * @return Talker.
216 *
217 * The default is "", which uses the default talker configured by user.
218 */
219 QString defaultTalker();
220
221 /**
222 * Sets the default talker for the application.
223 * @param defaultTalker Default talker. Example: "en".
224 */
225 void setDefaultTalker(const QString &defaultTalker);
226
227 /**
228 * Returns the default priority for speech jobs submitted by the application.
229 * @return Default job priority.
230 *
231 * @see JobPriority
232 */
233 int defaultPriority();
234
235 /**
236 * Sets the default priority for speech jobs submitted by the application.
237 * @param defaultPriority Default job priority.
238 *
239 * @see JobPriority
240 */
241 void setDefaultPriority(int defaultPriority);
242
243 /**
244 * Returns the regular expression used to perform Sentence Boundary
245 * Detection (SBD) for the application.
246 * @return Sentence delimiter regular expression.
247 *
248 * The default sentence delimiter is
249 @verbatim
250 ([\\.\\?\\!\\:\\;])(\\s|$|(\\n *\\n))
251 @endverbatim
252 *
253 * Note that backward slashes must be escaped.
254 *
255 * @see sentenceparsing
256 */
257 QString sentenceDelimiter();
258
259 /**
260 * Sets the regular expression used to perform Sentence Boundary
261 * Detection (SBD) for the application.
262 * @param sentenceDelimiter Sentence delimiter regular expression.
263 */
264 void setSentenceDelimiter(const QString &sentenceDelimiter);
265
266 /**
267 * Returns whether speech jobs for this application are filtered using configured
268 * filter plugins.
269 * @return True if filtering is on.
270 *
271 * Filtering is on by default.
272 */
273 bool filteringOn();
274
275 /**
276 * Sets whether speech jobs for this application are filtered using configured
277 * filter plugins.
278 * @param filteringOn True to set filtering on.
279 */
280 void setFilteringOn(bool filteringOn);
281
282 /**
283 * Returns whether KTTSD will automatically attempt to configure new
284 * talkers to meet required talker attributes.
285 * @return True if KTTSD will autoconfigure talkers.
286 *
287 * @see defaultTalker
288 */
289 bool autoConfigureTalkersOn();
290
291 /** Sets whether KTTSD will automatically attempt to configure new
292 * talkers to meet required talker attributes.
293 * @param autoConfigureTalkersOn True to enable auto configuration.
294 */
295 void setAutoConfigureTalkersOn(bool autoConfigureTalkersOn);
296
297 /**
298 * Returns whether application is paused.
299 * @return True if application is paused.
300 */
301 bool isApplicationPaused();
302
303 /**
304 * Returns the full path name to XSLT file used to convert HTML
305 * markup to speakable form.
306 * @return XSLT filename.
307 */
308 QString htmlFilterXsltFile();
309
310 /**
311 * Sets the full path name to an XSLT file used to convert HTML
312 * markup to speakable form.
313 * @param htmlFilterXsltFile XSLT filename.
314 */
315 void setHtmlFilterXsltFile(const QString &htmlFilterXsltFile);
316
317 /**
318 * Returns the full path name to XSLT file used to convert SSML
319 * markup to a speakable form.
320 * @return XSLT filename.
321 */
322 QString ssmlFilterXsltFile();
323
324 /**
325 * Sets the full path name to XSLT file used to convert SSML
326 * markup to a speakable form.
327 * @param ssmlFilterXsltFile XSLT filename.
328 */
329 void setSsmlFilterXsltFile(const QString &ssmlFilterXsltFile);
330
331 /**
332 * Returns whether this is a System Manager application.
333 * @return True if the application is a System Manager.
334 */
335 bool isSystemManager();
336
337 /**
338 * Sets whether this is a System Manager application.
339 * @param isSystemManager True if this is a System Manager.
340 *
341 * System Managers are used to control and configure overall TTS output.
342 * When True, many of the KSpeech methods alter their behavior.
343 */
344 void setIsSystemManager(bool isSystemManager);
345
346 /**
347 * Creates and starts a speech job. The job is created at the application's
348 * default job priority using the default talker.
349 * @param text The text to be spoken.
350 * @param options Speech options.
351 * @return Job Number for the new job.
352 *
353 * @see JobPriority
354 * @see SayOptions
355 */
356 int say(const QString &text, int options);
357
358 /**
359 * Creates and starts a speech job from a specified file.
360 * @param filename Full path name of the file.
361 * @param encoding The encoding of the file. Default UTF-8.
362 * @return Job Number for the new job.
363 *
364 * The job is spoken using application's default talker.
365 * @see defaultTalker
366 *
367 * Plain text is parsed into individual sentences using the current sentence delimiter.
368 * Call @ref setSentenceDelimiter to change the sentence delimiter prior to calling sayFile.
369 * Call @ref getSentenceCount to retrieve the sentence count after calling sayFile.
370 *
371 * The text may contain speech mark language, such as SMML,
372 * provided that the speech plugin/engine support it. In this case,
373 * sentence parsing follows the semantics of the markup language.
374 */
375 int sayFile(const QString &filename, const QString &encoding);
376
377 /**
378 * Submits a speech job from the contents of the clipboard.
379 * The job is spoken using application's default talker.
380 * @return Job Number for the new job.
381 *
382 * @see defaultTalker
383 */
384 int sayClipboard();
385
386 /**
387 * Pauses speech jobs belonging to the application.
388 * When called by a System Manager, pauses all jobs of all applications.
389 */
390 void pause();
391
392 /**
393 * Resumes speech jobs belonging to the application.
394 * When called by a System Manager, resumes all jobs of all applications.
395 */
396 void resume();
397
398
399 void stop();
400 void cancel();
401
402 void setSpeed(int speed);
403 void setPitch(int pitch);
404 void setVolume(int volume);
405
406 /**
407 * Removes the specified job. If the job is speaking, it is stopped.
408 * @param jobNum Job Number. If 0, the last job submitted by
409 * the application.
410 */
411 void removeJob(int jobNum);
412
413 /**
414 * Removes all jobs belonging to the application.
415 * When called from a System Manager, removes all jobs of all applications.
416 */
417 void removeAllJobs();
418
419 /**
420 * Returns the number of sentences in a job.
421 * @param jobNum Job Number. If 0, the last job submitted by
422 * the application.
423 * @return Number of sentences in the job.
424 */
425 int getSentenceCount(int jobNum);
426
427 /**
428 * Returns the job number of the currently speaking job (any application).
429 * @return Job Number
430 */
431 int getCurrentJob();
432
433 /**
434 * Returns the number of jobs belonging to the application
435 * with the specified job priority.
436 * @param priority Job Priority.
437 * @return Number of jobs.
438 *
439 * If priority is KSpeech::jpAll, returns the number of jobs belonging
440 * to the application (all priorities).
441 *
442 * When called from a System Manager, returns count of all jobs of the
443 * specified priority for all applications.
444 *
445 * @see JobPriority
446 */
447 int getJobCount(int priority);
448
449 /**
450 * Returns a list job numbers for the jobs belonging to the
451 * application with the specified priority.
452 * @param priority Job Priority.
453 * @return List of job numbers. Note that the numbers
454 * are strings.
455 *
456 * If priority is KSpeech::jpAll, returns the job numbers belonging
457 * to the application (all priorities).
458 *
459 * When called from a System Manager, returns job numbers of the
460 * specified priority for all applications.
461 *
462 * @see JobPriority
463 */
464 QStringList getJobNumbers(int priority);
465
466 /**
467 * Returns the state of a job.
468 * @param jobNum Job Number. If 0, the last job submitted by
469 * the application.
470 * @return Job state.
471 *
472 * @see JobState
473 */
474 int getJobState(int jobNum);
475
476 /**
477 * Get information about a job.
478 * @param jobNum Job Number. If 0, the last job submitted by
479 * the application.
480 * @return A QDataStream containing information about the job.
481 * Blank if no such job.
482 *
483 * The stream contains the following elements:
484 * - int priority Job Type.
485 * - int state Job state.
486 * - QString appId DBUS senderId of the application that requested the speech job.
487 * - QString talker Talker code as requested by application.
488 * - int sentenceNum Current sentence being spoken. Sentences are numbered starting at 1.
489 * - int sentenceCount Total number of sentences in the job.
490 * - QString applicationName Application's friendly name (if provided by app)
491 *
492 * If the job is currently filtering, waits for that to finish before returning.
493 *
494 * The following sample code will decode the stream:
495 @verbatim
496 QByteArray jobInfo = m_kspeech->getJobInfo(jobNum);
497 if (jobInfo != QByteArray()) {
498 QDataStream stream(&jobInfo, QIODevice::ReadOnly);
499 qint32 priority;
500 qint32 state;
501 QString talker;
502 qint32 sentenceNum;
503 qint32 sentenceCount;
504 QString applicationName;
505 stream >> priority;
506 stream >> state;
507 stream >> appId;
508 stream >> talker;
509 stream >> sentenceNum;
510 stream >> sentenceCount;
511 stream >> applicationName;
512 };
513 @endverbatim
514 */
515 QByteArray getJobInfo(int jobNum);
516
517 /**
518 * Return a sentence of a job.
519 * @param jobNum Job Number. If 0, the last job submitted by
520 * the application.
521 * @param sentenceNum Sentence Number. Sentence numbers start at 1.
522 * @return The specified sentence in the specified job. If no such
523 * job or sentence, returns "".
524 */
525 QString getJobSentence(int jobNum, int sentenceNum);
526
527 /**
528 * Return a list of full Talker Codes for configured talkers.
529 * @return List of Talker codes.
530 */
531 QStringList getTalkerCodes();
532
533 /**
534 * Given a talker, returns the Talker ID for the talker.
535 * that will speak the job.
536 * @param talker Talker. Example: "en".
537 * @return Talker ID. A Talker ID is an internally-assigned
538 * identifier for a talker.
539 *
540 * This method is normally used only by System Managers.
541 */
542 QString talkerToTalkerId(const QString &talker);
543
544 /**
545 * Returns a bitarray giving the capabilities of a talker.
546 * @param talker Talker. Example: "en".
547 * @return A word with bits set according to the capabilities
548 * of the talker.
549 *
550 * @see TalkerCapabilities1
551 * @see getTalkerCapabilities2
552 */
553 int getTalkerCapabilities1(const QString &talker);
554
555 /**
556 * Returns a bitarray giving the capabilities of a talker.
557 * @param talker Talker. Example: "en".
558 * @return A word with bits set according to the capabilities
559 * of the talker.
560 *
561 * @see TalkerCapabilities2
562 * @see getTalkerCapabilities1
563 */
564 int getTalkerCapabilities2(const QString &talker);
565
566 /**
567 * Return a list of the voice codes of voices available in the synthesizer
568 * corresponding to a talker.
569 * @param talker Talker. Example: "synthesizer='Festival'"
570 * @return List of voice codes.
571 *
572 * Voice codes are synthesizer specific.
573 */
574 QStringList getTalkerVoices(const QString &talker);
575
576 /**
577 * Change the talker of an already-submitted job.
578 * @param jobNum Job Number. If 0, the last job submitted by
579 * the application.
580 * @param talker Desired new talker.
581 */
582 void changeJobTalker(int jobNum, const QString &talker);
583
584 /**
585 * Move a job one position down in the queue so that it is spoken later.
586 * If the job is already speaking, it is stopped and will resume
587 * when processing next gets to it.
588 * @param jobNum Job Number. If 0, the last job submitted by
589 * the application.
590 *
591 * Since there is only one ScreenReaderOutput, this method is meaningless
592 * for ScreenReaderOutput jobs.
593 */
594 void moveJobLater(int jobNum);
595
596 /**
597 * Advance or rewind N sentences in a job.
598 * @param jobNum Job Number. If 0, the last job submitted by
599 * the application.
600 * @param n Number of sentences to advance (positive) or rewind (negative)
601 * in the job.
602 * @return Number of the sentence actually moved to. Sentence numbers
603 * are numbered starting at 1.
604 *
605 * If no such job, does nothing and returns 0.
606 * If n is zero, returns the current sentence number of the job.
607 * Does not affect the current speaking/not-speaking state of the job.
608 *
609 * Since ScreenReaderOutput jobs are not split into sentences, this method
610 * is meaningless for ScreenReaderOutput jobs.
611 */
612 int moveRelSentence(int jobNum, int n);
613
614 /**
615 * Display the KttsMgr program so that user can configure KTTS options.
616 * Only one instance of KttsMgr is displayed.
617 */
618 void showManagerDialog();
619
620 /**
621 * Shuts down KTTSD. Do not call this!
622 */
623 void kttsdExit();
624
625 /**
626 * post ctor helper method that instantiates the dbus adaptor class, and registers
627 */
628 void init();
629
630 /**
631 * Cause KTTSD to re-read its configuration.
632 */
633 void reinit();
634
635 /** Called by DBusAdaptor so that KTTSD knows the application that
636 * called it.
637 * @param appId DBUS connection name that called KSpeech.
638 */
639 void setCallingAppId(const QString& appId);
640
641Q_SIGNALS: // SIGNALS
642 /**
643 * This signal is emitted when KTTSD starts.
644 */
645 void kttsdStarted();
646
647 /**
648 * This signal is emitted just before KTTS exits.
649 */
650 void kttsdExiting();
651
652 /**
653 * This signal is emitted each time the state of a job changes.
654 * @param appId The DBUS connection name of the application that
655 * submitted the job.
656 * @param jobNum Job Number.
657 * @param state Job state. @ref JobState.
658 */
659 void jobStateChanged(const QString &appId, int jobNum, int state);
660
661 /**
662 * This signal is emitted when a marker is processed.
663 * Currently only emits mtSentenceBegin and mtSentenceEnd.
664 * @param appId The DBUS connection name of the application that submitted the job.
665 * @param jobNum Job Number of the job emitting the marker.
666 * @param markerType The type of marker.
667 * Currently either mtSentenceBegin or mtSentenceEnd.
668 * @param markerData Data for the marker.
669 * Currently, this is the sentence number of the sentence
670 * begun or ended. Sentence numbers begin at 1.
671 */
672 void marker(const QString &appId, int jobNum, int markerType, const QString &markerData);
673
674 /**
675 * This signal is emitted when a new job coming in is filtered (or not filtered if no filters
676 * are on).
677 * @param prefilterText The text of the speech job
678 * @param postfilterText The text of the speech job after any filters have been applied
679 */
680 void newJobFiltered(const QString &prefilterText, const QString &postfilterText);
681
682private Q_SLOTS:
683 void slotJobStateChanged(const QString& appId, int jobNum, KSpeech::JobState state);
684 void slotMarker(const QString& appId, int jobNum, KSpeech::MarkerType markerType, const QString& markerData);
685 void slotFilteringFinished();
686
687private:
688 /**
689 * The DBUS connection name of the last application that called KTTSD.
690 */
691 QString callingAppId();
692
693 /*
694 * Checks if KTTSD is ready to speak and at least one talker is configured.
695 * If not, user is prompted to display the configuration dialog.
696 */
697 bool ready();
698
699 /**
700 * Create and initialize the Configuration Data object.
701 */
702 bool initializeConfigData();
703
704 /*
705 * Create and initialize the SpeechData object.
706 * Deprecated, remove in KDE 5
707 */
708 bool initializeSpeechData();
709
710 /*
711 * Create and initialize the TalkerMgr object.
712 */
713 bool initializeTalkerMgr();
714
715 /*
716 * Create and initialize the speaker.
717 */
718 bool initializeSpeaker();
719
720 /*
721 * If a job number is 0, returns the default job number for a command.
722 * Returns the job number of the last job queued by the application, or if
723 * no such job, the current job number.
724 * @param jobNum The job number passed in the DBUS message. May be 0.
725 * @return Default job number. 0 if no such job.
726 */
727 int applyDefaultJobNum(int jobNum);
728
729 /*
730 * Announces an event to kDebug.
731 */
732 void announceEvent(const QString& slotName, const QString& eventName);
733 void announceEvent(const QString& slotName, const QString& eventName, const QString& appId,
734 int jobNum, MarkerType markerType, const QString& markerData);
735 void announceEvent(const QString& slotName, const QString& eventName, const QString& appId,
736 int jobNum, JobState state);
737
738private:
739 KSpeechPrivate* d;
740};
741
742#endif // KSPEECH_H
743