[TTBlue-devel] [423] branches/active: Fixes for TTAdsr:
Status: Alpha
Brought to you by:
tap
From: <ti...@gr...> - 2008-05-17 19:37:07
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[423] branches/active: Fixes for TTAdsr:</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>423</dd> <dt>Author</dt> <dd>tim</dd> <dt>Date</dt> <dd>2008-05-17 19:37:08 +0000 (Sat, 17 May 2008)</dd> </dl> <h3>Log Message</h3> <pre>Fixes for TTAdsr: * sign of NOISE_FLOOR was wrong, causing exponential mode to freak and write INF values to output * used the default attr getter where we don't need to use a custom accessor * the macro-created accessors were exhibiting bug where the values were always clipped to 1 no matter what. I couldn't debug them, so #ifdef'd around them for the time-being * added mode attr and code to support exponential mode again</pre> <h3>Modified Paths</h3> <ul> <li><a href="#branchesactiveincludesunitsTTAdsrh">branches/active/includes/units/TTAdsr.h</a></li> <li><a href="#branchesactivelibraryTTBluexcodeprojprojectpbxproj">branches/active/library/TTBlue.xcodeproj/project.pbxproj</a></li> <li><a href="#branchesactivesourceunitsTTAdsrcpp">branches/active/source/units/TTAdsr.cpp</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="branchesactiveincludesunitsTTAdsrh"></a> <div class="modfile"><h4>Modified: branches/active/includes/units/TTAdsr.h (422 => 423)</h4> <pre class="diff"><span> <span class="info">--- branches/active/includes/units/TTAdsr.h 2008-05-17 18:34:19 UTC (rev 422) +++ branches/active/includes/units/TTAdsr.h 2008-05-17 19:37:08 UTC (rev 423) </span><span class="lines">@@ -29,27 +29,30 @@ </span><span class="cx"> TTInt16 eg_state; </span><span class="cx"> TTBoolean trigger; </span><span class="cx"> </span><ins>+ TTSymbol& attrMode; </ins><span class="cx"> </span><span class="cx"> TTErr setAttack(const TTAttribute&, const TTValue& newValue); </span><del>- TTErr getAttack(const TTAttribute&, TTValue& value); </del><ins>+// TTErr getAttack(const TTAttribute&, TTValue& value); </ins><span class="cx"> </span><span class="cx"> TTErr setDecay(const TTAttribute&, const TTValue& newValue); </span><del>- TTErr getDecay(const TTAttribute&, TTValue& value); </del><ins>+// TTErr getDecay(const TTAttribute&, TTValue& value); </ins><span class="cx"> </span><span class="cx"> TTErr setSustainDb(const TTAttribute&, const TTValue& newValue); </span><span class="cx"> TTErr getSustainDb(const TTAttribute&, TTValue& newValue); </span><span class="cx"> </span><span class="cx"> TTErr setSustainAmp(const TTAttribute&, const TTValue& value); </span><del>- TTErr getSustainAmp(const TTAttribute&, TTValue& value); </del><ins>+// TTErr getSustainAmp(const TTAttribute&, TTValue& value); </ins><span class="cx"> </span><span class="cx"> TTErr setRelease(const TTAttribute&, const TTValue& newValue); </span><del>- TTErr getRelease(const TTAttribute&, TTValue& value); </del><ins>+// TTErr getRelease(const TTAttribute&, TTValue& value); + + TTErr setMode(const TTAttribute&, const TTValue& newValue); </ins><span class="cx"> </span><del>- //TTErr processAudio(TTAudioSignal& out); - TTErr processAudio(TTAudioSignal& in, TTAudioSignal& out); </del><ins>+ TTErr processAudioLinear(TTAudioSignal& in, TTAudioSignal& out); + TTErr processAudioExponential(TTAudioSignal& in, TTAudioSignal& out); </ins><span class="cx"> </span><span class="cx"> enum constants { </span><del>- NOISE_FLOOR = 120 </del><ins>+ NOISE_FLOOR = -120 </ins><span class="cx"> }; </span><span class="cx"> </span><span class="cx"> enum eg_states { </span></span></pre></div> <a id="branchesactivelibraryTTBluexcodeprojprojectpbxproj"></a> <div class="modfile"><h4>Modified: branches/active/library/TTBlue.xcodeproj/project.pbxproj (422 => 423)</h4> <pre class="diff"><span> <span class="info">--- branches/active/library/TTBlue.xcodeproj/project.pbxproj 2008-05-17 18:34:19 UTC (rev 422) +++ branches/active/library/TTBlue.xcodeproj/project.pbxproj 2008-05-17 19:37:08 UTC (rev 423) </span><span class="lines">@@ -323,9 +323,9 @@ </span><span class="cx"> isa = PBXGroup; </span><span class="cx"> children = ( </span><span class="cx"> 55332A6C0D9264AD00597792 /* TTAdsr.h */, </span><ins>+ 55332A6E0D9264B700597792 /* TTAdsr.cpp */, </ins><span class="cx"> 22C1BF400DA5CA43003747D3 /* TTAverage.h */, </span><span class="cx"> 22C1BF3D0DA5CA2F003747D3 /* TTAverage.cpp */, </span><del>- 55332A6E0D9264B700597792 /* TTAdsr.cpp */, </del><span class="cx"> A77FB4470D685CF60095A7FD /* TTBalance.h */, </span><span class="cx"> A77FB4490D685D020095A7FD /* TTBalance.cpp */, </span><span class="cx"> 22569C140D3E416F00328864 /* TTBandpassButterworth2.h */, </span></span></pre></div> <a id="branchesactivesourceunitsTTAdsrcpp"></a> <div class="modfile"><h4>Modified: branches/active/source/units/TTAdsr.cpp (422 => 423)</h4> <pre class="diff"><span> <span class="info">--- branches/active/source/units/TTAdsr.cpp 2008-05-17 18:34:19 UTC (rev 422) +++ branches/active/source/units/TTAdsr.cpp 2008-05-17 19:37:08 UTC (rev 423) </span><span class="lines">@@ -4,27 +4,21 @@ </span><span class="cx"> </span><span class="cx"> TTAdsr::TTAdsr(TTUInt8 newMaxNumChannels) </span><span class="cx"> : TTAudioObject("audio.adsr", newMaxNumChannels), output(0.), output_db(NOISE_FLOOR), </span><del>- eg_state(k_eg_inactive), trigger(false) </del><ins>+ eg_state(k_eg_inactive), trigger(false), attrMode(TT("linear")) </ins><span class="cx"> { </span><del>- registerAttribute(TT("attack"), kTypeFloat64, NULL, (TTGetterMethod)&TTAdsr::getAttack, - (TTSetterMethod)&TTAdsr::setAttack); - registerAttribute(TT("decay"), kTypeFloat64, NULL, (TTGetterMethod)&TTAdsr::getDecay, - (TTSetterMethod)&TTAdsr::setDecay); - registerAttribute(TT("release"), kTypeFloat64, NULL, (TTGetterMethod)&TTAdsr::getRelease, - (TTSetterMethod)&TTAdsr::setRelease); - registerAttribute(TT("sustain"), kTypeFloat64, NULL, (TTGetterMethod)&TTAdsr::getSustainAmp, - (TTSetterMethod)&TTAdsr::setSustainAmp); - registerAttribute(TT("sustain_db"), kTypeFloat64, NULL, (TTGetterMethod)&TTAdsr::getSustainDb, - (TTSetterMethod)&TTAdsr::setSustainDb); </del><ins>+ registerAttribute(TT("attack"), kTypeFloat64, &attack_ms, (TTSetterMethod)&TTAdsr::setAttack); + registerAttribute(TT("decay"), kTypeFloat64, &decay_ms, (TTSetterMethod)&TTAdsr::setDecay); + registerAttribute(TT("release"), kTypeFloat64, &release_ms, (TTSetterMethod)&TTAdsr::setRelease); + registerAttribute(TT("sustain"), kTypeFloat64, &sustain_amp, (TTSetterMethod)&TTAdsr::setSustainAmp); + registerAttribute(TT("sustain_db"), kTypeFloat64, NULL, (TTGetterMethod)&TTAdsr::getSustainDb, (TTSetterMethod)&TTAdsr::setSustainDb); </ins><span class="cx"> registerAttribute(TT("trigger"), kTypeBoolean, &trigger); </span><ins>+ registerAttribute(TT("mode"), kTypeSymbol, &attrMode, (TTSetterMethod)&TTAdsr::setMode); </ins><span class="cx"> </span><span class="cx"> setAttributeValue(TT("attack"), 50.); </span><span class="cx"> setAttributeValue(TT("decay"), 100.); </span><span class="cx"> setAttributeValue(TT("sustain_db"), -6.); </span><span class="cx"> setAttributeValue(TT("release"), 500.); </span><del>- - setProcess((TTProcessMethod)&TTAdsr::processAudio); - //setProcess((TTProcessMethodOneChan)&TTAdsr::processAudio); </del><ins>+ setAttributeValue(TT("mode"), TT("linear")); // <-- sets the process method </ins><span class="cx"> } </span><span class="cx"> </span><span class="cx"> TTAdsr::~TTAdsr() </span><span class="lines">@@ -32,6 +26,7 @@ </span><span class="cx"> ; </span><span class="cx"> } </span><span class="cx"> </span><ins>+#ifdef USE_MACRO_ACCESSORS </ins><span class="cx"> /** Defines a setter function, the first parameter creates a function prefixed with the word set </span><span class="cx"> * in front of it. The second parameter is the prefix for the variable that has been defined in the class */ </span><span class="cx"> #define DEFINE_SETPARAM(functionName, prefix) TTErr TTAdsr::set ## functionName (const TTAttribute&, const TTValue& newValue) { \ </span><span class="lines">@@ -58,6 +53,41 @@ </span><span class="cx"> DEFINE_PARAM(Decay, decay); </span><span class="cx"> DEFINE_PARAM(Release, release); </span><span class="cx"> </span><ins>+#else // using old fashioned not-generated-by-a-macro accessors + + +TTErr TTAdsr::setAttack(const TTAttribute&, const TTValue& newValue) +{ + attack_ms = TTClip((TTFloat64)newValue, 1.0, 60000.0); + attack_samples = long((attack_ms / 1000.0) * sr); + attack_step = 1.0 / attack_samples; + attack_step_db = -(double(NOISE_FLOOR) / attack_samples); + return kTTErrNone; +} + + +TTErr TTAdsr::setDecay(const TTAttribute&, const TTValue& newValue) +{ + decay_ms = TTClip((TTFloat64)newValue, 1.0, 60000.0); + decay_samples = long((decay_ms / 1000.0) * sr); + decay_step = 1.0 / decay_samples; + decay_step_db = -(double(NOISE_FLOOR) / decay_samples); + return kTTErrNone; +} + + +TTErr TTAdsr::setRelease(const TTAttribute&, const TTValue& newValue) +{ + release_ms = TTClip((TTFloat64)newValue, 1.0, 60000.0); + release_samples = long((release_ms / 1000.0) * sr); + release_step = 1.0 / release_samples; + release_step_db = -(double(NOISE_FLOOR) / release_samples); + return kTTErrNone; +} + +#endif + + </ins><span class="cx"> TTErr TTAdsr::setSustainAmp(const TTAttribute&, const TTValue& newValue) </span><span class="cx"> { </span><span class="cx"> sustain_amp = newValue; </span><span class="lines">@@ -65,11 +95,13 @@ </span><span class="cx"> return kTTErrNone; </span><span class="cx"> } </span><span class="cx"> </span><ins>+/* </ins><span class="cx"> TTErr TTAdsr::getSustainAmp(const TTAttribute&, TTValue& value) </span><span class="cx"> { </span><span class="cx"> value = sustain_amp; </span><span class="cx"> return kTTErrNone; </span><span class="cx"> } </span><ins>+*/ </ins><span class="cx"> </span><span class="cx"> TTErr TTAdsr::setSustainDb(const TTAttribute&, const TTValue& newValue) </span><span class="cx"> { </span><span class="lines">@@ -83,6 +115,18 @@ </span><span class="cx"> value = linearToDb(sustain_amp); </span><span class="cx"> return kTTErrNone; </span><span class="cx"> } </span><ins>+ + +TTErr TTAdsr::setMode(const TTAttribute&, const TTValue& newValue) +{ + attrMode = newValue; + if(attrMode == TT("exponential")) + setProcess((TTProcessMethod)&TTAdsr::processAudioExponential); + else + setProcess((TTProcessMethod)&TTAdsr::processAudioLinear); + return kTTErrNone; +} + </ins><span class="cx"> /* </span><span class="cx"> TTErr TTAdsr::processAudio(TTAudioSignal& out) </span><span class="cx"> { </span><span class="lines">@@ -134,7 +178,7 @@ </span><span class="cx"> } </span><span class="cx"> */ </span><span class="cx"> </span><del>-TTErr TTAdsr::processAudio(TTAudioSignal& in, TTAudioSignal& out) </del><ins>+TTErr TTAdsr::processAudioLinear(TTAudioSignal& in, TTAudioSignal& out) </ins><span class="cx"> { </span><span class="cx"> TTSampleValue* inSample; </span><span class="cx"> TTSampleValue* outSample; </span><span class="lines">@@ -194,3 +238,70 @@ </span><span class="cx"> </span><span class="cx"> return kTTErrNone; </span><span class="cx"> } </span><ins>+ + +TTErr TTAdsr::processAudioExponential(TTAudioSignal& in, TTAudioSignal& out) +{ + TTSampleValue* inSample; + TTSampleValue* outSample; + TTUInt16 vs = in.getVectorSize(); + bool checkAudioTrigger = false; + + // If the two signals are the same instance, then we know that only an output signal has been passed + // So in that case we use the control-rate trigger instead of an audio-rate trigger. + // TODO: Is there a decent way to do this without having to check this every single vector? + if(&in != &out) + checkAudioTrigger = true; + + inSample = in.sampleVectors[0]; + outSample = out.sampleVectors[0]; + + while(vs--) { + if(checkAudioTrigger) + trigger = (TTBoolean)(*inSample++ > 0.5); + + if(trigger) { + if(eg_state == k_eg_inactive || eg_state == k_eg_release) + eg_state = k_eg_attack; + } else { + if(eg_state != k_eg_inactive && eg_state != k_eg_release) + eg_state = k_eg_release; + } + + switch(eg_state){ + case k_eg_attack: // ATTACK + output_db += attack_step_db; // Increment the output + if (output_db >= 0.0){ // If we've hit the top of the attack, + eg_state = k_eg_decay; // start the decay stage + output = 1.0; // Make sure we didn't go over 1.0 + } + else + output = dbToLinear(output_db); + break; + case k_eg_decay: // DECAY + output_db -= decay_step_db; + output = dbToLinear(output_db); // Decrement the output + if (output <= sustain_amp){ // If we've hit the bottom of the decay, + eg_state = k_eg_sustain; // start the sustain stage + output = sustain_amp; // Lock in the sustain value + } + break; + case k_eg_sustain: // SUSTAIN + break; // leave it alone + + case k_eg_release: // RELEASE + output_db -= release_step_db; + if (output_db <= NOISE_FLOOR){ // If we've hit the basement, + eg_state = k_eg_inactive; // deactivate the eg + output = 0.0; // Make sure we didn't dip too low + } + else + output = dbToLinear(output_db); // Decrement the output + break; + } + *outSample++ = output; + } + + return kTTErrNone; +} + </ins></span></pre> </div> </div> </body> </html> |