FestivalGenerator.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *  TalkingHead - A talking head for robots
00003  *  Copyright (C) 2012 AG Aktives Sehen <agas@uni-koblenz.de>
00004  *                     Universitaet Koblenz-Landau
00005  *
00006  *  This program is free software: you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation, either version 3 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014  *  Library General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Library General Public
00017  *  License along with this library; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00019  *  MA 02110-1301  USA or see <http://www.gnu.org/licenses/>.
00020  *******************************************************************************/
00021 
00022 #include <string>
00023 
00024 #include "FestivalGenerator.h"
00025 
00026 FestivalGenerator::FestivalGenerator ( QObject* parent ) :
00027     QObject( parent ),
00028     synth_phonemes_( false ),
00029     synth_words_( false ),
00030     publish_smiley_( false ),
00031     punctuation_characters_( 0 )
00032 {
00033     timer_ = new QTimer ( this );  // create internal timer
00034     connect ( timer_, SIGNAL ( timeout() ), SLOT ( run() ) );
00035     timer_->start( 1000.0 / 25 );
00036 
00037     smileys_.push_back( ">:" );
00038     smileys_.push_back( ":)" );
00039     smileys_.push_back( ":(" );
00040     smileys_.push_back(":O");
00041     smileys_.push_back(":o");
00042     smileys_.push_back(":!");
00043     smileys_.push_back(":&");
00044 
00045     punctuation_characters_.push_back( ":" );
00046     punctuation_characters_.push_back( ")" );
00047     punctuation_characters_.push_back( "(" );
00048     punctuation_characters_.push_back( "'" );
00049     punctuation_characters_.push_back( "\"" );
00050     punctuation_characters_.push_back( "}" );
00051     punctuation_characters_.push_back( "{" );
00052     punctuation_characters_.push_back( "§" );
00053     punctuation_characters_.push_back( "!" );
00054     punctuation_characters_.push_back( "?" );
00055     punctuation_characters_.push_back( "`" );
00056     punctuation_characters_.push_back( "´" );
00057     punctuation_characters_.push_back( "-" );
00058     punctuation_characters_.push_back( ";" );
00059     punctuation_characters_.push_back( "€" );
00060     punctuation_characters_.push_back( "°" );
00061     punctuation_characters_.push_back( "<" );
00062     punctuation_characters_.push_back( ">" );
00063     punctuation_characters_.push_back( "." );
00064     punctuation_characters_.push_back( "," );
00065 }
00066 
00067 FestivalGenerator::~FestivalGenerator ()
00068 {
00069     festival_tidy_up();
00070 }
00071 
00072 void FestivalGenerator::run()
00073 {
00074     if( (publish_smiley_ && synth_phonemes_ && synth_words_) || (!publish_smiley_ && synth_phonemes_ && synth_words_) )
00075     {
00076         festival_wait_for_spooler();
00077 
00078         synthPhonemes( text_for_synth_ );
00079         synthWords( text_for_synth_ );
00080 
00081         std_msgs::Empty empty;
00082 
00083         phonemes_publisher_.publish( empty );
00084 
00085         synth_phonemes_ = false;
00086         synth_words_ = false;
00087 
00088         publish_smiley_ = false;
00089     }
00090     else
00091     {
00092         std_msgs::Empty empty;
00093 
00094         phonemes_publisher_.publish( empty );
00095         publish_smiley_ = false;
00096     }
00097 }
00098 
00099 void FestivalGenerator::callbackSynth( const std_msgs::String::ConstPtr& msg )
00100 {
00101     text_for_synth_ = prepareText( msg->data );
00102     if( text_for_synth_.length() > 0 )
00103     {
00104         synth_phonemes_ = true;
00105         synth_words_ = true;
00106     }
00107 }
00108 
00109 void FestivalGenerator::callbackTalkingFinished( const std_msgs::String::ConstPtr& msg )
00110 {
00111      timer_->start( 1000.0 / 25 );
00112 }
00113 
00114 void FestivalGenerator::synthPhonemes( std::string text )
00115 {
00116     ostringstream command;
00117     command << "(set! utt1 (SynthText \"" << text << "\"))";
00118     festival_eval_command( command.str().c_str() );
00119     festival_eval_command( "(utt.save.segs utt1 \"phonemes.txt\"))" );
00120 }
00121 
00122 void FestivalGenerator::synthWords( std::string text )
00123 {
00124     ostringstream command;
00125     command << "(set! utt2 (SynthText \"" << text << "\"))";
00126     festival_eval_command( command.str().c_str() );
00127     festival_eval_command( "(utt.save.words utt2 \"words.txt\"))" );
00128     timer_->start( 100000 );
00129 }
00130 
00131 void FestivalGenerator::subscribeWithNodeHandle( ros::NodeHandle node_handle )
00132 {
00133     subscriber_ = node_handle.subscribe( "robot_face/text_out", 1, &FestivalGenerator::callbackSynth, this );
00134     talking_finished_subscriber_ = node_handle.subscribe( "robot_face/talking_finished", 1, &FestivalGenerator::callbackTalkingFinished, this );
00135 
00136     // Subscribe to ROS message
00137     phonemes_publisher_ = node_handle.advertise<std_msgs::Empty>( "robot_face/festival_phonemes", 1 );
00138 }
00139 
00140 std::string FestivalGenerator::prepareText( std::string text )
00141 {
00142     std::string tmp_text = text;
00143 
00144     tmp_text = trimSpaces( tmp_text );
00145 
00146     for( unsigned int j = 0; j < smileys_.size(); j++ )
00147     {
00148         if( text_for_synth_.find( smileys_.at( j ) ) )
00149         {
00150             publish_smiley_ = true;
00151         }
00152     }
00153     tmp_text = clearSmileys( tmp_text );
00154 
00155     size_t i_symbol = std::string::npos;
00156 
00157     for( unsigned int j = 0; j < punctuation_characters_.size(); j++ )
00158     {
00159         for( unsigned int i = 0; i < tmp_text.length(); i++ )
00160         {
00161             i_symbol = tmp_text.find( punctuation_characters_.at( j ), 0 );
00162             if( i_symbol != std::string::npos )
00163             {
00164                 tmp_text.erase(i_symbol, punctuation_characters_.at( j ).length());
00165             }
00166         }
00167     }
00168     tmp_text = trimSpaces( tmp_text );
00169 
00170     return tmp_text;
00171 }
00172 
00173 std::string FestivalGenerator::clearSmileys( std::string text )
00174 {
00175     std::string tmp_text = text;
00176 
00177     size_t i_smiley = std::string::npos;
00178 
00179     for( unsigned int j = 0; j < smileys_.size(); j++ )
00180     {
00181         for( unsigned int i = 0; i < tmp_text.length(); i++ )
00182         {
00183             i_smiley = tmp_text.find( smileys_.at( j ), 0 );
00184             if( i_smiley != std::string::npos )
00185             {
00186                 tmp_text.erase(i_smiley, smileys_.at( j ).length());
00187             }
00188         }
00189     }
00190 
00191     return tmp_text;
00192 }
00193 
00194 std::string FestivalGenerator::trimSpaces( std::string text )
00195 {
00196     std::string tmp_text = text;
00197 
00198     size_t startpos = tmp_text.find_first_not_of(" \t");
00199     size_t endpos = tmp_text.find_last_not_of(" \t");
00200 
00201     if(( std::string::npos == startpos ) || ( std::string::npos == endpos))
00202     {
00203         tmp_text = "";
00204     }
00205     else
00206     {
00207         tmp_text = tmp_text.substr( startpos, endpos-startpos+1 );
00208     }
00209 
00210     return tmp_text;
00211 }


robot_face
Author(s): AGAS, Julian Giesen, David Gossow
autogenerated on Mon Oct 6 2014 04:10:26