1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
<HTML>
<HEAD>
<TITLE>The Synthesis ToolKit in C++ (STK)</TITLE>
<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<CENTER>
<img src="princeton.gif"> <img src="ccrma.gif"> <img src="mcgill.gif"><P>
<a class="qindex" href="index.html">Home</a> <a class="qindex" href="information.html">Information</a> <a class="qindex" href="classes.html">Classes</a> <a class="qindex" href="download.html">Download</a> <a class="qindex" href="usage.html">Usage</a> <a class="qindex" href="maillist.html">Mail List</a> <a class="qindex" href="system.html">Requirements</a> <a class="qindex" href="links.html">Links</a> <a class="qindex" href="faq.html">FAQ</a> <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
<HR>
<!-- Generated by Doxygen 1.6.2 -->
<div class="navpath"><a class="el" href="dir_221deb9bdff892d63ed1e409450a60d2.html">include</a>
</div>
<div class="contents">
<h1>FreeVerb.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="preprocessor">#ifndef STK_FREEVERB_H</span>
<a name="l00002"></a>00002 <span class="preprocessor"></span><span class="preprocessor">#define STK_FREEVERB_H</span>
<a name="l00003"></a>00003 <span class="preprocessor"></span>
<a name="l00004"></a>00004 <span class="preprocessor">#include "Effect.h"</span>
<a name="l00005"></a>00005 <span class="preprocessor">#include "Delay.h"</span>
<a name="l00006"></a>00006 <span class="preprocessor">#include "OnePole.h"</span>
<a name="l00007"></a>00007
<a name="l00008"></a>00008 <span class="keyword">namespace </span>stk {
<a name="l00009"></a>00009
<a name="l00010"></a>00010 <span class="comment">/***********************************************************************/</span>
<a name="l00024"></a>00024 <span class="comment">/***********************************************************************/</span>
<a name="l00025"></a>00025
<a name="l00026"></a><a class="code" href="classstk_1_1FreeVerb.html">00026</a> <span class="keyword">class </span><a class="code" href="classstk_1_1FreeVerb.html" title="Jezar at Dreampoint&#39;s FreeVerb, implemented in STK.">FreeVerb</a> : <span class="keyword">public</span> <a class="code" href="classstk_1_1Effect.html" title="STK abstract effects parent class.">Effect</a>
<a name="l00027"></a>00027 {
<a name="l00028"></a>00028 <span class="keyword">public</span>:
<a name="l00030"></a>00030
<a name="l00036"></a>00036 <a class="code" href="classstk_1_1FreeVerb.html#aba12855fab8cddc4119cbd854e86214a" title="FreeVerb Constructor.">FreeVerb</a>();
<a name="l00037"></a>00037
<a name="l00039"></a>00039 <a class="code" href="classstk_1_1FreeVerb.html#a203cd66e21f9ca127139b4948e26dfb9" title="Destructor.">~FreeVerb</a>();
<a name="l00040"></a>00040
<a name="l00042"></a>00042 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#af51f5592b04eba08092c2377debf16a8" title="Set the effect mix [0 = mostly dry, 1 = mostly wet].">setEffectMix</a>( StkFloat mix );
<a name="l00043"></a>00043
<a name="l00045"></a>00045 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#a60133f8378e8a6f775a01d7d3ca44307" title="Set the room size (comb filter feedback gain) parameter [0,1].">setRoomSize</a>( StkFloat value );
<a name="l00046"></a>00046
<a name="l00048"></a>00048 StkFloat <a class="code" href="classstk_1_1FreeVerb.html#af92c7e8a19aa0a265afc72cf45141d27" title="Get the room size (comb filter feedback gain) parameter.">getRoomSize</a>( <span class="keywordtype">void</span> );
<a name="l00049"></a>00049
<a name="l00051"></a>00051 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#a8576f27cfb65f06c019e80772eaed0fb" title="Set the damping parameter [0=low damping, 1=higher damping].">setDamping</a>( StkFloat value );
<a name="l00052"></a>00052
<a name="l00054"></a>00054 StkFloat <a class="code" href="classstk_1_1FreeVerb.html#a5dd46db58e656e5e9f1c1b1545a14036" title="Get the damping parameter.">getDamping</a>( <span class="keywordtype">void</span> );
<a name="l00055"></a>00055
<a name="l00057"></a>00057 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#a6ebb13f2d7d2940a0f49a08a191185c5" title="Set the width (left-right mixing) parameter [0,1].">setWidth</a>( StkFloat value );
<a name="l00058"></a>00058
<a name="l00060"></a>00060 StkFloat <a class="code" href="classstk_1_1FreeVerb.html#abb2e0328715a9446f0d5f625ffc88805" title="Get the width (left-right mixing) parameter.">getWidth</a>( <span class="keywordtype">void</span> );
<a name="l00061"></a>00061
<a name="l00063"></a>00063 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#af1070d0612b81c22031907269cf60cfc" title="Set the mode [frozen = 1, unfrozen = 0].">setMode</a>( <span class="keywordtype">bool</span> isFrozen );
<a name="l00064"></a>00064
<a name="l00066"></a>00066 StkFloat <a class="code" href="classstk_1_1FreeVerb.html#a6510448e8d12077bd475a714aace5177" title="Get the current freeze mode [frozen = 1, unfrozen = 0].">getMode</a>( <span class="keywordtype">void</span> );
<a name="l00067"></a>00067
<a name="l00069"></a>00069 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#a3a6551cb5dcf80f27f683c81f47284f3" title="Clears delay lines, etc.">clear</a>( <span class="keywordtype">void</span> );
<a name="l00070"></a>00070
<a name="l00072"></a>00072
<a name="l00080"></a>00080 StkFloat <a class="code" href="classstk_1_1FreeVerb.html#aab7afe56ff978369328cbf4dd4c4cfa3" title="Return the specified channel value of the last computed stereo frame.">lastOut</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> channel = 0 );
<a name="l00081"></a>00081
<a name="l00083"></a>00083
<a name="l00090"></a>00090 StkFloat <a class="code" href="classstk_1_1FreeVerb.html#a0cd5d18a9636029196415879e6a027ee" title="Input one or two samples to the effect and return the specified channel value of...">tick</a>( StkFloat inputL, StkFloat inputR = 0.0, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> channel = 0 );
<a name="l00091"></a>00091
<a name="l00093"></a>00093
<a name="l00103"></a>00103 <a class="code" href="classstk_1_1StkFrames.html" title="An STK class to handle vectorized audio data.">StkFrames</a>& <a class="code" href="classstk_1_1FreeVerb.html#a0cd5d18a9636029196415879e6a027ee" title="Input one or two samples to the effect and return the specified channel value of...">tick</a>( <a class="code" href="classstk_1_1StkFrames.html" title="An STK class to handle vectorized audio data.">StkFrames</a>& frames, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> channel = 0 );
<a name="l00104"></a>00104
<a name="l00106"></a>00106
<a name="l00117"></a>00117 <a class="code" href="classstk_1_1StkFrames.html" title="An STK class to handle vectorized audio data.">StkFrames</a>& <a class="code" href="classstk_1_1FreeVerb.html#a0cd5d18a9636029196415879e6a027ee" title="Input one or two samples to the effect and return the specified channel value of...">tick</a>( <a class="code" href="classstk_1_1StkFrames.html" title="An STK class to handle vectorized audio data.">StkFrames</a>& iFrames, <a class="code" href="classstk_1_1StkFrames.html" title="An STK class to handle vectorized audio data.">StkFrames</a> &oFrames, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> iChannel = 0, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oChannel = 0 );
<a name="l00118"></a>00118
<a name="l00119"></a>00119 <span class="keyword">protected</span>:
<a name="l00121"></a>00121 <span class="keywordtype">void</span> <a class="code" href="classstk_1_1FreeVerb.html#a5be3a015730462494a5807a86cd693d1" title="Update interdependent parameters.">update</a>( <span class="keywordtype">void</span> );
<a name="l00122"></a>00122
<a name="l00123"></a>00123 <span class="comment">// Clamp very small floats to zero, version from</span>
<a name="l00124"></a>00124 <span class="comment">// http://music.columbia.edu/pipermail/linux-audio-user/2004-July/013489.html .</span>
<a name="l00125"></a>00125 <span class="comment">// However, this is for 32-bit floats only.</span>
<a name="l00126"></a>00126 <span class="comment">//static inline StkFloat undenormalize( volatile StkFloat s ) { </span>
<a name="l00127"></a>00127 <span class="comment">// s += 9.8607615E-32f; </span>
<a name="l00128"></a>00128 <span class="comment">// return s - 9.8607615E-32f; </span>
<a name="l00129"></a>00129 <span class="comment">//}</span>
<a name="l00130"></a>00130
<a name="l00131"></a>00131 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> nCombs = 8;
<a name="l00132"></a>00132 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> nAllpasses = 4;
<a name="l00133"></a>00133 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> stereoSpread = 23;
<a name="l00134"></a>00134 <span class="keyword">static</span> <span class="keyword">const</span> StkFloat fixedGain;
<a name="l00135"></a>00135 <span class="keyword">static</span> <span class="keyword">const</span> StkFloat scaleWet;
<a name="l00136"></a>00136 <span class="keyword">static</span> <span class="keyword">const</span> StkFloat scaleDry;
<a name="l00137"></a>00137 <span class="keyword">static</span> <span class="keyword">const</span> StkFloat scaleDamp;
<a name="l00138"></a>00138 <span class="keyword">static</span> <span class="keyword">const</span> StkFloat scaleRoom;
<a name="l00139"></a>00139 <span class="keyword">static</span> <span class="keyword">const</span> StkFloat offsetRoom;
<a name="l00140"></a>00140
<a name="l00141"></a>00141 <span class="comment">// Delay line lengths for 44100Hz sampling rate.</span>
<a name="l00142"></a>00142 <span class="keyword">static</span> <span class="keywordtype">int</span> cDelayLengths[nCombs];
<a name="l00143"></a>00143 <span class="keyword">static</span> <span class="keywordtype">int</span> aDelayLengths[nAllpasses];
<a name="l00144"></a>00144
<a name="l00145"></a>00145 StkFloat g_; <span class="comment">// allpass coefficient</span>
<a name="l00146"></a>00146 StkFloat gain_;
<a name="l00147"></a>00147 StkFloat roomSizeMem_, roomSize_;
<a name="l00148"></a>00148 StkFloat dampMem_, damp_;
<a name="l00149"></a>00149 StkFloat wet1_, wet2_;
<a name="l00150"></a>00150 StkFloat dry_;
<a name="l00151"></a>00151 StkFloat width_;
<a name="l00152"></a>00152 <span class="keywordtype">bool</span> frozenMode_;
<a name="l00153"></a>00153
<a name="l00154"></a>00154 <span class="comment">// LBFC: Lowpass Feedback Comb Filters</span>
<a name="l00155"></a>00155 <a class="code" href="classstk_1_1Delay.html" title="STK non-interpolating delay line class.">Delay</a> combDelayL_[nCombs];
<a name="l00156"></a>00156 <a class="code" href="classstk_1_1Delay.html" title="STK non-interpolating delay line class.">Delay</a> combDelayR_[nCombs];
<a name="l00157"></a>00157 <a class="code" href="classstk_1_1OnePole.html" title="STK one-pole filter class.">OnePole</a> combLPL_[nCombs];
<a name="l00158"></a>00158 <a class="code" href="classstk_1_1OnePole.html" title="STK one-pole filter class.">OnePole</a> combLPR_[nCombs];
<a name="l00159"></a>00159
<a name="l00160"></a>00160 <span class="comment">// AP: Allpass Filters</span>
<a name="l00161"></a>00161 <a class="code" href="classstk_1_1Delay.html" title="STK non-interpolating delay line class.">Delay</a> allPassDelayL_[nAllpasses];
<a name="l00162"></a>00162 <a class="code" href="classstk_1_1Delay.html" title="STK non-interpolating delay line class.">Delay</a> allPassDelayR_[nAllpasses];
<a name="l00163"></a>00163 };
<a name="l00164"></a>00164
<a name="l00165"></a><a class="code" href="classstk_1_1FreeVerb.html#aab7afe56ff978369328cbf4dd4c4cfa3">00165</a> <span class="keyword">inline</span> StkFloat <a class="code" href="classstk_1_1FreeVerb.html#aab7afe56ff978369328cbf4dd4c4cfa3" title="Return the specified channel value of the last computed stereo frame.">FreeVerb :: lastOut</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> channel )
<a name="l00166"></a>00166 {
<a name="l00167"></a>00167 <span class="preprocessor">#if defined(_STK_DEBUG_)</span>
<a name="l00168"></a>00168 <span class="preprocessor"></span> <span class="keywordflow">if</span> ( channel > 1 ) {
<a name="l00169"></a>00169 oStream_ << <span class="stringliteral">"FreeVerb::lastOut(): channel argument must be less than 2!"</span>;
<a name="l00170"></a>00170 <a class="code" href="classstk_1_1Stk.html#a48ac73a0d8ca28445ba1a054e1f061ff" title="Static function for error reporting and handling using c-strings.">handleError</a>( StkError::FUNCTION_ARGUMENT );
<a name="l00171"></a>00171 }
<a name="l00172"></a>00172 <span class="preprocessor">#endif</span>
<a name="l00173"></a>00173 <span class="preprocessor"></span>
<a name="l00174"></a>00174 <span class="keywordflow">return</span> lastFrame_[channel];
<a name="l00175"></a>00175 }
<a name="l00176"></a>00176
<a name="l00177"></a><a class="code" href="classstk_1_1FreeVerb.html#a0cd5d18a9636029196415879e6a027ee">00177</a> <span class="keyword">inline</span> StkFloat <a class="code" href="classstk_1_1FreeVerb.html#a0cd5d18a9636029196415879e6a027ee" title="Input one or two samples to the effect and return the specified channel value of...">FreeVerb::tick</a>( StkFloat inputL, StkFloat inputR, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> channel )
<a name="l00178"></a>00178 {
<a name="l00179"></a>00179 <span class="preprocessor">#if defined(_STK_DEBUG_)</span>
<a name="l00180"></a>00180 <span class="preprocessor"></span> <span class="keywordflow">if</span> ( channel > 1 ) {
<a name="l00181"></a>00181 oStream_ << <span class="stringliteral">"FreeVerb::tick(): channel argument must be less than 2!"</span>;
<a name="l00182"></a>00182 <a class="code" href="classstk_1_1Stk.html#a48ac73a0d8ca28445ba1a054e1f061ff" title="Static function for error reporting and handling using c-strings.">handleError</a>(StkError::FUNCTION_ARGUMENT);
<a name="l00183"></a>00183 }
<a name="l00184"></a>00184 <span class="preprocessor">#endif</span>
<a name="l00185"></a>00185 <span class="preprocessor"></span>
<a name="l00186"></a>00186 <span class="keywordflow">if</span> ( !inputR ) {
<a name="l00187"></a>00187 inputR = inputL;
<a name="l00188"></a>00188 }
<a name="l00189"></a>00189
<a name="l00190"></a>00190 StkFloat fInput = (inputL + inputR) * gain_;
<a name="l00191"></a>00191 StkFloat outL = 0.0;
<a name="l00192"></a>00192 StkFloat outR = 0.0;
<a name="l00193"></a>00193
<a name="l00194"></a>00194 <span class="comment">// Parallel LBCF filters</span>
<a name="l00195"></a>00195 <span class="keywordflow">for</span> ( <span class="keywordtype">int</span> i = 0; i < nCombs; i++ ) {
<a name="l00196"></a>00196 <span class="comment">// Left channel</span>
<a name="l00197"></a>00197 <span class="comment">//StkFloat yn = fInput + (roomSize_ * FreeVerb::undenormalize(combLPL_[i].tick(FreeVerb::undenormalize(combDelayL_[i].nextOut()))));</span>
<a name="l00198"></a>00198 StkFloat yn = fInput + (roomSize_ * combLPL_[i].<a class="code" href="classstk_1_1OnePole.html#a3c83b6d43f76bec06f11caa9de76881e" title="Input one sample to the filter and return one output.">tick</a>( combDelayL_[i].nextOut() ) );
<a name="l00199"></a>00199 combDelayL_[i].<a class="code" href="classstk_1_1Delay.html#aa1a929e0e324417b8a55cbf8770532e9" title="Input one sample to the filter and return one output.">tick</a>(yn);
<a name="l00200"></a>00200 outL += yn;
<a name="l00201"></a>00201
<a name="l00202"></a>00202 <span class="comment">// Right channel</span>
<a name="l00203"></a>00203 <span class="comment">//yn = fInput + (roomSize_ * FreeVerb::undenormalize(combLPR_[i].tick(FreeVerb::undenormalize(combDelayR_[i].nextOut()))));</span>
<a name="l00204"></a>00204 yn = fInput + (roomSize_ * combLPR_[i].<a class="code" href="classstk_1_1OnePole.html#a3c83b6d43f76bec06f11caa9de76881e" title="Input one sample to the filter and return one output.">tick</a>( combDelayR_[i].nextOut() ) );
<a name="l00205"></a>00205 combDelayR_[i].<a class="code" href="classstk_1_1Delay.html#aa1a929e0e324417b8a55cbf8770532e9" title="Input one sample to the filter and return one output.">tick</a>(yn);
<a name="l00206"></a>00206 outR += yn;
<a name="l00207"></a>00207 }
<a name="l00208"></a>00208
<a name="l00209"></a>00209 <span class="comment">// Series allpass filters</span>
<a name="l00210"></a>00210 <span class="keywordflow">for</span> ( <span class="keywordtype">int</span> i = 0; i < nAllpasses; i++ ) {
<a name="l00211"></a>00211 <span class="comment">// Left channel</span>
<a name="l00212"></a>00212 <span class="comment">//StkFloat vn_m = FreeVerb::undenormalize(allPassDelayL_[i].nextOut());</span>
<a name="l00213"></a>00213 StkFloat vn_m = allPassDelayL_[i].<a class="code" href="classstk_1_1Delay.html#a2433e3246551f4fdf1366884cd2ae426" title="Return the value that will be output by the next call to tick().">nextOut</a>();
<a name="l00214"></a>00214 StkFloat vn = outL + (g_ * vn_m);
<a name="l00215"></a>00215 allPassDelayL_[i].<a class="code" href="classstk_1_1Delay.html#aa1a929e0e324417b8a55cbf8770532e9" title="Input one sample to the filter and return one output.">tick</a>(vn);
<a name="l00216"></a>00216
<a name="l00217"></a>00217 <span class="comment">// calculate output</span>
<a name="l00218"></a>00218 outL = -vn + (1.0 + g_)*vn_m;
<a name="l00219"></a>00219
<a name="l00220"></a>00220 <span class="comment">// Right channel</span>
<a name="l00221"></a>00221 <span class="comment">//vn_m = FreeVerb::undenormalize(allPassDelayR_[i].nextOut());</span>
<a name="l00222"></a>00222 vn_m = allPassDelayR_[i].<a class="code" href="classstk_1_1Delay.html#a2433e3246551f4fdf1366884cd2ae426" title="Return the value that will be output by the next call to tick().">nextOut</a>();
<a name="l00223"></a>00223 vn = outR + (g_ * vn_m);
<a name="l00224"></a>00224 allPassDelayR_[i].<a class="code" href="classstk_1_1Delay.html#aa1a929e0e324417b8a55cbf8770532e9" title="Input one sample to the filter and return one output.">tick</a>(vn);
<a name="l00225"></a>00225
<a name="l00226"></a>00226 <span class="comment">// calculate output</span>
<a name="l00227"></a>00227 outR = -vn + (1.0 + g_)*vn_m;
<a name="l00228"></a>00228 }
<a name="l00229"></a>00229
<a name="l00230"></a>00230 <span class="comment">// Mix output</span>
<a name="l00231"></a>00231 lastFrame_[0] = outL*wet1_ + outR*wet2_ + inputL*dry_;
<a name="l00232"></a>00232 lastFrame_[1] = outR*wet1_ + outL*wet2_ + inputR*dry_;
<a name="l00233"></a>00233
<a name="l00234"></a>00234 <span class="comment">/*</span>
<a name="l00235"></a>00235 <span class="comment"> // Hard limiter ... there's not much else we can do at this point</span>
<a name="l00236"></a>00236 <span class="comment"> if ( lastFrame_[0] >= 1.0 ) {</span>
<a name="l00237"></a>00237 <span class="comment"> lastFrame_[0] = 0.9999;</span>
<a name="l00238"></a>00238 <span class="comment"> }</span>
<a name="l00239"></a>00239 <span class="comment"> if ( lastFrame_[0] <= -1.0 ) {</span>
<a name="l00240"></a>00240 <span class="comment"> lastFrame_[0] = -0.9999;</span>
<a name="l00241"></a>00241 <span class="comment"> }</span>
<a name="l00242"></a>00242 <span class="comment"> if ( lastFrame_[1] >= 1.0 ) {</span>
<a name="l00243"></a>00243 <span class="comment"> lastFrame_[1] = 0.9999;</span>
<a name="l00244"></a>00244 <span class="comment"> }</span>
<a name="l00245"></a>00245 <span class="comment"> if ( lastFrame_[1] <= -1.0 ) {</span>
<a name="l00246"></a>00246 <span class="comment"> lastFrame_[1] = -0.9999;</span>
<a name="l00247"></a>00247 <span class="comment"> }</span>
<a name="l00248"></a>00248 <span class="comment"> */</span>
<a name="l00249"></a>00249
<a name="l00250"></a>00250 <span class="keywordflow">return</span> lastFrame_[channel];
<a name="l00251"></a>00251 }
<a name="l00252"></a>00252
<a name="l00253"></a>00253 }
<a name="l00254"></a>00254
<a name="l00255"></a>00255 <span class="preprocessor">#endif</span>
</pre></div></div>
<HR>
<table>
<tr><td><A HREF="http://ccrma.stanford.edu/software/stk/"><I>The Synthesis ToolKit in C++ (STK)</I></A></td></tr>
<tr><td>©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
</table>
</BODY>
</HTML>
|