Tom Says: Code something crazy every day you feel like it!
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.)
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
Posted Nov 14, 2007, in the late, late night.