<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Digital filtering</title>
		<link>http://forums.leaflabs.com/topic.php?id=10396</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:22:32 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=10396" rel="self" type="application/rss+xml" />

		<item>
			<title>mlundinse on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22972</link>
			<pubDate>Mon, 18 Mar 2013 14:11:29 +0000</pubDate>
			<dc:creator>mlundinse</dc:creator>
			<guid isPermaLink="false">22972@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Check the pow call, perhaps it should be pow( resonance + 24/16, 0.5 )  to calculate a square root.&#60;br /&#62;
Check the values of r and c with a debug println so the filter is stable&#60;br /&#62;
With array values between 0 and 1024 this corresponds to a very small amplitude, the Maple pwm resolution is 16 bits so scale it up by a factor of 32.&#60;br /&#62;
As long as the filter is stable the calculated values of the filtered signal, v1, are in the same range as the inputs, so the filtered values can be directly fed to the pwm.&#60;/p&#62;
&#60;p&#62;int v0,v1;&#60;br /&#62;
int ci, omrc;&#60;/p&#62;
&#60;p&#62;float c = 2*3.14*filterval/samplerate; //Small angles, tanx = x, samplerate is 28014hz&#60;br /&#62;
float r = pow(resonance+24/16, 0.5); //Resonance value lies in the range of 1 - 32ish&#60;/p&#62;
&#60;p&#62;/* convert filter coefficients to 16.16 fixed points&#60;br /&#62;
/* Both int and long are 32 bits on arm architecture */&#60;br /&#62;
ci = (int)(c*65536);&#60;br /&#62;
omrc = 65536-(int)(r*c*65536);&#60;/p&#62;
&#60;p&#62;/* In sample rate loop, Update the phase value, IncrementV2, then read wave table and update filter */&#60;/p&#62;
&#60;p&#62;v0 = (omrc*v0 - ci*v1 + ci*32*arrayu[IncrementV2]) &#38;gt;&#38;gt; 16;&#60;br /&#62;
v1 = (omrc*v1 + ci*v0) &#38;gt;&#38;gt; 16;&#60;/p&#62;
&#60;p&#62;/* Write output */&#60;br /&#62;
pwmWrite(BOARD_ANALOG_OUT, v1);&#60;/p&#62;
&#60;p&#62;Good luck, I have not tested it or even tried to compile it, but hope it helps.&#60;br /&#62;
As you have Matlab you can use Matlab to debug the sanity of the algorithms used.&#60;br /&#62;
Magnus
&#60;/p&#62;</description>
		</item>
		<item>
			<title>pyrohaz on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22971</link>
			<pubDate>Mon, 18 Mar 2013 09:53:01 +0000</pubDate>
			<dc:creator>pyrohaz</dc:creator>
			<guid isPermaLink="false">22971@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;No problem, thank you for the help so far anyway!&#60;/p&#62;
&#60;p&#62;The values in arrayu are just the values for a square wave between 1 and 1024:&#60;br /&#62;
int arrayu[512] = {1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1023, 1024, 1023, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1023, 1024, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1023, 1024, 1024, 1023, 1023, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1023, 1024, 1023, 1023, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1023, 1023, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1023, 1024, 1024, 1023, 1023, 1024, 1024, 1024, 1023, 1024, 1024, 1023, 1023, 1023, 1023, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1023, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1023, 1024, 1024, 1024, 1023, 1024, 1023, 1024, 1023, 1024, 1024, 1024, 1024, 1023, 1023, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1023, 1023, 1024, 1024, 1024, 1024, 1023, 1024, 1023, 1024, 1024, 1024, 1024, 1024, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};&#60;/p&#62;
&#60;p&#62;I created them on matlab, hence why a few are 1023 instead but thats not a problem.&#60;/p&#62;
&#60;p&#62;So sorry to be a pain but would you be able to write me the final piece of code that would be required, all relating v0, v1, r and c?&#60;/p&#62;
&#60;p&#62;Thanks a bunch!
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mlundinse on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22969</link>
			<pubDate>Mon, 18 Mar 2013 02:00:56 +0000</pubDate>
			<dc:creator>mlundinse</dc:creator>
			<guid isPermaLink="false">22969@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;yes I was a bit lazy, as you point out, the v1 must also be bitshifted after the multiplications. &#60;/p&#62;
&#60;p&#62;The values in the arrayu must also be scaled as 16.16 bit fixed point values (is this a sine table ?), and the output v1 scaled to fit the number of bits in the pwm.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>pyrohaz on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22967</link>
			<pubDate>Sun, 17 Mar 2013 21:53:31 +0000</pubDate>
			<dc:creator>pyrohaz</dc:creator>
			<guid isPermaLink="false">22967@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;gbulmer - unfortunately, I know absolutely nothing about the command line tools! Would they be hard to implement and would they increase the speed of the filter command i'm trying to use?&#60;/p&#62;
&#60;p&#62;mlundinse - cheers for the help! I tried the code you gave me and it didn't seem to work properly, the output just seemed to produce white noise. Since the code is dependent on both v0 and v1, do I need to do any bitshifts for v1?&#60;/p&#62;
&#60;p&#62;v0 = (omrc*v0 - (cfp)*v1 + (c)*arrayu[IncrementV2]) &#38;gt;&#38;gt; 16;&#60;br /&#62;
v1 = (omrc*v1 + (cfp)*v0) &#38;gt;&#38;gt; 16;&#60;/p&#62;
&#60;p&#62;Would the above work? Sorry for my lack of ingenuity, this is the final step of my project and it would be great if it worked haha.&#60;/p&#62;
&#60;p&#62;I just realised that as you say scaling by 2^32 because you can rearrange it to (0.1*0.3) * (2^16*2^16) which using simple indices maths turns out as (0.1*0.3*2^32).&#60;/p&#62;
&#60;p&#62;Cheers so far!
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mlundinse on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22964</link>
			<pubDate>Sun, 17 Mar 2013 17:00:53 +0000</pubDate>
			<dc:creator>mlundinse</dc:creator>
			<guid isPermaLink="false">22964@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;as long as there is only two factors in the product you can sum them before shifting.&#60;br /&#62;
r and c are float, dont multiply them with 2^16 until you convert them to fixed point integers.&#60;/p&#62;
&#60;p&#62;fixed point versions of the filter coefficients:&#60;/p&#62;
&#60;p&#62;int oneminusrc = 1&#38;lt;&#38;lt;16-(int)(r*c*65536);&#60;br /&#62;
int cfp = (int)(c*65536)&#60;/p&#62;
&#60;p&#62;v0 = (oneminusrc*v0 - cfp*v1 + cfp*arrayu[IncrementV1])&#38;gt;&#38;gt;16;&#60;/p&#62;
&#60;p&#62;Your example, in fixed point arithmetic the real, floating point, value is multiplied by 2^16. When you multily two such numbers the real walue will be scaled by 2^32, but then we shift by 16 bits to get the scaling back to 2^16, as a fixed point integer used in your filter loop. Then afterwards the fixed point value value is divided by floating point 65536.0 to get the real float value back.&#60;/p&#62;
&#60;p&#62;((0.1*2^16)*(0.3*2^16))&#38;gt;&#38;gt;16 == 0.03*2^16
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22961</link>
			<pubDate>Sun, 17 Mar 2013 13:04:28 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">22961@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;pyrohaz - are you comfortable with the command-line tools (used under the covers by Maple IDE?)&#60;/p&#62;
&#60;p&#62;I ask because the &#60;a href=&#34;https://launchpad.net/gcc-arm-embedded&#34;&#62;ARM Launchpad embedded gcc&#60;/a&#62; could either replace the parts in the IDE, or used from the command line. &#60;/p&#62;
&#60;p&#62;The important point about the Launchpad gcc is it's version 4.7, which supports fixed point, and saturating data types using integer operations &#60;a href=&#34;http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html&#34; rel=&#34;nofollow&#34;&#62;http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;There is a thread on the forum where someone has used it.&#60;/p&#62;
&#60;p&#62;I think this is non-trivial, and would take time and effort to get comfortable. However if you're intending to do a lot of coding, it might make the arithmetic expressions easy.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>pyrohaz on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22959</link>
			<pubDate>Sun, 17 Mar 2013 11:06:09 +0000</pubDate>
			<dc:creator>pyrohaz</dc:creator>
			<guid isPermaLink="false">22959@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hey, cheers for the reply! Well the v0 and v1 section is done within an interrupt to write the next sample to the PWM register.&#60;/p&#62;
&#60;p&#62;Am I right in assuming:&#60;br /&#62;
     filterval = (100+analogRead(filterpot));&#60;br /&#62;
     c = pow(2, 16)*(6.28*(100+filterval)/SampleRate);&#60;br /&#62;
     r = pow(2, 16)*pow(0.5, ((filterval/128)+30)/16); &#60;/p&#62;
&#60;p&#62;     v0 = ((65535-r*c)*v0 - (c)*v1 + (c)*arrayu[IncrementV1])&#38;gt;&#38;gt;16;&#60;br /&#62;
     v1 = ((65536-r*c)*v1 + (c)*v0)&#38;gt;&#38;gt;16;&#60;/p&#62;
&#60;p&#62;Or do I need to shift every multiplication by 16?&#60;/p&#62;
&#60;p&#62;By multiplying the c by 2^16, gives a range from 63114 to 1483 (within range of unsigned int) and multiplying r by 2^16 gives a range of 129818 to 89750 (within the range of a long).&#60;/p&#62;
&#60;p&#62;Am I correct in assuming that (1-r*c) needs to become (2^16-r*c)?&#60;/p&#62;
&#60;p&#62;The only reason I really find this hard to grasp is for example&#60;br /&#62;
0.1*0.3 in integer math would be&#60;/p&#62;
&#60;p&#62;((0.1*2^16)*(0.3*2^16))&#38;gt;&#38;gt;32&#60;/p&#62;
&#60;p&#62;Where the floats (0.1 and 0.3) are being multiplied to make them large integers then divided later again to turn them into floats if you get me.&#60;/p&#62;
&#60;p&#62;Thanks, Harris
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mlundinse on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22958</link>
			<pubDate>Sun, 17 Mar 2013 08:20:08 +0000</pubDate>
			<dc:creator>mlundinse</dc:creator>
			<guid isPermaLink="false">22958@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;The slow part here is probably the calculation of the filter coefficients. So if you read the filterpot at a lower frequency (10Hz ?) and reclaculate r and c only when the pot values or the resonance have changed, then the main filter loop should run real fast.&#60;/p&#62;
&#60;p&#62;Use 16.16 or 8.24 fixed point arithmetic. That means the low order 16 or 8 bits of a 32 bit integer are fraction, and the high bits are integer part.&#60;br /&#62;
- Add numbers as usual&#60;br /&#62;
- Multiply numbers and then normalize by shifting 16 or 8 bits to the right.&#60;br /&#62;
- Flot to pixed point, just multiply with the power of 2, 65536 or 256.&#60;/p&#62;
&#60;p&#62;Regards, Magnus
&#60;/p&#62;</description>
		</item>
		<item>
			<title>pyrohaz on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22955</link>
			<pubDate>Sat, 16 Mar 2013 22:08:20 +0000</pubDate>
			<dc:creator>pyrohaz</dc:creator>
			<guid isPermaLink="false">22955@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hmm after searcing the MusicDSP database, I implemented the 1-RC and C filter. So far it seems to be working well though its being used in a realtime situation and unfortunately seems to be running quite slow. Since its dependent on float math, how can I convert it to use integer math instead?&#60;/p&#62;
&#60;p&#62;filterval = 1+analogRead(filterpot)  //Between 1 and 4096&#60;br /&#62;
c = 2*3.14*filterval/samplerate  //Small angles, tanx = x, samplerate is 28014hz&#60;br /&#62;
r = pow(0.5, resonance+24/16))  //Resonance value lies in the range of 1 - 32ish&#60;br /&#62;
v0 = (1-r*c)*v0 - (c)*v1 + (c)*inputval;&#60;br /&#62;
v1 = (1-r*c)*v1 + (c)*v0;&#60;/p&#62;
&#60;p&#62;Output is v1, written to pwm, inputval is a sample in the range of 1 and 1024.&#60;/p&#62;
&#60;p&#62;Could anyone aid me in converting this to integer math?&#60;/p&#62;
&#60;p&#62;Thanks, Harris
&#60;/p&#62;</description>
		</item>
		<item>
			<title>pyrohaz on "Digital filtering"</title>
			<link>http://forums.leaflabs.com/topic.php?id=10396#post-22951</link>
			<pubDate>Sat, 16 Mar 2013 09:10:30 +0000</pubDate>
			<dc:creator>pyrohaz</dc:creator>
			<guid isPermaLink="false">22951@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hey again guys (sorry for the mass questions!)&#60;/p&#62;
&#60;p&#62;I'm wondering how I can make a variable low pass filter in code? It needs to be a chebyshev lowpass with a passband ripple of minimum 6dB (to give that resonant peak), cutoff frequency needs to be variable from about 100 up to about 5k or so. Sample rate is 28014Hz and my wavetable consists of values between 0 and 1024.&#60;/p&#62;
&#60;p&#62;I had a go with the website: &#60;a href=&#34;http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html&#34; rel=&#34;nofollow&#34;&#62;http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html&#60;/a&#62; in creating a couple of filters and these work in code but I can't figure out how to vary them! I know its dependent on the output gain, and the two values that preceed yv[0] and yv[1] but I can't seem to find any correlation in how these affect the cutoff frequency.&#60;/p&#62;
&#60;p&#62;As you can probably tell, i'm not very versed in filter knowledge!&#60;/p&#62;
&#60;p&#62;Cheers,
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
