summaryrefslogtreecommitdiffstats
path: root/kttsd/kttsd/speechdata.h
diff options
context:
space:
mode:
Diffstat (limited to 'kttsd/kttsd/speechdata.h')
-rw-r--r--kttsd/kttsd/speechdata.h731
1 files changed, 731 insertions, 0 deletions
diff --git a/kttsd/kttsd/speechdata.h b/kttsd/kttsd/speechdata.h
new file mode 100644
index 0000000..40294bf
--- /dev/null
+++ b/kttsd/kttsd/speechdata.h
@@ -0,0 +1,731 @@
+/*************************************************** vim:set ts=4 sw=4 sts=4:
+ This contains the SpeechData class which is in charge of maintaining
+ all the data on the memory.
+ It maintains queues manages the text.
+ We could say that this is the common repository between the KTTSD class
+ (dcop service) and the Speaker class (speaker, loads plug ins, call plug in
+ functions)
+ -------------------
+ Copyright:
+ (C) 2002-2003 by José Pablo Ezequiel "Pupeno" Fernández <pupeno@kde.org>
+ (C) 2003-2004 by Olaf Schmidt <ojschmidt@kde.org>
+ (C) 2004-2005 by Gary Cramblitt <garycramblitt@comcast.net>
+ -------------------
+ Original author: José Pablo Ezequiel "Pupeno" Fernández
+ ******************************************************************************/
+
+/******************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License. *
+ * *
+ ******************************************************************************/
+
+#ifndef _SPEECHDATA_H_
+#define _SPEECHDATA_H_
+
+// Qt includes.
+#include <qptrqueue.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qmap.h>
+
+// KDE includes.
+#include <kconfig.h>
+
+// KTTS includes.
+#include <kspeech.h>
+#include <talkercode.h>
+#include <filtermgr.h>
+
+class TalkerMgr;
+
+/**
+* Struct containing a text cell, for messages, warnings, and texts.
+* Contains the text itself, the associated talker,
+* the ID of the application that requested it be spoken, and a sequence number.
+*/
+struct mlText{
+ QString talker; /* Requested Talker code for the sentence. */
+ QString text; /* Text of sentence. */
+ QCString appId; /* DCOP senderId of the application that requested the speech. */
+ uint jobNum; /* Text jobNum. Only applies to text messages; not warning and messages. */
+ uint seq; /* Sequence number. */
+};
+
+/**
+ * Struct containing a text job.
+ */
+struct mlJob {
+ uint jobNum; /* Job number. */
+ KSpeech::kttsdJobState state; /* Job state. */
+ QCString appId; /* DCOP senderId of the application that requested the speech job. */
+ QString talker; /* Requested Talker code in which to speak the text. */
+ int seq; /* Current sentence being spoken. */
+ QValueList<int> partSeqNums; /* List containing last sequence number for each part of a job. */
+ QStringList sentences; /* List of sentences in the job. */
+ int partCount; /* Number of parts in the job. */
+};
+
+/**
+ * Struct used to keep a pool of FilterMgr objects.
+ */
+struct PooledFilterMgr {
+ FilterMgr* filterMgr; /* The FilterMgr object. */
+ bool busy; /* True if the FilterMgr is busy. */
+ mlJob* job; /* The job the FilterMgr is filtering. */
+ int partNum; /* The part number of the job that is filtering. */
+ TalkerCode* talkerCode; /* TalkerCode object passed to FilterMgr. */
+};
+
+/**
+ * Struct used to keep notification options.
+ */
+struct NotifyOptions {
+ QString eventName;
+ int action;
+ QString talker;
+ QString customMsg;
+};
+
+/**
+ * A list of notification options for a single app, indexed by event.
+ */
+typedef QMap<QString, NotifyOptions> NotifyEventMap;
+
+/**
+ * A list of notification event maps for all apps, indexed by app.
+ */
+typedef QMap<QString, NotifyEventMap> NotifyAppMap;
+
+/**
+ * SpeechData class which is in charge of maintaining all the data on the memory.
+ * It maintains queues and has methods to enque
+ * messages and warnings and manage the text queues.
+ * We could say that this is the common repository between the KTTSD class
+ * (dcop service) and the Speaker class (speaker, loads plug ins, call plug in
+ * functions)
+ */
+class SpeechData : public QObject {
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor
+ * Sets text to be stopped and warnings and messages queues to be autodelete (thread safe)
+ */
+ SpeechData();
+
+ /**
+ * Destructor
+ */
+ ~SpeechData();
+
+ /**
+ * Read the configuration
+ */
+ bool readConfig();
+
+ /**
+ * Say a message as soon as possible, interrupting any other speech in progress.
+ * IMPORTANT: This method is reserved for use by Screen Readers and should not be used
+ * by any other applications.
+ * @param msg The message to be spoken.
+ * @param talker Code for the talker to speak the message. Example "en".
+ * If NULL, defaults to the user's default talker.
+ * If no plugin has been configured for the specified Talker code,
+ * defaults to the closest matching talker.
+ * @param appId The DCOP senderId of the application.
+ *
+ * If an existing Screen Reader output is in progress, it is stopped and discarded and
+ * replaced with this new message.
+ */
+ void setScreenReaderOutput(const QString &msg, const QString &talker,
+ const QCString& appId);
+
+ /**
+ * Given an appId, returns the last (most recently queued) Job Number with that appId,
+ * or if no such job, the Job Number of the last (most recent) job in the queue.
+ * @param appId The DCOP senderId of the application.
+ * @return Job Number of the text job.
+ * If no such job, returns 0.
+ * If appId is NULL, returns the Job Number of the last job in the queue.
+ * Does not change textJobs.current().
+ */
+ uint findAJobNumByAppId(const QCString& appId);
+
+ /**
+ * Retrieves the Screen Reader Output.
+ */
+ mlText* getScreenReaderOutput();
+
+ /**
+ * Returns true if Screen Reader Output is ready to be spoken.
+ */
+ bool screenReaderOutputReady();
+
+ /**
+ * Add a new warning to the queue.
+ */
+ void enqueueWarning( const QString &, const QString &talker,
+ const QCString& appId);
+
+ /**
+ * Pop (get and erase) a warning from the queue.
+ * @return Pointer to mlText structure containing the warning.
+ *
+ * Caller is responsible for deleting the structure.
+ */
+ mlText* dequeueWarning();
+
+ /**
+ * Are there any Warnings?
+ */
+ bool warningInQueue();
+
+ /**
+ * Add a new message to the queue.
+ */
+ void enqueueMessage( const QString &, const QString &talker,
+ const QCString&);
+
+ /**
+ * Pop (get and erase) a message from the queue.
+ * @return Pointer to mlText structure containing the message.
+ *
+ * Caller is responsible for deleting the structure.
+ */
+ mlText* dequeueMessage();
+
+ /**
+ * Are there any Messages?
+ */
+ bool messageInQueue();
+
+ /**
+ * Sets the GREP pattern that will be used as the sentence delimiter.
+ * @param delimiter A valid GREP pattern.
+ * @param appId The DCOP senderId of the application.
+ *
+ * The default delimiter is
+ @verbatim
+ ([\\.\\?\\!\\:\\;])\\s
+ @endverbatim
+ *
+ * Note that backward slashes must be escaped.
+ *
+ * Changing the sentence delimiter does not affect other applications.
+ * @see sentenceparsing
+ */
+ void setSentenceDelimiter(const QString &delimiter, const QCString appId);
+
+ /* The following methods correspond to the methods in KSpeech interface. */
+
+ /**
+ * Queue a text job. Does not start speaking the text.
+ * (thread safe)
+ * @param text The message to be spoken.
+ * @param talker Code for the talker to speak the text. Example "en".
+ * If NULL, defaults to the user's default talker.
+ * If no plugin has been configured for the specified Talker code,
+ * defaults to the closest matching talker.
+ * @param appId The DCOP senderId of the application.
+ * @return Job number.
+ *
+ * The text is parsed into individual sentences. Call getTextCount to retrieve
+ * the sentence count. Call startText to mark the job as speakable and if the
+ * job is the first speakable job in the queue, speaking will begin.
+ * @see startText.
+ */
+ uint setText(const QString &text, const QString &talker, const QCString& appId);
+
+ /**
+ * Adds another part to a text job. Does not start speaking the text.
+ * (thread safe)
+ * @param jobNum Job number of the text job.
+ * @param text The message to be spoken.
+ * @param appId The DCOP senderId of the application.
+ * @return Part number for the added part. Parts are numbered starting at 1.
+ *
+ * The text is parsed into individual sentences. Call getTextCount to retrieve
+ * the sentence count. Call startText to mark the job as speakable and if the
+ * job is the first speakable job in the queue, speaking will begin.
+ * @see setText.
+ * @see startText.
+ */
+ int appendText(const QString &text, const uint jobNum, const QCString& appId);
+
+ /**
+ * Get the number of sentences in a text job.
+ * (thread safe)
+ * @param jobNum Job number of the text job.
+ * @return The number of sentences in the job. -1 if no such job.
+ *
+ * The sentences of a job are given sequence numbers from 1 to the number returned by this
+ * method. The sequence numbers are emitted in the sentenceStarted and sentenceFinished signals.
+ */
+ int getTextCount(const uint jobNum);
+
+ /**
+ * Get the number of jobs in the text job queue.
+ * (thread safe)
+ * @return Number of text jobs in the queue. 0 if none.
+ */
+ uint getTextJobCount();
+
+ /**
+ * Get a comma-separated list of text job numbers in the queue.
+ * @return Comma-separated list of text job numbers in the queue.
+ */
+ QString getTextJobNumbers();
+
+ /**
+ * Get the state of a text job.
+ * (thread safe)
+ * @param jobNum Job number of the text job.
+ * @return State of the job. -1 if invalid job number.
+ */
+ int getTextJobState(const uint jobNum);
+
+ /**
+ * Set the state of a text job.
+ * @param jobNum Job Number of the job.
+ * @param state New state for the job.
+ *
+ **/
+ void setTextJobState(const uint jobNum, const KSpeech::kttsdJobState state);
+
+ /**
+ * Get information about a text job.
+ * @param jobNum Job number of the text job.
+ * @return A QDataStream containing information about the job.
+ * Blank if no such job.
+ *
+ * The stream contains the following elements:
+ * - int state Job state.
+ * - QCString appId DCOP senderId of the application that requested the speech job.
+ * - QString talker Talker code as requested by application.
+ * - int seq Current sentence being spoken. Sentences are numbered starting at 1.
+ * - int sentenceCount Total number of sentences in the job.
+ * - int partNum Current part of the job begin spoken. Parts are numbered starting at 1.
+ * - int partCount Total number of parts in the job.
+ *
+ * Note that sequence numbers apply to the entire job.
+ * They do not start from 1 at the beginning of each part.
+ *
+ * The following sample code will decode the stream:
+ @verbatim
+ QByteArray jobInfo = getTextJobInfo(jobNum);
+ QDataStream stream(jobInfo, IO_ReadOnly);
+ int state;
+ QCString appId;
+ QString talker;
+ int seq;
+ int sentenceCount;
+ int partNum;
+ int partCount;
+ stream >> state;
+ stream >> appId;
+ stream >> talker;
+ stream >> seq;
+ stream >> sentenceCount;
+ stream >> partNum;
+ stream >> partCount;
+ @endverbatim
+ */
+ QByteArray getTextJobInfo(const uint jobNum);
+
+ /**
+ * Return a sentence of a job.
+ * @param jobNum Job number of the text job.
+ * @param seq Sequence number of the sentence.
+ * @return The specified sentence in the specified job. If no such
+ * job or sentence, returns "".
+ */
+ QString getTextJobSentence(const uint jobNum, const uint seq=1);
+
+ /**
+ * Remove a text job from the queue.
+ * (thread safe)
+ * @param jobNum Job number of the text job.
+ *
+ * The job is deleted from the queue and the textRemoved signal is emitted.
+ */
+ void removeText(const uint jobNum);
+
+ /**
+ * Change the talker for a text job.
+ * @param jobNum Job number of the text job.
+ * @param talker New code for the talker to do speaking. Example "en".
+ * If NULL, defaults to the user's default talker.
+ * If no plugin has been configured for the specified Talker code,
+ * defaults to the closest matching talker.
+ */
+ void changeTextTalker(const QString &talker, uint jobNum);
+
+ /**
+ * Move a text job down in the queue so that it is spoken later.
+ * @param jobNum Job number of the text job.
+ */
+ void moveTextLater(const uint jobNum);
+
+ /**
+ * Jump to the first sentence of a specified part of a text job.
+ * @param partNum Part number of the part to jump to. Parts are numbered starting at 1.
+ * @param jobNum Job number of the text job.
+ * @return Part number of the part actually jumped to.
+ *
+ * If partNum is greater than the number of parts in the job, jumps to last part.
+ * If partNum is 0, does nothing and returns the current part number.
+ * If no such job, does nothing and returns 0.
+ * Does not affect the current speaking/not-speaking state of the job.
+ */
+ int jumpToTextPart(const int partNum, const uint jobNum);
+
+ /**
+ * Advance or rewind N sentences in a text job.
+ * @param n Number of sentences to advance (positive) or rewind (negative)
+ * in the job.
+ * @param jobNum Job number of the text job.
+ * @return Sequence number of the sentence actually moved to. Sequence numbers
+ * are numbered starting at 1.
+ *
+ * If no such job, does nothing and returns 0.
+ * If n is zero, returns the current sequence number of the job.
+ * Does not affect the current speaking/not-speaking state of the job.
+ */
+ uint moveRelTextSentence(const int n, const uint jobNum);
+
+ /**
+ * Given a jobNum, returns the first job with that jobNum.
+ * @return Pointer to the text job.
+ * If no such job, returns 0.
+ * Does not change textJobs.current().
+ */
+ mlJob* findJobByJobNum(const uint jobNum);
+
+ /**
+ * Given a Job Number, returns the next speakable text job on the queue.
+ * @param prevJobNum Current job number (which should not be returned).
+ * @return Pointer to mlJob structure of the first speakable job
+ * not equal prevJobNum. If no such job, returns null.
+ *
+ * Caller must not delete the job.
+ */
+ mlJob* getNextSpeakableJob(const uint prevJobNum);
+
+ /**
+ * Given previous job number and sequence number, returns the next sentence from the
+ * text queue. If no such sentence is available, either because we've run out of
+ * jobs, or because all jobs are paused, returns null.
+ * @param prevJobNum Previous Job Number.
+ * @param prevSeq Previous sequency number.
+ * @return Pointer to n mlText structure containing the next sentence. If no
+ * sentence, returns null.
+ *
+ * Caller is responsible for deleting the returned mlText structure (if not null).
+ */
+ mlText* getNextSentenceText(const uint prevJobNum, const uint prevSeq);
+
+ /**
+ * Given a Job Number, sets the current sequence number of the job.
+ * @param jobNum Job Number.
+ * @param seq Sequence number.
+ * If for some reason, the job does not exist, nothing happens.
+ */
+ void setJobSequenceNum(const uint jobNum, const uint seq);
+
+ /**
+ * Given a Job Number, returns the current sequence number of the job.
+ * @param jobNum Job Number.
+ * @return Sequence number of the job. If no such job, returns 0.
+ */
+ uint getJobSequenceNum(const uint jobNum);
+
+ /**
+ * Given a jobNum, returns the appId of the application that owns the job.
+ * @param jobNum Job number of the text job.
+ * @return appId of the job.
+ * If no such job, returns "".
+ * Does not change textJobs.current().
+ */
+ QCString getAppIdByJobNum(const uint jobNum);
+
+ /**
+ * Sets pointer to the TalkerMgr object.
+ */
+ void setTalkerMgr(TalkerMgr* talkerMgr);
+
+ /* The following properties come from the configuration. */
+
+ /**
+ * Text pre message
+ */
+ QString textPreMsg;
+
+ /**
+ * Text pre message enabled ?
+ */
+ bool textPreMsgEnabled;
+
+ /**
+ * Text pre sound
+ */
+ QString textPreSnd;
+
+ /**
+ * Text pre sound enabled ?
+ */
+ bool textPreSndEnabled;
+
+ /**
+ * Text post message
+ */
+ QString textPostMsg;
+
+ /**
+ * Text post message enabled ?
+ */
+ bool textPostMsgEnabled;
+
+ /**
+ * Text post sound
+ */
+ QString textPostSnd;
+
+ /**
+ * Text post sound enabled ?
+ */
+ bool textPostSndEnabled;
+
+ /**
+ * Paragraph pre message
+ */
+ QString parPreMsg;
+
+ /**
+ * Paragraph pre message enabled ?
+ */
+ bool parPreMsgEnabled;
+
+ /**
+ * Paragraph pre sound
+ */
+ QString parPreSnd;
+
+ /**
+ * Paragraph pre sound enabled ?
+ */
+ bool parPreSndEnabled;
+
+ /**
+ * Paragraph post message
+ */
+ QString parPostMsg;
+
+ /**
+ * Paragraph post message enabled ?
+ */
+ bool parPostMsgEnabled;
+
+ /**
+ * Paragraph post sound
+ */
+ QString parPostSnd;
+
+ /**
+ * Paragraph post sound enabled ?
+ */
+ bool parPostSndEnabled;
+
+ /**
+ * Keep audio files. Do not delete generated tmp wav files.
+ */
+ bool keepAudio;
+ QString keepAudioPath;
+
+ /**
+ * Notification settings.
+ */
+ bool notify;
+ bool notifyExcludeEventsWithSound;
+ NotifyAppMap notifyAppMap;
+ int notifyDefaultPresent;
+ NotifyOptions notifyDefaultOptions;
+
+ /**
+ * Automatically start KTTSMgr whenever speaking.
+ */
+ bool autoStartManager;
+
+ /**
+ * Automatically exit auto-started KTTSMgr when speaking finishes.
+ */
+ bool autoExitManager;
+
+ /**
+ * Configuration
+ */
+ KConfig *config;
+
+ /**
+ * True if at least one XML Transformer plugin for html is enabled.
+ */
+ bool supportsHTML;
+
+ signals:
+ /**
+ * This signal is emitted whenever a new text job is added to the queue.
+ * @param appId The DCOP senderId of the application that created the job.
+ * @param jobNum Job number of the text job.
+ */
+ void textSet(const QCString& appId, const uint jobNum);
+
+ /**
+ * This signal is emitted whenever a new part is appended to a text job.
+ * @param appId The DCOP senderId of the application that created the job.
+ * @param jobNum Job number of the text job.
+ * @param partNum Part number of the new part. Parts are numbered starting
+ * at 1.
+ */
+ void textAppended(const QCString& appId, const uint jobNum, const int partNum);
+
+ /**
+ * This signal is emitted whenever a text job is deleted from the queue.
+ * The job is no longer in the queue when this signal is emitted.
+ * @param appId The DCOP senderId of the application that created the job.
+ * @param jobNum Job number of the text job.
+ */
+ void textRemoved(const QCString& appId, const uint jobNum);
+
+ private:
+ /**
+ * Screen Reader Output.
+ */
+ mlText screenReaderOutput;
+
+ /**
+ * Queue of warnings
+ */
+ QPtrQueue<mlJob> warnings;
+
+ /**
+ * Queue of messages
+ */
+ QPtrQueue<mlJob> messages;
+
+ /**
+ * Queue of text jobs.
+ */
+ QPtrList<mlJob> textJobs;
+
+ /**
+ * TalkerMgr object local pointer.
+ */
+ TalkerMgr* m_talkerMgr;
+
+ /**
+ * Pool of FilterMgrs.
+ */
+ QPtrList<PooledFilterMgr> m_pooledFilterMgrs;
+
+ /**
+ * Job counter. Each new job increments this counter.
+ */
+ uint jobCounter;
+
+ /**
+ * Talker of the text
+ */
+ QString textTalker;
+
+ /**
+ * Map of sentence delimiters. One per app. If none specified for an app, uses default.
+ */
+ QMap<QCString, QString> sentenceDelimiters;
+
+ /**
+ * Determines whether the given text is SSML markup.
+ */
+ bool isSsml(const QString &text);
+
+ /**
+ * Given an appId, returns the last (most recently queued) job with that appId.
+ * @param appId The DCOP senderId of the application.
+ * @return Pointer to the text job.
+ * If no such job, returns 0.
+ * If appId is NULL, returns the last job in the queue.
+ * Does not change textJobs.current().
+ */
+ mlJob* findLastJobByAppId(const QCString& appId);
+
+ /**
+ * Given an appId, returns the last (most recently queued) job with that appId,
+ * or if no such job, the last (most recent) job in the queue.
+ * @param appId The DCOP senderId of the application.
+ * @return Pointer to the text job.
+ * If no such job, returns 0.
+ * If appId is NULL, returns the last job in the queue.
+ * Does not change textJobs.current().
+ */
+ mlJob* findAJobByAppId(const QCString& appId);
+
+ /**
+ * Given a job and a sequence number, returns the part that sentence is in.
+ * If no such job or sequence number, returns 0.
+ * @param job The text job.
+ * @param seq Sequence number of the sentence. Sequence numbers begin with 1.
+ * @return Part number of the part the sentence is in. Parts are numbered
+ * beginning with 1. If no such job or sentence, returns 0.
+ */
+ int getJobPartNumFromSeq(const mlJob& job, const int seq);
+
+ /**
+ * Parses a block of text into sentences using the application-specified regular expression
+ * or (if not specified), the default regular expression.
+ * @param text The message to be spoken.
+ * @param appId The DCOP senderId of the application.
+ * @return List of parsed sentences.
+ */
+
+ QStringList parseText(const QString &text, const QCString &appId);
+
+ /**
+ * Delete expired jobs. At most, one finished job is kept on the queue.
+ * @param finishedJobNum Job number of a job that just finished
+ * The just finished job is not deleted, but any other finished jobs are.
+ * Does not change the textJobs.current() pointer.
+ */
+ void deleteExpiredJobs(const uint finishedJobNum);
+
+ /**
+ * Assigns a FilterMgr to a job and starts filtering on it.
+ */
+ void startJobFiltering(mlJob* job, const QString& text, bool noSBD);
+
+ /**
+ * Waits for filtering to be completed on a job.
+ * This is typically called because an app has requested job info that requires
+ * filtering to be completed, such as getJobInfo.
+ */
+ void waitJobFiltering(const mlJob* job);
+
+ /**
+ * Processes filters by looping across the pool of FilterMgrs.
+ * As each FilterMgr finishes, emits appropriate signals and flags it as no longer busy.
+ */
+ void doFiltering();
+
+ /**
+ * Loads notify events from a file. Clearing data if clear is True.
+ */
+ void loadNotifyEventsFromFile( const QString& filename, bool clear);
+
+ private slots:
+ void slotFilterMgrFinished();
+ void slotFilterMgrStopped();
+};
+
+#endif // _SPEECHDATA_H_