tag:blogger.com,1999:blog-8003003859380421483.post1251358031719872540..comments2017-06-22T14:23:58.207-07:00Comments on Open Audio: Faster Log10 and PowChiphttp://www.blogger.com/profile/10352943033779293161noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-8003003859380421483.post-42470727627606817152017-06-22T14:23:58.207-07:002017-06-22T14:23:58.207-07:00If this is in reference to your prior post about a...If this is in reference to your prior post about a dynamic range compressor (http://openaudio.blogspot.com/2017/01/basic-dynamic-range-compressor.html), I have been working on some very efficient ways to do the logarithmic processing in a compressor.<br />Observations:<br />1) a^b is just a*a*a...b number of times.<br />2) Compression curve is log-linear, so the final gain function is an exponential proportional to e^-x.<br />3) Given the attack & release times on a compressor, you don't have to resolve to log(n) within a single sampling period.<br />4) The ratio is the slope of the log of the exponential function, which is a ratio of e^rx/e^x. The slope "r" just makes it a steeper or less steep line in the log domain.<br /><br />Strategy can be implemented with a successive approximation routine:<br />--Pseudocode every sample--<br />target = peak_detect(audio)<br />if(tracker < target) {<br /> tracker *= beta;<br />if(ratio_counter == ratio) {<br /> gain *= beta; //every ratio iterations this is multiplied<br />}<br />}<br />else if (tracker > target) <br />{<br /> tracker *= alpha;<br />if(ratio_counter == ratio) {<br /> gain *= alpha; //every ratio iterations this is multiplied<br />}<br />}<br />if(ratio_counter > ratio) {<br /> ratio_counter = 0;<br />}<br />Pre-computed, alpha is a number < 1 and beta is a number > 1, and they correspond to attack and release times respectively.<br /><br />Now I found for shorter attack/release times this makes a limit-cycle oscillator about the target when the envelope is not changing as fast as release time. More complexity is needed to make alpha and beta closer to 1.0 as you get close to the target in order to reduce the amplitude of the oscillation to an inaudible level (<60 dBFS min).<br /><br />The periodic multiplication can be performed like this as long as you are not picky about being granular with available attack and release times:<br />a = (a + a<>N<br />"<<" is bit shift left and ">>" is bit shift right.<br />Notice this assumes fixed point (integer) math. This probably doesn't save you anything if you're using floating-point numbers.<br />Transmogrifoxhttp://www.blogger.com/profile/14991576725725140192noreply@blogger.com