ruby_speech 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # 0.1.5
2
+ Feature: Now added support for SSML <audio/>
3
+
1
4
  # 0.1.4
2
5
  Bugfix: Speak#+ now returns a brand new Speak rather than modifying the original object
3
6
  Bugfix: Speak#+ now re-sets the namespace on child elements to ensure no default namespace prefix is added
data/README.md CHANGED
@@ -54,6 +54,7 @@ Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_spee
54
54
  * `<emphasis/>`
55
55
  * `<say-as/>`
56
56
  * `<break/>`
57
+ * `<audio/>`
57
58
 
58
59
  ## TODO:
59
60
  ### SSML
@@ -65,7 +66,6 @@ Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_spee
65
66
  * `<meta/>` and `<metadata/>`
66
67
 
67
68
  #### Misc
68
- * `<audio/>`
69
69
  * `<mark/>`
70
70
  * `<desc/>`
71
71
 
@@ -0,0 +1,56 @@
1
+ module RubySpeech
2
+ module SSML
3
+ ##
4
+ # The audio element supports the insertion of recorded audio files (see Appendix A for required formats) and the insertion of other audio formats in conjunction with synthesized speech output. The audio element may be empty. If the audio element is not empty then the contents should be the marked-up text to be spoken if the audio document is not available. The alternate content may include text, speech markup, desc elements, or other audio elements. The alternate content may also be used when rendering the document to non-audible output and for accessibility (see the desc element). The required attribute is src, which is the URI of a document with an appropriate MIME type.
5
+ #
6
+ # An audio element is successfully rendered:
7
+ # * If the referenced audio source is played, or
8
+ # * If the synthesis processor is unable to execute #1 but the alternative content is successfully rendered, or
9
+ # * If the processor can detect that text-only output is required and the alternative content is successfully rendered.
10
+ #
11
+ # Deciding which conditions result in the alternative content being rendered is processor-dependent. If the audio element is not successfully rendered, a synthesis processor should continue processing and should notify the hosting environment. The processor may determine after beginning playback of an audio source that the audio cannot be played in its entirety. For example, encoding problems, network disruptions, etc. may occur. The processor may designate this either as successful or unsuccessful rendering, but it must document this behavior.
12
+ #
13
+ # http://www.w3.org/TR/speech-synthesis/#S3.3.1
14
+ #
15
+ class Audio < Element
16
+
17
+ VALID_CHILD_TYPES = [String, Audio, Break, Emphasis, Prosody, SayAs, Voice].freeze
18
+
19
+ ##
20
+ # Create a new SSML audio element
21
+ #
22
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
23
+ #
24
+ # @return [Break] an element for use in an SSML document
25
+ #
26
+ def self.new(atts = {}, &block)
27
+ super 'audio', atts, &block
28
+ end
29
+
30
+ ##
31
+ # The URI of a document with an appropriate MIME type
32
+ #
33
+ # @return [String]
34
+ #
35
+ def src
36
+ read_attr :src
37
+ end
38
+
39
+ ##
40
+ # @param [String] the source. Must be a valid URI
41
+ #
42
+ def src=(s)
43
+ write_attr :src, s
44
+ end
45
+
46
+ def <<(arg)
47
+ raise InvalidChildError, "An Audio can only accept String, Audio, Break, Emphasis, Mark, P, Phoneme, Prosody, SayAs, Sub, S, Voice as children" unless VALID_CHILD_TYPES.include? arg.class
48
+ super
49
+ end
50
+
51
+ def eql?(o)
52
+ super o, :src
53
+ end
54
+ end # Audio
55
+ end # SSML
56
+ end # RubySpeech
@@ -8,7 +8,7 @@ module RubySpeech
8
8
  class Emphasis < Element
9
9
 
10
10
  VALID_LEVELS = [:strong, :moderate, :none, :reduced].freeze
11
- VALID_CHILD_TYPES = [String, Break, Emphasis, Prosody, SayAs, Voice].freeze
11
+ VALID_CHILD_TYPES = [String, Audio, Break, Emphasis, Prosody, SayAs, Voice].freeze
12
12
 
13
13
  ##
14
14
  # Create a new SSML emphasis element
@@ -16,7 +16,7 @@ module RubySpeech
16
16
  VALID_PITCHES = [:'x-low', :low, :medium, :high, :'x-high', :default].freeze
17
17
  VALID_VOLUMES = [:silent, :'x-soft', :soft, :medium, :loud, :'x-loud', :default].freeze
18
18
  VALID_RATES = [:'x-slow', :slow, :medium, :fast, :'x-fast', :default].freeze
19
- VALID_CHILD_TYPES = [String, Break, Emphasis, Prosody, SayAs, Voice].freeze
19
+ VALID_CHILD_TYPES = [String, Audio, Break, Emphasis, Prosody, SayAs, Voice].freeze
20
20
 
21
21
  ##
22
22
  # Create a new SSML prosody element
@@ -8,7 +8,7 @@ module RubySpeech
8
8
  class Speak < Element
9
9
  include XML::Language
10
10
 
11
- VALID_CHILD_TYPES = [String, Break, Emphasis, Prosody, SayAs, Voice].freeze
11
+ VALID_CHILD_TYPES = [String, Audio, Break, Emphasis, Prosody, SayAs, Voice].freeze
12
12
 
13
13
  ##
14
14
  # Create a new SSML speak root element
@@ -9,7 +9,7 @@ module RubySpeech
9
9
  include XML::Language
10
10
 
11
11
  VALID_GENDERS = [:male, :female, :neutral].freeze
12
- VALID_CHILD_TYPES = [String, Break, Emphasis, Prosody, SayAs, Voice].freeze
12
+ VALID_CHILD_TYPES = [String, Audio,Break, Emphasis, Prosody, SayAs, Voice].freeze
13
13
 
14
14
  ##
15
15
  # Create a new SSML voice element
@@ -2,6 +2,7 @@ module RubySpeech
2
2
  module SSML
3
3
  extend ActiveSupport::Autoload
4
4
 
5
+ autoload :Audio
5
6
  autoload :Break
6
7
  autoload :Element
7
8
  autoload :Emphasis
@@ -1,3 +1,3 @@
1
1
  module RubySpeech
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+
3
+ module RubySpeech
4
+ module SSML
5
+ describe Audio do
6
+ its(:name) { should == 'audio' }
7
+
8
+ describe "setting options in initializers" do
9
+ subject { Audio.new :src => 'http://whatever.you-say-boss.com', :content => 'Hello' }
10
+
11
+ its(:src) { should == 'http://whatever.you-say-boss.com' }
12
+ its(:content) { should == 'Hello' }
13
+ end
14
+
15
+ describe "#src" do
16
+ before { subject.src = 'http://whatever.you-say-boss.com' }
17
+
18
+ its(:src) { should == 'http://whatever.you-say-boss.com' }
19
+ end
20
+
21
+ describe "#content" do
22
+ context "with a valid value" do
23
+ before { subject.content = "Hello" }
24
+
25
+ its(:content) { should == "Hello" }
26
+ end
27
+ end
28
+
29
+ describe "<<" do
30
+ it "should accept String" do
31
+ lambda { subject << 'anything' }.should_not raise_error
32
+ end
33
+
34
+ it "should accept Audio" do
35
+ lambda { subject << Audio.new }.should_not raise_error
36
+ end
37
+
38
+ it "should accept Break" do
39
+ lambda { subject << Break.new }.should_not raise_error
40
+ end
41
+
42
+ it "should accept Emphasis" do
43
+ lambda { subject << Emphasis.new }.should_not raise_error
44
+ end
45
+
46
+ it "should accept Mark" do
47
+ pending
48
+ lambda { subject << Mark.new }.should_not raise_error
49
+ end
50
+
51
+ it "should accept P" do
52
+ pending
53
+ lambda { subject << P.new }.should_not raise_error
54
+ end
55
+
56
+ it "should accept Phoneme" do
57
+ pending
58
+ lambda { subject << Phoneme.new }.should_not raise_error
59
+ end
60
+
61
+ it "should accept Prosody" do
62
+ lambda { subject << Prosody.new }.should_not raise_error
63
+ end
64
+
65
+ it "should accept SayAs" do
66
+ lambda { subject << SayAs.new(:interpret_as => :foo) }.should_not raise_error
67
+ end
68
+
69
+ it "should accept Sub" do
70
+ pending
71
+ lambda { subject << Sub.new }.should_not raise_error
72
+ end
73
+
74
+ it "should accept S" do
75
+ pending
76
+ lambda { subject << S.new }.should_not raise_error
77
+ end
78
+
79
+ it "should accept Voice" do
80
+ lambda { subject << Voice.new }.should_not raise_error
81
+ end
82
+
83
+ it "should raise InvalidChildError with non-acceptable objects" do
84
+ lambda { subject << 1 }.should raise_error(InvalidChildError, "An Audio can only accept String, Audio, Break, Emphasis, Mark, P, Phoneme, Prosody, SayAs, Sub, S, Voice as children")
85
+ end
86
+ end
87
+
88
+ describe "comparing objects" do
89
+ it "should be equal if the content, and src are the same" do
90
+ Audio.new(:src => "one", :content => "Hello there").should == Audio.new(:src => "one", :content => "Hello there")
91
+ end
92
+
93
+ describe "when the content is different" do
94
+ it "should not be equal" do
95
+ Audio.new(:content => "Hello").should_not == Audio.new(:content => "Hello there")
96
+ end
97
+ end
98
+
99
+ describe "when the src is different" do
100
+ it "should not be equal" do
101
+ Audio.new(:src => 'one').should_not == Audio.new(:src => 'two')
102
+ end
103
+ end
104
+ end
105
+ end # Break
106
+ end # SSML
107
+ end # RubySpeech
@@ -52,7 +52,6 @@ module RubySpeech
52
52
  end
53
53
 
54
54
  it "should accept Audio" do
55
- pending
56
55
  lambda { subject << Audio.new }.should_not raise_error
57
56
  end
58
57
 
@@ -238,7 +238,6 @@ module RubySpeech
238
238
  end
239
239
 
240
240
  it "should accept Audio" do
241
- pending
242
241
  lambda { subject << Audio.new }.should_not raise_error
243
242
  end
244
243
 
@@ -65,7 +65,6 @@ module RubySpeech
65
65
  end
66
66
 
67
67
  it "should accept Audio" do
68
- pending
69
68
  lambda { subject << Audio.new }.should_not raise_error
70
69
  end
71
70
 
@@ -130,7 +130,6 @@ module RubySpeech
130
130
  end
131
131
 
132
132
  it "should accept Audio" do
133
- pending
134
133
  lambda { subject << Audio.new }.should_not raise_error
135
134
  end
136
135
 
@@ -72,9 +72,19 @@ module RubySpeech
72
72
  doc = RubySpeech::SSML.draw do
73
73
  string "Hello world."
74
74
  ssml_break
75
+ audio :src => "hello" do
76
+ string "HELLO?"
77
+ ssml_break
78
+ audio :src => "hello"
79
+ emphasis
80
+ prosody
81
+ say_as 'date'
82
+ voice
83
+ end
75
84
  emphasis do
76
85
  string "HELLO?"
77
86
  ssml_break
87
+ audio :src => "hello"
78
88
  emphasis
79
89
  prosody
80
90
  say_as 'date'
@@ -83,6 +93,7 @@ module RubySpeech
83
93
  prosody :rate => :slow do
84
94
  string "H...E...L...L...O?"
85
95
  ssml_break
96
+ audio :src => "hello"
86
97
  emphasis
87
98
  prosody
88
99
  say_as 'date'
@@ -97,6 +108,7 @@ module RubySpeech
97
108
  "01/02/1960"
98
109
  end
99
110
  ssml_break
111
+ audio :src => "hello"
100
112
  emphasis do
101
113
  "I'm so old"
102
114
  end
@@ -110,8 +122,17 @@ module RubySpeech
110
122
  end
111
123
  expected_doc = SSML::Speak.new(:content => "Hello world.")
112
124
  expected_doc << SSML::Break.new
125
+ audio = SSML::Audio.new(:src => "hello", :content => "HELLO?")
126
+ audio << SSML::Break.new
127
+ audio << SSML::Audio.new(:src => "hello")
128
+ audio << SSML::Emphasis.new
129
+ audio << SSML::Prosody.new
130
+ audio << SSML::SayAs.new('date')
131
+ audio << SSML::Voice.new
132
+ expected_doc << audio
113
133
  emphasis = SSML::Emphasis.new(:content => "HELLO?")
114
134
  emphasis << SSML::Break.new
135
+ emphasis << SSML::Audio.new(:src => "hello")
115
136
  emphasis << SSML::Emphasis.new
116
137
  emphasis << SSML::Prosody.new
117
138
  emphasis << SSML::SayAs.new('date')
@@ -119,6 +140,7 @@ module RubySpeech
119
140
  expected_doc << emphasis
120
141
  prosody = SSML::Prosody.new(:rate => :slow, :content => "H...E...L...L...O?")
121
142
  prosody << SSML::Break.new
143
+ prosody << SSML::Audio.new(:src => "hello")
122
144
  prosody << SSML::Emphasis.new
123
145
  prosody << SSML::Prosody.new
124
146
  prosody << SSML::SayAs.new('date')
@@ -128,6 +150,7 @@ module RubySpeech
128
150
  voice = SSML::Voice.new(:gender => :male, :name => 'fred', :content => "Hi, I'm Fred. The time is currently ")
129
151
  voice << SSML::SayAs.new('date', :format => 'dmy', :content => "01/02/1960")
130
152
  voice << SSML::Break.new
153
+ voice << SSML::Audio.new(:src => "hello")
131
154
  voice << SSML::Emphasis.new(:content => "I'm so old")
132
155
  voice << SSML::Prosody.new(:rate => :fast, :content => "And yet so spritely!")
133
156
  voice << SSML::Voice.new(:age => 12, :content => "And I'm young Fred")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_speech
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-06 00:00:00.000000000 +01:00
12
+ date: 2011-08-25 00:00:00.000000000 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: niceogiri
17
- requirement: &2157192140 !ruby/object:Gem::Requirement
17
+ requirement: &2152986200 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.0.4
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2157192140
25
+ version_requirements: *2152986200
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: activesupport
28
- requirement: &2157191620 !ruby/object:Gem::Requirement
28
+ requirement: &2152985680 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 3.0.7
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2157191620
36
+ version_requirements: *2152985680
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: bundler
39
- requirement: &2157191140 !ruby/object:Gem::Requirement
39
+ requirement: &2153018720 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.0.0
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *2157191140
47
+ version_requirements: *2153018720
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec
50
- requirement: &2157190660 !ruby/object:Gem::Requirement
50
+ requirement: &2153018240 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 2.3.0
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *2157190660
58
+ version_requirements: *2153018240
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: ci_reporter
61
- requirement: &2157190180 !ruby/object:Gem::Requirement
61
+ requirement: &2153017760 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.6.3
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *2157190180
69
+ version_requirements: *2153017760
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: yard
72
- requirement: &2157183900 !ruby/object:Gem::Requirement
72
+ requirement: &2153017280 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 0.7.0
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *2157183900
80
+ version_requirements: *2153017280
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rake
83
- requirement: &2157183320 !ruby/object:Gem::Requirement
83
+ requirement: &2153016800 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *2157183320
91
+ version_requirements: *2153016800
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: mocha
94
- requirement: &2157182760 !ruby/object:Gem::Requirement
94
+ requirement: &2153016320 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: '0'
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *2157182760
102
+ version_requirements: *2153016320
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: i18n
105
- requirement: &2157182140 !ruby/object:Gem::Requirement
105
+ requirement: &2153015840 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: '0'
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *2157182140
113
+ version_requirements: *2153015840
114
114
  description: Prepare SSML and GRXML documents with ease
115
115
  email:
116
116
  - ben@langfeld.me
@@ -131,6 +131,7 @@ files:
131
131
  - assets/xml.xsd
132
132
  - lib/ruby_speech.rb
133
133
  - lib/ruby_speech/ssml.rb
134
+ - lib/ruby_speech/ssml/audio.rb
134
135
  - lib/ruby_speech/ssml/break.rb
135
136
  - lib/ruby_speech/ssml/element.rb
136
137
  - lib/ruby_speech/ssml/emphasis.rb
@@ -142,6 +143,7 @@ files:
142
143
  - lib/ruby_speech/xml.rb
143
144
  - lib/ruby_speech/xml/language.rb
144
145
  - ruby_speech.gemspec
146
+ - spec/ruby_speech/ssml/audio_spec.rb
145
147
  - spec/ruby_speech/ssml/break_spec.rb
146
148
  - spec/ruby_speech/ssml/emphasis_spec.rb
147
149
  - spec/ruby_speech/ssml/prosody_spec.rb
@@ -177,6 +179,7 @@ signing_key:
177
179
  specification_version: 3
178
180
  summary: A ruby library for TTS & ASR document preparation
179
181
  test_files:
182
+ - spec/ruby_speech/ssml/audio_spec.rb
180
183
  - spec/ruby_speech/ssml/break_spec.rb
181
184
  - spec/ruby_speech/ssml/emphasis_spec.rb
182
185
  - spec/ruby_speech/ssml/prosody_spec.rb