plant-sirens 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +26 -2
- data/Rakefile +21 -21
- data/VERSION +1 -1
- data/examples/segmentation.rb +88 -0
- data/examples/sound.wav +0 -0
- data/ext/sirens/extconf.rb +2 -1
- data/ext/sirens/sirens.cpp +216 -83
- data/sirens.gemspec +5 -8
- metadata +6 -8
- data/test/sirens/sirens_test.rb +0 -67
- data/test/sirens/test.wav +0 -0
- data/test/sirens/test_helper.rb +0 -10
data/README.markdown
CHANGED
@@ -5,6 +5,7 @@ sirens-ruby is a ruby extension for [Sirens](http://github.com/plant/sirens), a
|
|
5
5
|
To install sirens-ruby, it is necessary to have these two libraries:
|
6
6
|
|
7
7
|
1. [FFTW](http://www.fftw.org/download.html)
|
8
|
+
2. [libsndfile](http://www.mega-nerd.com/libsndfile/)
|
8
9
|
2. [Sirens](http://github.com/plant/sirens)
|
9
10
|
|
10
11
|
Additionally, sirens-ruby has the following gem dependencies, which RubyGems should take care of:
|
@@ -13,14 +14,37 @@ Additionally, sirens-ruby has the following gem dependencies, which RubyGems sho
|
|
13
14
|
2. [jeweler](http://github.com/technicalpickles/jeweler/)
|
14
15
|
2. [rice](http://github.com/cout/rice/)
|
15
16
|
|
16
|
-
*Rice Note:* I've had some problems with installing the Rice 1.1.0 gem. Try 1.0.2 if it doesn't work. On OSX, [neither seems to work](http://rubyforge.org/tracker/index.php?func=detail&aid=19828&group_id=4163&atid=16066), so try the [workaround on the Wiki](http://wiki.github.com/plant/sirens-ruby/installing-rice-on-osx).
|
17
|
-
|
18
17
|
## Installation
|
19
18
|
To install sirens-ruby, type:
|
20
19
|
|
21
20
|
gem sources -a http://gems.github.com
|
22
21
|
sudo gem install plant-sirens
|
23
22
|
|
23
|
+
If you are using OSX, [Rice has some issues with building in some environments](http://rubyforge.org/tracker/index.php?func=detail&aid=19828&group_id=4163&atid=16066). To fix this, you need to specify which architecture (Intel or PowerPC) to use when you install the gem, e.g.:
|
24
|
+
|
25
|
+
sudo bash
|
26
|
+
ARCHFLAGS="-arch i386" gem install plant-sirens -- --build-flags
|
27
|
+
|
28
|
+
replacing `i386` with `ppc` if you are using a PowerPC machine.
|
29
|
+
|
30
|
+
### Local installation
|
31
|
+
If you do not have root access, you may have some problems, as the Rice gem uses a nonstandard installation procedure that attempts to install the library in a path outside where the gem is installed. There may be an easier workaround for this by passing some options to rubygems, but the only solution I've found so far is to [install Rice manually from source](http://rice.rubyforge.org/) before installing sirens-ruby. If you are installing on OSX, please see [this ticket](http://rubyforge.org/tracker/index.php?func=detail&aid=19828&group_id=4163&atid=16066) for tips on installing from source.
|
32
|
+
|
33
|
+
FFTW and libsndfile can both be installed locally by changing the prefix path in their configure steps, e.g.
|
34
|
+
|
35
|
+
./configure --prefix=$HOME/local
|
36
|
+
|
37
|
+
Sirens can be installed similarly:
|
38
|
+
|
39
|
+
scons install --prefix=$HOME/local
|
40
|
+
|
41
|
+
|
42
|
+
After installing Rice from source, if you have not installed it as a gem, you may have troubles with gem dependencies when installing sirens-ruby. To get around this, you can ignore gem dependencies:
|
43
|
+
|
44
|
+
gem --ignore-dependencies install plant-sirens
|
45
|
+
|
46
|
+
If you have any problems with this process, please [submit an issue](http://github.com/plant/sirens-ruby/issues) and I'll try to help as soon as possible.
|
47
|
+
|
24
48
|
## Usage
|
25
49
|
Sirens is pretty minimal at the moment and only supports the extraction of six basic features. In the future, Sirens will include feature-based segmentation and comparison.
|
26
50
|
|
data/Rakefile
CHANGED
@@ -22,27 +22,27 @@ end
|
|
22
22
|
require 'rake/extensiontask'
|
23
23
|
Rake::ExtensionTask.new('sirens', spec.gemspec)
|
24
24
|
|
25
|
-
require 'rake/testtask'
|
26
|
-
Rake::TestTask.new(:test) do |test|
|
27
|
-
test.libs << 'lib' << 'test'
|
28
|
-
test.pattern = 'test/**/*_test.rb'
|
29
|
-
test.verbose = true
|
30
|
-
end
|
31
|
-
|
32
|
-
begin
|
33
|
-
require 'rcov/rcovtask'
|
34
|
-
Rcov::RcovTask.new do |test|
|
35
|
-
test.libs << 'test'
|
36
|
-
test.pattern = 'test/**/*_test.rb'
|
37
|
-
test.verbose = true
|
38
|
-
end
|
39
|
-
rescue LoadError
|
40
|
-
task :rcov do
|
41
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
task :default => :test
|
25
|
+
#require 'rake/testtask'
|
26
|
+
#Rake::TestTask.new(:test) do |test|
|
27
|
+
# test.libs << 'lib' << 'test'
|
28
|
+
# test.pattern = 'test/**/*_test.rb'
|
29
|
+
# test.verbose = true
|
30
|
+
#end
|
31
|
+
|
32
|
+
#begin
|
33
|
+
# require 'rcov/rcovtask'
|
34
|
+
# Rcov::RcovTask.new do |test|
|
35
|
+
# test.libs << 'test'
|
36
|
+
# test.pattern = 'test/**/*_test.rb'
|
37
|
+
# test.verbose = true
|
38
|
+
# end
|
39
|
+
#rescue LoadError
|
40
|
+
# task :rcov do
|
41
|
+
# abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
+
# end
|
43
|
+
#end
|
44
|
+
|
45
|
+
#task :default => :test
|
46
46
|
|
47
47
|
require 'rake/rdoctask'
|
48
48
|
Rake::RDocTask.new do |rdoc|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sirens'
|
3
|
+
include Sirens
|
4
|
+
|
5
|
+
# Open sound.
|
6
|
+
s = Sound.new
|
7
|
+
s.frameLength = 0.04
|
8
|
+
s.hopLength = 0.02
|
9
|
+
s.open('sound.wav')
|
10
|
+
|
11
|
+
# Initialize features.
|
12
|
+
l = Loudness.new
|
13
|
+
l.maxHistorySize = s.frames
|
14
|
+
l.max = 0
|
15
|
+
l.min = -60
|
16
|
+
l.segmentationParameters.alpha = 0.15
|
17
|
+
l.segmentationParameters.r = 0.0098
|
18
|
+
l.segmentationParameters.cStayOff = 0.0015
|
19
|
+
l.segmentationParameters.cTurnOn = 0.085
|
20
|
+
l.segmentationParameters.cTurningOn = 0.085
|
21
|
+
l.segmentationParameters.cTurnOff = 0.085
|
22
|
+
l.segmentationParameters.cNewSegment = 0.085
|
23
|
+
l.segmentationParameters.cStayOn = 0.05
|
24
|
+
l.segmentationParameters.pLagPlus = 0.75
|
25
|
+
l.segmentationParameters.pLagMinus = 0.75
|
26
|
+
|
27
|
+
sc = SpectralCentroid.new
|
28
|
+
sc.maxHistorySize = s.frames
|
29
|
+
sc.max = 25.7848
|
30
|
+
sc.min = 0.4994
|
31
|
+
sc.spectrumSize = s.spectrumSize
|
32
|
+
sc.sampleRate = s.sampleRate
|
33
|
+
sc.segmentationParameters.alpha = 0.05
|
34
|
+
sc.segmentationParameters.r = 0.00000196
|
35
|
+
sc.segmentationParameters.cStayOff = 0.0000933506
|
36
|
+
sc.segmentationParameters.cTurnOn = 0.85
|
37
|
+
sc.segmentationParameters.cTurningOn = 0.85
|
38
|
+
sc.segmentationParameters.cTurnOff = 0.85
|
39
|
+
sc.segmentationParameters.cNewSegment = 0.85
|
40
|
+
sc.segmentationParameters.cStayOn = 0.0025296018
|
41
|
+
sc.segmentationParameters.pLagPlus = 0.75
|
42
|
+
sc.segmentationParameters.pLagMinus = 0.075
|
43
|
+
|
44
|
+
ss = SpectralSparsity.new
|
45
|
+
ss.maxHistorySize = s.frames
|
46
|
+
ss.max = 0.6509
|
47
|
+
ss.min = 1.0 / 1024.0
|
48
|
+
ss.segmentationParameters.alpha = 0.05
|
49
|
+
ss.segmentationParameters.r = 0.0196
|
50
|
+
ss.segmentationParameters.cStayOff = 0.001833506
|
51
|
+
ss.segmentationParameters.cTurnOn = 0.85
|
52
|
+
ss.segmentationParameters.cTurningOn = 0.85
|
53
|
+
ss.segmentationParameters.cTurnOff = 0.85
|
54
|
+
ss.segmentationParameters.cNewSegment = 0.85
|
55
|
+
ss.segmentationParameters.cStayOn = 0.009296018
|
56
|
+
ss.segmentationParameters.pLagPlus = 0.75
|
57
|
+
ss.segmentationParameters.pLagMinus = 0.75
|
58
|
+
|
59
|
+
features = FeatureSet.new
|
60
|
+
features.sampleFeatures = [l]
|
61
|
+
features.spectralFeatures =[sc, ss]
|
62
|
+
|
63
|
+
# Extract features.
|
64
|
+
before = Time.now
|
65
|
+
|
66
|
+
s.features = features
|
67
|
+
s.extractFeatures
|
68
|
+
s.close
|
69
|
+
|
70
|
+
elapsed = Time.now - before
|
71
|
+
puts "Feature extraction took #{elapsed} seconds."
|
72
|
+
|
73
|
+
# Segment sound.
|
74
|
+
segmenter = Segmenter.new
|
75
|
+
segmenter.pNew = 0.00000000001
|
76
|
+
segmenter.pOff = 0.00000000001
|
77
|
+
segmenter.beams = 20
|
78
|
+
|
79
|
+
before = Time.now
|
80
|
+
|
81
|
+
segments = segmenter.segment(features)
|
82
|
+
|
83
|
+
elapsed = Time.now - before
|
84
|
+
puts "Segmentation took #{elapsed} seconds."
|
85
|
+
|
86
|
+
segments.each do |start, duration|
|
87
|
+
puts "%d-%d" % [start, start + duration]
|
88
|
+
end
|
data/examples/sound.wav
CHANGED
Binary file
|
data/ext/sirens/extconf.rb
CHANGED
@@ -12,10 +12,11 @@ require 'mkmf-rice'
|
|
12
12
|
|
13
13
|
$CPPFLAGS << " #{ENV['CPPFLAGS']}"
|
14
14
|
$LDFLAGS << " #{ENV['LDFLAGS']}"
|
15
|
-
$CFLAGS << " #{ENV['CFLAGS']}
|
15
|
+
$CFLAGS << " #{ENV['CFLAGS']}"
|
16
16
|
|
17
17
|
have_library('c')
|
18
18
|
have_library('stdc++')
|
19
|
+
have_library('sndfile')
|
19
20
|
have_library('sirens')
|
20
21
|
have_library('fftw3')
|
21
22
|
|
data/ext/sirens/sirens.cpp
CHANGED
@@ -5,26 +5,84 @@
|
|
5
5
|
#include "rice/Constructor.hpp"
|
6
6
|
using namespace Rice;
|
7
7
|
|
8
|
-
#include "sirens/
|
9
|
-
#include "sirens/CircularArray.h"
|
10
|
-
#include "sirens/features/Loudness.h"
|
11
|
-
#include "sirens/features/Harmonicity.h"
|
12
|
-
#include "sirens/features/TransientIndex.h"
|
13
|
-
#include "sirens/features/SpectralCentroid.h"
|
14
|
-
#include "sirens/features/SpectralSparsity.h"
|
15
|
-
#include "sirens/features/TemporalSparsity.h"
|
8
|
+
#include "sirens/Sirens.h"
|
16
9
|
using namespace Sirens;
|
17
10
|
|
11
|
+
/*---------------------*
|
12
|
+
* Rice class wrappers *
|
13
|
+
*---------------------*/
|
14
|
+
|
15
|
+
// All of this is just so that we can wrap getSegmentationParameters() to avoid putting the returned pointer in the garbage collector.
|
16
|
+
// 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.
|
19
|
+
|
20
|
+
class RiceFeature : public Feature {
|
21
|
+
public:
|
22
|
+
Object getRiceSegmentationParameters() {
|
23
|
+
return Rice::Data_Object<SegmentationParameters>(getSegmentationParameters(), Rice::Data_Type<SegmentationParameters>::klass(), 0, 0);
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
class RiceLoudness : public Loudness, public RiceFeature {};
|
28
|
+
class RiceSpectralSparsity : public SpectralSparsity, public RiceFeature {};
|
29
|
+
class RiceTemporalSparsity : public TemporalSparsity, public RiceFeature {};
|
30
|
+
class RiceSpectralCentroid : public SpectralCentroid, public RiceFeature {
|
31
|
+
public:
|
32
|
+
void setSpectrumSize(int value) {SpectralCentroid::setSpectrumSize(value);}
|
33
|
+
void setSampleRate(int value) {SpectralCentroid::setSampleRate(value);}
|
34
|
+
int getSpectrumSize() {return SpectralCentroid::getSpectrumSize();}
|
35
|
+
int getSampleRate() {return SpectralCentroid::getSpectrumSize();}
|
36
|
+
};
|
37
|
+
|
38
|
+
class RiceTransientIndex : public TransientIndex, public RiceFeature {
|
39
|
+
public:
|
40
|
+
void setSpectrumSize(int value) {TransientIndex::setSpectrumSize(value);}
|
41
|
+
void setSampleRate(int value) {TransientIndex::setSampleRate(value);}
|
42
|
+
void setMels(int value) {TransientIndex::setMels(value);}
|
43
|
+
void setFilters(int value) {TransientIndex::setFilters(value);}
|
44
|
+
int getSpectrumSize() {return TransientIndex::getSpectrumSize();}
|
45
|
+
int getSampleRate() {return TransientIndex::getSpectrumSize();}
|
46
|
+
int getMels() {return TransientIndex::getMels();}
|
47
|
+
int getFilters() {return TransientIndex::getFilters();}
|
48
|
+
};
|
49
|
+
|
50
|
+
class RiceHarmonicity : public Harmonicity, public RiceFeature {
|
51
|
+
public:
|
52
|
+
void setSpectrumSize(int value) {Harmonicity::setSpectrumSize(value);}
|
53
|
+
void setSampleRate(int value) {Harmonicity::setSampleRate(value);}
|
54
|
+
void setSearchRegionLength(int value) {Harmonicity::setSearchRegionLength(value);}
|
55
|
+
void setAbsThreshold(double value) {Harmonicity::setAbsThreshold(value);}
|
56
|
+
void setThreshold(double value) {Harmonicity::setThreshold(value);}
|
57
|
+
void setLPFCoefficient(double value) {Harmonicity::setLPFCoefficient(value);}
|
58
|
+
void setMaxPeaks(int value) {Harmonicity::setMaxPeaks(value);}
|
59
|
+
int getSpectrumSize() {return Harmonicity::getSpectrumSize();}
|
60
|
+
int getSampleRate() {return Harmonicity::getSampleRate();}
|
61
|
+
int getSearchRegionLength() {return Harmonicity::getSearchRegionLength();}
|
62
|
+
double getAbsThreshold() {return Harmonicity::getAbsThreshold();}
|
63
|
+
double getThreshold() {return Harmonicity::getThreshold();}
|
64
|
+
double getLPFCoefficient() {return Harmonicity::getLPFCoefficient();}
|
65
|
+
int getMaxPeaks() {return Harmonicity::getMaxPeaks();}
|
66
|
+
};
|
67
|
+
|
68
|
+
/*----------------------*
|
69
|
+
* Rice object wrappers *
|
70
|
+
*----------------------*/
|
71
|
+
|
72
|
+
// These helper methods do things like converting to/from vectors of objects, multidimensional vectors, etc.
|
73
|
+
|
74
|
+
// CircularArray
|
18
75
|
template <>
|
19
76
|
Object to_ruby<CircularArray*>(CircularArray* const & x) {
|
20
77
|
Array y;
|
21
78
|
|
22
79
|
for (int i = 0; i < x->getSize(); i++)
|
23
|
-
y.push(x->
|
80
|
+
y.push(x->getValue(i));
|
24
81
|
|
25
82
|
return y;
|
26
83
|
}
|
27
84
|
|
85
|
+
// Feature
|
28
86
|
template <>
|
29
87
|
Object to_ruby<vector<Feature*> >(vector<Feature*> const & x) {
|
30
88
|
return Array(x.begin(), x.end());
|
@@ -42,29 +100,50 @@ vector<Feature*> from_ruby<vector<Feature*> >(Object x) {
|
|
42
100
|
return y;
|
43
101
|
}
|
44
102
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
void rb_mFeatureCalculate() {
|
50
|
-
|
103
|
+
// 2D double vector
|
104
|
+
template <>
|
105
|
+
Object to_ruby<vector<double> >(vector<double> const & x) {
|
106
|
+
return Array(x.begin(), x.end());
|
51
107
|
}
|
52
108
|
|
53
|
-
|
54
|
-
|
109
|
+
template <>
|
110
|
+
Object to_ruby<vector<vector<double> > >(vector<vector<double> > const & x) {
|
111
|
+
return Array(x.begin(), x.end());
|
55
112
|
}
|
56
113
|
|
57
|
-
|
58
|
-
|
59
|
-
|
114
|
+
template <>
|
115
|
+
vector<vector<double> > from_ruby<vector<vector<double> > >(Object x) {
|
116
|
+
vector<vector<double> > matrix;
|
117
|
+
|
118
|
+
Array ruby_matrix(x);
|
119
|
+
|
120
|
+
for (unsigned int i = 0; i < ruby_matrix.size(); i++) {
|
121
|
+
vector<double> row;
|
122
|
+
Array ruby_row(ruby_matrix[i]);
|
123
|
+
|
124
|
+
for (unsigned int j = 0; j < ruby_row.size(); j++) {
|
125
|
+
double* value = (double*)(ruby_row[j].value());
|
126
|
+
row.push_back(*value);
|
127
|
+
}
|
128
|
+
|
129
|
+
matrix.push_back(row);
|
130
|
+
}
|
60
131
|
|
61
|
-
|
62
|
-
return Array();
|
132
|
+
return matrix;
|
63
133
|
}
|
64
134
|
|
135
|
+
/*------------------------*
|
136
|
+
* Rice class definitions *
|
137
|
+
*------------------------*/
|
138
|
+
|
65
139
|
extern "C" void Init_sirens() {
|
66
140
|
Module rb_mSirens = define_module("Sirens");
|
67
141
|
|
142
|
+
/*
|
143
|
+
The following are simple class implementations with Rice.
|
144
|
+
Nothing special. Just simple wrappers.
|
145
|
+
*/
|
146
|
+
|
68
147
|
Data_Type<Sound> rb_cSound =
|
69
148
|
define_class_under<Sound>(rb_mSirens, "Sound")
|
70
149
|
.define_constructor(Constructor<Sound>())
|
@@ -83,77 +162,131 @@ extern "C" void Init_sirens() {
|
|
83
162
|
.define_method("spectrumSize", &Sound::getSpectrumSize)
|
84
163
|
.define_method("path", &Sound::getPath)
|
85
164
|
.define_method("extractFeatures", &Sound::extractFeatures)
|
86
|
-
.define_method("
|
87
|
-
.define_method("
|
88
|
-
|
89
|
-
|
90
|
-
|
165
|
+
.define_method("features", &Sound::getFeatures)
|
166
|
+
.define_method("features=", &Sound::setFeatures);
|
167
|
+
|
168
|
+
Data_Type<FeatureSet> rb_cFeatureSet =
|
169
|
+
define_class_under<FeatureSet>(rb_mSirens, "FeatureSet")
|
170
|
+
.define_constructor(Constructor<FeatureSet>())
|
171
|
+
.define_method("sampleFeatures", &FeatureSet::getSampleFeatures)
|
172
|
+
.define_method("sampleFeatures=", &FeatureSet::setSampleFeatures)
|
173
|
+
.define_method("spectralFeatures", &FeatureSet::getSpectralFeatures)
|
174
|
+
.define_method("spectralFeatures=", &FeatureSet::setSpectralFeatures)
|
175
|
+
.define_method("features", &FeatureSet::getFeatures);
|
91
176
|
|
177
|
+
Data_Type<SegmentationParameters> rb_cSegmentationParameters =
|
178
|
+
define_class_under<SegmentationParameters>(rb_mSirens, "SegmentationParameters")
|
179
|
+
.define_method("pLagPlus", &SegmentationParameters::getPLagPlus)
|
180
|
+
.define_method("pLagPlus=", &SegmentationParameters::setPLagPlus)
|
181
|
+
.define_method("pLagMinus", &SegmentationParameters::getPLagMinus)
|
182
|
+
.define_method("pLagMinus=", &SegmentationParameters::setPLagMinus)
|
183
|
+
.define_method("alpha", &SegmentationParameters::getAlpha)
|
184
|
+
.define_method("alpha=", &SegmentationParameters::setAlpha)
|
185
|
+
.define_method("r", &SegmentationParameters::getR)
|
186
|
+
.define_method("r=", &SegmentationParameters::setR)
|
187
|
+
.define_method("cStayOff", &SegmentationParameters::getCStayOff)
|
188
|
+
.define_method("cStayOff=", &SegmentationParameters::setCStayOff)
|
189
|
+
.define_method("cStayOn", &SegmentationParameters::getCStayOn)
|
190
|
+
.define_method("cStayOn=", &SegmentationParameters::setCStayOn)
|
191
|
+
.define_method("cTurnOn", &SegmentationParameters::getCTurnOn)
|
192
|
+
.define_method("cTurnOn=", &SegmentationParameters::setCTurnOn)
|
193
|
+
.define_method("cTurningOn", &SegmentationParameters::getCTurningOn)
|
194
|
+
.define_method("cTurningOn=", &SegmentationParameters::setCTurningOn)
|
195
|
+
.define_method("cTurnOff", &SegmentationParameters::getCTurnOff)
|
196
|
+
.define_method("cTurnOff=", &SegmentationParameters::setCTurnOff)
|
197
|
+
.define_method("cNewSegment", &SegmentationParameters::getCNewSegment)
|
198
|
+
.define_method("cNewSegment=", &SegmentationParameters::setCNewSegment);
|
199
|
+
|
200
|
+
Data_Type<Segmenter> rb_cSegmenter =
|
201
|
+
define_class_under<Segmenter>(rb_mSirens, "Segmenter")
|
202
|
+
.define_constructor(Constructor<Segmenter>())
|
203
|
+
.define_method("pNew", &Segmenter::getPNew)
|
204
|
+
.define_method("pNew=", &Segmenter::setPNew)
|
205
|
+
.define_method("pOff", &Segmenter::getPOff)
|
206
|
+
.define_method("pOff=", &Segmenter::setPOff)
|
207
|
+
.define_method("beams", &Segmenter::getBeams)
|
208
|
+
.define_method("beams=", &Segmenter::setBeams)
|
209
|
+
.define_method("segment", &Segmenter::getSegments);
|
210
|
+
|
211
|
+
/*
|
212
|
+
FeatureBase is an unused base class that implements Feature. Feature is the
|
213
|
+
actual class that implements RiceFeature, the wrapper Feature class that
|
214
|
+
ensures Feature::segmentationParameters won't be garbage collected.
|
215
|
+
*/
|
216
|
+
|
92
217
|
Data_Type<Feature> rb_cFeature =
|
93
|
-
define_class_under<Feature>(rb_mSirens, "
|
218
|
+
define_class_under<Feature>(rb_mSirens, "FeatureBase")
|
94
219
|
.define_constructor(Constructor<Feature>())
|
95
220
|
.define_method("to_s", &Feature::toString)
|
96
221
|
.define_method("history", &Feature::getHistory)
|
97
222
|
.define_method("history[]", &Feature::getHistoryFrame)
|
98
223
|
.define_method("maxHistorySize", &Feature::getMaxHistorySize)
|
99
224
|
.define_method("maxHistorySize=", &Feature::setMaxHistorySize)
|
100
|
-
.define_method("value", &Feature::getValue)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
.
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
.
|
123
|
-
.define_method("
|
124
|
-
.define_method("
|
125
|
-
.define_method("
|
126
|
-
.define_method("
|
127
|
-
.define_method("
|
128
|
-
.define_method("
|
225
|
+
.define_method("value", &Feature::getValue)
|
226
|
+
.define_method("min", &Feature::getMin)
|
227
|
+
.define_method("min=", &Feature::setMin)
|
228
|
+
.define_method("max", &Feature::getMax)
|
229
|
+
.define_method("max=", &Feature::setMax);
|
230
|
+
|
231
|
+
Data_Type<RiceFeature> rb_cRiceFeature =
|
232
|
+
define_class_under<RiceFeature, Feature>(rb_mSirens, "Feature")
|
233
|
+
.define_method("segmentationParameters", &RiceFeature::getRiceSegmentationParameters);
|
234
|
+
|
235
|
+
/*
|
236
|
+
All the following features implement Rice[FeatueName] and inherit from RiceFeature.
|
237
|
+
Rice makes it necessary to re-implement all accessors, as it does not support
|
238
|
+
sending a pointer to a parent class's method for method implementations.
|
239
|
+
*/
|
240
|
+
|
241
|
+
Data_Type<RiceLoudness> rb_cLoudness =
|
242
|
+
define_class_under<RiceLoudness, RiceFeature>(rb_mSirens, "Loudness")
|
243
|
+
.define_constructor(Constructor<RiceLoudness>());
|
244
|
+
|
245
|
+
Data_Type<RiceHarmonicity> rb_cHarmonicity =
|
246
|
+
define_class_under<RiceHarmonicity, RiceFeature>(rb_mSirens, "Harmonicity")
|
247
|
+
.define_constructor(Constructor<RiceHarmonicity>())
|
248
|
+
.define_method("sampleRate", &RiceHarmonicity::getSampleRate)
|
249
|
+
.define_method("sampleRate=", &RiceHarmonicity::setSampleRate)
|
250
|
+
.define_method("spectrumSize", &RiceHarmonicity::getSpectrumSize)
|
251
|
+
.define_method("spectrumSize=", &RiceHarmonicity::setSpectrumSize)
|
252
|
+
.define_method("searchRegionLength", &RiceHarmonicity::getSearchRegionLength)
|
253
|
+
.define_method("searchRegionLength=", &RiceHarmonicity::setSearchRegionLength)
|
254
|
+
.define_method("absThreshold", &RiceHarmonicity::getAbsThreshold)
|
255
|
+
.define_method("absThreshold=", &RiceHarmonicity::setAbsThreshold)
|
256
|
+
.define_method("threshold", &RiceHarmonicity::getThreshold)
|
257
|
+
.define_method("threshold=", &RiceHarmonicity::setThreshold)
|
258
|
+
.define_method("lpfCoefficient", &RiceHarmonicity::getLPFCoefficient)
|
259
|
+
.define_method("lpfCoefficient=", &RiceHarmonicity::setLPFCoefficient)
|
260
|
+
.define_method("maxPeaks", &RiceHarmonicity::getMaxPeaks)
|
261
|
+
.define_method("maxPeaks=", &RiceHarmonicity::setMaxPeaks);
|
129
262
|
|
130
|
-
Data_Type<
|
131
|
-
define_class_under<
|
132
|
-
.define_constructor(Constructor<
|
133
|
-
.define_method("sampleRate", &
|
134
|
-
.define_method("sampleRate=", &
|
135
|
-
.define_method("spectrumSize", &
|
136
|
-
.define_method("spectrumSize=", &
|
137
|
-
.define_method("filters", &
|
138
|
-
.define_method("filters=", &
|
139
|
-
.define_method("mels", &
|
140
|
-
.define_method("mels=", &
|
263
|
+
Data_Type<RiceTransientIndex> rb_cTransientIndex =
|
264
|
+
define_class_under<RiceTransientIndex, RiceFeature>(rb_mSirens, "TransientIndex")
|
265
|
+
.define_constructor(Constructor<RiceTransientIndex>())
|
266
|
+
.define_method("sampleRate", &RiceTransientIndex::getSampleRate)
|
267
|
+
.define_method("sampleRate=", &RiceTransientIndex::setSampleRate)
|
268
|
+
.define_method("spectrumSize", &RiceTransientIndex::getSpectrumSize)
|
269
|
+
.define_method("spectrumSize=", &RiceTransientIndex::setSpectrumSize)
|
270
|
+
.define_method("filters", &RiceTransientIndex::getFilters)
|
271
|
+
.define_method("filters=", &RiceTransientIndex::setFilters)
|
272
|
+
.define_method("mels", &RiceTransientIndex::getMels)
|
273
|
+
.define_method("mels=", &RiceTransientIndex::setMels);
|
141
274
|
|
142
|
-
Data_Type<
|
143
|
-
define_class_under<
|
144
|
-
.define_constructor(Constructor<
|
145
|
-
.define_method("sampleRate", &
|
146
|
-
.define_method("sampleRate=", &
|
147
|
-
.define_method("spectrumSize", &
|
148
|
-
.define_method("spectrumSize=", &
|
275
|
+
Data_Type<RiceSpectralCentroid> rb_cSpectralCentroid =
|
276
|
+
define_class_under<RiceSpectralCentroid, RiceFeature>(rb_mSirens, "SpectralCentroid")
|
277
|
+
.define_constructor(Constructor<RiceSpectralCentroid>())
|
278
|
+
.define_method("sampleRate", &RiceSpectralCentroid::getSampleRate)
|
279
|
+
.define_method("sampleRate=", &RiceSpectralCentroid::setSampleRate)
|
280
|
+
.define_method("spectrumSize", &RiceSpectralCentroid::getSpectrumSize)
|
281
|
+
.define_method("spectrumSize=", &RiceSpectralCentroid::setSpectrumSize);
|
149
282
|
|
150
|
-
Data_Type<
|
151
|
-
define_class_under<
|
152
|
-
.define_constructor(Constructor<
|
283
|
+
Data_Type<RiceSpectralSparsity> rb_cSpectralSparsity =
|
284
|
+
define_class_under<RiceSpectralSparsity, RiceFeature>(rb_mSirens, "SpectralSparsity")
|
285
|
+
.define_constructor(Constructor<RiceSpectralSparsity>());
|
153
286
|
|
154
|
-
Data_Type<
|
155
|
-
define_class_under<
|
156
|
-
.define_constructor(Constructor<
|
157
|
-
.define_method("windowSize", &
|
158
|
-
.define_method("windowSize=", &
|
287
|
+
Data_Type<RiceTemporalSparsity> rb_cTemporalSparsity =
|
288
|
+
define_class_under<RiceTemporalSparsity, RiceFeature>(rb_mSirens, "TemporalSparsity")
|
289
|
+
.define_constructor(Constructor<RiceTemporalSparsity>())
|
290
|
+
.define_method("windowSize", &RiceTemporalSparsity::getWindowSize)
|
291
|
+
.define_method("windowSize=", &RiceTemporalSparsity::setWindowSize);
|
159
292
|
}
|
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.
|
5
|
+
s.version = "0.2.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-
|
9
|
+
s.date = %q{2009-08-24}
|
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,16 +19,14 @@ Gem::Specification.new do |s|
|
|
19
19
|
"README.markdown",
|
20
20
|
"Rakefile",
|
21
21
|
"VERSION",
|
22
|
+
"examples/segmentation.rb",
|
22
23
|
"examples/sound.wav",
|
23
24
|
"examples/three_features.rb",
|
24
25
|
"ext/sirens/extconf.rb",
|
25
26
|
"ext/sirens/extconf.rb",
|
26
27
|
"ext/sirens/sirens.cpp",
|
27
28
|
"ext/sirens/sirens.cpp",
|
28
|
-
"sirens.gemspec"
|
29
|
-
"test/sirens/sirens_test.rb",
|
30
|
-
"test/sirens/test.wav",
|
31
|
-
"test/sirens/test_helper.rb"
|
29
|
+
"sirens.gemspec"
|
32
30
|
]
|
33
31
|
s.homepage = %q{http://github.com/plant/sirens-ruby}
|
34
32
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -36,8 +34,7 @@ Gem::Specification.new do |s|
|
|
36
34
|
s.rubygems_version = %q{1.3.3}
|
37
35
|
s.summary = %q{Ruby gem that for the Sirens library.}
|
38
36
|
s.test_files = [
|
39
|
-
"
|
40
|
-
"test/sirens/test_helper.rb",
|
37
|
+
"examples/segmentation.rb",
|
41
38
|
"examples/three_features.rb"
|
42
39
|
]
|
43
40
|
|
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.
|
4
|
+
version: 0.2.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-
|
12
|
+
date: 2009-08-24 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -36,16 +36,15 @@ files:
|
|
36
36
|
- README.markdown
|
37
37
|
- Rakefile
|
38
38
|
- VERSION
|
39
|
+
- examples/segmentation.rb
|
39
40
|
- examples/sound.wav
|
40
41
|
- examples/three_features.rb
|
41
42
|
- ext/sirens/extconf.rb
|
42
43
|
- ext/sirens/sirens.cpp
|
43
44
|
- sirens.gemspec
|
44
|
-
- test/sirens/sirens_test.rb
|
45
|
-
- test/sirens/test.wav
|
46
|
-
- test/sirens/test_helper.rb
|
47
45
|
has_rdoc: false
|
48
46
|
homepage: http://github.com/plant/sirens-ruby
|
47
|
+
licenses:
|
49
48
|
post_install_message:
|
50
49
|
rdoc_options:
|
51
50
|
- --charset=UTF-8
|
@@ -66,11 +65,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
65
|
requirements: []
|
67
66
|
|
68
67
|
rubyforge_project:
|
69
|
-
rubygems_version: 1.
|
68
|
+
rubygems_version: 1.3.5
|
70
69
|
signing_key:
|
71
70
|
specification_version: 3
|
72
71
|
summary: Ruby gem that for the Sirens library.
|
73
72
|
test_files:
|
74
|
-
-
|
75
|
-
- test/sirens/test_helper.rb
|
73
|
+
- examples/segmentation.rb
|
76
74
|
- examples/three_features.rb
|
data/test/sirens/sirens_test.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sirens'
|
3
|
-
|
4
|
-
s = Sirens::Sound.new
|
5
|
-
s.frameLength = 0.04
|
6
|
-
s.hopLength = 0.02
|
7
|
-
s.open 'test/sirens/test.wav'
|
8
|
-
|
9
|
-
print "\n", s
|
10
|
-
print "\n\tPath: ", s.path
|
11
|
-
print "\n\tSamples: ", s.samples
|
12
|
-
print "\n\tSample rate: ", s.sampleRate
|
13
|
-
print "\n\tFrame length: ", s.frameLength, "s (", s.samplesPerFrame, " samples)"
|
14
|
-
print "\n\tHop length: ", s.hopLength, "s (", s.samplesPerHop, " samples)"
|
15
|
-
print "\n\tFFT Size: ", s.fftSize
|
16
|
-
print "\n\tSpectrum size: ", s.spectrumSize
|
17
|
-
print "\n\n"
|
18
|
-
|
19
|
-
loudness = Sirens::LoudnessFeature.new
|
20
|
-
temporal_sparsity = Sirens::TemporalSparsityFeature.new
|
21
|
-
spectral_sparsity = Sirens::SpectralSparsityFeature.new
|
22
|
-
spectral_centroid = Sirens::SpectralCentroidFeature.new
|
23
|
-
|
24
|
-
harmonicity = Sirens::HarmonicityFeature.new
|
25
|
-
harmonicity.absThreshold = 1
|
26
|
-
harmonicity.threshold = 0.1
|
27
|
-
harmonicity.searchRegionLength = 5
|
28
|
-
harmonicity.maxPeaks = 3
|
29
|
-
harmonicity.lpfCoefficient = 0.7
|
30
|
-
|
31
|
-
transient_index = Sirens::TransientIndexFeature.new
|
32
|
-
transient_index.mels = 15
|
33
|
-
transient_index.filters = 30
|
34
|
-
|
35
|
-
Array[loudness, temporal_sparsity, spectral_sparsity, spectral_centroid, harmonicity, transient_index].each do |feature|
|
36
|
-
feature.historySize = s.frames
|
37
|
-
end
|
38
|
-
|
39
|
-
Array[spectral_centroid, harmonicity, transient_index].each do |feature|
|
40
|
-
feature.sampleRate = s.sampleRate
|
41
|
-
feature.spectrumSize = s.spectrumSize
|
42
|
-
end
|
43
|
-
|
44
|
-
s.sampleFeatures = Array[loudness, temporal_sparsity]
|
45
|
-
s.spectralFeatures = Array[spectral_sparsity, spectral_centroid, transient_index, harmonicity]
|
46
|
-
|
47
|
-
t1 = Time.new
|
48
|
-
|
49
|
-
s.extractFeatures
|
50
|
-
|
51
|
-
t2 = Time.new
|
52
|
-
|
53
|
-
print 'Elapsed time: ', (t2 - t1), "\n\n"
|
54
|
-
|
55
|
-
histories = Array[loudness.history, temporal_sparsity.history, spectral_sparsity.history,
|
56
|
-
spectral_centroid.history, transient_index.history, harmonicity.history]
|
57
|
-
|
58
|
-
file = File.new("test/sirens/features.csv", File::CREAT|File::RDWR, 0644)
|
59
|
-
for i in 0..s.frames - 1
|
60
|
-
for j in 0..histories.size - 1
|
61
|
-
file.write(histories[j][i])
|
62
|
-
file.write(',') if i < histories.size - 1
|
63
|
-
end
|
64
|
-
|
65
|
-
file.write("\n")
|
66
|
-
end
|
67
|
-
|
data/test/sirens/test.wav
DELETED
Binary file
|
data/test/sirens/test_helper.rb
DELETED