Class: SPCore::Envelope
- Inherits:
-
Object
- Object
- SPCore::Envelope
- Defined in:
- lib/spcore/analysis/envelope.rb
Overview
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
Instance Method Summary collapse
-
#initialize(samples) ⇒ Envelope
constructor
A new instance of Envelope.
Constructor Details
#initialize(samples) ⇒ Envelope
Returns a new instance of Envelope.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/spcore/analysis/envelope.rb', line 11 def initialize samples # combine absolute values of positive maxima and negative minima extrema = Extrema.new(samples) starting_outline = {} extrema.minima.each do |idx,val| if val <= 0.0 starting_outline[idx] =val.abs end end extrema.maxima.each do |idx,val| if val >= 0.0 starting_outline[idx] = val.abs end end # add in first and last samples so the envelope follows entire signal starting_outline[0] = samples[0].abs starting_outline[samples.count - 1] = samples[samples.count - 1].abs # the extrema we have now are probably not spaced evenly. Upsampling at # this point would lead to a time-distorted signal. So the next step is to # interpolate between all the extrema to make a crude but properly sampled # envelope. proper_outline = Array.new(samples.count, 0) indices = starting_outline.keys.sort for i in 1...indices.count l_idx = indices[i-1] r_idx = indices[i] l_val = starting_outline[l_idx] r_val = starting_outline[r_idx] proper_outline[l_idx] = l_val proper_outline[r_idx] = r_val idx_span = r_idx - l_idx for j in (l_idx + 1)...(r_idx) x = (j - l_idx).to_f / idx_span y = Interpolation.linear l_val, r_val, x proper_outline[j] = y end end # Now downsample by dropping samples, back to the number of starting_outline we had # with just the extrema, but this time with samples properly spaced so as # to avoid time distortion after upsampling. downsample_factor = (samples.count / starting_outline.count).to_i downsampled_outline = [] (0...proper_outline.count).step(downsample_factor) do |n| downsampled_outline.push proper_outline[n] end # finally, use polynomial interpolation to upsample to the original sample rate. upsample_factor = samples.count / downsampled_outline.count.to_f @data = PolynomialResampling.upsample(downsampled_outline, upsample_factor) end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
9 10 11 |
# File 'lib/spcore/analysis/envelope.rb', line 9 def data @data end |