Class: SPCore::Signal
- Inherits:
-
Object
- Object
- SPCore::Signal
- Includes:
- Hashmake::HashMakeable
- Defined in:
- lib/spcore/analysis/signal.rb
Overview
Constant Summary collapse
- ARG_SPECS =
Used to process hashed arguments in #initialize.
{ :data => arg_spec(:reqd => true, :type => Array, :validator => ->(a){ a.any? }), :sample_rate => arg_spec(:reqd => true, :type => Fixnum, :validator => ->(a){ a > 0.0 }) }
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#sample_rate ⇒ Object
readonly
Returns the value of attribute sample_rate.
Instance Method Summary collapse
-
#[](arg) ⇒ Object
Access signal data.
-
#abs ⇒ Object
Operate on copy of the Signal object with the absolute value function.
-
#abs! ⇒ Object
Operate on the signal data (in place) with the absolute value function.
-
#add(other) ⇒ Object
(also: #+)
Add value, values in array, or values in other signal to the current data values, and return a new Signal object with the results.
-
#add!(other) ⇒ Object
Add value, values in array, or values in other signal to the current data values, and update the current data with the results.
-
#append(other) ⇒ Object
Add data in array or other signal to the end of current data.
-
#append!(other) ⇒ Object
Add data in array or other signal to the end of current data.
-
#bandpass(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandpass filter over the signal data (using DualSincFilter).
-
#bandpass!(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandpass filter over the signal data (using DualSincFilter).
-
#bandstop(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandstop filter over the signal data (using DualSincFilter).
-
#bandstop!(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandstop filter over the signal data (using DualSincFilter).
-
#clone ⇒ Object
Produce a new Signal object with the same data.
-
#count ⇒ Object
Size of the signal data.
-
#cross_correlation(other_signal, normalize = true) ⇒ Object
Determine how well the another signal (g) correlates to the current signal (f).
-
#derivative ⇒ Object
Differentiates the signal data.
-
#divide(other) ⇒ Object
(also: #/)
Divide value, values in array, or values in other signal into the current data values, and return a new Signal object with the results.
-
#divide!(other) ⇒ Object
Divide value, values in array, or values in other signal into the current data values, and update the current data with the results.
-
#downsample_discrete(downsample_factor, filter_order) ⇒ Object
Decrease the sample rate of signal data by the given factor using discrete downsampling method.
-
#downsample_discrete!(downsample_factor, filter_order) ⇒ Object
Decrease the sample rate of signal data by the given factor using discrete downsampling method.
-
#duration ⇒ Object
Signal duration in seconds.
-
#energy ⇒ Object
Calculate the energy in current signal data.
-
#envelope ⇒ Object
Determine the envelope of the current Signal and return either a Envelope or a new Signal object as a result.
-
#extrema ⇒ Object
Find extrema (maxima, minima) within signal data.
-
#freq_magnitudes(convert_to_db = false) ⇒ Hash
Run FFT on signal data to find magnitude of frequency components.
-
#highpass(cutoff_freq, order) ⇒ Object
Run a discrete highpass filter over the signal data (using SincFilter).
-
#highpass!(cutoff_freq, order) ⇒ Object
Run a discrete highpass filter over the signal data (using SincFilter).
-
#initialize(hashed_args) ⇒ Signal
constructor
A new instance of Signal.
-
#keep_frequencies(freq_range) ⇒ Object
Removes all but the given range of frequencies from the signal, using frequency domain filtering.
-
#keep_frequencies!(freq_range) ⇒ Object
Removes all but the given range of frequencies from the signal, using frequency domain filtering.
-
#lowpass(cutoff_freq, order) ⇒ Object
Run a discrete lowpass filter over the signal data (using SincFilter).
-
#lowpass!(cutoff_freq, order) ⇒ Object
Run a discrete lowpass filter over the signal data (using SincFilter).
-
#mean ⇒ Object
Compute the mean of signal data.
-
#multiply(other) ⇒ Object
(also: #*)
Multiply value, values in array, or values in other signal with the current data values, and return a new Signal object with the results.
-
#multiply!(other) ⇒ Object
Multiply value, values in array, or values in other signal with the current data values, and update the current data with the results.
-
#normalize(level = 1.0) ⇒ Object
reduce all samples to.
- #normalize!(level = 1.0) ⇒ Object
-
#plot_1d ⇒ Object
Plot the signal data against sample numbers.
-
#plot_2d ⇒ Object
Plot the signal data against time.
-
#prepend(other) ⇒ Object
Add data in array or other signal to the beginning of current data.
-
#prepend!(other) ⇒ Object
Add data in array or other signal to the beginning of current data.
-
#remove_frequencies(freq_range) ⇒ Object
Removes the given range of frequencies from the signal, using frequency domain filtering.
-
#remove_frequencies!(freq_range) ⇒ Object
Removes all but the given range of frequencies from the signal, using frequency domain filtering.
-
#resample_discrete(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using discrete upsampling and downsampling methods.
-
#resample_discrete!(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using discrete upsampling and downsampling methods.
-
#resample_hybrid(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using polynomial upsampling and discrete downsampling.
-
#resample_hybrid!(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using polynomial upsampling and discrete downsampling.
-
#rms ⇒ Object
Calculate signal RMS (root-mean square), also known as quadratic mean, a statistical measure of the magnitude.
-
#size ⇒ Object
Size of the signal data.
-
#subset(range) ⇒ Object
Produce a new Signal object with a subset of the current signal data.
-
#subtract(other) ⇒ Object
(also: #-)
Subtract value, values in array, or values in other signal from the current data values, and return a new Signal object with the results.
-
#subtract!(other) ⇒ Object
Subtract value, values in array, or values in other signal from the current data values, and update the current data with the results.
-
#upsample_discrete(upsample_factor, filter_order) ⇒ Object
Increase the sample rate of signal data by the given factor using discrete upsampling method.
-
#upsample_discrete!(upsample_factor, filter_order) ⇒ Object
Increase the sample rate of signal data by the given factor using discrete upsampling method.
-
#upsample_polynomial(upsample_factor) ⇒ Object
Increase the sample rate of signal data by the given factor using polynomial interpolation.
-
#upsample_polynomial!(upsample_factor) ⇒ Object
Increase the sample rate of signal data by the given factor using polynomial interpolation.
Constructor Details
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
15 16 17 |
# File 'lib/spcore/analysis/signal.rb', line 15 def data @data end |
#sample_rate ⇒ Object (readonly)
Returns the value of attribute sample_rate.
15 16 17 |
# File 'lib/spcore/analysis/signal.rb', line 15 def sample_rate @sample_rate end |
Instance Method Details
#[](arg) ⇒ Object
Access signal data.
52 53 54 |
# File 'lib/spcore/analysis/signal.rb', line 52 def [](arg) @data[arg] end |
#abs ⇒ Object
Operate on copy of the Signal object with the absolute value function.
287 288 289 |
# File 'lib/spcore/analysis/signal.rb', line 287 def abs self.clone.abs! end |
#abs! ⇒ Object
Operate on the signal data (in place) with the absolute value function.
281 282 283 284 |
# File 'lib/spcore/analysis/signal.rb', line 281 def abs! @data = @data.map {|x| x.abs } return self end |
#add(other) ⇒ Object Also known as: +
Add value, values in array, or values in other signal to the current data values, and return a new Signal object with the results.
365 366 367 |
# File 'lib/spcore/analysis/signal.rb', line 365 def add(other) clone.add! other end |
#add!(other) ⇒ Object
Add value, values in array, or values in other signal to the current data values, and update the current data with the results.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/spcore/analysis/signal.rb', line 341 def add!(other) if other.is_a?(Numeric) @data.each_index do |i| @data[i] += other end elsif other.is_a?(Signal) raise ArgumentError, "other.data.size #{other.size} is not equal to data.size #{@data.size}" if other.data.size != @data.size @data.each_index do |i| @data[i] += other.data[i] end elsif other.is_a?(Array) raise ArgumentError, "other.size #{other.size} is not equal to data.size #{@data.size}" if other.size != @data.size @data.each_index do |i| @data[i] += other[i] end else raise ArgumentError, "other is not a Numeric, Signal, or Array" end return self end |
#append(other) ⇒ Object
Add data in array or other signal to the end of current data.
334 335 336 |
# File 'lib/spcore/analysis/signal.rb', line 334 def append other clone.append! other end |
#append!(other) ⇒ Object
Add data in array or other signal to the end of current data.
324 325 326 327 328 329 330 331 |
# File 'lib/spcore/analysis/signal.rb', line 324 def append! other if other.is_a?(Array) @data = @data.concat other elsif other.is_a?(Signal) @data = @data.concat other.data end return self end |
#bandpass(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandpass filter over the signal data (using DualSincFilter). Return result in a new Signal object.
118 119 120 |
# File 'lib/spcore/analysis/signal.rb', line 118 def bandpass left_cutoff, right_cutoff, order self.clone.bandpass! left_cutoff, right_cutoff, order end |
#bandpass!(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandpass filter over the signal data (using DualSincFilter). Modifies current object.
105 106 107 108 109 110 111 112 113 114 |
# File 'lib/spcore/analysis/signal.rb', line 105 def bandpass! left_cutoff, right_cutoff, order filter = DualSincFilter.new( :sample_rate => @sample_rate, :order => order, :left_cutoff_freq => left_cutoff, :right_cutoff_freq => right_cutoff ) @data = filter.bandpass(@data) return self end |
#bandstop(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandstop filter over the signal data (using DualSincFilter). Return result in a new Signal object.
137 138 139 |
# File 'lib/spcore/analysis/signal.rb', line 137 def bandstop left_cutoff, right_cutoff, order self.clone.bandstop! left_cutoff, right_cutoff, order end |
#bandstop!(left_cutoff, right_cutoff, order) ⇒ Object
Run a discrete bandstop filter over the signal data (using DualSincFilter). Modifies current object.
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/spcore/analysis/signal.rb', line 124 def bandstop! left_cutoff, right_cutoff, order filter = DualSincFilter.new( :sample_rate => @sample_rate, :order => order, :left_cutoff_freq => left_cutoff, :right_cutoff_freq => right_cutoff ) @data = filter.bandstop(@data) return self end |
#clone ⇒ Object
Produce a new Signal object with the same data.
26 27 28 |
# File 'lib/spcore/analysis/signal.rb', line 26 def clone Signal.new(:data => @data.clone, :sample_rate => @sample_rate) end |
#count ⇒ Object
Size of the signal data.
42 43 44 |
# File 'lib/spcore/analysis/signal.rb', line 42 def count @data.size end |
#cross_correlation(other_signal, normalize = true) ⇒ Object
Determine how well the another signal (g) correlates to the current signal (f). Correlation is determined at every point in f. The signal g must not be longer than f. Correlation involves moving g along f and performing convolution. Starting a the beginning of f, it continues until the end of g hits the end of f. Doesn’t actually convolve, though. Instead, it adds
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
# File 'lib/spcore/analysis/signal.rb', line 484 def cross_correlation other_signal, normalize = true if other_signal.is_a? Signal other_data = other_signal.data elsif other_signal.is_a? Array other_data = other_signal else raise ArgumentError, "other_signal is not a Signal or Array" end f = @data g = other_data raise ArgumentError, "g.count #{g.count} is greater than f.count #{f.count}" if g.count > f.count g_size = g.count f_size = f.count f_g_diff = f_size - g_size cross_correlation = [] if normalize max = (f.max_by {|x| x.abs }).abs.to_f f = f.clone g = g.clone f.each_index {|i| f[i] = f[i] / max } g.each_index {|i| g[i] = g[i] / max } end #puts "f: #{f.inspect}" #puts "g: #{g.inspect}" for n in 0..f_g_diff do f_window = (n...(n + g_size)).entries g_window = (0...g_size).entries sample = 0.0 for i in 0...f_window.count do i_f = f_window[i] i_g = g_window[i] #if use_relative_error target = g[i_g].to_f actual = f[i_f] #if target == 0.0 && actual != 0.0 && normalize # puts "target is #{target} and actual is #{actual}" # error = 1.0 #else error = (target - actual).abs# / target #end sample += error #else # sample += (f[i_f] * g[i_g]) #end end cross_correlation << (sample)# / g_size.to_f) end return cross_correlation end |
#derivative ⇒ Object
Differentiates the signal data.
553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/spcore/analysis/signal.rb', line 553 def derivative raise "Signal does not have at least 2 samples" unless @data.size > 2 derivative = Array.new(@data.size) sample_period = 1.0 / @sample_rate for i in 1...@data.count derivative[i] = (@data[i] - @data[i-1]) / sample_period end derivative[0] = derivative[1] return Signal.new(:sample_rate => @sample_rate, :data => derivative) end |
#divide(other) ⇒ Object Also known as: /
Divide value, values in array, or values in other signal into the current data values, and return a new Signal object with the results.
462 463 464 |
# File 'lib/spcore/analysis/signal.rb', line 462 def divide(other) clone.divide! other end |
#divide!(other) ⇒ Object
Divide value, values in array, or values in other signal into the current data values, and update the current data with the results.
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/spcore/analysis/signal.rb', line 437 def divide!(other) if other.is_a?(Numeric) @data.each_index do |i| @data[i] /= other end elsif other.is_a?(Signal) raise ArgumentError, "other.data.size #{other.size} is not equal to data.size #{@data.size}" if other.data.size != @data.size @data.each_index do |i| @data[i] /= other.data[i] end elsif other.is_a?(Array) raise ArgumentError, "other.size #{other.size} is not equal to data.size #{@data.size}" if other.size != @data.size @data.each_index do |i| @data[i] /= other[i] end else raise ArgumentError, "other is not a Numeric, Signal, or Array" end return self end |
#downsample_discrete(downsample_factor, filter_order) ⇒ Object
Decrease the sample rate of signal data by the given factor using discrete downsampling method. Return result in a new Signal object.
173 174 175 |
# File 'lib/spcore/analysis/signal.rb', line 173 def downsample_discrete downsample_factor, filter_order return self.clone.downsample_discrete!(downsample_factor, filter_order) end |
#downsample_discrete!(downsample_factor, filter_order) ⇒ Object
Decrease the sample rate of signal data by the given factor using discrete downsampling method. Modifies current object.
163 164 165 166 167 |
# File 'lib/spcore/analysis/signal.rb', line 163 def downsample_discrete! downsample_factor, filter_order @data = DiscreteResampling.downsample @data, @sample_rate, downsample_factor, filter_order @sample_rate /= downsample_factor return self end |
#duration ⇒ Object
Signal duration in seconds.
47 48 49 |
# File 'lib/spcore/analysis/signal.rb', line 47 def duration return @data.size.to_f / @sample_rate end |
#energy ⇒ Object
Calculate the energy in current signal data.
259 260 261 |
# File 'lib/spcore/analysis/signal.rb', line 259 def energy return @data.inject(0.0){|sum,x| sum + (x * x)} end |
#envelope ⇒ Object
Determine the envelope of the current Signal and return either a Envelope or a new Signal object as a result.
304 305 306 |
# File 'lib/spcore/analysis/signal.rb', line 304 def envelope Signal.new(:sample_rate => @sample_rate, :data => Envelope.new(@data).data) end |
#extrema ⇒ Object
Find extrema (maxima, minima) within signal data.
276 277 278 |
# File 'lib/spcore/analysis/signal.rb', line 276 def extrema return Extrema.new(@data) end |
#freq_magnitudes(convert_to_db = false) ⇒ Hash
Run FFT on signal data to find magnitude of frequency components.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/spcore/analysis/signal.rb', line 238 def freq_magnitudes convert_to_db = false fft_output = FFT.forward @data fft_output = fft_output[0...(fft_output.size / 2)] # ignore second half fft_output = fft_output.map {|x| x.magnitude } # map complex value to magnitude if convert_to_db fft_output = fft_output.map {|x| Gain.linear_to_db x} end freq_magnitudes = {} fft_output.each_index do |i| size = fft_output.size * 2 # mul by 2 because the second half of original fft_output was removed freq = (@sample_rate * i) / size freq_magnitudes[freq] = fft_output[i] end return freq_magnitudes end |
#highpass(cutoff_freq, order) ⇒ Object
Run a discrete highpass filter over the signal data (using SincFilter). Return result in a new Signal object.
99 100 101 |
# File 'lib/spcore/analysis/signal.rb', line 99 def highpass cutoff_freq, order self.clone.highpass! cutoff_freq, order end |
#highpass!(cutoff_freq, order) ⇒ Object
Run a discrete highpass filter over the signal data (using SincFilter). Modifies current object.
91 92 93 94 95 |
# File 'lib/spcore/analysis/signal.rb', line 91 def highpass! cutoff_freq, order filter = SincFilter.new(:sample_rate => @sample_rate, :order => order, :cutoff_freq => cutoff_freq) @data = filter.highpass(@data) return self end |
#keep_frequencies(freq_range) ⇒ Object
Removes all but the given range of frequencies from the signal, using frequency domain filtering. Modifes a clone of the current object, returning the clone.
590 591 592 |
# File 'lib/spcore/analysis/signal.rb', line 590 def keep_frequencies freq_range return self.clone.keep_frequencies!(freq_range) end |
#keep_frequencies!(freq_range) ⇒ Object
Removes all but the given range of frequencies from the signal, using frequency domain filtering. Modifes and returns the current object.
583 584 585 |
# File 'lib/spcore/analysis/signal.rb', line 583 def keep_frequencies! freq_range modify_freq_content freq_range, :keep end |
#lowpass(cutoff_freq, order) ⇒ Object
Run a discrete lowpass filter over the signal data (using SincFilter). Return result in a new Signal object.
85 86 87 |
# File 'lib/spcore/analysis/signal.rb', line 85 def lowpass cutoff_freq, order self.clone.lowpass! cutoff_freq, order end |
#lowpass!(cutoff_freq, order) ⇒ Object
Run a discrete lowpass filter over the signal data (using SincFilter). Modifies current object.
77 78 79 80 81 |
# File 'lib/spcore/analysis/signal.rb', line 77 def lowpass! cutoff_freq, order filter = SincFilter.new(:sample_rate => @sample_rate, :order => order, :cutoff_freq => cutoff_freq) @data = filter.lowpass(@data) return self end |
#mean ⇒ Object
Compute the mean of signal data.
270 271 272 273 |
# File 'lib/spcore/analysis/signal.rb', line 270 def mean sum = @data.inject(0){ |s, x| s + x } return sum.to_f / size end |
#multiply(other) ⇒ Object Also known as: *
Multiply value, values in array, or values in other signal with the current data values, and return a new Signal object with the results.
429 430 431 |
# File 'lib/spcore/analysis/signal.rb', line 429 def multiply(other) clone.multiply! other end |
#multiply!(other) ⇒ Object
Multiply value, values in array, or values in other signal with the current data values, and update the current data with the results.
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'lib/spcore/analysis/signal.rb', line 404 def multiply!(other) if other.is_a?(Numeric) @data.each_index do |i| @data[i] *= other end elsif other.is_a?(Signal) raise ArgumentError, "other.data.size #{other.size} is not equal to data.size #{@data.size}" if other.data.size != @data.size @data.each_index do |i| @data[i] *= other.data[i] end elsif other.is_a?(Array) raise ArgumentError, "other.size #{other.size} is not equal to data.size #{@data.size}" if other.size != @data.size @data.each_index do |i| @data[i] *= other[i] end else raise ArgumentError, "other is not a Numeric, Signal, or Array" end return self end |
#normalize(level = 1.0) ⇒ Object
reduce all samples to
296 297 298 |
# File 'lib/spcore/analysis/signal.rb', line 296 def normalize level = 1.0 self.clone.normalize! level end |
#normalize!(level = 1.0) ⇒ Object
291 292 293 |
# File 'lib/spcore/analysis/signal.rb', line 291 def normalize! level = 1.0 self.divide!(@data.max / level) end |
#plot_1d ⇒ Object
Plot the signal data against sample numbers.
57 58 59 60 |
# File 'lib/spcore/analysis/signal.rb', line 57 def plot_1d plotter = Plotter.new(:title => "Signal: values vs. sample number", :xtitle => "sample number", :ytitle => "sample value") plotter.plot_1d "signal data" => @data end |
#plot_2d ⇒ Object
Plot the signal data against time.
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/spcore/analysis/signal.rb', line 63 def plot_2d plotter = Plotter.new(:title => "Signal: values vs. time", :xtitle => "time (sec)", :ytitle => "sample value") data_vs_time = {} sp = 1.0 / @sample_rate @data.each_index do |i| data_vs_time[i * sp] = @data[i] end plotter.plot_2d "signal data" => data_vs_time end |
#prepend(other) ⇒ Object
Add data in array or other signal to the beginning of current data.
319 320 321 |
# File 'lib/spcore/analysis/signal.rb', line 319 def prepend other clone.prepend! other end |
#prepend!(other) ⇒ Object
Add data in array or other signal to the beginning of current data.
309 310 311 312 313 314 315 316 |
# File 'lib/spcore/analysis/signal.rb', line 309 def prepend! other if other.is_a?(Array) @data = other.concat @data elsif other.is_a?(Signal) @data = other.data.concat @data end return self end |
#remove_frequencies(freq_range) ⇒ Object
Removes the given range of frequencies from the signal, using frequency domain filtering. Modifes a clone of the current object, returning the clone.
577 578 579 |
# File 'lib/spcore/analysis/signal.rb', line 577 def remove_frequencies freq_range return self.clone.remove_frequencies!(freq_range) end |
#remove_frequencies!(freq_range) ⇒ Object
Removes all but the given range of frequencies from the signal, using frequency domain filtering. Modifes and returns the current object.
570 571 572 |
# File 'lib/spcore/analysis/signal.rb', line 570 def remove_frequencies! freq_range modify_freq_content freq_range, :remove end |
#resample_discrete(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using discrete upsampling and downsampling methods. Return result in a new Signal object.
194 195 196 |
# File 'lib/spcore/analysis/signal.rb', line 194 def resample_discrete upsample_factor, downsample_factor, filter_order return self.clone.resample_discrete!(upsample_factor, downsample_factor, filter_order) end |
#resample_discrete!(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using discrete upsampling and downsampling methods. Modifies current object.
182 183 184 185 186 187 |
# File 'lib/spcore/analysis/signal.rb', line 182 def resample_discrete! upsample_factor, downsample_factor, filter_order @data = DiscreteResampling.resample @data, @sample_rate, upsample_factor, downsample_factor, filter_order @sample_rate *= upsample_factor @sample_rate /= downsample_factor return self end |
#resample_hybrid(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using polynomial upsampling and discrete downsampling. Return result as a new Signal object.
231 232 233 |
# File 'lib/spcore/analysis/signal.rb', line 231 def resample_hybrid upsample_factor, downsample_factor, filter_order return self.clone.resample_hybrid!(upsample_factor, downsample_factor, filter_order) end |
#resample_hybrid!(upsample_factor, downsample_factor, filter_order) ⇒ Object
Change the sample rate of signal data by the given up/down factors, using polynomial upsampling and discrete downsampling. Modifies current Signal object.
219 220 221 222 223 224 |
# File 'lib/spcore/analysis/signal.rb', line 219 def resample_hybrid! upsample_factor, downsample_factor, filter_order @data = HybridResampling.resample @data, @sample_rate, upsample_factor, downsample_factor, filter_order @sample_rate *= upsample_factor @sample_rate /= downsample_factor return self end |
#rms ⇒ Object
Calculate signal RMS (root-mean square), also known as quadratic mean, a statistical measure of the magnitude.
265 266 267 |
# File 'lib/spcore/analysis/signal.rb', line 265 def rms Math.sqrt(energy / size) end |
#size ⇒ Object
Size of the signal data.
37 38 39 |
# File 'lib/spcore/analysis/signal.rb', line 37 def size @data.size end |
#subset(range) ⇒ Object
Produce a new Signal object with a subset of the current signal data.
32 33 34 |
# File 'lib/spcore/analysis/signal.rb', line 32 def subset range Signal.new(:data => @data[range], :sample_rate => @sample_rate) end |
#subtract(other) ⇒ Object Also known as: -
Subtract value, values in array, or values in other signal from the current data values, and return a new Signal object with the results.
396 397 398 |
# File 'lib/spcore/analysis/signal.rb', line 396 def subtract(other) clone.subtract! other end |
#subtract!(other) ⇒ Object
Subtract value, values in array, or values in other signal from the current data values, and update the current data with the results.
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/spcore/analysis/signal.rb', line 372 def subtract!(other) if other.is_a?(Numeric) @data.each_index do |i| @data[i] -= other end elsif other.is_a?(Signal) raise ArgumentError, "other.data.size #{other.size} is not equal to data.size #{@data.size}" if other.data.size != @data.size @data.each_index do |i| @data[i] -= other.data[i] end elsif other.is_a?(Array) raise ArgumentError, "other.size #{other.size} is not equal to data.size #{@data.size}" if other.size != @data.size @data.each_index do |i| @data[i] -= other[i] end else raise ArgumentError, "other is not a Numeric, Signal, or Array" end return self end |
#upsample_discrete(upsample_factor, filter_order) ⇒ Object
Increase the sample rate of signal data by the given factor using discrete upsampling method. Return result in a new Signal object.
155 156 157 |
# File 'lib/spcore/analysis/signal.rb', line 155 def upsample_discrete upsample_factor, filter_order return self.clone.upsample_discrete!(upsample_factor, filter_order) end |
#upsample_discrete!(upsample_factor, filter_order) ⇒ Object
Increase the sample rate of signal data by the given factor using discrete upsampling method. Modifies current object.
145 146 147 148 149 |
# File 'lib/spcore/analysis/signal.rb', line 145 def upsample_discrete! upsample_factor, filter_order @data = DiscreteResampling.upsample @data, @sample_rate, upsample_factor, filter_order @sample_rate *= upsample_factor return self end |
#upsample_polynomial(upsample_factor) ⇒ Object
Increase the sample rate of signal data by the given factor using polynomial interpolation. Returns result as a new Signal object.
210 211 212 |
# File 'lib/spcore/analysis/signal.rb', line 210 def upsample_polynomial upsample_factor return self.clone.upsample_polynomial!(upsample_factor) end |
#upsample_polynomial!(upsample_factor) ⇒ Object
Increase the sample rate of signal data by the given factor using polynomial interpolation. Modifies current Signal object.
201 202 203 204 205 |
# File 'lib/spcore/analysis/signal.rb', line 201 def upsample_polynomial! upsample_factor @data = PolynomialResampling.upsample @data, upsample_factor @sample_rate *= upsample_factor return self end |