Click here to Skip to main content
15,896,154 members
Articles / Programming Languages / C#

Audio DSP with C#

Rate me:
Please Sign up or sign in to vote.
4.55/5 (23 votes)
6 Sep 20032 min read 219.9K   8.7K   92  
A .NET class library for audio processing.
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.

License

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


Written By
Brazil Brazil
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions