Fix include
[kdeaccessibility.git] / kttsd / filters / sbd / sbdproc.h
blobdcd52457a308208edf5c3d268ec6500e8133108e
1 /***************************************************** vim:set ts=4 sw=4 sts=4:
2 Sentence Boundary Detection (SBD) Filter class.
3 -------------------
4 Copyright:
5 (C) 2005 by Gary Cramblitt <garycramblitt@comcast.net>
6 -------------------
7 Original author: Gary Cramblitt <garycramblitt@comcast.net>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 ******************************************************************************/
24 /******************************************************************************
26 This class performs three kinds of SBD:
27 1. If the text is SSML, generates new SSML where the prosody and voice
28 tags are fully specified for each sentence. This allows user to
29 advance or rewind by sentence without losing SSML context.
30 Input is considered to be SSML if the top-level element is a
31 <speak> tag.
32 2. If the text is code, each line is considered to be a sentence.
33 Input is considered to be code if any of the following strings are
34 detected:
35 slash asterisk
36 if left-paren
37 pound include
38 3. If the text is plain text, performs SBD using specified Regular
39 Expression.
41 Text is output with tab characters (\t) separating sentences.
43 ******************************************************************************/
45 #ifndef _SBDPROC_H_
46 #define _SBDPROC_H_
48 // Qt includes.
49 #include <QObject>
50 #include <QThread>
51 #include <QEvent>
52 #include <QStack>
54 // KTTS includes.
55 #include "filterproc.h"
57 class TalkerCode;
58 class KConfig;
59 class QDomElement;
60 class QDomNode;
62 class SbdThread: public QThread
64 Q_OBJECT
66 public:
67 /**
68 * Constructor.
70 SbdThread( QObject *parent = 0);
72 /**
73 * Destructor.
75 virtual ~SbdThread();
77 /**
78 * Get/Set text being processed.
80 void setText( const QString& text );
81 QString text();
83 /**
84 * Set/Get TalkerCode.
86 void setTalkerCode( TalkerCode* talkerCode );
87 TalkerCode* talkerCode();
89 /**
90 * Set Sentence Boundary Regular Expression.
91 * This method will only be called if the application overrode the default.
93 * @param re The sentence delimiter regular expression.
95 void setSbRegExp( const QString& re );
97 /**
98 * The configured Sentence Boundary Regular Expression.
100 * @param re The sentence delimiter regular expression.
102 void setConfiguredSbRegExp( const QString& re );
105 * The configured Sentence Boundary that replaces SB regular expression.
107 * @param sb The sentence boundary replacement.
110 void setConfiguredSentenceBoundary( const QString& sb );
113 * Did this filter do anything? If the filter returns the input as output
114 * unmolested, it should return False when this method is called.
116 void setWasModified(bool wasModified);
117 bool wasModified();
119 signals:
120 void filteringFinished();
122 protected:
123 virtual void run();
124 virtual bool event ( QEvent * e );
126 private:
127 enum TextType {
128 ttSsml, // SSML
129 ttCode, // Code
130 ttPlain // Plain text
133 enum SsmlElemType {
134 etSpeak,
135 etVoice,
136 etProsody,
137 etEmphasis,
138 etPS, // Paragraph or sentence (we don't care).
139 etBreak,
140 etNotSsml
143 // Speak Element.
144 struct SpeakElem {
145 QString lang; // xml:lang="en".
148 // Voice Element.
149 struct VoiceElem {
150 QString lang; // xml:lang="en".
151 QString gender; // "male", "female", or "neutral".
152 uint age; // Age in years.
153 QString name; // Synth-specific voice name.
154 QString variant; // Ignored.
157 // Prosody Element.
158 struct ProsodyElem {
159 QString pitch; // "x-low", "low", "medium", "high", "x-high", "default".
160 QString contour; // Pitch contour (ignored).
161 QString range; // "x-low", "low", "medium", "high", "x-high", "default".
162 QString rate; // "x-slow", "slow", "medium", "fast", "x-fast", "default".
163 QString duration; // Ignored.
164 QString volume; // "silent", "x-soft", "soft", "medium", "load", "x-load", "default".
167 // Emphasis Element.
168 struct EmphasisElem {
169 QString level; // "strong", "moderate", "none" and "reduced"
172 // Break Element.
173 struct BreakElem {
174 QString strength; // "x-weak", "weak", "medium" (default value), "strong",
175 // or "x-strong", "none"
176 QString time; // Ignored.
179 // Paragraph and Sentence Elements.
180 struct PSElem {
181 QString lang; // xml:lang="en".
184 // Given a tag name, returns SsmlElemType.
185 SsmlElemType tagToSsmlElemType(const QString tagName);
186 // Parses an SSML element, pushing current settings onto the context stack.
187 void pushSsmlElem( SsmlElemType et, const QDomElement& elem );
188 // Given an attribute name and value, constructs an XML representation of the attribute,
189 // i.e., name="value".
190 QString makeAttr( const QString& name, const QString& value );
191 // Returns an XML representation of an SSML tag from the top of the context stack.
192 QString makeSsmlElem( SsmlElemType et );
193 // Pops element from the indicated context stack.
194 void popSsmlElem( SsmlElemType et );
195 QString makeBreakElem( const QDomElement& e );
196 // Converts a text fragment into a CDATA section.
197 QString makeCDATA( const QString& text );
198 // Returns an XML representation of an utterance node consisting of voice,
199 // prosody, and emphasis elements.
200 QString makeSentence( const QString& text );
201 // Starts a sentence by returning a speak tag.
202 QString startSentence();
203 // Ends a sentence and appends a Tab.
204 QString endSentence();
205 // Parses a node of the SSML tree and recursively parses its children.
206 // Returns the filtered text with each sentence a complete ssml tree.
207 QString parseSsmlNode( QDomNode& n, const QString& re );
209 // Parses Ssml.
210 QString parseSsml( const QString& inputText, const QString& re );
211 // Parses code. Each newline is converted into a tab character (\t).
212 QString parseCode( const QString& inputText );
213 // Parses plain text.
214 QString parsePlainText( const QString& inputText, const QString& re );
216 // Context stacks.
217 QStack<SpeakElem> m_speakStack;
218 QStack<VoiceElem> m_voiceStack;
219 QStack<ProsodyElem> m_prosodyStack;
220 QStack<EmphasisElem> m_emphasisStack;
221 QStack<PSElem> m_psStack;
223 // The text being processed.
224 QString m_text;
225 // Talker Code.
226 TalkerCode* m_talkerCode;
227 // Configured default Sentence Delimiter regular expression.
228 QString m_configuredRe;
229 // Configured Sentence Boundary replacement expression.
230 QString m_configuredSentenceBoundary;
231 // Application-specified Sentence Delimiter regular expression (if any).
232 QString m_re;
233 // False if input was not modified.
234 bool m_wasModified;
235 // True when a sentence has been started.
236 bool m_sentenceStarted;
239 class SbdProc : virtual public KttsFilterProc
241 Q_OBJECT
243 public:
245 * Constructor.
247 SbdProc( QObject *parent, const QStringList &args = QStringList() );
250 * Destructor.
252 virtual ~SbdProc();
255 * Initialize the filter.
256 * @param config Settings object.
257 * @param configGroup Settings Group.
258 * @return False if filter is not ready to filter.
260 * Note: The parameters are for reading from kttsdrc file. Plugins may wish to maintain
261 * separate configuration files of their own.
263 virtual bool init( KConfig *config, const QString &configGroup );
266 * Returns True if this filter is a Sentence Boundary Detector.
267 * If so, the filter should implement @ref setSbRegExp() .
268 * @return True if this filter is a SBD.
270 virtual bool isSBD();
273 * Returns True if the plugin supports asynchronous processing,
274 * i.e., supports asyncConvert method.
275 * @return True if this plugin supports asynchronous processing.
277 * If the plugin returns True, it must also implement @ref getState .
278 * It must also emit @ref filteringFinished when filtering is completed.
279 * If the plugin returns True, it must also implement @ref stopFiltering .
280 * It must also emit @ref filteringStopped when filtering has been stopped.
282 virtual bool supportsAsync();
285 * Convert input, returning output. Runs synchronously.
286 * @param inputText Input text.
287 * @param talkerCode TalkerCode structure for the talker that KTTSD intends to
288 * use for synthing the text. Useful for extracting hints about
289 * how to filter the text. For example, languageCode.
290 * @param appId The DCOP appId of the application that queued the text.
291 * Also useful for hints about how to do the filtering.
293 virtual QString convert( const QString& inputText, TalkerCode* talkerCode, const QString& appId );
296 * Convert input. Runs asynchronously.
297 * @param inputText Input text.
298 * @param talkerCode TalkerCode structure for the talker that KTTSD intends to
299 * use for synthing the text. Useful for extracting hints about
300 * how to filter the text. For example, languageCode.
301 * @param appId The DCOP appId of the application that queued the text.
302 * Also useful for hints about how to do the filtering.
303 * @return False if the filter cannot perform the conversion.
305 * When conversion is completed, emits signal @ref filteringFinished. Calling
306 * program may then call @ref getOutput to retrieve converted text. Calling
307 * program must call @ref ackFinished to acknowledge the conversion.
309 virtual bool asyncConvert( const QString& inputText, TalkerCode* talkerCode, const QString& appId );
312 * Waits for a previous call to asyncConvert to finish.
314 virtual void waitForFinished();
317 * Returns the state of the Filter.
319 virtual int getState();
322 * Returns the filtered output.
324 virtual QString getOutput();
327 * Acknowledges the finished filtering.
329 virtual void ackFinished();
332 * Stops filtering. The filteringStopped signal will emit when filtering
333 * has in fact stopped and state returns to fsIdle;
335 virtual void stopFiltering();
338 * Did this filter do anything? If the filter returns the input as output
339 * unmolested, it should return False when this method is called.
341 virtual bool wasModified();
344 * Set Sentence Boundary Regular Expression.
346 virtual void setSbRegExp( const QString& re );
348 private slots:
349 // Received when SBD Thread finishes.
350 void slotSbdThreadFilteringFinished();
352 private:
353 // If not empty, apply filters only to apps using talkers speaking these language codes.
354 QStringList m_languageCodeList;
355 // If not empty, apply filter only to apps containing this string.
356 QStringList m_appIdList;
357 // SBD Thread Object.
358 SbdThread* m_sbdThread;
359 // State.
360 int m_state;
361 // Configured default Sentence Delimiter regular expression.
362 QString m_configuredRe;
365 #endif // _SBDPROC_H_