flite 0.0.3.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a39cd40e7679ec33aa61c41dcb4c9146b1afd25
4
- data.tar.gz: e5f23ffecf1a6a4bf3c27ad119d1a6b4c4dd0c79
3
+ metadata.gz: 7a1d5627fba26b34d2417f52876bdab6272624f8
4
+ data.tar.gz: fddcf4371388ef8258db15dc0a0aa2b8828924a3
5
5
  SHA512:
6
- metadata.gz: 8f279489cb2d69a669d3320ee824a92a8be04201dead4e867b436a0bae4e568ca80324fc381189077d11e9df229d7f9f6b65668bdfcdd991a44ab3178877fa4b
7
- data.tar.gz: f5714b9e110424e31ad7d7a2a456d0fb1f334ee46b7b181364a628768aceb3f8ca16a79b719829e9994ecd18d2cb8b6842eed4c5d754751fa0963ac115c1e928
6
+ metadata.gz: 81961b439859672eec7b978c8e893a911e3ae44e68257debd20597cbbf8bddec898929541acc1b0d3496609f36941546fea049ea3e06a74253fa50265792a89c
7
+ data.tar.gz: 03370c926ff39c8fd461c8093bff07a8dafdcccd8934ce2e9895aa0466090681e019843912c2ba5328857218ebe18d790c7633df0fb9b0d7287fef1fbbce2cb3
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # ruby-flite
1
+ # Ruby Flite
2
2
 
3
- Ruby-flite is a small speech synthesis library for ruby using [CMU Flite](http://cmuflite.org).
3
+ Ruby Flite is a small speech synthesis library for ruby using [CMU Flite](http://cmuflite.org).
4
4
 
5
5
  CMU Flite (festival-lite) is a small, fast run-time synthesis engine developed
6
6
  at CMU and primarily designed for small embedded machines and/or large
@@ -14,115 +14,140 @@ voices built using the [FestVox](http://festvox.org/) suite of voice building to
14
14
 
15
15
  ## Installation
16
16
 
17
- Add this line to your application's Gemfile:
18
-
19
- ```ruby
20
- gem 'flite'
21
- ```
22
-
23
- Install [CMU Flite](http://cmuflite.org):
17
+ Install [CMU Flite](http://cmuflite.org) and (optionally) [LAME](http://lame.sourceforge.net/).
24
18
 
25
19
  ```shell
26
20
  # On ubuntu
27
21
  sudo apt-get install flite1-dev
22
+ sudo apt-get install libmp3lame-dev # for mp3 support (optionally)
28
23
 
29
24
  # On redhat
30
- yum install flite flite-devel
25
+ yum install flite-devel
26
+ yum install libmp3lame-devel # for mp3 support (optionally)
31
27
 
32
28
  # On Windows
33
- # you have no need to install CMU Flite if you use the flite binary gem.
34
- # CMU Flite is statically linked.
29
+ # You have no need to install CMU Flite and LAME if you use rubies distributed by
30
+ # rubyinstaller.org. Binary gems for the rubies include them.
31
+
32
+ # Others
33
+ # You need to install them by yourself.
35
34
  ```
36
35
 
37
36
  And then execute:
38
37
 
39
- $ bundle
40
-
41
- Or install it yourself as:
42
-
43
38
  $ gem install flite
44
39
 
45
- Ruby-flite tries to link with **all voices and languages**.
40
+ Ruby Flite tries to link with **all voices and languages**.
46
41
  If you want to reduce dependent libraries, execute the followings
47
- instead of above commands.
48
-
49
- $ bundle config --local build.flite --with-voices=kal --with-langs=eng
50
- $ bundle
51
-
52
- Or install it yourself as:
42
+ instead of above command.
53
43
 
54
44
  $ gem install flite -- --with-voices=kal --with-langs=eng
55
45
 
56
- ## Simple Usage
46
+ ## Examples
57
47
 
58
48
  ```ruby
59
49
  require 'flite'
60
50
 
61
- # output to the speeker.
62
- "Hello World!".to_speech
51
+ # Speak "Hello World!"
52
+ "Hello World!".speak
63
53
 
64
- # save as a WAVE file
65
- "Hello World!".to_speech("hello_world.wave")
66
-
67
- # write to an I/O object if it responds to 'write'.
68
- File.open("hello_world.wave", "wb") do |f|
69
- "Hello World!".to_speech(f)
70
- end
71
- ```
72
- ## Advanced Usage
73
-
74
- ```ruby
75
- require 'flite'
54
+ # Create a wav data and save as "hello_world.wav"
55
+ File.binwrite("hello_world.wav", "Hello World!".to_speech)
76
56
 
77
- # array of builtin voice names.
78
- Flite.list_builtin_voices
57
+ # Create a mp3 data and save as "hello_world.mp3"
58
+ # This works if mp3 support is enabled.
59
+ File.binwrite("hello_world.mp3", "Hello World!".to_speech(:mp3))
79
60
 
80
- # create a voice. 'slt' is a voice name.
81
- voice = Flite::Voice.new("slt")
82
-
83
- # output to the speeker.
84
- voice.speech("Hello World!")
85
-
86
- # save as a WAVE file
87
- voice.speech("Hello World!", "hello_world.wave")
88
-
89
- # write to an I/O object if it responds to 'write'.
90
- File.open("hello_world.wave", "wb") do |f|
91
- voice.speech("Hello World!", f)
92
- end
93
-
94
- # Change the voice used for String#to_speech
61
+ # Change the voice used for String#speak and String#to_speech
95
62
  Flite.default_voice = 'rms'
96
- ```
97
63
 
98
- ## Sample Application
64
+ # Speak again
65
+ "Hello World!".speak
66
+ ```
99
67
 
100
- * [saytime.rb](https://github.com/kubo/ruby-flite/blob/master/bin/saytime.rb)
68
+ See:
69
+
70
+ * http://www.rubydoc.info/gems/flite/Flite/Voice
71
+ * http://www.rubydoc.info/gems/flite/String
72
+
73
+ ## Sample Applications
74
+
75
+ ### [saytime](https://github.com/kubo/ruby-flite/blob/master/bin/saytime) - talking clock
76
+
77
+ This is inspired by [saytime - talking clock for SPARCstations](http://acme.com/software/saytime/).
78
+
79
+ Example:
80
+
81
+ > Talk the current time once:
82
+ >
83
+ > ```shell
84
+ > saytime
85
+ > ```
86
+ >
87
+ > Talk the current time forever:
88
+ >
89
+ > ```shell
90
+ > saytime --loop
91
+ > ```
92
+ >
93
+ > Talk the current time 5 times
94
+ >
95
+ > ```shell
96
+ > saytime --loop 5
97
+ > ```
98
+ >
99
+ > Talk the current time 5 times with 10 second intervals
100
+ >
101
+ > ```shell
102
+ > saytime --loop 5 --interval 10
103
+ > ```
104
+
105
+ ### [speaking-web-server](https://github.com/kubo/ruby-flite/blob/master/bin/speaking-web-server) - Web server replying synthesized speech
106
+
107
+ Usage:
108
+
109
+ > Start a web server:
110
+ >
111
+ > ```shell
112
+ > speaking-web-server
113
+ > ```
114
+ >
115
+ > Open a browser and access:
116
+ >
117
+ > http://HOSTNAME_OR_IP_ADDRESS:9080
118
+ > (Change HOSTNAME_OR_IP_ADDRESS.)
119
+ >
120
+ > Click 'Play' buttons.
101
121
 
102
122
  ## Restrictions
103
123
 
104
- * `String#to_speech(io_object)` and `Flite::Voice#speech(text, io_object)`
105
- are not thread-safe. You need to create `Flite::Voice` objects for
106
- each threads and use `Flite::Voice#speech`.
107
-
108
- * `String#to_speech("play")` and `Flite::Voice#speech(text, "play")`
109
- don't save wave data to the specified file `play`. They output speech
110
- data to the speaker instead.
111
-
112
- * `String#to_speech("stream")`, `String#to_speech("none")`,
113
- `Flite::Voice#speech(text, "stream")` and `Flite::Voice#speech(text, "none")`
114
- don't save wave data to the specified file `stream` or `none`. They
115
- synthesize speech and discard the result.
124
+ * Ruby process doesn't terminate while talking.
116
125
 
117
126
  * When an error occurs in CMU Flite, the error message is outputted to
118
127
  the standard error.
119
128
 
129
+ * When a fatal error occurs in CMU Flite, the error message is outputted to
130
+ the standard error and the process is terminated. (CMU Flite calls `exit(-1)`...)
131
+
132
+ ## NEWS
133
+
134
+ ### 0.1.0
135
+
136
+ Almost methods were changed. Especially {String#to_speech} returns WAV
137
+ audio data instead of speaking. Use {String#speak} to speak a text.
138
+
120
139
  ## License
121
140
 
122
- * Ruby-flite itself is licensed under 2-clause BSD-style license.
123
- * CMU Flite is licensed under BSD-like license.
141
+ * Ruby Flite is licensed under 2-clause BSD-style license.
142
+ * CMU Flite bundled in Windows binary gems is licensed under BSD-like license.
124
143
  See http://www.festvox.org/flite/download.html
144
+ * LAME bundled in Windows binary gems is licensed under LGPL.
145
+
146
+ ## Related Works
125
147
 
148
+ * [flite4r](http://www.rubydoc.info/gems/flite4r/) - Flite for Ruby (GPL)
149
+ * [FestivalTTS4r](https://github.com/spejman/festivaltts4r) - Festival Text-To-Speech for Ruby
150
+
126
151
  ## Contributing
127
152
 
128
153
  1. Fork it ( https://github.com/kubo/ruby-flite/fork )
@@ -1,5 +1,23 @@
1
1
  #! /usr/bin/env ruby
2
2
  #
3
+ # saytime - talking clock
4
+ #
5
+ # Usage:
6
+ # # Talk the current time once
7
+ # saytime
8
+ #
9
+ # # Talk the current time forever
10
+ # saytime --loop
11
+ #
12
+ # # Talk the current time 5 times
13
+ # saytime --loop 5
14
+ #
15
+ # # Talk the current time 5 times with 10 second intervals
16
+ # saytime --loop 5 --interval 10
17
+ #
18
+ # # Talk the current time with 'slt' and 'awb' voices
19
+ # saytime --voices=slt,awb
20
+ #
3
21
  require 'flite'
4
22
  require 'optparse'
5
23
 
@@ -40,7 +58,7 @@ def saytime(voice_name)
40
58
  puts "voice: #{voice_name}"
41
59
 
42
60
  voice = ($cached_voices[voice_name] ||= Flite::Voice.new(voice_name))
43
- voice.speech(text)
61
+ voice.speak(text)
44
62
  end
45
63
 
46
64
  voices = []
@@ -0,0 +1,121 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # speaking-web-server - Web server replying synthesized speech
4
+ #
5
+ # Usage:
6
+ #
7
+ # 1. Start a Web server.
8
+ #
9
+ # speaking-web-server
10
+ #
11
+ # 2. Access to the web server.
12
+ #
13
+ # Open browser and access: http://HOSTNAME_OR_IP_ADDRESS:9080
14
+ # (Change HOSTNAME_OR_IP_ADDRESS.)
15
+ #
16
+ # 3. Click 'Play' buttons.
17
+ #
18
+ require 'webrick'
19
+ require 'flite'
20
+
21
+ def start_server(html_content)
22
+ srv = WEBrick::HTTPServer.new({:Port => 9080})
23
+
24
+ srv.mount_proc('/') do |req, res|
25
+ h = req.query
26
+ if h['text']
27
+ audio_type = if h['type'] == 'mp3'
28
+ :mp3
29
+ else
30
+ :wav
31
+ end
32
+ res['Content-type'] = "audio/#{audio_type}"
33
+ res['Content-Disposition'] = %Q{attachment; filename="audio.#{audio_type}"}
34
+
35
+ voice = Flite::Voice.new(h['voice'] || 'kal')
36
+ res.body = voice.to_speech(h['text'], audio_type)
37
+ else
38
+ res['Content-type'] = 'text/html'
39
+ res.body = html_content
40
+ end
41
+ end
42
+ trap("INT"){ srv.shutdown }
43
+ srv.start
44
+ end
45
+
46
+ html_content = <<EOS
47
+ <html>
48
+ <head>
49
+ <title>Flite CGI</title>
50
+
51
+ <script>
52
+ audio_type = 'wav';
53
+
54
+ function check_audio_type() {
55
+ var audio = new Audio;
56
+ if (audio.canPlayType('audio/wav') == '') {
57
+ if (#{Flite.supported_audio_types.include? :mp3} && audio.canPlayType('audio/mp3') != '') {
58
+ audio_type = 'mp3';
59
+ } else {
60
+ var text = document.getElementById('text');
61
+ text.disabled = true;
62
+ enable_buttons(false);
63
+ alert('Cannot play audio/wav in this browser.\\nUse Chrome, Firefox, Safari or Opera.');
64
+ }
65
+ }
66
+ }
67
+
68
+ function speak(voice) {
69
+ var text = document.getElementById('text');
70
+ if (text != '') {
71
+ var status = document.getElementById('status');
72
+ status.innerHTML = 'Playing'
73
+ enable_buttons(false);
74
+ var url = '/?voice=' + voice + '&type=' + audio_type + '&text=' + encodeURIComponent(text.value);
75
+ var audio = new Audio(url);
76
+ audio.onended = function() {
77
+ status.innerHTML = 'Finished'
78
+ enable_buttons(true);
79
+ };
80
+ audio.onabort = function() {
81
+ status.innerHTML = 'Abort'
82
+ enable_buttons(true);
83
+ };
84
+ audio.onerror = function() {
85
+ status.innerHTML = 'Error'
86
+ enable_buttons(true);
87
+ };
88
+ audio.play();
89
+ }
90
+ }
91
+
92
+ function enable_buttons(bval) {
93
+ var form = document.getElementById('speech_form');
94
+ var elements = form.elements;
95
+ for (var i = 0; i < elements.length; i++) {
96
+ var element = elements[i];
97
+ if (element.tagName == 'INPUT') {
98
+ element.disabled = !bval;
99
+ }
100
+ }
101
+ }
102
+ </script>
103
+
104
+ </head>
105
+ <body onLoad="check_audio_type();">
106
+
107
+ <form id="speech_form">
108
+ <textarea id="text" name="text" cols=80 rows=4>Hello Flite World!</textarea>
109
+ <br />
110
+ <input type="button" value="Play(voice: kal)" onClick="speak('kal');">
111
+ <input type="button" value="Play(voice: kal16)" onClick="speak('kal16');">
112
+ <input type="button" value="Play(voice: awb)" onClick="speak('awb');">
113
+ <input type="button" value="Play(voice: rms)" onClick="speak('rms');">
114
+ <input type="button" value="Play(voice: slt)" onClick="speak('slt');">
115
+ </form>
116
+ Status: <span id="status" />
117
+ </body>
118
+ </html>
119
+ EOS
120
+
121
+ start_server(html_content)
@@ -2,6 +2,8 @@ require "mkmf"
2
2
 
3
3
  dir_config('flite')
4
4
 
5
+ libs_old = $libs
6
+
5
7
  unless have_library('flite', 'flite_init')
6
8
  saved_libs = $libs
7
9
  puts "checkign for audio libraries depended by flite ..."
@@ -74,17 +76,52 @@ EOS
74
76
  end
75
77
  f.write <<EOS
76
78
 
77
- const rbflite_builtin_voice_t rbflite_builtin_voice_list[] = {
79
+ #undef ENTRY
80
+ #ifdef RBFLITE_WIN32_BINARY_GEM
81
+ static cst_voice *dummy;
82
+ #define ENTRY(name, dll_name, func_name, var_name) {#name, func_name, &dummy, #dll_name, #func_name, #var_name}
83
+ #else
84
+ #define ENTRY(name, dll_name, func_name, var_name) {#name, func_name, &var_name}
85
+ const
86
+ #endif
87
+
88
+ rbflite_builtin_voice_t rbflite_builtin_voice_list[] = {
78
89
  EOS
79
90
  voices.each do |v|
80
- f.puts(%Q[ {"#{v[0]}", register_#{v[1]}, &#{v[2]}},])
91
+ f.puts(" ENTRY(#{v[0]}, flite_#{v[1]}.dll, register_#{v[1]}, #{v[2]}),")
81
92
  end
82
93
  f.write <<EOS
83
- {NULL, NULL, NULL},
94
+ {NULL, },
84
95
  };
96
+
97
+ #ifdef RBFLITE_WIN32_BINARY_GEM
98
+ EOS
99
+ voices.each_with_index do |v, idx|
100
+ f.write <<EOS
101
+ cst_voice *register_#{v[1]}(const char *voxdir)
102
+ {
103
+ return rbfile_call_voice_register_func(&rbflite_builtin_voice_list[#{idx}], voxdir);
104
+ }
105
+ EOS
106
+ end
107
+ f.write <<EOS
108
+ #endif
85
109
  EOS
86
110
  end
87
111
 
112
+ if have_library('mp3lame')
113
+ have_header('lame.h') || have_header('lame/lame.h')
114
+ end
115
+
88
116
  RUBY_VERSION =~ /(\d+).(\d+)/
89
117
  $defs << "-DInit_flite=Init_flite_#{$1}#{$2}0"
118
+
119
+ $objs = ['rbflite.o', 'rbflite_builtin_voice_list.o']
120
+
121
+ if with_config('win32-binary-gem')
122
+ $libs = libs_old
123
+ $defs << "-DRBFLITE_WIN32_BINARY_GEM"
124
+ $objs << 'win32_binary_gem.o'
125
+ end
126
+
90
127
  create_makefile("flite_#{$1}#{$2}0")