win32-loquendo 1.0.1-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 +15 -0
- data/.gitignore +17 -0
- data/.yardopts +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +78 -0
- data/Rakefile +6 -0
- data/lib/win32/loquendo.rb +189 -0
- data/lib/win32/loquendo/version.rb +5 -0
- data/win32-loquendo.gemspec +30 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Njc2MWYzOWJlYzhjNGQ4MGVmMjlkZDM1NzMyOTBlYzI5ZGJmZjYwNg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YjYyM2Q2MWVmOWE5ZGU2MzA2MDUzNjBhYTg5YjNmMTY0ZjdlOTIzZQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDhiZTUyM2U4OTg5NWU4NmEzNDU0MjA4NmJjMDYwNWY2NTcxNjJlYTFlYjI4
|
10
|
+
ODU5NTdlOTE1ZDMzZGRkNzY2MzU2ZGRmZjllM2VmNjdkMzMxNmJlNWE5MDUw
|
11
|
+
YjQ0NjE3OTVkYTZmMjg0YWFjMGI3Mzc5MzVlM2M3OGEzOGIzMGU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NDgxMDBiMDM5YzdlZmIzNWY2ODFkOWU3MWFlZGRhNzE4M2Q1YzBiOTA2NTU2
|
14
|
+
NmM4Y2ZjYTQ2Y2ExYjg3NjdkY2ZmNGM4MWE0YzhiZmRiNzllNzBhZjNmNjQ0
|
15
|
+
ZTNhYmNkYWRmNWQxYTI0ZTRmMDFhOThhZTNlYjEyM2U0M2FmZjc=
|
data/.gitignore
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jonas Tingeborn
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Win32::Loquendo
|
2
|
+
|
3
|
+
Ruby interface to the Loquendo speech synthesis (text to speech / TTS) program.
|
4
|
+
|
5
|
+
This gem only runs on Microsoft Windows as it relies both on the Win32 API as
|
6
|
+
well as the DLL files used by the Loquendo distribution. For that reason it
|
7
|
+
has been name spaced in the win32 module to make it abundantly clear which
|
8
|
+
platform it supports.
|
9
|
+
|
10
|
+
## Prerequisites
|
11
|
+
|
12
|
+
* Must have Loquendo installed on the machine in order to use this gem.
|
13
|
+
* ruby ffi library, will be installed automatically through rubygems
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
$ gem install win32-loquendo
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Basic example showing the three types of use
|
22
|
+
|
23
|
+
require 'win32/loquendo'
|
24
|
+
|
25
|
+
reader = Win32::Loquendo::Reader.new()
|
26
|
+
|
27
|
+
reader.say("Say it aloud") # Send the text to the sound card
|
28
|
+
|
29
|
+
reader.say("Give me the data") do |data|
|
30
|
+
# do stuff with the string of PCM WAVE bytes
|
31
|
+
end
|
32
|
+
|
33
|
+
reader.write("audio.wav", "Save the spoken text to a file")
|
34
|
+
|
35
|
+
Customize how the text is spoken
|
36
|
+
|
37
|
+
reader = Win32::Loquendo::Reader.new({
|
38
|
+
:sample_rate => 32000, # Pick a sample rate in Hz
|
39
|
+
:channels => 2, # Stereo or mono (1 or 2 audio channels)
|
40
|
+
:voice => "Elizabeth" # Specify the default voice to use
|
41
|
+
})
|
42
|
+
|
43
|
+
reader.say "Hi, this is Elizabeth speaking" # Speak with the default voice.
|
44
|
+
reader.say "and this is Simon", "Simon" # Override the default voice
|
45
|
+
# for this utterance.
|
46
|
+
|
47
|
+
reader.voices.each do |name| # List installed voices that can
|
48
|
+
reader.say "My name is #{name}", name # be used for speaking.
|
49
|
+
end
|
50
|
+
|
51
|
+
Note that you can customize a lot on the fly regarding how Loquendo speaks, by
|
52
|
+
simply adding commands as part of the text being spoken. For example:
|
53
|
+
|
54
|
+
* Trigger whatever pre-programmed demo phrase the voice used was shipped with.
|
55
|
+
|
56
|
+
reader.say("\\demosentence and I'm speaking through ruby win32-loquendo")
|
57
|
+
|
58
|
+
* Provide proper pronunciation for words using [X-SAMPA][*]
|
59
|
+
|
60
|
+
reader.say("Hello, or in Finnish; \SAMPA=;('t_de4ve)", "Dave")
|
61
|
+
|
62
|
+
Finally you can launch speech prompts in parallel, overlapping to the degree
|
63
|
+
you'd like by running reader instances in separate threads. This example
|
64
|
+
generates something eerily similar to Google's audio captchas, using 10
|
65
|
+
overlapping voices.
|
66
|
+
|
67
|
+
(0...40).to_a.shuffle.each_slice(4).map{|a| a.join(" ") }.map{|s|
|
68
|
+
Thread.new { Win32::Loquendo::Reader.new.say(s) }
|
69
|
+
}.each {|t|
|
70
|
+
t.join
|
71
|
+
}
|
72
|
+
|
73
|
+
A note of caution: Only ever interact with a reader from one and the same thread.
|
74
|
+
If used from different threads it will cause undefined behavior (errors,
|
75
|
+
hangs, crashes), since the library interact with C-code over FFI and such
|
76
|
+
interactions are not thread safe.
|
77
|
+
|
78
|
+
[*]: http://en.wikipedia.org/wiki/X-SAMPA
|
data/Rakefile
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'win32/registry'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module Win32
|
6
|
+
module Loquendo
|
7
|
+
|
8
|
+
###
|
9
|
+
# Reads text out loud or to file using the Loquendo TTS engine.
|
10
|
+
class Reader
|
11
|
+
|
12
|
+
###
|
13
|
+
# @param [Hash] opts options to be used as default configuration.
|
14
|
+
# @option opts [Integer] :sample_rate (32000) in Hz.
|
15
|
+
# @option opts [Integer] :channels (2) denotes Stereo or mono, 2 or 1 channel.
|
16
|
+
# @option opts [String] :voice (Elisabeth) default voice to use unless
|
17
|
+
# overridden when calling {#say} or {#write}.
|
18
|
+
def initialize(opts={})
|
19
|
+
@opts = {
|
20
|
+
:sample_rate => 32000,
|
21
|
+
:channels => 2,
|
22
|
+
:voice => "Elizabeth"
|
23
|
+
}.merge(opts)
|
24
|
+
@speaking = false
|
25
|
+
|
26
|
+
# Sanity checking of input parameters
|
27
|
+
unless @opts[:sample_rate].kind_of?(Integer) && @opts[:sample_rate] > 0
|
28
|
+
raise LoquendoException, ":sample_rate must be an integer and larger than zero, but %s was specified" % @opts[:sample_rate].to_s
|
29
|
+
end
|
30
|
+
unless [1,2].include?( @opts[:channels] )
|
31
|
+
raise LoquendoException, "audio :channels must be either 1 or 2, but %s was specified" % @opts[:channels].to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
# Instantiate the TTS reader
|
35
|
+
ptr = FFI::MemoryPointer.new :pointer
|
36
|
+
|
37
|
+
unless LoqTTS7.ttsNewReader(ptr,nil) == 0
|
38
|
+
LoqTTS7.ttsDeleteSession(nil)
|
39
|
+
raise LoquendoException, "Failed to create TTS reader"
|
40
|
+
end
|
41
|
+
@reader_ptr = ptr.read_pointer
|
42
|
+
@reader_ptr.freeze
|
43
|
+
|
44
|
+
# Register a callback for speaking so we know when speeches end, since
|
45
|
+
# we're interacting with the TTS engine asynchronously in order to avoid
|
46
|
+
# blocking the entire main thread while speaking is going on.
|
47
|
+
@callback = FFI::Function.new(:void, [:uint, :int, :pointer, :pointer]) do |speech_id, event, *ignore|
|
48
|
+
if event == 1
|
49
|
+
@speaking = false
|
50
|
+
info "End of speech ##{speech_id}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
unless LoqTTS7.ttsSetCallback(@reader_ptr, @callback, nil, 0) == 0
|
55
|
+
raise LoquendoException, "Failed to register TTS reading callback"
|
56
|
+
end
|
57
|
+
|
58
|
+
end # init
|
59
|
+
|
60
|
+
###
|
61
|
+
# Writes +text+ spoken with +voice+ to +filename+.
|
62
|
+
# @param [String] filename to write the PCM WAV data to.
|
63
|
+
# @param [String,#read] text to be rendered to audio.
|
64
|
+
# @param [String] voice defaults to whatever voice was
|
65
|
+
# specified during the creation of the Reader object.
|
66
|
+
def write(filename, text, voice = @opts[:voice])
|
67
|
+
device = "LTTS7AudioFile"
|
68
|
+
load_voice(voice)
|
69
|
+
unless LoqTTS7.ttsSetAudio(@reader_ptr, device, filename, @opts[:sample_rate], 0, @opts[:channels], nil) == 0
|
70
|
+
raise LoquendoException, "Failed to prepare writing audio to file via #{device} library"
|
71
|
+
end
|
72
|
+
render_speech(text, device)
|
73
|
+
end
|
74
|
+
|
75
|
+
###
|
76
|
+
# Speaks the provided +text+ using +voice+ through the sound card.
|
77
|
+
# If a block is provided, the spoken WAVE-data is handed as a string of
|
78
|
+
# bytes to the block instead of being sent to the sound card.
|
79
|
+
# @param [String,#read] text to be spoken.
|
80
|
+
# @param [String] voice uses whatever voice wasspecified during the
|
81
|
+
# creation of the Reader object unless overridden.
|
82
|
+
def say(text, voice = @opts[:voice])
|
83
|
+
if block_given?
|
84
|
+
data = nil
|
85
|
+
Dir.mktmpdir("loquendo_audio") do |dir|
|
86
|
+
file = File.join(dir,"spoken_text.wav")
|
87
|
+
write(file, text, voice)
|
88
|
+
data = open(file,'rb'){|f| f.read }
|
89
|
+
end
|
90
|
+
yield data
|
91
|
+
else
|
92
|
+
say_aloud(text, voice)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
###
|
97
|
+
# @return [Array<String>] a list of the installed voices, that can be
|
98
|
+
# used for speaking.
|
99
|
+
def voices
|
100
|
+
buff = FFI::MemoryPointer.new(:string, 1024)
|
101
|
+
unless LoqTTS7.ttsQuery(nil, 1, "Id", nil, buff, buff.size, false, false) == 0
|
102
|
+
raise LoquendoException, "Failed to query voices"
|
103
|
+
end
|
104
|
+
buff.read_string.split(";")
|
105
|
+
end
|
106
|
+
|
107
|
+
private #################################################################
|
108
|
+
|
109
|
+
def say_aloud(text, voice = @opts[:voice])
|
110
|
+
device = "LTTS7AudioBoard"
|
111
|
+
load_voice(voice)
|
112
|
+
unless LoqTTS7.ttsSetAudio(@reader_ptr, device, nil, @opts[:sample_rate], 0, @opts[:channels], nil) == 0
|
113
|
+
raise LoquendoException, "Failed to prepare playing audio via #{device} library"
|
114
|
+
end
|
115
|
+
render_speech(text, device)
|
116
|
+
end
|
117
|
+
|
118
|
+
def render_speech(text, device)
|
119
|
+
text = text.read if text.respond_to? :read
|
120
|
+
unless LoqTTS7.ttsRead(@reader_ptr, text, true, false, 0) == 0
|
121
|
+
raise LoquendoException, "Failed to playing audio via #{device} library"
|
122
|
+
end
|
123
|
+
@speaking = true # simulate synchronous behavior without making the program
|
124
|
+
while @speaking # "soft-block" for the speaking duration
|
125
|
+
sleep(0.01)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def load_voice(voice)
|
130
|
+
unless LoqTTS7.ttsLoadPersona(@reader_ptr, voice, nil, nil) == 0
|
131
|
+
LoqTTS7.ttsDeleteSession(nil)
|
132
|
+
raise LoquendoException, "Failed to load voice '#{voice}'"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def info(msg)
|
137
|
+
puts msg if $VERBOSE
|
138
|
+
end
|
139
|
+
|
140
|
+
end # Reader
|
141
|
+
|
142
|
+
# Custom exception used for this library
|
143
|
+
class LoquendoException < Exception
|
144
|
+
end
|
145
|
+
|
146
|
+
###########################################################################
|
147
|
+
private ###################################################################
|
148
|
+
|
149
|
+
# Locate the installation path of the program and its DLLs
|
150
|
+
[ [ Win32::Registry::HKEY_LOCAL_MACHINE, "SOFTWARE\\Loquendo\\LTTS7\\Engine" ],
|
151
|
+
[ Win32::Registry::HKEY_CURRENT_USER, "SOFTWARE\\Loquendo\\LTTS7\\Engine" ]
|
152
|
+
].each do |base,key|
|
153
|
+
begin
|
154
|
+
base.open(key) do |reg|
|
155
|
+
DLL_PATH ||= reg['DataPath']
|
156
|
+
end
|
157
|
+
rescue Win32::Registry::Error
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
raise LoquendoException, "Failed to find Loquendo TTS engine. Is the program installed?" unless defined?(DLL_PATH)
|
162
|
+
|
163
|
+
# @private
|
164
|
+
module LoqTTS7
|
165
|
+
extend FFI::Library
|
166
|
+
ffi_lib "#{DLL_PATH}bin\\LoqTTS7"
|
167
|
+
# reader ?
|
168
|
+
attach_function :ttsNewReader, [ :pointer, :pointer ], :int
|
169
|
+
# reader voice language ?
|
170
|
+
attach_function :ttsLoadPersona, [ :pointer, :string, :string, :string ], :int
|
171
|
+
# session
|
172
|
+
attach_function :ttsDeleteSession, [ :pointer ], :int
|
173
|
+
# reader device filename samplr ? chan ?
|
174
|
+
attach_function :ttsSetAudio, [ :pointer, :string, :string, :uint, :int, :int, :pointer ], :int
|
175
|
+
# reader text async ? ?
|
176
|
+
attach_function :ttsRead, [ :pointer, :string, :bool, :bool, :ulong ], :int
|
177
|
+
# nil 1 atts nil resbuff cbuff false false
|
178
|
+
attach_function :ttsQuery, [ :pointer, :int, :string, :string, :pointer, :uint, :bool, :bool ], :int
|
179
|
+
# reader callback nil 0
|
180
|
+
attach_function :ttsSetCallback, [ :pointer, :pointer, :pointer, :int ], :int
|
181
|
+
#
|
182
|
+
attach_function :ttsGetErrorMessage, [ :int ], :string
|
183
|
+
# reader
|
184
|
+
#attach_function :ttsStop, [ :pointer ], :int # Causes nasty hang in Ruby, probably GIL related..
|
185
|
+
end
|
186
|
+
|
187
|
+
end # Loquendo
|
188
|
+
|
189
|
+
end #Win32
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'win32/loquendo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "win32-loquendo"
|
8
|
+
spec.version = Win32::Loquendo::VERSION
|
9
|
+
spec.platform = Gem::Platform::CURRENT
|
10
|
+
spec.authors = ["Jonas Tingeborn"]
|
11
|
+
spec.email = ["tinjon@gmail.com"]
|
12
|
+
spec.description = %q{Ruby for the Win32 API of Loquendo speech synthesis programs}
|
13
|
+
spec.summary = %q{Ruby API for Loquendo speech synthesis}
|
14
|
+
spec.homepage = "https://github.com/jojje/win32-loquendo"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "ffi"
|
23
|
+
|
24
|
+
spec.rdoc_options += ['-m', 'README.md', '-x', 'lib/win32/(?!loquendo.rb).*',
|
25
|
+
'lib/win32/loquendo.rb', 'LICENSE', 'README.md']
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "yard"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: win32-loquendo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: x86-mingw32
|
6
|
+
authors:
|
7
|
+
- Jonas Tingeborn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
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
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Ruby for the Win32 API of Loquendo speech synthesis programs
|
70
|
+
email:
|
71
|
+
- tinjon@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .yardopts
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/win32/loquendo.rb
|
83
|
+
- lib/win32/loquendo/version.rb
|
84
|
+
- win32-loquendo.gemspec
|
85
|
+
homepage: https://github.com/jojje/win32-loquendo
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options:
|
91
|
+
- -m
|
92
|
+
- README.md
|
93
|
+
- -x
|
94
|
+
- lib/win32/(?!loquendo.rb).*
|
95
|
+
- lib/win32/loquendo.rb
|
96
|
+
- LICENSE
|
97
|
+
- README.md
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 2.0.6
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: Ruby API for Loquendo speech synthesis
|
116
|
+
test_files: []
|
117
|
+
has_rdoc:
|