Class: AudioStream::Fx::SchroederReverb

Inherits:
Object
  • Object
show all
Defined in:
lib/audio_stream/fx/schroeder_reverb.rb

Instance Method Summary collapse

Constructor Details

#initialize(soundinfo, time:, dry: 1.0, wet: 0.7) ⇒ SchroederReverb

Returns a new instance of SchroederReverb.


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/audio_stream/fx/schroeder_reverb.rb', line 5

def initialize(soundinfo, time:, dry: 1.0, wet: 0.7)
  @window_size = soundinfo.window_size
  @combs = [
    CombFilter.new(soundinfo, freq: ms2freq(39.85 / 2.0 * time), q: 0.871402),
    CombFilter.new(soundinfo, freq: ms2freq(36.10 / 2.0 * time), q: 0.882762),
    CombFilter.new(soundinfo, freq: ms2freq(33.27 / 2.0 * time), q: 0.891443),
    CombFilter.new(soundinfo, freq: ms2freq(30.15 / 2.0 * time), q: 0.901117),
  ]
  @allpasss = [
    AllPassFilter.create(soundinfo, freq: ms2freq(5.0), q: 0.7),
    AllPassFilter.create(soundinfo, freq: ms2freq(1.7), q: 0.7),
  ]

  @dry = dry.to_f
  @wet = wet.to_f
end

Instance Method Details

#ms2freq(ms) ⇒ Object


47
48
49
# File 'lib/audio_stream/fx/schroeder_reverb.rb', line 47

def ms2freq(ms)
  1.0 / (ms / 1000.0)
end

#process(input) ⇒ Object


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/audio_stream/fx/schroeder_reverb.rb', line 22

def process(input)
  window_size = input.window_size
  if @window_size!=window_size
    raise "window size is not match: impulse.size=#{@window_size} input.size=#{window_size}"
  end

  wets = @combs.map {|comb|
    comb.process(input)
  }
  wet = Buffer.merge(wets, average: true)

  @allpasss.each {|allpass|
    wet = allpass.process(wet)
  }

  streams = wet.streams.map.with_index {|wet_stream, i|
    dry_stream = input.streams[i]
    dst = Vdsp::DoubleArray.new(window_size)
    Vdsp::UnsafeDouble.vsmsma(dry_stream, 0, 1, @dry, wet_stream, 0, 1, @wet, dst, 0, 1, window_size)
    dst
  }

  Buffer.new(*streams)
end