|
using System;
namespace Garbe.Sound
{
public sealed class GardnerReverb : SoundObj
{
private EarlyReflection _er;
private SmallGardnerReverb _small;
private MediumGardnerReverb _medium;
private LargeGardnerReverb _large;
private Delay _delay;
private float _revTime;
private float _gain;
private float _fbGain;
private float _rt60;
private uint _sampleRate;
public GardnerReverb(Room r, ReflectionCollection rc, uint sr) : base()
{
_rt60 = r.RT60;
_er = new EarlyReflection(rc, sr);
_sampleRate = sr;
if(_rt60 < 0.58f)
{
_revTime = _rt60 - rc.MaxDelay + rc.MaxGainDelay - 0.059f; //RT60-d_last+d_max-.059;
_gain = (float)(Math.Exp(-Math.Log(1000d, Math.E) * (1-_revTime/_rt60) ) / 0.22f); //exp(-log10(1000)*(1-D_time/RT60))/.22;
_fbGain = -1.64f * (_revTime * _revTime) + 2.92f * _revTime - 0.66f; //-1.64*D_time^2+2.92*D_time-.66;
_small = new SmallGardnerReverb(_fbGain);
_small.Input = _er;
}
else if((_rt60 >= 0.58f) && (_rt60 < 1.3f))
{
_revTime = _rt60 - rc.MaxDelay - rc.MaxGainDelay + 0.027f;
_gain = (float)(Math.Exp(-Math.Log(1000d, Math.E) * (1-_revTime/_rt60) ) / 0.22f);
_fbGain = -0.42f * (_revTime * _revTime) + 1.35f * _revTime - 0.39f;
_medium = new MediumGardnerReverb(_fbGain);
_medium.Input = _er;
}
else
{
_revTime = _rt60 - 0.024f;
_gain = (float)(Math.Exp(-Math.Log(1000d, 10) * (1-_revTime/_rt60) ) / 0.28f);
_fbGain = (float)(-0.001f * Math.Pow(_revTime, 4) + 0.016 * Math.Pow(_revTime, 3) -
0.1f * Math.Pow(_revTime, 2) + 0.256f * _revTime + 0.696f - 0.39f);
//-.001*D_time^4+.016*D_time^3-.095*D_time^2+.256*D_time+.696-.29;
_large = new LargeGardnerReverb(_fbGain);
_large.Input = _er;
}
}
/// <summary> Do the signal processing </summary>
public override void DoProcess()
{
if(_rt60 < 0.58f)
{
_er.DoProcess();
_small.DoProcess();
base._output = _small.Output;
}
else if((_rt60 >= 0.58f) && (_rt60 < 1.3f))
{
_er.DoProcess();
_medium.DoProcess();
base._output = _medium.Output;
}
else
{
_er.DoProcess();
_large.DoProcess();
base._output = _large.Output;
}
}
/// <summary> Get or Set the input object </summary>
public override SoundObj Input
{
get{return(_input);}
set
{
_input = value;
_er.Input= value;
}
}
/// <summary> Number of interations expected to do the signal processing </summary>
public override int Interations
{
get
{
return(base._input.Interations + (int)(_revTime * _sampleRate));
}
}
}
}
//% Start process
//
//cl_data = wavrd2(wav_input); % Read clean file samples
//cl_data(length(cl_data)+2*RT60*fsamp)=0; % Lengthen original vector so that reverb tail can fit into it
//e_data = early_r(cl_data, datafile); % Process early reflections
//
//% Below: According to reverberation time computed above,
//% Select the adequate tail network and compute gain (to scale relatively to early reflections)
//% and network feedback gain
//% Note: For network 3 (large rooms), late reverberation algorithm is applied to clean file instead
//% of early reflections.
//
//if RT60 < 0.58,
//D_time = RT60-d_last+d_max-.059;
//gain = exp(-log10(1000)*(1-D_time/RT60))/.22;
//fbgain = -1.64*D_time^2+2.92*D_time-.66;
//l_data = gardnerS(e_data, fbgain);
//elseif (RT60 >= 0.58) & (RT60 < 1.30),
//D_time = RT60-(d_last-d_max+.027);
//gain = exp(-log(1000)*(1-D_time/RT60))/.22;
//fbgain = -.42*D_time^2+1.35*D_time-.39;
//l_data = gardnerM(e_data, fbgain);
//else
//D_time = RT60-.024;
//gain = exp(-log(1000)*(1-D_time/RT60))/.28;
//fbgain = -.001*D_time^4+.016*D_time^3-.095*D_time^2+.256*D_time+.696-.29;
//l_data = gardnerL(cl_data, fbgain);
//end
//
//r_data = plus(e_data, gain*dodelay(l_data, ceil(fsamp*d_last))); % Add early reflections to tail properly delayed
//wavwr16m(r_data, fsamp, wav_output) % Write output wav file
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.