diarize-ruby 0.3.7 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/diarize.rb +3 -103
- data/lib/diarize/audio.rb +1 -1
- data/lib/diarize/speaker.rb +106 -74
- data/lib/diarize/super_vector.rb +8 -0
- data/lib/diarize/version.rb +1 -1
- data/lib/rjb/java_object_wrapper.rb +101 -0
- data/test/speaker_test.rb +42 -9
- data/test/super_vector_test.rb +12 -0
- data/test/version_test.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0ca7dc41b19eb2fe4496e20cb87f260ebf52141
|
4
|
+
data.tar.gz: 85d3e9cda2554f69737ffb11fee7ff0b5e9b54e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 219f481f7243ac904a35af383530b0308ddb0476afae76efcd954ac444112f9509080beabbd6797ff3e33266f48e75cce22af25385cf9170572d35c73d9feb61
|
7
|
+
data.tar.gz: 844543077abb226237e1e6ccdb28a3564a977360361686a820b00e190dd243f0545f8ee8313f25effaf192a4622e543482da561d78ade9567d331ad633515397
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## [v0.3.8] - 2016-11-29
|
2
|
+
|
3
|
+
- Speaker#load_model to return Java object instead of Rjb wrapper
|
4
|
+
- Added sha to SuperVector
|
5
|
+
- Added `as_json`/`to_json` for speakers
|
6
|
+
- `to_rdf`, `as_json` and `to_json` to return supervector_sha for speaker identification
|
7
|
+
- Refactored Rjb wrapper into separate folder
|
8
|
+
|
1
9
|
## [v0.3.7] - 2016-11-18
|
2
10
|
|
3
11
|
- Sort segments by start time by default
|
data/lib/diarize.rb
CHANGED
@@ -9,9 +9,11 @@ require "matrix"
|
|
9
9
|
|
10
10
|
require "uri"
|
11
11
|
require "open-uri"
|
12
|
-
require "digest
|
12
|
+
require "digest"
|
13
13
|
require "to_rdf"
|
14
14
|
|
15
|
+
require "rjb/java_object_wrapper"
|
16
|
+
|
15
17
|
require "diarize/version"
|
16
18
|
require "diarize/audio"
|
17
19
|
require "diarize/segment"
|
@@ -19,105 +21,3 @@ require "diarize/speaker"
|
|
19
21
|
require "diarize/segmentation"
|
20
22
|
require "diarize/super_vector"
|
21
23
|
require "diarize/server"
|
22
|
-
|
23
|
-
# Extenions to the {Ruby-Java Bridge}[http://rjb.rubyforge.org/] module that
|
24
|
-
# adds a generic Java object wrapper class.
|
25
|
-
module Rjb
|
26
|
-
# A generic wrapper for a Java object loaded via the Ruby Java Bridge. The
|
27
|
-
# wrapper class handles intialization and stringification, and passes other
|
28
|
-
# method calls down to the underlying Java object. Objects returned by the
|
29
|
-
# underlying Java object are converted to the appropriate Ruby object.
|
30
|
-
#
|
31
|
-
# This object is enumerable, yielding items in the order defined by the Java
|
32
|
-
# object's iterator.
|
33
|
-
class JavaObjectWrapper
|
34
|
-
include Enumerable
|
35
|
-
|
36
|
-
# The underlying Java object.
|
37
|
-
attr_reader :java_object
|
38
|
-
|
39
|
-
# Initialize with a Java object <em>obj</em>. If <em>obj</em> is a
|
40
|
-
# String, assume it is a Java class name and instantiate it. Otherwise,
|
41
|
-
# treat <em>obj</em> as an instance of a Java object.
|
42
|
-
def initialize(obj, *args)
|
43
|
-
@java_object = obj.class == String ?
|
44
|
-
Rjb::import(obj).send(:new, *args) : obj
|
45
|
-
end
|
46
|
-
|
47
|
-
# Enumerate all the items in the object using its iterator. If the object
|
48
|
-
# has no iterator, this function yields nothing.
|
49
|
-
def each
|
50
|
-
if @java_object.getClass.getMethods.any? {|m| m.getName == "iterator"}
|
51
|
-
i = @java_object.iterator
|
52
|
-
while i.hasNext
|
53
|
-
yield wrap_java_object(i.next)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end # each
|
57
|
-
|
58
|
-
# Reflect unhandled method calls to the underlying Java object.
|
59
|
-
def method_missing(m, *args)
|
60
|
-
wrap_java_object(@java_object.send(m, *args))
|
61
|
-
end
|
62
|
-
|
63
|
-
# Convert a value returned by a call to the underlying Java object to the
|
64
|
-
# appropriate Ruby object as follows:
|
65
|
-
# * RJB objects are placed inside a generic JavaObjectWrapper wrapper.
|
66
|
-
# * <tt>java.util.ArrayList</tt> objects are converted to Ruby Arrays.
|
67
|
-
# * <tt>java.util.HashSet</tt> objects are converted to Ruby Sets
|
68
|
-
# * Other objects are left unchanged.
|
69
|
-
#
|
70
|
-
# This function is applied recursively to items in collection objects such
|
71
|
-
# as set and arrays.
|
72
|
-
def wrap_java_object(object)
|
73
|
-
if object.kind_of?(Array)
|
74
|
-
object.collect {|item| wrap_java_object(item)}
|
75
|
-
# Ruby-Java Bridge Java objects all have a _classname member which tells
|
76
|
-
# the name of their Java class.
|
77
|
-
elsif object.respond_to?(:_classname)
|
78
|
-
case object._classname
|
79
|
-
when /java\.util\.ArrayList/
|
80
|
-
# Convert java.util.ArrayList objects to Ruby arrays.
|
81
|
-
array_list = []
|
82
|
-
object.size.times do
|
83
|
-
|i| array_list << wrap_java_object(object.get(i))
|
84
|
-
end
|
85
|
-
array_list
|
86
|
-
when /java\.util\.HashSet/
|
87
|
-
# Convert java.util.HashSet objects to Ruby sets.
|
88
|
-
set = Set.new
|
89
|
-
i = object.iterator
|
90
|
-
while i.hasNext
|
91
|
-
set << wrap_java_object(i.next)
|
92
|
-
end
|
93
|
-
set
|
94
|
-
else
|
95
|
-
# Pass other RJB objects off to a handler.
|
96
|
-
wrap_rjb_object(object)
|
97
|
-
end # case
|
98
|
-
else
|
99
|
-
# Return non-RJB objects unchanged.
|
100
|
-
object
|
101
|
-
end # if
|
102
|
-
end # wrap_java_object
|
103
|
-
|
104
|
-
# By default, all RJB classes other than <tt>java.util.ArrayList</tt> and
|
105
|
-
# <tt>java.util.HashSet</tt> go in a generic wrapper. Derived classes may
|
106
|
-
# change this behavior.
|
107
|
-
def wrap_rjb_object(object)
|
108
|
-
JavaObjectWrapper.new(object)
|
109
|
-
end
|
110
|
-
|
111
|
-
# Show the classname of the underlying Java object.
|
112
|
-
def inspect
|
113
|
-
"<#{@java_object._classname}>"
|
114
|
-
end
|
115
|
-
|
116
|
-
# Use the underlying Java object's stringification.
|
117
|
-
def to_s
|
118
|
-
toString
|
119
|
-
end
|
120
|
-
|
121
|
-
protected :wrap_java_object, :wrap_rjb_object
|
122
|
-
end # JavaObjectWrapper
|
123
|
-
end # Rjb
|
data/lib/diarize/audio.rb
CHANGED
data/lib/diarize/speaker.rb
CHANGED
@@ -1,90 +1,110 @@
|
|
1
1
|
module Diarize
|
2
2
|
class Speaker
|
3
|
+
include ToRdf
|
4
|
+
|
3
5
|
@@log_likelihood_threshold = -33
|
4
6
|
@@detection_threshold = 0.2
|
7
|
+
@@speakers = {}
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
attr_accessor :model_uri, :model, :normalized
|
9
|
+
attr_accessor :model_uri, :model
|
9
10
|
attr_reader :gender
|
11
|
+
attr_writer :normalized
|
10
12
|
|
11
13
|
def initialize(uri = nil, gender = nil, model_file = nil)
|
12
|
-
@model
|
13
|
-
@uri
|
14
|
-
@gender
|
14
|
+
@model = Speaker.load_model(model_file) if model_file
|
15
|
+
@uri = uri
|
16
|
+
@gender = gender
|
15
17
|
@normalized = false
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
speaker = Speaker.new
|
20
|
-
speaker.normalized = true
|
21
|
-
speaker.model = Speaker.load_model(File.join(File.expand_path(File.dirname(__FILE__)), 'ubm.gmm'))
|
22
|
-
speaker
|
23
|
-
end
|
20
|
+
class << self
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
def ubm
|
23
|
+
speaker = Speaker.new
|
24
|
+
speaker.normalized = true
|
25
|
+
speaker.model = Speaker.load_model(File.join(File.expand_path(File.dirname(__FILE__)), 'ubm.gmm'))
|
26
|
+
speaker
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def detection_threshold=(threshold)
|
30
|
+
@@detection_threshold = threshold
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
33
|
+
def detection_threshold
|
34
|
+
@@detection_threshold
|
35
|
+
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
def load_model(filename)
|
38
|
+
read_gmm(filename)
|
39
|
+
end
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
def find_or_create(uri, gender)
|
42
|
+
return @@speakers[uri] if @@speakers[uri]
|
43
|
+
@@speakers[uri] = Speaker.new(uri, gender)
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
def divergence(speaker1, speaker2)
|
47
|
+
# TODO bundle in mean_log_likelihood to weight down unlikely models?
|
48
|
+
return unless speaker1.model and speaker2.model
|
49
|
+
# MAP Gaussian divergence
|
50
|
+
# See "A model space framework for efficient speaker detection", Interspeech'05
|
51
|
+
divergence_lium(speaker1, speaker2)
|
52
|
+
end
|
49
53
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
+
def divergence_lium(speaker1, speaker2)
|
55
|
+
Rjb::import('fr.lium.spkDiarization.libModel.Distance').GDMAP(speaker1.model, speaker2.model)
|
56
|
+
end
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# MAP Gaussian divergence
|
59
|
-
# See "A model space framework for efficient speaker detection", Interspeech'05
|
60
|
-
divergence_lium(speaker1, speaker2)
|
61
|
-
end
|
58
|
+
def divergence_ruby(speaker1, speaker2)
|
59
|
+
SuperVector.divergence(speaker1.supervector, speaker2.supervector)
|
60
|
+
end
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
def match_sets(speakers1, speakers2)
|
63
|
+
matches = []
|
64
|
+
speakers1.each do |s1|
|
65
|
+
speakers2.each do |s2|
|
66
|
+
matches << [ s1, s2 ] if s1.same_speaker_as(s2)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
matches
|
70
|
+
end
|
71
|
+
|
72
|
+
def match(speakers)
|
73
|
+
speakers.combination(2).select { |s1, s2| s1.same_speaker_as(s2) }
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
def read_gmm(filename)
|
79
|
+
gmmlist = Rjb::JavaObjectWrapper.new("java.util.ArrayList")
|
80
|
+
input = Rjb::import('fr.lium.spkDiarization.lib.IOFile').new(filename, 'rb')
|
81
|
+
input.open
|
82
|
+
Rjb::import('fr.lium.spkDiarization.libModel.ModelIO').readerGMMContainer(input, gmmlist.java_object)
|
83
|
+
input.close
|
84
|
+
gmmlist.to_a.first.java_object
|
85
|
+
end
|
86
|
+
|
87
|
+
end # class
|
88
|
+
|
89
|
+
def mean_log_likelihood
|
90
|
+
@mean_log_likelihood ? @mean_log_likelihood : model.mean_log_likelihood # Will be NaN if model was loaded from somewhere
|
66
91
|
end
|
67
92
|
|
68
|
-
def
|
69
|
-
|
93
|
+
def mean_log_likelihood=(mll)
|
94
|
+
@mean_log_likelihood = mll
|
70
95
|
end
|
71
96
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
speakers2.each do |s2|
|
76
|
-
matches << [ s1, s2 ] if s1.same_speaker_as(s2)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
matches
|
97
|
+
def save_model(filename)
|
98
|
+
# TODO perhaps a warning if a normalized model is being saved?
|
99
|
+
write_gmm(filename, @model)
|
80
100
|
end
|
81
101
|
|
82
|
-
def
|
83
|
-
|
102
|
+
def normalized?
|
103
|
+
!!@normalized
|
84
104
|
end
|
85
105
|
|
86
106
|
def normalize!
|
87
|
-
unless
|
107
|
+
unless normalized?
|
88
108
|
# Applies M-Norm from "D-MAP: a Distance-Normalized MAP Estimation of Speaker Models for Automatic Speaker Verification"
|
89
109
|
# to the associated GMM, placing it on a unit hyper-sphere with a UBM centre (model will be at distance one from the UBM
|
90
110
|
# according to GDMAP)
|
@@ -113,12 +133,15 @@ module Diarize
|
|
113
133
|
end
|
114
134
|
|
115
135
|
def supervector
|
116
|
-
|
117
|
-
|
136
|
+
if normalized?
|
137
|
+
@supervector ||= begin
|
138
|
+
SuperVector.generate_from_model(model)
|
139
|
+
end
|
140
|
+
else
|
141
|
+
SuperVector.generate_from_model(model)
|
142
|
+
end
|
118
143
|
end
|
119
144
|
|
120
|
-
include ToRdf
|
121
|
-
|
122
145
|
def namespaces
|
123
146
|
super.merge 'ws' => 'http://wsarchive.prototype0.net/ontology/'
|
124
147
|
end
|
@@ -132,23 +155,31 @@ module Diarize
|
|
132
155
|
end
|
133
156
|
|
134
157
|
def rdf_mapping
|
135
|
-
{
|
158
|
+
{
|
159
|
+
'ws:gender' => gender,
|
160
|
+
'ws:model' => model_uri,
|
161
|
+
'ws:mean_log_likelihood' => mean_log_likelihood,
|
162
|
+
'ws:supervector_hash' => supervector.hash.to_s,
|
163
|
+
'ws:supervector_sha' => supervector.sha
|
164
|
+
}
|
136
165
|
end
|
137
166
|
|
138
|
-
|
167
|
+
def as_json
|
168
|
+
{
|
169
|
+
'gender' => gender,
|
170
|
+
'model' => model_uri,
|
171
|
+
'mean_log_likelihood' => mean_log_likelihood,
|
172
|
+
'supervector_hash' => supervector.hash.to_s,
|
173
|
+
'supervector_sha' => supervector.sha
|
174
|
+
}
|
175
|
+
end
|
139
176
|
|
140
|
-
def
|
141
|
-
|
142
|
-
gmmlist = Rjb::JavaObjectWrapper.new("java.util.ArrayList")
|
143
|
-
# input = fr.lium.spkDiarization.lib.IOFile.new(filename, 'rb')
|
144
|
-
input = Rjb::import('fr.lium.spkDiarization.lib.IOFile').new(filename, 'rb')
|
145
|
-
input.open
|
146
|
-
# fr.lium.spkDiarization.libModel.ModelIO.readerGMMContainer(input, gmmlist)
|
147
|
-
Rjb::import('fr.lium.spkDiarization.libModel.ModelIO').readerGMMContainer(input, gmmlist.java_object)
|
148
|
-
input.close
|
149
|
-
gmmlist.to_a.first.java_object
|
177
|
+
def to_json
|
178
|
+
as_json.to_json
|
150
179
|
end
|
151
180
|
|
181
|
+
protected
|
182
|
+
|
152
183
|
def write_gmm(filename, model)
|
153
184
|
# gmmlist = java.util.ArrayList.new
|
154
185
|
gmmlist = Rjb::JavaObjectWrapper.new("java.util.ArrayList")
|
@@ -160,5 +191,6 @@ module Diarize
|
|
160
191
|
Rjb::import('fr.lium.spkDiarization.libModel.ModelIO').writerGMMContainer(output, gmmlist.java_object)
|
161
192
|
output.close
|
162
193
|
end
|
194
|
+
|
163
195
|
end # Speaker
|
164
196
|
end
|
data/lib/diarize/super_vector.rb
CHANGED
data/lib/diarize/version.rb
CHANGED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Extenions to the {Ruby-Java Bridge}[http://rjb.rubyforge.org/] module that
|
2
|
+
# adds a generic Java object wrapper class.
|
3
|
+
module Rjb
|
4
|
+
# A generic wrapper for a Java object loaded via the Ruby Java Bridge. The
|
5
|
+
# wrapper class handles intialization and stringification, and passes other
|
6
|
+
# method calls down to the underlying Java object. Objects returned by the
|
7
|
+
# underlying Java object are converted to the appropriate Ruby object.
|
8
|
+
#
|
9
|
+
# This object is enumerable, yielding items in the order defined by the Java
|
10
|
+
# object's iterator.
|
11
|
+
class JavaObjectWrapper
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
# The underlying Java object.
|
15
|
+
attr_reader :java_object
|
16
|
+
|
17
|
+
# Initialize with a Java object <em>obj</em>. If <em>obj</em> is a
|
18
|
+
# String, assume it is a Java class name and instantiate it. Otherwise,
|
19
|
+
# treat <em>obj</em> as an instance of a Java object.
|
20
|
+
def initialize(obj, *args)
|
21
|
+
@java_object = obj.class == String ?
|
22
|
+
Rjb::import(obj).send(:new, *args) : obj
|
23
|
+
end
|
24
|
+
|
25
|
+
# Enumerate all the items in the object using its iterator. If the object
|
26
|
+
# has no iterator, this function yields nothing.
|
27
|
+
def each
|
28
|
+
if @java_object.getClass.getMethods.any? {|m| m.getName == "iterator"}
|
29
|
+
i = @java_object.iterator
|
30
|
+
while i.hasNext
|
31
|
+
yield wrap_java_object(i.next)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end # each
|
35
|
+
|
36
|
+
# Reflect unhandled method calls to the underlying Java object.
|
37
|
+
def method_missing(m, *args)
|
38
|
+
wrap_java_object(@java_object.send(m, *args))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convert a value returned by a call to the underlying Java object to the
|
42
|
+
# appropriate Ruby object as follows:
|
43
|
+
# * RJB objects are placed inside a generic JavaObjectWrapper wrapper.
|
44
|
+
# * <tt>java.util.ArrayList</tt> objects are converted to Ruby Arrays.
|
45
|
+
# * <tt>java.util.HashSet</tt> objects are converted to Ruby Sets
|
46
|
+
# * Other objects are left unchanged.
|
47
|
+
#
|
48
|
+
# This function is applied recursively to items in collection objects such
|
49
|
+
# as set and arrays.
|
50
|
+
def wrap_java_object(object)
|
51
|
+
if object.kind_of?(Array)
|
52
|
+
object.collect {|item| wrap_java_object(item)}
|
53
|
+
# Ruby-Java Bridge Java objects all have a _classname member which tells
|
54
|
+
# the name of their Java class.
|
55
|
+
elsif object.respond_to?(:_classname)
|
56
|
+
case object._classname
|
57
|
+
when /java\.util\.ArrayList/
|
58
|
+
# Convert java.util.ArrayList objects to Ruby arrays.
|
59
|
+
array_list = []
|
60
|
+
object.size.times do
|
61
|
+
|i| array_list << wrap_java_object(object.get(i))
|
62
|
+
end
|
63
|
+
array_list
|
64
|
+
when /java\.util\.HashSet/
|
65
|
+
# Convert java.util.HashSet objects to Ruby sets.
|
66
|
+
set = Set.new
|
67
|
+
i = object.iterator
|
68
|
+
while i.hasNext
|
69
|
+
set << wrap_java_object(i.next)
|
70
|
+
end
|
71
|
+
set
|
72
|
+
else
|
73
|
+
# Pass other RJB objects off to a handler.
|
74
|
+
wrap_rjb_object(object)
|
75
|
+
end # case
|
76
|
+
else
|
77
|
+
# Return non-RJB objects unchanged.
|
78
|
+
object
|
79
|
+
end # if
|
80
|
+
end # wrap_java_object
|
81
|
+
|
82
|
+
# By default, all RJB classes other than <tt>java.util.ArrayList</tt> and
|
83
|
+
# <tt>java.util.HashSet</tt> go in a generic wrapper. Derived classes may
|
84
|
+
# change this behavior.
|
85
|
+
def wrap_rjb_object(object)
|
86
|
+
JavaObjectWrapper.new(object)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Show the classname of the underlying Java object.
|
90
|
+
def inspect
|
91
|
+
"<#{@java_object._classname}>"
|
92
|
+
end
|
93
|
+
|
94
|
+
# Use the underlying Java object's stringification.
|
95
|
+
def to_s
|
96
|
+
toString
|
97
|
+
end
|
98
|
+
|
99
|
+
protected :wrap_java_object, :wrap_rjb_object
|
100
|
+
end # JavaObjectWrapper
|
101
|
+
end # Rjb
|
data/test/speaker_test.rb
CHANGED
@@ -2,6 +2,9 @@ require 'test_helper'
|
|
2
2
|
require 'tempfile'
|
3
3
|
|
4
4
|
class SpeakerTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@model_file = File.join(File.dirname(__FILE__), 'data', 'speaker1.gmm')
|
7
|
+
end
|
5
8
|
|
6
9
|
def test_detection_threshold
|
7
10
|
Diarize::Speaker.detection_threshold = 0.1
|
@@ -28,8 +31,7 @@ class SpeakerTest < Test::Unit::TestCase
|
|
28
31
|
end
|
29
32
|
|
30
33
|
def test_initialize_with_model
|
31
|
-
|
32
|
-
speaker = Diarize::Speaker.new(nil, nil, model_file)
|
34
|
+
speaker = Diarize::Speaker.new(nil, nil, @model_file)
|
33
35
|
assert_equal speaker.model.name, 'S0'
|
34
36
|
end
|
35
37
|
|
@@ -66,8 +68,7 @@ class SpeakerTest < Test::Unit::TestCase
|
|
66
68
|
end
|
67
69
|
|
68
70
|
def test_divergence_is_symmetric
|
69
|
-
|
70
|
-
speaker1 = Diarize::Speaker.new(nil, nil, model_file)
|
71
|
+
speaker1 = Diarize::Speaker.new(nil, nil, @model_file)
|
71
72
|
speaker2 = Diarize::Speaker.ubm
|
72
73
|
assert Diarize::Speaker.divergence(speaker1, speaker2) > 0
|
73
74
|
assert_equal Diarize::Speaker.divergence(speaker1, speaker2), Diarize::Speaker.divergence(speaker2, speaker1)
|
@@ -75,16 +76,14 @@ class SpeakerTest < Test::Unit::TestCase
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def test_divergence_ruby_is_same_as_divergence_lium
|
78
|
-
|
79
|
-
speaker1 = Diarize::Speaker.new(nil, nil, model_file)
|
79
|
+
speaker1 = Diarize::Speaker.new(nil, nil, @model_file)
|
80
80
|
speaker2 = Diarize::Speaker.ubm
|
81
81
|
assert_equal Diarize::Speaker.divergence_lium(speaker1, speaker2).round(12), Diarize::Speaker.divergence_ruby(speaker1, speaker2).round(12)
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
84
|
+
def test_normalize
|
85
85
|
# Testing M-Norm
|
86
|
-
|
87
|
-
speaker1 = Diarize::Speaker.new(nil, nil, model_file)
|
86
|
+
speaker1 = Diarize::Speaker.new(nil, nil, @model_file)
|
88
87
|
speaker2 = Diarize::Speaker.ubm
|
89
88
|
assert Diarize::Speaker.divergence(speaker1, speaker2) != 1.0
|
90
89
|
speaker1.normalize! # Putting speaker1.gmm at distance 1 from UBM
|
@@ -98,4 +97,38 @@ class SpeakerTest < Test::Unit::TestCase
|
|
98
97
|
assert_equal old_supervector, speaker.supervector
|
99
98
|
end
|
100
99
|
|
100
|
+
def test_to_rdf
|
101
|
+
speaker = Diarize::Speaker.new(URI.parse(""), "F", @model_file)
|
102
|
+
speaker.model_uri = URI.parse("https://www.example.com/model/1")
|
103
|
+
speaker.mean_log_likelihood = 0.9
|
104
|
+
to_rdf = speaker.to_rdf
|
105
|
+
assert_equal true, to_rdf.include?("ws:gender")
|
106
|
+
assert_equal true, to_rdf.include?("ws:model")
|
107
|
+
assert_equal true, to_rdf.include?("ws:mean_log_likelihood")
|
108
|
+
assert_equal true, to_rdf.include?("ws:supervector_hash")
|
109
|
+
assert_equal true, to_rdf.include?("https://www.example.com/model/1")
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_as_json
|
113
|
+
speaker = Diarize::Speaker.new(URI.parse(""), "F", @model_file)
|
114
|
+
speaker.mean_log_likelihood = 0.9
|
115
|
+
as_json = speaker.as_json
|
116
|
+
assert_equal true, as_json.has_key?('gender')
|
117
|
+
assert_equal true, as_json.has_key?('model')
|
118
|
+
assert_equal true, as_json.has_key?('mean_log_likelihood')
|
119
|
+
assert_equal true, as_json.has_key?('supervector_hash')
|
120
|
+
assert_equal true, as_json.has_key?('supervector_sha')
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_to_json
|
124
|
+
speaker = Diarize::Speaker.new(URI.parse(""), "F", @model_file)
|
125
|
+
speaker.mean_log_likelihood = 0.9
|
126
|
+
to_json = speaker.to_json
|
127
|
+
as_json = JSON.parse(to_json)
|
128
|
+
assert_equal true, as_json.has_key?('gender')
|
129
|
+
assert_equal true, as_json.has_key?('model')
|
130
|
+
assert_equal true, as_json.has_key?('mean_log_likelihood')
|
131
|
+
assert_equal true, as_json.has_key?('supervector_hash')
|
132
|
+
assert_equal true, as_json.has_key?('supervector_sha')
|
133
|
+
end
|
101
134
|
end
|
data/test/super_vector_test.rb
CHANGED
@@ -21,4 +21,16 @@ class SuperVectorTest < Test::Unit::TestCase
|
|
21
21
|
assert_equal sv.vector.hash, sv.hash
|
22
22
|
end
|
23
23
|
|
24
|
+
def test_sha
|
25
|
+
model = Diarize::Speaker.load_model(File.join(File.dirname(__FILE__), 'data', 'speaker1.gmm'))
|
26
|
+
sv = Diarize::SuperVector.generate_from_model(model)
|
27
|
+
assert_equal Digest::SHA256.hexdigest(sv.hash.to_s), sv.sha
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_to_a
|
31
|
+
model = Diarize::Speaker.load_model(File.join(File.dirname(__FILE__), 'data', 'speaker1.gmm'))
|
32
|
+
sv = Diarize::SuperVector.generate_from_model(model)
|
33
|
+
assert_equal sv.instance_variable_get("@vector").to_a, sv.to_a
|
34
|
+
end
|
35
|
+
|
24
36
|
end
|
data/test/version_test.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diarize-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yves Raimond
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- lib/diarize/super_vector.rb
|
154
154
|
- lib/diarize/ubm.gmm
|
155
155
|
- lib/diarize/version.rb
|
156
|
+
- lib/rjb/java_object_wrapper.rb
|
156
157
|
- test/audio_test.rb
|
157
158
|
- test/data/foo.wav
|
158
159
|
- test/data/speaker1.gmm
|