flite 0.0.3.1-x86-mingw32 → 0.1.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +97 -72
- data/bin/{saytime.rb → saytime} +19 -1
- data/bin/speaking-web-server +121 -0
- data/ext/flite/extconf.rb +40 -3
- data/ext/flite/rbflite.c +604 -83
- data/ext/flite/rbflite.h +10 -0
- data/ext/flite/win32_binary_gem.c +432 -0
- data/flite.gemspec +7 -3
- data/lib/flite.dll +0 -0
- data/lib/flite.rb +45 -2
- data/lib/flite/version.rb +1 -1
- data/lib/flite_200.so +0 -0
- data/lib/flite_210.so +0 -0
- data/lib/flite_cmu_grapheme_lang.dll +0 -0
- data/lib/flite_cmu_grapheme_lex.dll +0 -0
- data/lib/flite_cmu_indic_lang.dll +0 -0
- data/lib/flite_cmu_indic_lex.dll +0 -0
- data/lib/flite_cmu_time_awb.dll +0 -0
- data/lib/flite_cmu_us_awb.dll +0 -0
- data/lib/flite_cmu_us_kal.dll +0 -0
- data/lib/flite_cmu_us_kal16.dll +0 -0
- data/lib/flite_cmu_us_rms.dll +0 -0
- data/lib/flite_cmu_us_slt.dll +0 -0
- data/lib/flite_cmulex.dll +0 -0
- data/lib/flite_usenglish.dll +0 -0
- data/lib/libmp3lame-0.dll +0 -0
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b560233c309bd7af03b1ac0f95557f8fc192a9bc
|
4
|
+
data.tar.gz: a7daab41636055e76c96e6de2b43a2097c7ddac1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 207f57318d1461d893ff4a7e92cb5653264db7b1a30214ba495aa51fc8083886865421fb9b52cb063192e3c62969f566bb0d9d464f276166a07f3c11f5b890d0
|
7
|
+
data.tar.gz: 40786dff84067ef7a21bbc559a3dabc040cfe8d143820832ab2d0ad847afd69055e412b5ece8f8c37b9ed7584d01fcdec08a2a9672b7f9c4c772a19f094d1846
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# Ruby Flite
|
2
2
|
|
3
|
-
Ruby
|
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
|
-
|
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
|
25
|
+
yum install flite-devel
|
26
|
+
yum install libmp3lame-devel # for mp3 support (optionally)
|
31
27
|
|
32
28
|
# On Windows
|
33
|
-
#
|
34
|
-
#
|
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
|
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
|
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
|
-
##
|
46
|
+
## Examples
|
57
47
|
|
58
48
|
```ruby
|
59
49
|
require 'flite'
|
60
50
|
|
61
|
-
#
|
62
|
-
"Hello World!".
|
51
|
+
# Speak "Hello World!"
|
52
|
+
"Hello World!".speak
|
63
53
|
|
64
|
-
# save as
|
65
|
-
"Hello World!".to_speech
|
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
|
-
#
|
78
|
-
|
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
|
-
#
|
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
|
-
|
64
|
+
# Speak again
|
65
|
+
"Hello World!".speak
|
66
|
+
```
|
99
67
|
|
100
|
-
|
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
|
-
*
|
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
|
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 )
|
data/bin/{saytime.rb → saytime}
RENAMED
@@ -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.
|
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)
|
data/ext/flite/extconf.rb
CHANGED
@@ -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
|
-
|
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(
|
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,
|
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")
|