[Sugar-devel] New and revised chapters of "Make Your Own Sugar Activities!" ready for review, feedback

Aleksey Lim alsroot at member.fsf.org
Thu Jan 21 17:53:30 EST 2010


On Thu, Jan 21, 2010 at 10:41:59PM +0000, Aleksey Lim wrote:
> On Thu, Jan 21, 2010 at 10:24:50AM -0600, Jim Simmons wrote:
> > I just finished writing another chapter of the book, this one on
> > adding Text to Speech to your Activities.  I've also made various
> > additions and corrections to the rest of it.  If you want to check out
> > what I have a PDF created with OBJAVI! is available here:
> > 
> > http://objavi.flossmanuals.net/books/ActivitiesGuideSugar-en-2010.01.21-18.33.56.pdf
> 
> Thanks for your efforts!
> 
> just minor cleanups you can consider to make code less verbose and
> easily understandable(perhaps), see attached speech.py

and also, could be useful to mention words tracking feature of espeak,
like http://wiki.sugarlabs.org/go/Activity_Team/gst-plugins-espeak#Simple_TTS_example

Yes, some espeak versions(at least old ones) could miss some words but
its getting better(I didn't check last espeak version but at least
espeak developers are working on track improvements) and in case of
simple tts usage, just reusing espeak native feature would be more
useful than coding marking stuff.

> 
> > I'm going to start working on code samples for a Collaboration chapter
> > next, and I want to do a chapter on debugging Sugar Activities after
> > that.  I think Walter had developed some code to let you run Sugar
> > Activities outside of the Sugar environment and that would be a good
> > fit for the debugging chapter.  For collaboration I'm going to try to
> > put together a sort of half-finished game called "Battle Royale Tic
> > Tac Toe".  I'll also write about file sharing as used by Read Etexts.
> > 
> > Once I have this material added I think I'll have enough to make it
> > worth putting on the front page of the site.  That won't mean it's
> > finished, but enough of it will be that the book could be considered
> > complete.
> > 
> > I welcome collaborators as well as editors on this.  There are many
> > topics you could put in a book like this that I'm not qualified to
> > write.
> > 
> > I'm up to 87 pages now.
> > 
> > James Simmons
> > 
> 
> -- 
> Aleksey

> import gst
> 
> voice = 'default'
> pitch = 0
> 
> rate = -20
> highlight_cb = None
> 
> def _create_pipe():
>     pipeline = 'espeak name=source ! autoaudiosink'
>     pipe = gst.parse_launch(pipeline)
> 
>     def stop_cb(bus, message):
>         pipe.set_state(gst.STATE_NULL)
> 
>     def mark_cb(bus, message):
>         if message.structure.get_name() == 'espeak-mark':
>             mark = message.structure['mark']
>             highlight_cb(int(mark))
> 
>     bus = pipe.get_bus()
>     bus.add_signal_watch()
>     bus.connect('message::eos', stop_cb)
>     bus.connect('message::error', stop_cb)
>     bus.connect('message::element', mark_cb)
> 
>     return (pipe.get_by_name('source'), pipe)
> 
> def _speech(source, pipe, words):
>     source.props.pitch = pitch
>     source.props.rate = rate
>     source.props.voice = voice
>     source.props.text = words;
>     pipe.set_state(gst.STATE_PLAYING)
> 
> info_source, info_pipe = _create_pipe()
> play_source, play_pipe = _create_pipe()
> 
> # track for marks
> play_source.props.track = 2
> 
> def voices():
>     return info_source.props.voices
> 
> def say(words):
>     _speech(info_source, info_pipe, words)
>     print words
> 
> def play(words):
>     _speech(play_source, play_pipe, words)
> 
> def is_stopped():
>     for i in play_pipe.get_state():
>         if isinstance(i, gst.State) and i == gst.STATE_NULL:
>              return True
>     return False
> 
> def stop():
>     play_pipe.set_state(gst.STATE_NULL)
> 
> def is_paused():
>     for i in play_pipe.get_state():
>         if isinstance(i, gst.State) and i == gst.STATE_PAUSED:
>              return True
>     return False
> 
> def pause():
>     play_pipe.set_state(gst.STATE_PAUSED)
> 
> def rate_up():
>     global rate
>     rate = min(99, rate + 10)
> 
> def rate_down():
>     global rate
>     rate = max(-99, rate - 10)
> 
> def pitch_up():
>     global pitch
>     pitch = min(99, pitch + 10)
> 
> def pitch_down():
>     global pitch
>     pitch = max(-99, pitch - 10)
> 
> def prepare_highlighting(label_text):
>     i = 0
>     j = 0
>     word_begin = 0
>     word_end = 0
>     current_word = 0
>     word_tuples = []
>     omitted = [' ', '\n', u'\r', '_', '[', '{', ']', '}', '|', '<',\
>         '>', '*', '+', '/', '\\' ]
>     omitted_chars = set(omitted)
>     while i < len(label_text):
>         if label_text[i] not in omitted_chars:
>             word_begin = i
>             j = i
>             while j < len(label_text) and label_text[j] not in omitted_chars:
>                  j = j + 1
>                  word_end = j
>                  i = j
>             word_t = (word_begin, word_end, label_text[word_begin: word_end].strip())
>             if word_t[2] != u'\r':
>                  word_tuples.append(word_t)
>         i = i + 1
>     return word_tuples
> 
> def add_word_marks(word_tuples):
>     "Adds a mark between each word of text."
>     i = 0
>     marked_up_text = '<speak> '
>     while i < len(word_tuples):
>         word_t = word_tuples[i]
>         marked_up_text = marked_up_text + '<mark name="' + str(i) + '"/>' + word_t[2]
>         i = i + 1
>     return marked_up_text + '</speak>'


-- 
Aleksey


More information about the Sugar-devel mailing list