flite 0.0.3.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f8d3b620e12230b065a33b16f4e27f6b2bf91f91
4
+ data.tar.gz: 1bb44fdb50d352c1b5732a74bdcd216ddc5c24f6
5
+ SHA512:
6
+ metadata.gz: 2357d7351fc493ed3d8c246a65364aa1ce73e4608120910f585c6b9640d3d82c7c45668bff9fac250aa5d80f0f92c3dd95930270283fc000ebab7f6c4c4d4e97
7
+ data.tar.gz: b2a0908198032b78b13ac912b6f35c08e0a4572a6808ac92600f7dca6e3025b7a2c64c5a0a4956f0a7925ad51dc253ff264dbcc5d3bf45ad506d939dddf84a64
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flite.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (C) 2015 Kubo Takehiro <kubo@jiubao.org>
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above
10
+ copyright notice, this list of conditions and the following
11
+ disclaimer in the documentation and/or other materials provided
12
+ with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR
15
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
18
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
21
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ The views and conclusions contained in the software and documentation
27
+ are those of the authors and should not be interpreted as representing
28
+ official policies, either expressed or implied, of the authors.
data/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # ruby-flite
2
+
3
+ Ruby-flite is a small speech synthesis library for ruby using [CMU Flite](http://cmuflite.org).
4
+
5
+ CMU Flite (festival-lite) is a small, fast run-time synthesis engine developed
6
+ at CMU and primarily designed for small embedded machines and/or large
7
+ servers. Flite is designed as an alternative synthesis engine to [Festival](http://festvox.org/festival) for
8
+ voices built using the [FestVox](http://festvox.org/) suite of voice building tools.
9
+
10
+ ## Supported versions
11
+
12
+ * ruby 2.0.0 and uppper
13
+ * CMU Flite 1.4 and 2.0.
14
+
15
+ ## Installation
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):
24
+
25
+ ```shell
26
+ # On ubuntu
27
+ sudo apt-get install flite1-dev
28
+
29
+ # On redhat
30
+ yum install flite flite-devel
31
+
32
+ # On Windows
33
+ # you have no need to install CMU Flite if you use the flite binary gem.
34
+ # CMU Flite is statically linked.
35
+ ```
36
+
37
+ And then execute:
38
+
39
+ $ bundle
40
+
41
+ Or install it yourself as:
42
+
43
+ $ gem install flite
44
+
45
+ Ruby-flite tries to link with **all voices and languages**.
46
+ 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:
53
+
54
+ $ gem install flite -- --with-voices=kal --with-langs=eng
55
+
56
+ ## Simple Usage
57
+
58
+ ```ruby
59
+ require 'flite'
60
+
61
+ # output to the speeker.
62
+ "Hello World!".to_speech
63
+
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'
76
+
77
+ # array of builtin voice names.
78
+ Flite.list_builtin_voices
79
+
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
95
+ Flite.default_voice = 'rms'
96
+ ```
97
+
98
+ ## Sample Application
99
+
100
+ * [saytime.rb](https://github.com/kubo/ruby-flite/blob/master/bin/saytime.rb)
101
+
102
+ ## Restrictions
103
+
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.
116
+
117
+ * When an error occurs in CMU Flite, the error message is outputted to
118
+ the standard error.
119
+
120
+ ## License
121
+
122
+ * Ruby-flite itself is licensed under 2-clause BSD-style license.
123
+ * CMU Flite is licensed under BSD-like license.
124
+ See http://www.festvox.org/flite/download.html
125
+
126
+ ## Contributing
127
+
128
+ 1. Fork it ( https://github.com/kubo/ruby-flite/fork )
129
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
130
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
131
+ 4. Push to the branch (`git push origin my-new-feature`)
132
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rake/extensiontask"
4
+
5
+ Rake::ExtensionTask.new("flite") do |ext|
6
+ ext.lib_dir = "lib/flite"
7
+ end
data/bin/saytime.rb ADDED
@@ -0,0 +1,71 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ require 'flite'
4
+ require 'optparse'
5
+
6
+ available_voices = Flite.list_builtin_voices
7
+ available_voices.delete('awb_time') # exclude awb_time
8
+
9
+ $cached_voices = {}
10
+
11
+ def saytime(voice_name)
12
+ sec, min, hour = Time.now.to_a
13
+
14
+ case hour
15
+ when 0
16
+ hour = 12
17
+ when 13 .. 23
18
+ hour -= 12
19
+ end
20
+
21
+ case min
22
+ when 0
23
+ min = " o'clock"
24
+ else
25
+ min = ':%02d' % min
26
+ end
27
+
28
+ case sec
29
+ when 0
30
+ sec = "exactly"
31
+ when 1
32
+ sec = "and #{sec} second"
33
+ else
34
+ sec = "and #{sec} seconds"
35
+ end
36
+
37
+ text = "The time is #{hour}#{min} #{sec}."
38
+
39
+ puts "text: #{text}"
40
+ puts "voice: #{voice_name}"
41
+
42
+ voice = ($cached_voices[voice_name] ||= Flite::Voice.new(voice_name))
43
+ voice.speech(text)
44
+ end
45
+
46
+ voices = []
47
+ loop_count = 1
48
+ interval = nil
49
+
50
+ OptionParser.new do |opts|
51
+ opts.on('--voices NAMES', "voice names (default: #{available_voices.join(',')})") {|v| voices += v.split(',')}
52
+ opts.on('--loop [COUNT]', Integer, 'loop count (default: 1)') {|v| loop_count = v}
53
+ opts.on('--interval INTERVAL', Integer, 'sleep interval between loops (default: 0)') {|v| interval = v}
54
+ end.parse!
55
+
56
+ if voices.size == 0
57
+ voices = available_voices
58
+ end
59
+
60
+ if loop_count && loop_count <= 0
61
+ puts "invalid loop_count #{loop_count}. It must be positive number."
62
+ exit(1)
63
+ end
64
+
65
+ srand()
66
+ saytime(voices.sample)
67
+ cnt = 1
68
+ while loop_count.nil? || (cnt += 1) <= loop_count
69
+ sleep(interval) if interval
70
+ saytime(voices.sample)
71
+ end
@@ -0,0 +1,90 @@
1
+ require "mkmf"
2
+
3
+ dir_config('flite')
4
+
5
+ unless have_library('flite', 'flite_init')
6
+ saved_libs = $libs
7
+ puts "checkign for audio libraries depended by flite ..."
8
+ unless [['asound'], ['winmm'], ['pulse-simple', 'pulse']].any? do |libs|
9
+ $libs = saved_libs
10
+ libs.all? { |lib| have_library(lib) } && have_library('flite', 'flite_init')
11
+ end
12
+ raise "Failed to find flite libraries."
13
+ end
14
+ end
15
+
16
+ have_func('flite_voice_load')
17
+ have_func('flite_add_lang')
18
+ have_struct_member('cst_audio_streaming_info', 'utt', 'flite/cst_audio.h')
19
+
20
+ langs = with_config('langs', 'eng,indic,grapheme')
21
+
22
+ langs.split(',').each do |lang|
23
+ lib = if lang == 'eng'
24
+ ['flite_usenglish', 'usenglish_init',
25
+ 'flite_cmulex', 'cmu_lex_init']
26
+ else
27
+ ["flite_cmu_#{lang}_lang", "cmu_#{lang}_lang_init",
28
+ "flite_cmu_#{lang}_lex", "cmu_#{lang}_lex_init"]
29
+ end
30
+ if have_library(lib[0], lib[1]) and have_library(lib[2], lib[3])
31
+ $defs << "-DHAVE_LANG_#{lang.upcase}"
32
+ end
33
+ end
34
+
35
+ builtin_voices = {
36
+ 'kal' => ['cmu_us_kal', 'cmu_us_kal_diphone'],
37
+ 'awb_time' => ['cmu_time_awb', 'cmu_time_awb_ldom'],
38
+ 'kal16' => ['cmu_us_kal16', 'cmu_us_kal16_diphone'],
39
+ 'awb' => ['cmu_us_awb', 'cmu_us_awb_cg'],
40
+ 'rms' => ['cmu_us_rms', 'cmu_us_rms_cg'],
41
+ 'slt' => ['cmu_us_slt', 'cmu_us_slt_cg'],
42
+ }
43
+
44
+ voices = with_config('voices', 'kal,awb_time,kal16,awb,rms,slt')
45
+
46
+ voices = voices.split(',').inject([]) do |memo, name|
47
+ v = builtin_voices[name]
48
+ if v
49
+ puts "checking for voice #{name}... "
50
+ if have_library("flite_#{v[0]}", "register_#{v[0]}")
51
+ memo << [name, *v]
52
+ end
53
+ else
54
+ puts "warning: #{name} is not a builtin voice."
55
+ end
56
+ memo
57
+ end
58
+
59
+ File.open('rbflite_builtin_voice_list.c', 'w') do |f|
60
+ f.write <<EOS
61
+ /*
62
+ * This file is automatically generated by extconf.rb.
63
+ * Don't edit this.
64
+ */
65
+ #include "rbflite.h"
66
+
67
+ EOS
68
+ voices.each do |v|
69
+ f.puts "cst_voice *register_#{v[1]}(const char *voxdir);"
70
+ end
71
+ f.puts ""
72
+ voices.each do |v|
73
+ f.puts "extern cst_voice *#{v[2]};"
74
+ end
75
+ f.write <<EOS
76
+
77
+ const rbflite_builtin_voice_t rbflite_builtin_voice_list[] = {
78
+ EOS
79
+ voices.each do |v|
80
+ f.puts(%Q[ {"#{v[0]}", register_#{v[1]}, &#{v[2]}},])
81
+ end
82
+ f.write <<EOS
83
+ {NULL, NULL, NULL},
84
+ };
85
+ EOS
86
+ end
87
+
88
+ RUBY_VERSION =~ /(\d+).(\d+)/
89
+ $defs << "-DInit_flite=Init_flite_#{$1}#{$2}0"
90
+ create_makefile("flite_#{$1}#{$2}0")
@@ -0,0 +1,377 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*-
2
+ *
3
+ * ruby-flite - a small speech synthesis module
4
+ * https://github.com/kubo/ruby-flite
5
+ *
6
+ * Copyright (C) 2015 Kubo Takehiro <kubo@jiubao.org>
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above
15
+ * copyright notice, this list of conditions and the following
16
+ * disclaimer in the documentation and/or other materials provided
17
+ * with the distribution.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR
20
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * The views and conclusions contained in the software and documentation
32
+ * are those of the authors and should not be interpreted as representing
33
+ * official policies, either expressed or implied, of the authors.
34
+ */
35
+ #include <ruby.h>
36
+ #include <ruby/thread.h>
37
+ #include <ruby/encoding.h>
38
+ #include "rbflite.h"
39
+ #include <flite/flite_version.h>
40
+
41
+ #ifdef WORDS_BIGENDIAN
42
+ #define TO_LE4(num) SWAPINT(num)
43
+ #defien TO_LE2(num) SWAPSHORT(num)
44
+ #else
45
+ #define TO_LE4(num) (num)
46
+ #define TO_LE2(num) (num)
47
+ #endif
48
+
49
+ #ifdef HAVE_CST_AUDIO_STREAMING_INFO_UTT
50
+ /* flite 2.0.0 */
51
+ typedef struct cst_audio_streaming_info_struct *asc_last_arg_t;
52
+ #define ASC_LAST_ARG_TO_USERDATA(last_arg) (last_arg)->userdata
53
+ #else
54
+ /* flite 1.4.0 */
55
+ typedef void *asc_last_arg_t;
56
+ #define ASC_LAST_ARG_TO_USERDATA(last_arg) (last_arg)
57
+ #endif
58
+
59
+ void usenglish_init(cst_voice *v);
60
+ cst_lexicon *cmulex_init(void);
61
+
62
+ void cmu_indic_lang_init(cst_voice *v);
63
+ cst_lexicon *cmu_indic_lex_init(void);
64
+
65
+ void cmu_grapheme_lang_init(cst_voice *v);
66
+ cst_lexicon *cmu_grapheme_lex_init(void);
67
+
68
+ typedef struct {
69
+ cst_voice *voice;
70
+ } rbflite_voice_t;
71
+
72
+ typedef struct {
73
+ cst_voice *voice;
74
+ const char *text;
75
+ const char *outtype;
76
+ VALUE io;
77
+ int state;
78
+ } voice_speech_arg_t;
79
+
80
+ typedef struct {
81
+ VALUE io;
82
+ void *data;
83
+ long size;
84
+ } io_write_arg_t;
85
+
86
+ static VALUE rb_mFlite;
87
+ static VALUE rb_cVoice;
88
+ static ID id_write;
89
+
90
+ /*
91
+ * call graph:
92
+ *
93
+ * rbflite_audio_write_cb()
94
+ * --> rbfile_io_write_protect() via rb_thread_call_with_gvl()
95
+ * --> rbfile_io_write() via rb_protect()
96
+ */
97
+ static int rbflite_audio_write_cb(const cst_wave *w, int start, int size, int last, asc_last_arg_t last_arg);
98
+ static void *rbfile_io_write_protect(void *data);
99
+ static VALUE rbfile_io_write(VALUE data);
100
+
101
+ static VALUE
102
+ flite_s_list_builtin_voices(VALUE klass)
103
+ {
104
+ VALUE ary = rb_ary_new();
105
+ const rbflite_builtin_voice_t *builtin = rbflite_builtin_voice_list;
106
+
107
+ while (builtin->name != NULL) {
108
+ rb_ary_push(ary, rb_usascii_str_new_cstr(builtin->name));
109
+ builtin++;
110
+ }
111
+
112
+ return ary;
113
+ }
114
+
115
+ static void
116
+ rbfile_voice_free(rbflite_voice_t *voice)
117
+ {
118
+ if (voice->voice) {
119
+ delete_voice(voice->voice);
120
+ voice->voice = NULL;
121
+ }
122
+ }
123
+
124
+ static VALUE
125
+ rbflite_voice_s_allocate(VALUE klass)
126
+ {
127
+ rbflite_voice_t *voice;
128
+
129
+ return Data_Make_Struct(klass, rbflite_voice_t, NULL, rbfile_voice_free, voice);
130
+ }
131
+
132
+ #ifdef HAVE_FLITE_VOICE_LOAD
133
+ static void *
134
+ rbflite_voice_load(void *data)
135
+ {
136
+ return flite_voice_load((const char *)data);
137
+ }
138
+ #endif
139
+
140
+ static VALUE
141
+ rbflite_voice_initialize(int argc, VALUE *argv, VALUE self)
142
+ {
143
+ VALUE name;
144
+ const rbflite_builtin_voice_t *builtin = rbflite_builtin_voice_list;
145
+ rbflite_voice_t *voice = DATA_PTR(self);
146
+
147
+ rb_scan_args(argc, argv, "01", &name);
148
+ if (!NIL_P(name)) {
149
+ char *voice_name = StringValueCStr(name);
150
+ while (builtin->name != NULL) {
151
+ if (strcmp(voice_name, builtin->name) == 0) {
152
+ break;
153
+ }
154
+ builtin++;
155
+ }
156
+ if (builtin->name == NULL) {
157
+ #ifdef HAVE_FLITE_VOICE_LOAD
158
+ if (strchr(voice_name, '/') != NULL || strchr(voice_name, '.') != NULL) {
159
+ voice->voice = rb_thread_call_without_gvl(rbflite_voice_load, voice_name, NULL, NULL);
160
+ RB_GC_GUARD(name);
161
+ if (voice->voice != NULL) {
162
+ return self;
163
+ }
164
+ }
165
+ #endif
166
+ rb_raise(rb_eArgError, "Unkonw voice %s", voice_name);
167
+ }
168
+ }
169
+ *builtin->cached = NULL; /* disable voice caching in libflite.so. */
170
+ voice->voice = builtin->register_(NULL);
171
+ return self;
172
+ }
173
+
174
+ static void *
175
+ voice_speech_without_gvl(void *data)
176
+ {
177
+ voice_speech_arg_t *arg = (voice_speech_arg_t *)data;
178
+ flite_text_to_speech(arg->text, arg->voice, arg->outtype);
179
+ return NULL;
180
+ }
181
+
182
+ static int
183
+ rbflite_audio_write_cb(const cst_wave *w, int start, int size, int last, asc_last_arg_t last_arg)
184
+ {
185
+ voice_speech_arg_t *ud = (voice_speech_arg_t *)ASC_LAST_ARG_TO_USERDATA(last_arg);
186
+ io_write_arg_t arg;
187
+
188
+ arg.io = ud->io;
189
+
190
+ if (start == 0) {
191
+ /* write WAVE file header. */
192
+ struct {
193
+ const char riff_id[4];
194
+ int file_size;
195
+ const char wave_id[4];
196
+ const char fmt_id[4];
197
+ const int fmt_size;
198
+ const short format;
199
+ short channels;
200
+ int samplerate;
201
+ int bytepersec;
202
+ short blockalign;
203
+ short bitswidth;
204
+ const char data[4];
205
+ int data_size;
206
+ } header = {
207
+ {'R', 'I', 'F', 'F'},
208
+ 0,
209
+ {'W', 'A', 'V', 'E'},
210
+ {'f', 'm', 't', ' '},
211
+ TO_LE4(16),
212
+ TO_LE2(0x0001),
213
+ 0, 0, 0, 0, 0,
214
+ {'d', 'a', 't', 'a'},
215
+ 0,
216
+ };
217
+ int num_samples = cst_wave_num_samples(w);
218
+ int num_channels = cst_wave_num_channels(w);
219
+ int sample_rate = cst_wave_sample_rate(w);
220
+ int data_size = num_channels * num_samples * sizeof(short);
221
+
222
+ header.file_size = TO_LE4(sizeof(header) + data_size - 8);
223
+ header.channels = TO_LE2(num_channels);
224
+ header.samplerate = TO_LE2(sample_rate);
225
+ header.bytepersec = TO_LE4(sample_rate * num_channels * sizeof(short));
226
+ header.blockalign = TO_LE2(num_channels * sizeof(short));
227
+ header.bitswidth = TO_LE2(sizeof(short) * 8);
228
+ header.data_size = TO_LE4(data_size);
229
+
230
+ arg.data = &header;
231
+ arg.size = sizeof(header);
232
+ ud->state = (int)(VALUE)rb_thread_call_with_gvl(rbfile_io_write_protect, &arg);
233
+ if (ud->state != 0) {
234
+ return CST_AUDIO_STREAM_STOP;
235
+ }
236
+ }
237
+
238
+ arg.data = &w->samples[start];
239
+ arg.size = size * sizeof(short);
240
+ ud->state = (int)(VALUE)rb_thread_call_with_gvl(rbfile_io_write_protect, &arg);
241
+ if (ud->state != 0) {
242
+ return CST_AUDIO_STREAM_STOP;
243
+ }
244
+
245
+ return CST_AUDIO_STREAM_CONT;
246
+ }
247
+
248
+ static void *
249
+ rbfile_io_write_protect(void *data)
250
+ {
251
+ int state = 0;
252
+ rb_protect(rbfile_io_write, (VALUE)data, &state);
253
+ return (void*)(VALUE)state;
254
+ }
255
+
256
+ static VALUE
257
+ rbfile_io_write(VALUE data)
258
+ {
259
+ const io_write_arg_t *arg = (const io_write_arg_t *)data;
260
+ rb_funcall(arg->io, id_write, 1, rb_str_new(arg->data, arg->size));
261
+ return Qnil;
262
+ }
263
+
264
+ static VALUE
265
+ rbflite_voice_speech(int argc, VALUE *argv, VALUE self)
266
+ {
267
+ rbflite_voice_t *voice = DATA_PTR(self);
268
+ VALUE text;
269
+ VALUE out;
270
+ cst_audio_streaming_info *asi = NULL;
271
+ voice_speech_arg_t arg;
272
+
273
+ if (voice->voice == NULL) {
274
+ rb_raise(rb_eRuntimeError, "not initialized");
275
+ }
276
+
277
+ rb_scan_args(argc, argv, "11", &text, &out);
278
+ arg.voice = voice->voice;
279
+ arg.text = StringValueCStr(text);
280
+ arg.io = Qnil;
281
+ arg.state = 0;
282
+
283
+ if (NIL_P(out)) {
284
+ /* play audio */
285
+ arg.outtype = "play";
286
+ } else if (rb_respond_to(out, id_write)) {
287
+ /* write to an object */
288
+ asi = new_audio_streaming_info();
289
+ if (asi == NULL) {
290
+ rb_raise(rb_eNoMemError, "failed to allocate audio_streaming_info");
291
+ }
292
+ asi->asc = rbflite_audio_write_cb;
293
+ asi->userdata = (void*)&arg;
294
+ feat_set(voice->voice->features, "streaming_info", audio_streaming_info_val(asi));
295
+ arg.outtype = "stream";
296
+ arg.io = out;
297
+ } else {
298
+ /* write to a file */
299
+ out = rb_str_export_to_enc(out, rb_filesystem_encoding());
300
+ arg.outtype = StringValueCStr(out);
301
+ }
302
+
303
+ rb_thread_call_without_gvl(voice_speech_without_gvl, &arg, NULL, NULL);
304
+ RB_GC_GUARD(text);
305
+ RB_GC_GUARD(out);
306
+
307
+ if (asi != NULL) {
308
+ flite_feat_remove(voice->voice->features, "streaming_info");
309
+ if (arg.state != 0) {
310
+ rb_jump_tag(arg.state);
311
+ }
312
+ }
313
+ return self;
314
+ }
315
+
316
+ static VALUE
317
+ rbflite_voice_name(VALUE self)
318
+ {
319
+ rbflite_voice_t *voice = DATA_PTR(self);
320
+
321
+ if (voice->voice == NULL) {
322
+ rb_raise(rb_eRuntimeError, "not initialized");
323
+ }
324
+ return rb_usascii_str_new_cstr(voice->voice->name);
325
+ }
326
+
327
+ static VALUE
328
+ rbflite_voice_pathname(VALUE self)
329
+ {
330
+ rbflite_voice_t *voice = DATA_PTR(self);
331
+ const char *pathname;
332
+
333
+ if (voice->voice == NULL) {
334
+ rb_raise(rb_eRuntimeError, "not initialized");
335
+ }
336
+ pathname = get_param_string(voice->voice->features, "pathname", "");
337
+ if (pathname[0] == '\0') {
338
+ return Qnil;
339
+ }
340
+ return rb_usascii_str_new_cstr(pathname);
341
+ }
342
+
343
+ void
344
+ Init_flite(void)
345
+ {
346
+ VALUE cmu_flite_version;
347
+
348
+ id_write = rb_intern("write");
349
+
350
+ rb_mFlite = rb_define_module("Flite");
351
+
352
+ cmu_flite_version = rb_usascii_str_new_cstr(FLITE_PROJECT_VERSION);
353
+ OBJ_FREEZE(cmu_flite_version);
354
+ rb_define_const(rb_mFlite, "CMU_FLITE_VERSION", cmu_flite_version);
355
+
356
+ #ifdef HAVE_FLITE_ADD_LANG
357
+ #ifdef HAVE_LANG_ENG
358
+ flite_add_lang("eng", usenglish_init, cmulex_init);
359
+ flite_add_lang("usenglish", usenglish_init, cmulex_init);
360
+ #endif
361
+ #ifdef HAVE_LANG_INDIC
362
+ flite_add_lang("cmu_indic_lang", cmu_indic_lang_init, cmu_indic_lex_init);
363
+ #endif
364
+ #ifdef HAVE_LANG_GRAPHEME
365
+ flite_add_lang("cmu_grapheme_lang",cmu_grapheme_lang_init,cmu_grapheme_lex_init);
366
+ #endif
367
+ #endif
368
+
369
+ rb_define_singleton_method(rb_mFlite, "list_builtin_voices", flite_s_list_builtin_voices, 0);
370
+ rb_cVoice = rb_define_class_under(rb_mFlite, "Voice", rb_cObject);
371
+ rb_define_alloc_func(rb_cVoice, rbflite_voice_s_allocate);
372
+
373
+ rb_define_method(rb_cVoice, "initialize", rbflite_voice_initialize, -1);
374
+ rb_define_method(rb_cVoice, "speech", rbflite_voice_speech, -1);
375
+ rb_define_method(rb_cVoice, "name", rbflite_voice_name, 0);
376
+ rb_define_method(rb_cVoice, "pathname", rbflite_voice_pathname, 0);
377
+ }
@@ -0,0 +1,48 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*-
2
+ *
3
+ * ruby-flite - a small speech synthesis library
4
+ * https://github.com/kubo/ruby-flite
5
+ *
6
+ * Copyright (C) 2015 Kubo Takehiro <kubo@jiubao.org>
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ *
14
+ * 2. Redistributions in binary form must reproduce the above
15
+ * copyright notice, this list of conditions and the following
16
+ * disclaimer in the documentation and/or other materials provided
17
+ * with the distribution.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR
20
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ *
31
+ * The views and conclusions contained in the software and documentation
32
+ * are those of the authors and should not be interpreted as representing
33
+ * official policies, either expressed or implied, of the authors.
34
+ */
35
+ #ifndef RBFLITE_H
36
+ #define RBFLITE_H 1
37
+
38
+ #include "flite/flite.h"
39
+
40
+ typedef struct {
41
+ const char *name;
42
+ cst_voice *(*register_)(const char *voxdir);
43
+ cst_voice **cached;
44
+ } rbflite_builtin_voice_t;
45
+
46
+ extern const rbflite_builtin_voice_t rbflite_builtin_voice_list[];
47
+
48
+ #endif /* RBFLITE_H */
data/flite.gemspec ADDED
@@ -0,0 +1,48 @@
1
+ # -*- ruby -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'flite/version'
6
+
7
+ if ARGV.include?("--") and ARGV[(ARGV.index("--") + 1)] == 'current'
8
+ gem_platform = 'current'
9
+ else
10
+ gem_platform = Gem::Platform::RUBY
11
+ end
12
+
13
+ Gem::Specification.new do |spec|
14
+ spec.name = "flite"
15
+ spec.version = Flite::VERSION
16
+ spec.authors = ["Kubo Takehiro"]
17
+ spec.email = ["kubo@jiubao.org"]
18
+ spec.extensions = ["ext/flite/extconf.rb"] if gem_platform == Gem::Platform::RUBY
19
+ spec.summary = %q{a small speech synthesis library}
20
+ spec.description = <<EOS
21
+ Ruby-flite is a small speech synthesis library using CMU flite[http://cmuflite.org].
22
+
23
+ CMU Flite (festival-lite) is a small, fast run-time synthesis engine
24
+ developed at CMU and primarily designed for small embedded machines
25
+ and/or large servers. Flite is designed as an alternative synthesis
26
+ engine to Festival for voices built using the FestVox suite of voice
27
+ building tools.
28
+ EOS
29
+ spec.homepage = "https://github.com/kubo/ruby-flite/"
30
+ spec.license = "2-clause BSD-style license"
31
+ spec.platform = gem_platform
32
+
33
+ files = `git ls-files -z`.split("\x0")
34
+ files.delete('build.bat')
35
+ files.delete('.gitignore')
36
+ if gem_platform == 'current'
37
+ files << 'lib/flite_200.so' << 'lib/flite_210.so'
38
+ end
39
+ spec.files = files
40
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
41
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
42
+ spec.require_paths = ["lib"]
43
+ spec.required_ruby_version = '>= 2.0.0'
44
+
45
+ spec.add_development_dependency "bundler", "~> 1.7"
46
+ spec.add_development_dependency "rake", "~> 10.0"
47
+ spec.add_development_dependency "rake-compiler", '~> 0'
48
+ end
@@ -0,0 +1,3 @@
1
+ module Flite
2
+ VERSION = "0.0.3.1"
3
+ end
data/lib/flite.rb ADDED
@@ -0,0 +1,58 @@
1
+ #
2
+ # ruby-flite - a small speech synthesis library
3
+ # https://github.com/kubo/ruby-flite
4
+ #
5
+ # Copyright (C) 2015 Kubo Takehiro <kubo@jiubao.org>
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ #
13
+ # 2. Redistributions in binary form must reproduce the above
14
+ # copyright notice, this list of conditions and the following
15
+ # disclaimer in the documentation and/or other materials provided
16
+ # with the distribution.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR
19
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ # DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
22
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28
+ # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ #
30
+ # The views and conclusions contained in the software and documentation
31
+ # are those of the authors and should not be interpreted as representing
32
+ # official policies, either expressed or implied, of the authors.
33
+
34
+ require "flite/version"
35
+ RUBY_VERSION =~ /(\d+).(\d+)/
36
+ require "flite_#{$1}#{$2}0"
37
+
38
+ module Flite
39
+ @@default_voice = Flite::Voice.new
40
+
41
+ def self.default_voice
42
+ @@default_voice
43
+ end
44
+
45
+ def self.default_voice=(name)
46
+ if name.is_a? Flite::Voice
47
+ @@default_voice = name
48
+ else
49
+ @@default_voice = Flite::Voice.new(name)
50
+ end
51
+ end
52
+ end
53
+
54
+ class String
55
+ def to_speech(out = nil)
56
+ Flite.default_voice.speech(self, out)
57
+ end
58
+ end
data/lib/flite_200.so ADDED
Binary file
data/lib/flite_210.so ADDED
Binary file
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3.1
5
+ platform: x86-mingw32
6
+ authors:
7
+ - Kubo Takehiro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ Ruby-flite is a small speech synthesis library using CMU flite[http://cmuflite.org].
57
+
58
+ CMU Flite (festival-lite) is a small, fast run-time synthesis engine
59
+ developed at CMU and primarily designed for small embedded machines
60
+ and/or large servers. Flite is designed as an alternative synthesis
61
+ engine to Festival for voices built using the FestVox suite of voice
62
+ building tools.
63
+ email:
64
+ - kubo@jiubao.org
65
+ executables:
66
+ - saytime.rb
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - bin/saytime.rb
75
+ - ext/flite/extconf.rb
76
+ - ext/flite/rbflite.c
77
+ - ext/flite/rbflite.h
78
+ - flite.gemspec
79
+ - lib/flite.rb
80
+ - lib/flite/version.rb
81
+ - lib/flite_200.so
82
+ - lib/flite_210.so
83
+ homepage: https://github.com/kubo/ruby-flite/
84
+ licenses:
85
+ - 2-clause BSD-style license
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: 2.0.0
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.0.0
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: a small speech synthesis library
107
+ test_files: []