ssmd 0.2.3 → 0.3.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: 221fb4fbe3144a2331545c9ac3ab79a0dc4933b4
4
- data.tar.gz: 508c4b8101fad140db26dc76350e45dc0d324d6d
3
+ metadata.gz: d1ffe3b65bc7397e1f4138e801428aa8c456c2ed
4
+ data.tar.gz: 9f8276cc70d5a50606d1a0f009a9c1f11819e739
5
5
  SHA512:
6
- metadata.gz: 511a816ea8a953420f4a7bb7433fed1618c4c68f872add28efc73c38ff2045718fddedd134c5629682e1071d24085e0e484084368db36a1db2d16339ef534725
7
- data.tar.gz: 23d2381df4964f49dfb0bf3f377fd2d0a827b6ebcb580a82be145cdf9034008e7a896d3765cf1dc844bef1599e7988c607aa3b98ec4087bb15bcde125a9bd4a9
6
+ metadata.gz: a68f17a706a90a8f534030c58ac41c00d12eb1bef1bc1eb7a057fb100b09e8d4a7dae9e3faa0ad4f5097951a5b6fb7d4212c36c96e1e1ae1af4eead95721f1bd
7
+ data.tar.gz: 9f0e8a1c837c1f2b0602bada363fb01061c24248e7b3faacb71d36c2ac43747aa0e97dd18686211faf7ce939bdcf062a0929f22d4d4017a894f1481ec0a0bad3
data/SPECIFICATION.md CHANGED
@@ -183,7 +183,7 @@ Volume:
183
183
  --extra soft--
184
184
  -soft-
185
185
  medium
186
- +loud+ or LOUD
186
+ +loud+
187
187
  ++extra loud++
188
188
 
189
189
  Rate:
@@ -202,7 +202,6 @@ medium
202
202
  ^high^
203
203
  ^^extra high^^
204
204
 
205
- ++>>^^extra loud, fast and high^^>>++ or
206
205
  [extra loud, fast, and high](vrp: 555) or
207
206
  [extra loud, fast, and high](v: 5, r: 5, p: 5)
208
207
  ```
@@ -215,7 +214,7 @@ Volume:
215
214
  <prosody volume="x-soft">extra soft</prosody>
216
215
  <prosody volume="soft">soft</prosody>
217
216
  medium
218
- <prosody volume="loud">loud</prosody> or <prosody volume="loud">loud</prosody>
217
+ <prosody volume="loud">loud</prosody>
219
218
  <prosody volume="x-loud">extra loud</prosody>
220
219
 
221
220
  Rate:
@@ -234,9 +233,8 @@ medium
234
233
  <prosody pitch="high">high</prosody>
235
234
  <prosody pitch="x-high">extra high</prosody>
236
235
 
237
- <prosody volume="x-loud" rate="x-fast" pitch="x-high">extra loud, fast and high</prosody> or
238
- <prosody volume="x-loud" rate="x-fast" pitch="x-high">extra loud, fast and high</prosody> or
239
- <prosody volume="x-loud" rate="x-fast" pitch="x-high">extra loud, fast and high</prosody>
236
+ <prosody volume="x-loud" rate="x-fast" pitch="x-high">extra loud, fast, and high</prosody> or
237
+ <prosody volume="x-loud" rate="x-fast" pitch="x-high">extra loud, fast, and high</prosody>
240
238
  ```
241
239
 
242
240
  The shortcuts are listed first. While they can be combined, sometimes it's easier and shorter to just use
@@ -5,3 +5,4 @@ end
5
5
  require 'ssmd/annotations/annotation'
6
6
  require 'ssmd/annotations/language_annotation'
7
7
  require 'ssmd/annotations/phoneme_annotation'
8
+ require 'ssmd/annotations/prosody_annotation'
@@ -0,0 +1,97 @@
1
+ require_relative 'annotation'
2
+
3
+ module SSMD::Annotations
4
+ class ProsodyAnnotation < Annotation
5
+ class << self
6
+ def regex
7
+ /(?:vrp: ?(\d{3}))|(?:([vrp]): ?(\d))/
8
+ end
9
+
10
+ def volumes
11
+ {
12
+ 0 => "silent",
13
+ 1 => "x-soft",
14
+ 2 => "soft",
15
+ 3 => "medium",
16
+ 4 => "loud",
17
+ 5 => "x-loud"
18
+ }
19
+ end
20
+
21
+ def rates
22
+ {
23
+ 1 => "x-slow",
24
+ 2 => "slow",
25
+ 3 => "medium",
26
+ 4 => "fast",
27
+ 5 => "x-fast"
28
+ }
29
+ end
30
+
31
+ def pitches
32
+ {
33
+ 1 => "x-low",
34
+ 2 => "low",
35
+ 3 => "medium",
36
+ 4 => "high",
37
+ 5 => "x-high"
38
+ }
39
+ end
40
+ end
41
+
42
+ attr_reader :volume, :rate, :pitch
43
+
44
+ def initialize(vrp, *tuples)
45
+ begin
46
+ if vrp && vrp.size == 3
47
+ set_vrp! vrp
48
+ elsif tuples.compact.size % 2 == 0
49
+ set_tuples! tuples.take(6)
50
+ else
51
+ # ignore invalid values
52
+ end
53
+ rescue ArgumentError
54
+ # ignore if there are invalid values
55
+ end
56
+ end
57
+
58
+ def wrap(text)
59
+ attributes = [
60
+ ("volume=\"#{volume}\"" if volume),
61
+ ("rate=\"#{rate}\"" if rate),
62
+ ("pitch=\"#{pitch}\"" if pitch)
63
+ ]
64
+
65
+ "<prosody #{attributes.join(' ')}>#{text}</prosody>"
66
+ end
67
+
68
+ def combine(annotation)
69
+ @volume ||= annotation.volume
70
+ @rate ||= annotation.rate
71
+ @pitch ||= annotation.pitch
72
+
73
+ self
74
+ end
75
+
76
+ private
77
+
78
+ def set_vrp!(vrp)
79
+ @volume = self.class.volumes.fetch Integer(vrp[0])
80
+ @rate = self.class.rates.fetch Integer(vrp[1])
81
+ @pitch = self.class.pitches.fetch Integer(vrp[2])
82
+ end
83
+
84
+ def set_tuples!(tuples)
85
+ tuples.each_slice(2).each do |key, value|
86
+ case key
87
+ when 'v'
88
+ @volume = self.class.volumes.fetch Integer(value)
89
+ when 'r'
90
+ @rate = self.class.rates.fetch Integer(value)
91
+ when 'p'
92
+ @pitch = self.class.pitches.fetch Integer(value)
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -26,7 +26,8 @@ module SSMD
26
26
  p = SSMD::Processors
27
27
 
28
28
  [
29
- p::EmphasisProcessor, p::AnnotationProcessor, p::MarkProcessor
29
+ p::EmphasisProcessor, p::AnnotationProcessor, p::MarkProcessor,
30
+ p::ProsodyProcessor
30
31
  ]
31
32
  end
32
33
 
@@ -5,4 +5,5 @@ end
5
5
  require 'ssmd/processors/processor'
6
6
  require 'ssmd/processors/annotation_processor'
7
7
  require 'ssmd/processors/emphasis_processor'
8
- require 'ssmd/processors/mark_processor'
8
+ require 'ssmd/processors/mark_processor'
9
+ require 'ssmd/processors/prosody_processor'
@@ -21,7 +21,7 @@ module SSMD::Processors
21
21
  def self.annotations
22
22
  a = SSMD::Annotations
23
23
 
24
- [a::LanguageAnnotation, a::PhonemeAnnotation]
24
+ [a::LanguageAnnotation, a::PhonemeAnnotation, a::ProsodyAnnotation]
25
25
  end
26
26
 
27
27
  def ok?
@@ -39,7 +39,7 @@ module SSMD::Processors
39
39
  annotation = find_annotation annotation_text
40
40
 
41
41
  if annotation.nil?
42
- @warnings.push "Unknown annotation: #{text}"
42
+ warnings.push "Unknown annotation: #{text}"
43
43
  end
44
44
 
45
45
  [annotation].compact
@@ -72,7 +72,7 @@ module SSMD::Processors
72
72
  \( # opening annotations
73
73
  ((?:
74
74
  (?:
75
- #{annotations_regex}
75
+ #{annotations_regex} # annotations
76
76
  )(?:,\s?)?
77
77
  )+)
78
78
  \) # closing annotations
@@ -82,5 +82,9 @@ module SSMD::Processors
82
82
  def annotations_regex
83
83
  self.class.annotations.map(&:regex).join("|")
84
84
  end
85
+
86
+ def warnings
87
+ @warnings ||= []
88
+ end
85
89
  end
86
90
  end
@@ -0,0 +1,102 @@
1
+ require_relative 'processor'
2
+
3
+ module SSMD::Processors
4
+ class ProsodyProcessor < Processor
5
+ def result
6
+ with_volume || with_rate || with_pitch
7
+ end
8
+
9
+ def regex
10
+ Regex.prosody
11
+ end
12
+
13
+ private
14
+
15
+ def with_volume
16
+ name, text = volume_keys.map { |k| [k, match[k]] }.find { |k, v| !v.nil? }
17
+
18
+ "<prosody volume=\"#{name}\">#{text}</prosody>" if name && text
19
+ end
20
+
21
+ def with_rate
22
+ name, text = rate_keys.map { |k| [k, match[k]] }.find { |k, v| !v.nil? }
23
+
24
+ "<prosody rate=\"#{name}\">#{text}</prosody>" if name && text
25
+ end
26
+
27
+ def with_pitch
28
+ name, text = pitch_keys.map { |k| [k, match[k]] }.find { |k, v| !v.nil? }
29
+
30
+ "<prosody pitch=\"#{name}\">#{text}</prosody>" if name && text
31
+ end
32
+
33
+ def volume_keys
34
+ ['silent', 'x-soft', 'soft', 'loud', 'x-loud']
35
+ end
36
+
37
+ def rate_keys
38
+ ['x-slow', 'slow', 'fast', 'x-fast']
39
+ end
40
+
41
+ def pitch_keys
42
+ ['x-low', 'low', 'high', 'x-high']
43
+ end
44
+
45
+ module Regex
46
+ module_function
47
+
48
+ def prosody
49
+ %r{
50
+ (?:#{slow_rate}) |
51
+ (?:#{fast_rate}) |
52
+ (?:#{silent_volume}) |
53
+ (?:#{soft_volume}) |
54
+ (?:#{loud_volume}) |
55
+ (?:#{low_pitch}) |
56
+ (?:#{high_pitch})
57
+ }x
58
+ end
59
+
60
+ def silent_volume
61
+ /~#{content('silent')}~/
62
+ end
63
+
64
+ def soft_volume
65
+ /(?:#{ws_start}--#{content('x-soft')}--#{ws_end})|(?:#{ws_start}-#{content('soft')}-#{ws_end})/
66
+ end
67
+
68
+ def loud_volume
69
+ /(?:#{ws_start}\+\+#{content('x-loud')}\+\+#{ws_end})|(?:#{ws_start}\+#{content('loud')}\+#{ws_end})/
70
+ end
71
+
72
+ def slow_rate
73
+ /(?:#{ws_start}&lt;&lt;#{content('x-slow')}&lt;&lt;#{ws_end})|(?:#{ws_start}&lt;#{content('slow')}&lt;#{ws_end})/
74
+ end
75
+
76
+ def fast_rate
77
+ /(?:#{ws_start}&gt;&gt;#{content('x-fast')}&gt;&gt;#{ws_end})|(?:#{ws_start}&gt;#{content('fast')}&gt;#{ws_end})/
78
+ end
79
+
80
+ def low_pitch
81
+ /(?:#{ws_start}__#{content('x-low')}__#{ws_end})|(?:#{ws_start}_#{content('low')}_#{ws_end})/
82
+ end
83
+
84
+ def high_pitch
85
+ /(?:#{ws_start}\^\^#{content('x-high')}\^\^#{ws_end})|(?:#{ws_start}\^#{content('high')}\^#{ws_end})/
86
+ end
87
+
88
+ def content(name = nil)
89
+ id = name ? "?<#{name}>" : ""
90
+ /(#{id}(?:[^\s])|(?:[^\s].*[^\s]))/
91
+ end
92
+
93
+ def ws_start
94
+ /(?<=(\A)|(?:\s))/
95
+ end
96
+
97
+ def ws_end
98
+ /(?=(\Z)|(?:\s))/
99
+ end
100
+ end
101
+ end
102
+ end
data/lib/ssmd/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module SSMD
2
- VERSION = "0.2.3"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssmd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Kahl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-14 00:00:00.000000000 Z
11
+ date: 2017-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -109,6 +109,7 @@ files:
109
109
  - lib/ssmd/annotations/annotation.rb
110
110
  - lib/ssmd/annotations/language_annotation.rb
111
111
  - lib/ssmd/annotations/phoneme_annotation.rb
112
+ - lib/ssmd/annotations/prosody_annotation.rb
112
113
  - lib/ssmd/annotations/xsampa_to_ipa_table.txt
113
114
  - lib/ssmd/converter.rb
114
115
  - lib/ssmd/processors.rb
@@ -116,6 +117,7 @@ files:
116
117
  - lib/ssmd/processors/emphasis_processor.rb
117
118
  - lib/ssmd/processors/mark_processor.rb
118
119
  - lib/ssmd/processors/processor.rb
120
+ - lib/ssmd/processors/prosody_processor.rb
119
121
  - lib/ssmd/version.rb
120
122
  - ssmd.gemspec
121
123
  homepage: https://github.com/machisuji/ssmd