RSS
 

Archive for August 23rd, 2009

FreeTTS, a java library used from jRuby on Rails

23 Aug

In this article we will see how to use the Java classes contained in a JAR file.
For this purpose we use a nice open source library developed by Carnegie Mellon University: FreeTTS.
The acronym TTS means Text To speech, makes it possible to transform a text into audio format. We’ll use it in a jRuby on Rails’s project to make us read the text we enter in the db.

In a previous article, we have seen how to configure the environment, so let’s start creating the new application:


C:>rails ProvaFreeTTS

In the lib folder from the root, create a sub folder freetts. Download the file freetts-1.2.2freetts-1.2.2-bin.zip, unpack the contents to a temporary folder, copy only the contents of the folder lib (jar files and JSAPI) into the dir just created: your_applibfreetts.

Now we create the jar’s interface to the jar:

#libfreetts.rb
 
require 'freetts/freetts.jar'
 
import com.sun.speech.freetts.Voice
import com.sun.speech.freetts.VoiceManager
import com.sun.speech.freetts.util.Utilities
 
class FreeTTS
  def initialize
    @voice = VoiceManager.getInstance.getVoice(Utilities.getProperty("voice16kName","kevin16"))
    @voice.allocate
  end
 
  def speak(txt=nil)
    return nil unless txt
    @voice.speak txt
  end
end

Let’s create a simple resource “sentence” with a single field “body“.


C:ProvaFreeTTS>jruby script/generate scaffold sentence body:text

Now we create two new operations, as I explained in detail in a previous article.

We start from the controller by adding at the bottom :

  #appcontrollerssentences_controller.rb
 
  def speak
    @sentence = Sentence.new(params[:sentence])
    require 'freetts'
    tts = FreeTTS.new
    tts.speak @sentence.body
    render (@sentence.new_record? ? :new : :edit)
  end
 
  def read
    @sentence = Sentence.find(params[:id])
    require 'freetts'
    tts = FreeTTS.new
    tts.speak @sentence.body
    redirect_to :back
  end

Now it’s the views turn.

We create a new partial where we’ll move into the resource’s data form, so to have only one form for every operation:

#appviewssentence_sentence.html.erb
 
<% form_for(@sentence) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>
 
<h2>Preview</h2>
<% form_for @sentence, :url => speak_sentences_path, :method => :put do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit 'Speak' %>
  </p>
<% end %>

Add a clone of the form created by the scaffold but with a different action, to call the transaction speak.

Now modify the views created automatically:

#appviewssentencenew.html.erb
 
<h1>New sentence</h1>
 
<%= render @sentence %>
 
<%= link_to 'Back', sentences_path %>
 
#appviewssentenceedit.html.erb
 
<h1>Editing sentence</h1>
 
<%= render @sentence %>
 
<%= link_to 'Show', @sentence %> |
<%= link_to 'Back', sentences_path %>

Now, we modify the index in order to retrieve the second operation: the “read”. Basically, clicking on the corresponding line, will read the text previously stored in the db.

We only need to add a line to obtain this view:

#appviewssentenceindex.html.erb
<h1>Listing sentences</h1>
 
<table>
  <tr>
    <th>Body</th>
  </tr>
 
<% @sentences.each do |sentence| %>
  <tr>
    <td><%=h sentence.body %></td>
    <td><%= link_to 'Read', read_sentence_path(sentence) %></td>
    <td><%= link_to 'Show', sentence %></td>
    <td><%= link_to 'Edit', edit_sentence_path(sentence) %></td>
    <td><%= link_to 'Destroy', sentence, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>
 
<br />
 
<%= link_to 'New sentence', new_sentence_path %>

We modify the routing:

#configroutes.rb
 
#change map.resources :sentences with
map.resources :sentences, :member => { :read => :get }, :collection => { :speak => :put }
 
#add
map.root :controller => "sentences"

Configure the database.yml file, we create the db and tables with rake and start up Glassfish as explained in this previous article (find database.yml).

As we have seen, using java libraries with jruby on rails is very simple, we are ready to make our server to say the most dirty words!

The project can be downloaded from here.

Enjoy!

 
Comments Off

Posted in JRuby, Ruby on Rails