Class: SPCore::Signal

Inherits:
Object
  • Object
show all
Includes:
Hashmake::HashMakeable
Defined in:
lib/spcore/analysis/signal.rb

Overview

Author:

  • James Tunnell

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

Instance Method Summary collapse

Constructor Details

#initialize(hashed_args) ⇒ Signal

A new instance of Signal.

Parameters:

  • hashed_args (Hash)

    Hashed arguments. Required keys are :data and :sample_rate. See ARG_SPECS for more details.



21
22
23
# File 'lib/spcore/analysis/signal.rb', line 21

def initialize hashed_args
  hash_make Signal::ARG_SPECS, hashed_args
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



15
16
17
# File 'lib/spcore/analysis/signal.rb', line 15

def data
  @data
end

#sample_rateObject (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

#absObject

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.

Parameters:

  • other

    Can be Numeric (add same value to all data values), Array, or Signal.



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.

Parameters:

  • other

    Can be Numeric (add same value to all data values), Array, or Signal.



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

#cloneObject

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

#countObject

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

Parameters:

  • other_signal (Array)

    The signal to look for in the current signal.

  • normalize (true/false) (defaults to: true)

    Flag to indicate if normalization should be performed on input signals (performed on a copy of the original data).

Raises:

  • (ArgumentError)

    if other_signal is not a Signal or Array.

  • (ArgumentError)

    if other_signal is longer than the current signal data.



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

#derivativeObject

Differentiates the signal data.

Parameters:

  • make_signal (true/false)

    If true, return the result as a new Signal object. Otherwise, return result as an array.



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.

Parameters:

  • other

    Can be Numeric (divide same all data values by the same value), Array, or Signal.



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.

Parameters:

  • other

    Can be Numeric (divide same all data values by the same value), Array, or Signal.



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.

Parameters:

  • downsample_factor (Fixnum)

    Decrease the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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.

Parameters:

  • downsample_factor (Fixnum)

    Decrease the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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

#durationObject

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

#energyObject

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

#envelopeObject

Determine the envelope of the current Signal and return either a Envelope or a new Signal object as a result.

Parameters:

  • make_signal (True/False)

    If true, return envelope data in a new Otherwise, return an Envelope object.



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

#extremaObject

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.

Parameters:

  • convert_to_db (defaults to: false)

    If true, magnitudes are converted to dB values.

Returns:

  • (Hash)

    contains frequencies mapped to magnitudes.



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

#meanObject

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.

Parameters:

  • other

    Can be Numeric (multiply all data values by the same value), Array, or Signal.



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.

Parameters:

  • other

    Can be Numeric (multiply all data values by the same value), Array, or Signal.



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_1dObject

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_2dObject

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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.

  • downsample_factor (Fixnum)

    Decrease the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.

  • downsample_factor (Fixnum)

    Decrease the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.

  • downsample_factor (Fixnum)

    Decrease the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.

  • downsample_factor (Fixnum)

    Decrease the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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

#rmsObject

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

#sizeObject

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.

Parameters:

  • range (Range)

    Used to pick the data range.



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.

Parameters:

  • other

    Can be Numeric (subtract same value from all data values), Array, or Signal.



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.

Parameters:

  • other

    Can be Numeric (subtract same value from all data values), Array, or Signal.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.

  • filter_order (Fixnum)

    The filter order for the discrete lowpass filter.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.



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.

Parameters:

  • upsample_factor (Fixnum)

    Increase the sample rate by this factor.



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