plant-sirens 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'sirens'
3
+ include Sirens
4
+
5
+ # Open the sound.
6
+ s = Sound.new
7
+ s.frameLength = 0.04
8
+ s.hopLength = 0.02
9
+ s.open('sounds/whistle4.wav')
10
+
11
+ # Create the feature objects.
12
+ l = Loudness.new
13
+ ts = TemporalSparsity.new
14
+ ss = SpectralSparsity.new
15
+ sc = SpectralCentroid.new
16
+ ti = TransientIndex.new
17
+ h = Harmonicity.new
18
+
19
+ # Set feature history size for all features.
20
+ [l, ts, ss, sc, ti, h].each do |f|
21
+ f.maxHistorySize = s.frames - 1
22
+ end
23
+
24
+ # Set spectrum size and sample rate for relevant spectral features.
25
+ [sc, ti, h].each do |f|
26
+ f.spectrumSize = s.spectrumSize
27
+ f.sampleRate = s.sampleRate
28
+ end
29
+
30
+ # Set other feature-specific parameters.
31
+ ts.windowSize = 50
32
+ ti.filters = 30
33
+ ti.mels = 15
34
+ h.absThreshold = 1
35
+ h.threshold = 0.1
36
+ h.searchRegionLength = 5
37
+ h.maxPeaks = 3
38
+ h.lpfCoefficient = 0.7
39
+
40
+ # Create a feature set to hold all the features.
41
+ features = FeatureSet.new
42
+
43
+ [l, ts].each do |f|
44
+ features.addSampleFeature f
45
+ end
46
+
47
+ [ss, sc, ti, h].each do |f|
48
+ features.addSpectralFeature f
49
+ end
50
+
51
+ s.features = features
52
+
53
+ # Extract feature histories.
54
+ s.extractFeatures
55
+ s.close
56
+
57
+ # Print the feature histories.
58
+ [l, ts, ss, sc, ti, h].each do |f|
59
+ f.history.each {|value| print value, ','}
60
+ print "\n"
61
+ end
@@ -0,0 +1,89 @@
1
+ require 'rubygems'
2
+ require 'sirens'
3
+ require 'matrix'
4
+
5
+ #---------#
6
+ # Helpers #
7
+ #---------#
8
+
9
+ # Why Matrix isn't built with this is beyond me.
10
+ class Matrix
11
+ def []=(i,j,x)
12
+ @rows[i][j] = x
13
+ end
14
+ end
15
+
16
+ # Normalize a log-likelihood similarity matrix to be a scaled distance matrix.
17
+ def normalize_affinity(matrix)
18
+ ones = Matrix.row_vector(Array.new(matrix.row_size) {1})
19
+ diag = Matrix.column_vector(Array.new(matrix.row_size) {|i| matrix[i, i]})
20
+
21
+ (diag * ones) + (ones.transpose * diag.transpose) - matrix - matrix.transpose
22
+ end
23
+
24
+ #--------#
25
+ # Script #
26
+ #--------#
27
+
28
+ files = ['sounds/whistle1.wav', 'sounds/whistle2.wav', 'sounds/whistle3.wav', 'sounds/whistle4.wav']
29
+ comparators = []
30
+
31
+ # Create the sound object, which will be reused to open and extract features from each sound.
32
+ s = Sirens::Sound.new
33
+ s.frameLength = 0.04
34
+ s.hopLength = 0.02
35
+
36
+ # For each sound, open it, extract its features, and create a comparator for it.
37
+ files.each do |filename|
38
+ # Open the sound.
39
+ s.open(filename)
40
+
41
+ # Create the feature objects.
42
+ l = Sirens::Loudness.new
43
+ ts = Sirens::TemporalSparsity.new
44
+ ss = Sirens::SpectralSparsity.new
45
+ sc = Sirens::SpectralCentroid.new
46
+ ti = Sirens::TransientIndex.new
47
+ h = Sirens::Harmonicity.new
48
+
49
+ # Set feature history size for all features.
50
+ [l, ts, ss, sc, ti, h].each do |f|
51
+ f.maxHistorySize = s.frames - 1
52
+ end
53
+
54
+ # Set spectrum size and sample rate for relevant spectral features.
55
+ [sc, ti, h].each do |f|
56
+ f.spectrumSize = s.spectrumSize
57
+ f.sampleRate = s.sampleRate
58
+ end
59
+
60
+ # Create a feature set to hold all the features.
61
+ features = Sirens::FeatureSet.new
62
+
63
+ [l, ts].each do |f|
64
+ features.addSampleFeature f
65
+ end
66
+
67
+ [ss, sc, ti, h].each do |f|
68
+ features.addSpectralFeature f
69
+ end
70
+
71
+ s.features = features
72
+
73
+ # Extract feature histories.
74
+ s.extractFeatures
75
+ s.close
76
+
77
+ # Make the retrieval model.
78
+ comparators.push Sirens::SoundComparator.new
79
+ comparators.last.features = features
80
+ end
81
+
82
+ # Compute log-likelihood similarity matrix.
83
+ log_likelihood = Matrix.rows(Array.new(comparators.size) {|i| Array.new(comparators.size) {|j| comparators[i].compare(comparators[j])}})
84
+
85
+ # Compute log-scale normalized distance matrix.
86
+ affinity = normalize_affinity log_likelihood
87
+
88
+ # Print results.
89
+ puts log_likelihood, affinity
@@ -6,7 +6,7 @@ include Sirens
6
6
  s = Sound.new
7
7
  s.frameLength = 0.04
8
8
  s.hopLength = 0.02
9
- s.open('sound.wav')
9
+ s.open('sounds/whistle4.wav')
10
10
 
11
11
  # Initialize features.
12
12
  l = Loudness.new
@@ -44,7 +44,7 @@ sc.segmentationParameters.pLagMinus = 0.075
44
44
  ss = SpectralSparsity.new
45
45
  ss.maxHistorySize = s.frames
46
46
  ss.max = 0.6509
47
- ss.min = 1.0 / 1024.0
47
+ ss.min = 0
48
48
  ss.segmentationParameters.alpha = 0.05
49
49
  ss.segmentationParameters.r = 0.0196
50
50
  ss.segmentationParameters.cStayOff = 0.001833506
@@ -56,33 +56,37 @@ ss.segmentationParameters.cStayOn = 0.009296018
56
56
  ss.segmentationParameters.pLagPlus = 0.75
57
57
  ss.segmentationParameters.pLagMinus = 0.75
58
58
 
59
+ # Create a feature set to hold the features.
59
60
  features = FeatureSet.new
60
- features.sampleFeatures = [l]
61
- features.spectralFeatures =[sc, ss]
61
+ features.addSampleFeature l
62
+ features.addSpectralFeature sc
63
+ features.addSpectralFeature ss
64
+ s.features = features
62
65
 
63
66
  # Extract features.
64
67
  before = Time.now
65
68
 
66
- s.features = features
67
69
  s.extractFeatures
68
70
  s.close
69
71
 
70
72
  elapsed = Time.now - before
71
73
  puts "Feature extraction took #{elapsed} seconds."
72
74
 
73
- # Segment sound.
75
+ # Initialize a segmenter.
74
76
  segmenter = Segmenter.new
77
+ segmenter.features = features
75
78
  segmenter.pNew = 0.00000000001
76
79
  segmenter.pOff = 0.00000000001
77
- segmenter.beams = 20
78
80
 
81
+ # Segment sound.
79
82
  before = Time.now
80
83
 
81
- segments = segmenter.segment(features)
84
+ segmenter.segment
82
85
 
83
86
  elapsed = Time.now - before
84
87
  puts "Segmentation took #{elapsed} seconds."
85
88
 
86
- segments.each do |start, duration|
87
- puts "%d-%d" % [start, start + duration]
89
+ # Print segments.
90
+ segmenter.segments.each do |start, stop|
91
+ puts "%d-%d" % [start, stop]
88
92
  end
Binary file
Binary file
Binary file
@@ -1,3 +1,30 @@
1
+ /*
2
+ * Copyright (c) 2009 Brandon Mechtley
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining
5
+ * a copy of this software and associated documentation files (the
6
+ * "Software"), to deal in the Software without restriction, including
7
+ * without limitation the rights to use, copy, modify, merge, publish,
8
+ * distribute, sublicense, and/or sell copies of the Software, and to
9
+ * permit persons to whom the Software is furnished to do so, subject to
10
+ * the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be
13
+ * included in all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
23
+
24
+ // Make sure to include Sirens before Rice so that there aren't conflicts between uBLAS and Rice.
25
+ #include "sirens/Sirens.h"
26
+ using namespace Sirens;
27
+
1
28
  #include "rice/Class.hpp"
2
29
  #include "rice/Array.hpp"
3
30
  #include "rice/String.hpp"
@@ -5,17 +32,14 @@
5
32
  #include "rice/Constructor.hpp"
6
33
  using namespace Rice;
7
34
 
8
- #include "sirens/Sirens.h"
9
- using namespace Sirens;
10
-
11
35
  /*---------------------*
12
36
  * Rice class wrappers *
13
37
  *---------------------*/
14
38
 
15
39
  // All of this is just so that we can wrap getSegmentationParameters() to avoid putting the returned pointer in the garbage collector.
16
40
  // Rice requires that we wrap every descendent of Feature. For whatever reason, it won't support things like
17
- // &SpectralCentroid::getSampleRate (the parent classº in the class definition for RiceSpectralCentroid, so it's necessary to provide
18
- // delegate functions for every parameter.
41
+ // &SpectralCentroid::getSampleRate (the parent class) in the class definition for RiceSpectralCentroid, so it's necessary to wrap
42
+ // every accessor.
19
43
 
20
44
  class RiceFeature : public Feature {
21
45
  public:
@@ -26,7 +50,13 @@ public:
26
50
 
27
51
  class RiceLoudness : public Loudness, public RiceFeature {};
28
52
  class RiceSpectralSparsity : public SpectralSparsity, public RiceFeature {};
29
- class RiceTemporalSparsity : public TemporalSparsity, public RiceFeature {};
53
+
54
+ class RiceTemporalSparsity : public TemporalSparsity, public RiceFeature {
55
+ public:
56
+ void setWindowSize(int value) {TemporalSparsity::setWindowSize(value);}
57
+ int getWindowSize() {return TemporalSparsity::getWindowSize();}
58
+ };
59
+
30
60
  class RiceSpectralCentroid : public SpectralCentroid, public RiceFeature {
31
61
  public:
32
62
  void setSpectrumSize(int value) {SpectralCentroid::setSpectrumSize(value);}
@@ -120,7 +150,7 @@ vector<int> from_ruby<vector<int> >(Object x) {
120
150
  return values;
121
151
  }
122
152
 
123
- // 2D double vector
153
+ // 2D double vector.
124
154
  template <>
125
155
  Object to_ruby<vector<double> >(vector<double> const & x) {
126
156
  return Array(x.begin(), x.end());
@@ -152,6 +182,33 @@ vector<vector<double> > from_ruby<vector<vector<double> > >(Object x) {
152
182
  return matrix;
153
183
  }
154
184
 
185
+ // 2D int vector.
186
+ template <>
187
+ Object to_ruby<vector<vector<int> > >(vector<vector<int> > const & x) {
188
+ return Array(x.begin(), x.end());
189
+ }
190
+
191
+ template <>
192
+ vector<vector<int> > from_ruby<vector<vector<int> > >(Object x) {
193
+ vector<vector<int> > matrix;
194
+
195
+ Array ruby_matrix(x);
196
+
197
+ for (unsigned int i = 0; i < ruby_matrix.size(); i++) {
198
+ vector<int> row;
199
+ Array ruby_row(ruby_matrix[i]);
200
+
201
+ for (unsigned int j = 0; j < ruby_row.size(); j++) {
202
+ int* value = (int*)(ruby_row[j].value());
203
+ row.push_back(*value);
204
+ }
205
+
206
+ matrix.push_back(row);
207
+ }
208
+
209
+ return matrix;
210
+ }
211
+
155
212
  /*------------------------*
156
213
  * Rice class definitions *
157
214
  *------------------------*/
@@ -188,11 +245,12 @@ extern "C" void Init_sirens() {
188
245
  Data_Type<FeatureSet> rb_cFeatureSet =
189
246
  define_class_under<FeatureSet>(rb_mSirens, "FeatureSet")
190
247
  .define_constructor(Constructor<FeatureSet>())
248
+ .define_method("addSampleFeature", &FeatureSet::addSampleFeature)
249
+ .define_method("addSpectralFeature", &FeatureSet::addSpectralFeature)
191
250
  .define_method("sampleFeatures", &FeatureSet::getSampleFeatures)
192
- .define_method("sampleFeatures=", &FeatureSet::setSampleFeatures)
193
251
  .define_method("spectralFeatures", &FeatureSet::getSpectralFeatures)
194
- .define_method("spectralFeatures=", &FeatureSet::setSpectralFeatures)
195
- .define_method("features", &FeatureSet::getFeatures);
252
+ .define_method("features", &FeatureSet::getFeatures)
253
+ .define_method("minHistorySize", &FeatureSet::getMinHistorySize);
196
254
 
197
255
  Data_Type<SegmentationParameters> rb_cSegmentationParameters =
198
256
  define_class_under<SegmentationParameters>(rb_mSirens, "SegmentationParameters")
@@ -220,14 +278,24 @@ extern "C" void Init_sirens() {
220
278
  Data_Type<Segmenter> rb_cSegmenter =
221
279
  define_class_under<Segmenter>(rb_mSirens, "Segmenter")
222
280
  .define_constructor(Constructor<Segmenter>())
281
+ .define_method("features=", &Segmenter::setFeatures)
282
+ .define_method("features", &Segmenter::getFeatures)
223
283
  .define_method("pNew", &Segmenter::getPNew)
224
284
  .define_method("pNew=", &Segmenter::setPNew)
225
285
  .define_method("pOff", &Segmenter::getPOff)
226
286
  .define_method("pOff=", &Segmenter::setPOff)
227
287
  .define_method("segments", &Segmenter::getSegments)
228
288
  .define_method("modes", &Segmenter::getModes)
229
- .define_method("segment", &Segmenter::getSegments);
230
-
289
+ .define_method("segment", &Segmenter::segment);
290
+
291
+ Data_Type<SoundComparator> rb_cSoundComparator =
292
+ define_class_under<SoundComparator>(rb_mSirens, "SoundComparator")
293
+ .define_constructor(Constructor<SoundComparator>())
294
+ .define_method("features=", &SoundComparator::setFeatures)
295
+ .define_method("features", &SoundComparator::getFeatures)
296
+ .define_method("compare", &SoundComparator::compare)
297
+ .define_method("initializeModel", &SoundComparator::initialize);
298
+
231
299
  /*
232
300
  FeatureBase is an unused base class that implements Feature. Feature is the
233
301
  actual class that implements RiceFeature, the wrapper Feature class that
@@ -237,7 +305,7 @@ extern "C" void Init_sirens() {
237
305
  Data_Type<Feature> rb_cFeature =
238
306
  define_class_under<Feature>(rb_mSirens, "FeatureBase")
239
307
  .define_constructor(Constructor<Feature>())
240
- .define_method("to_s", &Feature::toString)
308
+ .define_method("featureName", &Feature::toString)
241
309
  .define_method("history", &Feature::getHistory)
242
310
  .define_method("history[]", &Feature::getHistoryFrame)
243
311
  .define_method("maxHistorySize", &Feature::getMaxHistorySize)
data/sirens.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{sirens}
5
- s.version = "0.3.0"
5
+ s.version = "0.4.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Brandon Mechtley"]
9
- s.date = %q{2009-08-25}
9
+ s.date = %q{2009-09-01}
10
10
  s.description = %q{Ruby gem that implements Sirens, a library for segmentation, indexing, and retrieval of environmental and natural sounds.}
11
11
  s.email = %q{bmechtley+github@gmail.com}
12
12
  s.extensions = ["ext/sirens/extconf.rb"]
@@ -19,9 +19,13 @@ Gem::Specification.new do |s|
19
19
  "README.markdown",
20
20
  "Rakefile",
21
21
  "VERSION",
22
+ "examples/features.rb",
23
+ "examples/retrieval.rb",
22
24
  "examples/segmentation.rb",
23
- "examples/sound.wav",
24
- "examples/three_features.rb",
25
+ "examples/sounds/whistle1.wav",
26
+ "examples/sounds/whistle2.wav",
27
+ "examples/sounds/whistle3.wav",
28
+ "examples/sounds/whistle4.wav",
25
29
  "ext/sirens/extconf.rb",
26
30
  "ext/sirens/extconf.rb",
27
31
  "ext/sirens/sirens.cpp",
@@ -34,8 +38,9 @@ Gem::Specification.new do |s|
34
38
  s.rubygems_version = %q{1.3.3}
35
39
  s.summary = %q{Ruby gem that for the Sirens library.}
36
40
  s.test_files = [
37
- "examples/segmentation.rb",
38
- "examples/three_features.rb"
41
+ "examples/features.rb",
42
+ "examples/retrieval.rb",
43
+ "examples/segmentation.rb"
39
44
  ]
40
45
 
41
46
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plant-sirens
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Mechtley
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-25 00:00:00 -07:00
12
+ date: 2009-09-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -36,15 +36,18 @@ files:
36
36
  - README.markdown
37
37
  - Rakefile
38
38
  - VERSION
39
+ - examples/features.rb
40
+ - examples/retrieval.rb
39
41
  - examples/segmentation.rb
40
- - examples/sound.wav
41
- - examples/three_features.rb
42
+ - examples/sounds/whistle1.wav
43
+ - examples/sounds/whistle2.wav
44
+ - examples/sounds/whistle3.wav
45
+ - examples/sounds/whistle4.wav
42
46
  - ext/sirens/extconf.rb
43
47
  - ext/sirens/sirens.cpp
44
48
  - sirens.gemspec
45
49
  has_rdoc: false
46
50
  homepage: http://github.com/plant/sirens-ruby
47
- licenses:
48
51
  post_install_message:
49
52
  rdoc_options:
50
53
  - --charset=UTF-8
@@ -65,10 +68,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
68
  requirements: []
66
69
 
67
70
  rubyforge_project:
68
- rubygems_version: 1.3.5
71
+ rubygems_version: 1.2.0
69
72
  signing_key:
70
73
  specification_version: 3
71
74
  summary: Ruby gem that for the Sirens library.
72
75
  test_files:
76
+ - examples/features.rb
77
+ - examples/retrieval.rb
73
78
  - examples/segmentation.rb
74
- - examples/three_features.rb
@@ -1,27 +0,0 @@
1
- require 'rubygems'
2
- require 'sirens'
3
- include Sirens
4
-
5
- s = Sound.new
6
- s.frameLength = 0.04
7
- s.hopLength = 0.02
8
- s.open('sound.wav')
9
- l = Loudness.new
10
- ss = SpectralSparsity.new
11
- ts = TemporalSparsity.new
12
-
13
- [l, ss, ts].each do |f|
14
- f.maxHistorySize = s.frames
15
- end
16
-
17
- s.sampleFeatures = [l, ts]
18
- s.spectralFeatures = [ss]
19
-
20
- s.extractFeatures
21
-
22
- s.close
23
-
24
- [l, ss, ts].each do |f|
25
- f.history.each {|value| print value, ','}
26
- print "\n"
27
- end