class RemiAudio::DSP::ZitaReverb

Overview

Implements a Hall-like reverb effect.

This is a port of Zita-Rev1, a mostly-a-hall-partially-a-plate reverb based on a feedback delay network and allpass comb filters.

The original Zita-Rev1 supports an "ambisonic" mode, which allows for two inputs and four outputs. This implementation does not support the calculations for ambisonic mode, however, so it's strictly a reverb with stereo output.

Direct Known Subclasses

Defined in:

remiaudio/dsp/reverbs/zita-paraeq.cr
remiaudio/dsp/reverbs/zita-presets.cr
remiaudio/dsp/reverbs/zita.cr

Constant Summary

DEFAULT_PRE_DELAY = 0.02
DEFAULT_REVERB_DAMPING = 4300.0
DEFAULT_REVERB_EQ1_FREQ = 200.0
DEFAULT_REVERB_EQ1_GAIN = -1.3
DEFAULT_REVERB_EQ2_FREQ = 2500.0
DEFAULT_REVERB_EQ2_GAIN = 0.0
DEFAULT_REVERB_TIME_HIGH = 2.84
DEFAULT_REVERB_TIME_LOW = 2.12
DEFAULT_REVERB_XOVER = 369.0
MAXIMUM_PRE_DELAY = 0.10
MAXIMUM_REVERB_DAMPING = 24000.0
MAXIMUM_REVERB_EQ1_FREQ = 2500.0
MAXIMUM_REVERB_EQ1_GAIN = 15.0
MAXIMUM_REVERB_EQ2_FREQ = 10000.0
MAXIMUM_REVERB_EQ2_GAIN = 15.0
MAXIMUM_REVERB_TIME_HIGH = 8.0
MAXIMUM_REVERB_TIME_LOW = 8.0
MAXIMUM_REVERB_XOVER = 1000.0
MINIMUM_PRE_DELAY = 0.02
MINIMUM_REVERB_DAMPING = 1500.0
MINIMUM_REVERB_EQ1_FREQ = 40.0
MINIMUM_REVERB_EQ1_GAIN = -15.0
MINIMUM_REVERB_EQ2_FREQ = 160.0
MINIMUM_REVERB_EQ2_GAIN = -15.0
MINIMUM_REVERB_TIME_HIGH = 1.0
MINIMUM_REVERB_TIME_LOW = 1.0
MINIMUM_REVERB_XOVER = 50.0
NUM_DELAYS = 8
NUM_DIFFS = 8
NUM_FILTERS = 8
PARA_EQ_MAX_CH = 2
PRESETS = {PresetNames::GmDefault => Preset.new(predelay: DEFAULT_PRE_DELAY, crossover: DEFAULT_REVERB_XOVER, timeLow: DEFAULT_REVERB_TIME_LOW, timeHigh: DEFAULT_REVERB_TIME_HIGH, damping: DEFAULT_REVERB_DAMPING, eq1Freq: DEFAULT_REVERB_EQ1_FREQ, eq1Gain: DEFAULT_REVERB_EQ1_GAIN, eq2Freq: DEFAULT_REVERB_EQ2_FREQ, eq2Gain: DEFAULT_REVERB_EQ2_GAIN), PresetNames::SmallRoom => Preset.new(predelay: 0.03, crossover: 300.0, timeLow: 1.0, timeHigh: 1.1, damping: 7500.0, eq1Freq: 40.0, eq2Freq: 160.0, eq1Gain: 0.0, eq2Gain: 0.0), PresetNames::Hall => Preset.new(predelay: 0.042, crossover: 290.0, timeLow: 3.0, timeHigh: 4.0, damping: 3900.0, eq1Freq: 200.0, eq2Freq: 8000.0, eq1Gain: -1.1, eq2Gain: 1.2)}

Pre-constructed Preset instances for MVerb that correspond to the names in PresetNames.

TDELAY = [153129.0e-6, 210389.0e-6, 127837.0e-6, 256891.0e-6, 174713.0e-6, 192303.0e-6, 125000.0e-6, 219991.0e-6]
TDIFF = [20346.0e-6, 24421.0e-6, 31604.0e-6, 27333.0e-6, 22904.0e-6, 29291.0e-6, 13458.0e-6, 19123.0e-6]
ZITA_G = Math.sqrt(0.125)

Constructors

Class Method Summary

Macro Summary

Instance Method Summary

Instance methods inherited from class RemiAudio::DSP::Reverb

mute : Nil mute, process(inputLeft : Array(Float64) | Slice(Float64), inputRight : Array(Float64) | Slice(Float64), outputLeft : Array(Float64) | Slice(Float64), outputRight : Array(Float64) | Slice(Float64)) : Nil process, usePreset(preset : Reverb::Preset) : Nil usePreset

Constructor Detail

def self.new(newSampleRate : Int32, numFrames : Int32) #

[View source]

Class Method Detail

def self.checkCrossover(value) : Nil #

Checks if value is a valid crossover frequency for the two bands. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkDamping(value) : Nil #

Checks if value is a valid damping amount. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkEQ1Freq(value) : Nil #

Checks if value is a valid frequency for EQ1. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkEQ1Gain(value) : Nil #

Checks if value is a valid gain for EQ1. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkEQ2Freq(value) : Nil #

Checks if value is a valid frequency for EQ2. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkEQ2Gain(value) : Nil #

Checks if value is a valid gain for EQ2. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkPredelay(value) : Nil #

Checks if value is a valid predelay time. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkTimeHigh(value) : Nil #

Checks if value is a valid time length for the high band. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]
def self.checkTimeLow(value) : Nil #

Checks if value is a valid time length for the low band. If it is, this does nothing. Otherwise it raises a ReverbError with an explanation.


[View source]

Macro Detail

macro processZ(z, x0, x1) #

[View source]

Instance Method Detail

def crossover : Float64 #

[View source]
def crossover=(value : Float64) #

[View source]
def damping : Float64 #

[View source]
def damping=(value : Float64) #

[View source]
def eq(number : Int) : Tuple(Float64, Float64) #

[View source]
def mute : Nil #

[View source]
def predelay : Float64 #

[View source]
def predelay=(value : Float64) #

[View source]
def process(inputLeft : Array(Float64) | Slice(Float64), inputRight : Array(Float64) | Slice(Float64), outputLeft : Array(Float64) | Slice(Float64), outputRight : Array(Float64) | Slice(Float64)) : Nil #

[View source]
def process(inputLeft : Array(Float32) | Slice(Float32), inputRight : Array(Float32) | Slice(Float32), outputLeft : Array(Float32) | Slice(Float32), outputRight : Array(Float32) | Slice(Float32)) : Nil #

[View source]
def process(input : Array(Float64) | Slice(Float64), output : Array(Float64) | Slice(Float64)) : Nil #

[View source]
def process(input : Array(Float32) | Slice(Float32), output : Array(Float32) | Slice(Float32)) : Nil #

[View source]
def process(buffer : Array(Float64) | Slice(Float64), amount : Float64 | Float64 = 1.0) : Nil #

[View source]
def process(buffer : Array(Float32) | Slice(Float32), amount : Float32 | Float64 = 1.0) : Nil #

[View source]
def setEq(number : Int, frequency : Float64, gain : Float64) #

[View source]
def timeHigh : Float64 #

[View source]
def timeHigh=(value : Float64) #

[View source]
def timeLow : Float64 #

[View source]
def timeLow=(value : Float64) #

[View source]
def updateInternalParams(*, numFrames : Int32 = 0) #

[View source]
def usePreset(preset : Reverb::Preset) : Nil #

[View source]