Ruby Digital Signal Processing Library

We're just starting digital signal processing in my Human-Computer Interfaces course, so pardon the simplicity of this "library." I see this being useful over the next few lectures to experiment with a few very simple filters.

class Sin
  attr_accessor :value

  def update(time)
    @value = Math.sin(time)
  end
end

class Gain
  attr_accessor :value

  def initialize(gain, source)
    @source = source
    @gain = gain
  end

  def update(time)
    if @time != time
      @source.update(time)
      @value = @source.value * @gain
      @time = time
    end
  end
end

class Delay
  attr_accessor :value

  def initialize(source)
    @source = source
    @next = 0.0
  end

  def update(time)
    if @time != time
      @source.update(time)
      @value = @next
      @next = @source.value
      @time = time
    end
  end
end

# There must be a better name for this
class Addition
  attr_accessor :value

  def initialize(source_a, source_b)
    @a, @b = source_a, source_b
  end

  def update(time)
    if @time != time
      @a.update(time)
      @b.update(time)
      @value = @a.value + @b.value
      @time = time
    end
  end
end

Drive it with code like this:

# head(n)---[Z^-1]>---tail(n)
head = Sin.new
tail = Delay.new(head)

time = 0
10.times do
  tail.update(time)
  puts "#{time}: #{head.value} -> #{tail.value}"
  time += 1
end

Which gives output like this:

0: 0.0 -> 0.0
1: 0.841470984807897 -> 0.0
2: 0.909297426825682 -> 0.841470984807897
3: 0.141120008059867 -> 0.909297426825682
4: -0.756802495307928 -> 0.141120008059867
5: -0.958924274663138 -> -0.756802495307928
6: -0.279415498198926 -> -0.958924274663138
7: 0.656986598718789 -> -0.279415498198926
8: 0.989358246623382 -> 0.656986598718789
9: 0.412118485241757 -> 0.989358246623382

(Inputs are delayed by one sample in the output.)

One Zero Filter

This is a "one zero" filter configured to give a two-sample running average.

# head(n)--- |> -|-----------[+]> -- tail(n)
#            g   |            |
#                |            ^ a
#                |-- [Z^-1] --|
# See this page if, like to me, that's gibberish to you:
# http://www.cs.princeton.edu/courses/archive/fall07/cos436/DSP/DSP.html

g = 0.5
a = 1.0

head = Sin.new
gain = Gain.new(g, head)
delay = Delay.new(gain)
delay_gain = Gain.new(a, delay)
tail = Addition.new(gain, delay_gain)

time = 0
10.times do
  tail.update(time)
  puts "#{time}: #{head.value} -> #{tail.value}"
  time += 1
end

Comments

Click here to view the comments on this post.