Speaker photo 157534  

Speak Up!

Published Dec 4, 2015

My favorite projects are when I get to find solution to small problems for clients and solve them quickly for them. This week I had a client that needed some Text To Speech (TTS) capabilities on a small Linux system in their shipping department. Easy enough right? After a little research I found some really simple code example of TTS on Rosetta Code that someone had contributed that would work on Windows, Linux, and a Mac.

After updating the example code to work with Ruby 2.3, I did a bit of re-factoring and customizing ended up with a pretty cool little command-line utility that will read any text you feed it from the command prompt.

First we need to be able to identify which operating system we are running on. So let's create a module file called operating_system.rb

module OperatingSystem

    require 'rbconfig'

    module_function

    def operating_system
        case RbConfig::CONFIG['host_os']
            when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
                :windows
            when /darwin|mac os/
                :macosx
            when /linux/
                :linux
            else
                nil
        end
    end

    def linux?;   operating_system == :linux;   end
    def windows?; operating_system == :windows; end
    def mac?; operating_system == :macosx; end
end

This will allow us to cleanly determine which OS we are running our main program file on. Next, if you are running on Windows you will need to make a Gemfile to your project and add the win32-sapi gem.

source 'https://rubygems.org'

# Uncomment gem definition below if you are running this on windows
#gem 'win32-sapi'

Also, if you will be running this application on Windows don't forget to run gem install win32-sapi at the command prompt to install the gem.

One more thing... If you are going to run this sample on Linux you need install the espeak utility using your distributions software manager.

Now lets get to the meat and potatoes of this app. Create a file called speak.rb and type or paste the following code:

load 'operating_system.rb'

def speak(text)
  if OperatingSystem.windows?
    require 'win32/sapi5'
    v = Win32::SpVoice.new
    v.Speak(text)
  elsif OperatingSystem.mac?
    IO.popen(['say'], 'w') {|pipe| pipe.puts text}
  else
    #Try to run "espeak". No OperatingSystem check: "espeak" is
    #for Linux but is also an optional package for BSD.
    IO.popen(["espeak", "-stdin"], "w") {|pipe| pipe.puts text}
  end
end

ARGV.each do|a|
  speak a
end 

Then at the prompt simply type ruby speak.rb "This is a test" and you should hear the TTS engine speaking. Also, note you can pass multiple string arguments like this ruby speak.rb "This is a test" "Can you hear me?" and the TTS will speak all of the string arguments.

I hope you found this small utility handy and interesting as I did. It is a great stepping stone to more complex applications. You can download the sample code from my GitHub repository.

Tags: Speak, Linux, Windows, Mac, Ruby