{"id":50,"date":"2016-05-06T09:00:33","date_gmt":"2016-05-06T09:00:33","guid":{"rendered":"http:\/\/symbioticindia.in\/docu\/?p=50"},"modified":"2016-05-06T09:00:33","modified_gmt":"2016-05-06T09:00:33","slug":"build-your-texttospeech-service-with-freetts","status":"publish","type":"post","link":"http:\/\/symbioticindia.in\/docu\/2016\/05\/06\/build-your-texttospeech-service-with-freetts\/","title":{"rendered":"Build your TextToSpeech service with FreeTTS"},"content":{"rendered":"<div align=\"center\">A simple http enabled text to speech server<\/div>\n<p>&nbsp;<\/p>\n<h3><strong>Introduction<\/strong><br \/>\nOne of the technologies I&#8217;m more fond of is <a href=\"http:\/\/en.wikipedia.org\/wiki\/Domotics\">domotics<\/a>. I don&#8217;t have the budget for a java enabled oven, but with some x10 plugs I&#8217;ve recently had a lot of fun building a system where a midlet on my mobile periodically polls my home server communicating its current gsm cell so that my oven can be switched on when I&#8217;m coming back home. I know, it&#8217;s kitsch ( and expensive, depending on your gprs provider), but I love this kind of useless things.<br \/>\nLast month, an old dream came back to my mind; my home system talking to me. Easy to achieve today. I&#8217;m quite obsessed with web services, system integration and so on, and I wanted to build some kind of talking appliance directly exposed to all of my systems (desktop, laptop, mobile etc), so this time I opted for a simple http approach, no SOAP, xml-rpc or raw socket.<br \/>\nThen I had to choose my TextToSpeech engine. I had already messed around with <a href=\"http:\/\/freetts.sourceforge.net\/docs\/index.php\">FreeTTS<\/a>, a <em>speech synthesizer written entirely in the JavaTM programming language<\/em>, and had been quite satisfied with it.<br \/>\nIt was also a good chance to use jdk&#8217;s <em>com.sun.net.httpserver.HttpServer<\/em> class to implement the simple http server I needed. So I had everything to build my &#8220;talking appliance&#8221;. Note that FreeTTS includes in its sample codebase a client\/server solution which is different from what I&#8217;m explaining in this article. In our case we will have an appliance with server code, an audio board and speakers whereas in FreeTTS client\/server sample, the server produces the audio but it is played by the client.<\/h3>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Overview<\/strong><br \/>\nI&#8217;ve used a jdk 1.5 and FreeTTS 1.2 .You obviously need to put FreeTTS jars in your classpath. Nothing else is required and, being the tts engine 100% java, it is also platform independent.<br \/>\nWith just 2 simple classes, our talking engine will be ready. I&#8217;m not going to enter into the details of <em>com.sun.net.httpserver.HttpServer<\/em>, the only thing we need to know about it for our purposes is that we can create a context associated to handlers. The code will clearly explain all of this.<br \/>\nImagine we want to have an http service listening on port 8000, with an http context like &#8220;\/ttsserver\/say&#8221;, which will &#8220;speak&#8221; the URI query ( the text after &#8220;?&#8221;).<br \/>\nA tipical call will be something like this:<br \/>\n<em>&#8220;http:\/\/localhost:8000\/ttsserver\/say?How&#8217;s the weather like today&#8221;<\/em><\/p>\n<p><strong>The code<\/strong><br \/>\nLet&#8217;s first code the main class. It will just initialize and start the http server. Here is the code:<\/p>\n<div>\n<pre><span style=\"color: #f5deb3;\"><span style=\"color: #00cc99;\">package<\/span> org.beanizer.ttsserver;\r\n\r\n<span style=\"color: #00cc99;\">import<\/span> com.sun.net.httpserver.HttpServer;\r\n<span style=\"color: #00cc99;\">import<\/span> java.io.IOException;\r\n<span style=\"color: #00cc99;\">import<\/span> java.net.InetSocketAddress;\r\n\r\n<span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">class<\/span> Server <span style=\"color: #00ffff;\">{<\/span>\r\n    <span style=\"color: #ffa500;\">private<\/span> HttpServer server<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #ffff66;\">null<\/span>;    \r\n    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">void<\/span> <span style=\"color: #b2dfee;\">start<\/span>()<span style=\"color: #00ffff;\">{<\/span>\r\n        <span style=\"color: #ffa500;\">try<\/span> <span style=\"color: #00ffff;\">{<\/span>\r\n            server <span style=\"color: #00ffff;\">=<\/span> HttpServer.<span style=\"color: #b2dfee;\">create<\/span>(<span style=\"color: #ffa500;\">new<\/span> <span style=\"color: #b2dfee;\">InetSocketAddress<\/span>(<span style=\"color: #cdcd00;\">8000<\/span>), <span style=\"color: #cdcd00;\">0<\/span>);\r\n            server.<span style=\"color: #b2dfee;\">createContext<\/span>(<span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">\/ttsserver\/say<\/span><span style=\"color: #00cd00;\">\"<\/span>, <span style=\"color: #ffa500;\">new<\/span> <span style=\"color: #b2dfee;\">VoiceHandler<\/span>());\r\n            server.<span style=\"color: #b2dfee;\">setExecutor<\/span>(<span style=\"color: #ffff66;\">null<\/span>); \r\n            server.<span style=\"color: #b2dfee;\">start<\/span>();        \r\n            \r\n        <span style=\"color: #00ffff;\">}<\/span> <span style=\"color: #ffa500;\">catch<\/span> (IOException ex) <span style=\"color: #00ffff;\">{<\/span>\r\n            ex.<span style=\"color: #b2dfee;\">printStackTrace<\/span>();\r\n        <span style=\"color: #00ffff;\">}<\/span>\r\n    <span style=\"color: #00ffff;\">}<\/span>\r\n    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #ffa500;\">static<\/span> <span style=\"color: #cc6600;\">void<\/span> <span style=\"color: #b2dfee;\">main<\/span>(String args[])<span style=\"color: #00ffff;\">{<\/span>\r\n        Server s<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #ffa500;\">new<\/span> <span style=\"color: #b2dfee;\">Server<\/span>();\r\n        s.<span style=\"color: #b2dfee;\">start<\/span>();\r\n    <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #00ffff;\">}<\/span> <\/span><\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <em>main<\/em> method creates an instance of the class and calls its <em>start<\/em> method.<br \/>\nLet&#8217;s analyze the code within the try\/catch block in <em>start<\/em>:<br \/>\n1) an http server is created listening on tcp port 8000.<br \/>\n2) The context &#8220;\/ttsserver\/say&#8221; will be handled by <em>VoiceHandler<\/em>, which is the second class we&#8217;ll code.<br \/>\n3) We create a default executor (an object that executes submitted Runnable tasks).<br \/>\n4) Finally we start the http server.<\/p>\n<p>We need just one more simple class to handle http requests received on the created context.<\/p>\n<p>&nbsp;<\/p>\n<div>\n<pre><span style=\"color: #f5deb3;\"><span style=\"color: #00cc99;\">package<\/span> org.beanizer.ttsserver;\r\n\r\n<span style=\"color: #00cc99;\">import<\/span> com.sun.net.httpserver.HttpExchange;\r\n<span style=\"color: #00cc99;\">import<\/span> com.sun.net.httpserver.HttpHandler;\r\n<span style=\"color: #00cc99;\">import<\/span> java.io.IOException;\r\n<span style=\"color: #00cc99;\">import<\/span> java.io.InputStream;\r\n<span style=\"color: #00cc99;\">import<\/span> java.io.OutputStream;\r\n\r\n<span style=\"color: #00cc99;\">import<\/span> com.sun.speech.freetts.Voice;\r\n<span style=\"color: #00cc99;\">import<\/span> com.sun.speech.freetts.VoiceManager;\r\n<span style=\"color: #00cc99;\">import<\/span> com.sun.speech.freetts.util.Utilities;\r\n\r\n<span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">class<\/span> VoiceHandler <span style=\"color: #ffa500;\">implements<\/span> HttpHandler<span style=\"color: #00ffff;\">{<\/span>\r\n    <span style=\"color: #ffa500;\">private<\/span> Voice voice;\r\n    \r\n    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #b2dfee;\">VoiceHandler<\/span>() <span style=\"color: #00ffff;\">{<\/span>\r\n        <span style=\"color: #ffa500;\">try<\/span> <span style=\"color: #00ffff;\">{<\/span>\r\n            voice <span style=\"color: #00ffff;\">=<\/span> VoiceManager.<span style=\"color: #b2dfee;\">getInstance<\/span>().<span style=\"color: #b2dfee;\">getVoice<\/span>(\r\n                    Utilities.<span style=\"color: #b2dfee;\">getProperty<\/span>(<span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">voice16kName<\/span><span style=\"color: #00cd00;\">\"<\/span>, <span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">kevin16<\/span><span style=\"color: #00cd00;\">\"<\/span>));\r\n            voice.<span style=\"color: #b2dfee;\">allocate<\/span>();\r\n        <span style=\"color: #00ffff;\">}<\/span> <span style=\"color: #ffa500;\">catch<\/span> (Exception e) <span style=\"color: #00ffff;\">{<\/span>\r\n            e.<span style=\"color: #b2dfee;\">printStackTrace<\/span>();\r\n            System.<span style=\"color: #b2dfee;\">exit<\/span>(<span style=\"color: #cdcd00;\">1<\/span>);\r\n        <span style=\"color: #00ffff;\">}<\/span>\r\n    <span style=\"color: #00ffff;\">}<\/span>\r\n    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">void<\/span> <span style=\"color: #b2dfee;\">handle<\/span>(HttpExchange t) <span style=\"color: #ffa500;\">throws<\/span> IOException <span style=\"color: #00ffff;\">{<\/span>\r\n        voice.<span style=\"color: #b2dfee;\">speak<\/span>(t.<span style=\"color: #b2dfee;\">getRequestURI<\/span>().<span style=\"color: #b2dfee;\">getQuery<\/span>());\r\n        String response <span style=\"color: #00ffff;\">=<\/span> <span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">Ok<\/span><span style=\"color: #00cd00;\">\"<\/span>;\r\n        t.<span style=\"color: #b2dfee;\">sendResponseHeaders<\/span>(<span style=\"color: #cdcd00;\">200<\/span>, response.<span style=\"color: #b2dfee;\">length<\/span>());\r\n        OutputStream os <span style=\"color: #00ffff;\">=<\/span> t.<span style=\"color: #b2dfee;\">getResponseBody<\/span>();\r\n        os.<span style=\"color: #b2dfee;\">write<\/span>(response.<span style=\"color: #b2dfee;\">getBytes<\/span>());\r\n        os.<span style=\"color: #b2dfee;\">close<\/span>();\r\n    <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #00ffff;\">}<\/span>\r\n\r\n<\/span><\/pre>\n<\/div>\n<h3>\n<p>Our <em>VoiceHandler<\/em> class extends <em>com.sun.net.httpserver.HttpHandler<\/em> , overriding its <em>handle<\/em> method to manage incoming requests.<br \/>\nIn the class constructor we grab an instance of FreeTTS <em>VoiceManager<\/em>, get a <em>Voice<\/em> out of it using the <em>Utilities<\/em> class, and then allocate it. At this point the voice is ready to be used with a simple <em>speak(String)<\/em> call.<br \/>\nOne note about setting the voice. FreeTTS comes with a couple of included voices: an 8k quality, 16k quality (the one we&#8217;re using here) and a limited domain one, with better quality but specific(limited) for speaking date\/time. On the net it is possible to find other voices also for different languages and it&#8217;s even possible to build your own voices(though not easy). Read <a href=\"http:\/\/freetts.sourceforge.net\/docs\/index.php#festvox\">here<\/a> for this.<\/p>\n<p>Back to our class. The <em>handle<\/em> method will:<br \/>\n1) &#8220;speak&#8221; what&#8217;s been passed with the http request (everything after the question mark in the URI)<br \/>\n2) send an &#8220;Ok&#8221; response to the caller.<\/p>\n<p>To start our service, make sure you have FreeTTS jars in your classpath and launch <em>org.beanizer.ttsserver.Server<\/em> class with java.<\/p>\n<p><strong>Conclusions<\/strong><br \/>\nThis is basically all. It is possible to extend this structure to manage an access control list, parameters for choosing the voice etc., but just with these two trivial classes every device capable of making an http call (included browsers) can make our appliance speak.<br \/>\nAt home I&#8217;m using it for the most disparate things, and it&#8217;s really funny and addicting. Some of the uses:<br \/>\n1) Some important log messages (opportunely filtered to avoid &#8220;spam&#8221;)<br \/>\n2) I don&#8217;t like phone ring tones, so my asterisk server just commands the tts server to say who&#8217;s calling me, using the name instead of the caller number for known ones.<\/p>\n<p>Currently I&#8217;m working on a similar service for voice recognition, but this is a completely different beast&#8230;..Build your TextToSpeech service with FreeTTS<\/h3>\n","protected":false},"excerpt":{"rendered":"<p>A simple http enabled text to speech server &nbsp; Introduction One of the technologies I&#8217;m more fond of is domotics. I don&#8217;t have the budget for a java enabled oven, but with some x10 plugs I&#8217;ve recently had a lot of fun building a system where a midlet on my mobile periodically polls my home ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"http:\/\/symbioticindia.in\/docu\/2016\/05\/06\/build-your-texttospeech-service-with-freetts\/\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6],"tags":[11],"class_list":["post-50","post","type-post","status-publish","format-standard","hentry","category-java","category-php","tag-texttospeech"],"_links":{"self":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/comments?post=50"}],"version-history":[{"count":1,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":51,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/50\/revisions\/51"}],"wp:attachment":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/categories?post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/tags?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}