Scott Dattalo says
Speaking of mixing tones, during my hiatus I wrote a cute little twist routine. While primarily intended for adjusting the twist in DTMF generated signals, it has applications elsewhere too. It would work here to mix two arbitrary waves. You could cascade calls to this routine for mixing more than two tones. For N tones you'd need N1 calls. That's not terribly efficient, but at least you'd have a way of combining fixed waveforms with non 2^k weighted coefficients.The purpose of this routine is to evaluate:
A*x + B*y  A + BSuch that A+B = 2^N
This formula is useful for several applications. For example, DTMF generartors sometimes need to weight the individual sine waves differently. The term used to describe the difference in amplitudes is 'twist'. It's the ratio of the amplitudes in dB.
Another application of this formulation is for lowpass filtering. If 'x' is the current filtered value, and 'y' is the latest sample, then this equation will be a recursive lowpass filter. ztransforms may be used to calculate the frequency response, but that's beyond the scope of this simple description. An intui tive way to look at it is as weighted averages. If A is made large relative to B, then more emphasis is placed on the average. If B is large then the latest samples are given more weight.
Algorithm:
This algorithm exploits the relationship: A + B = 2^N. For example, consider N=4. Then the (A,B) pairs are:
(1,15), (2,14), (3,13), (4,12), (5,11), (6,10), (7,9), (8,8) i.e. B = 2^N  A , and , A = 2^N  BUpon closer examination, it's observed that the (A,B) pairs are two's complements of one another (modulo 2^N). E.g., the 2's complement of 1 mod 16 is 15. In general:
B = (~A + 1) % 2^NSubstituting this into the twist formula yields:
A*x + ((~A + 1) % 2^N)*y  2^NA modulo N operation means that only the lower N bits are significant. So dropping the notation and keeping this observation in mind we can simplify this equation:
A*x + (~A + 1)*y A*x + ~A*y + y  =  2^N 2^NWhich can be evaluated in psuedoC:
int A; /* initialized somewhere's else */ int twist ( int x, int y) { int num = y; num += (A & 0x01) ? x : y; num >>= 1 num += (A & 0x02) ? x : y; num >>= 1 num += (A & 0x04) ? x : y; num >>= 1 num += (A & 0x08) ? x : y; num >>= 1 /* etc. for N>4 */ return num; }Excution time: 1 + 5*N cycles (e.g. 21cycles for A+B=16=2^4)
twist: movf y,w movwf num btfsc A,0 movf x,w addwf num,f rrf num,f movf y,w ;A macro would work well here... btfsc A,1 ;All we're doing is an unrolled movf x,w ;multiplication. If a bit in 'A' is addwf num,f ;set, we add 'y' to the running sum rrf num,f ;otherwise we add 'x'. In either case ;we divide by 2. movf y,w btfsc A,2 movf x,w addwf num,f rrf num,f movf y,w btfsc A,3 movf x,w addwf num,f rrf num,f return
See also:
file: /Techref/microchip/dttwist.htm, 4KB, , updated: 2005/10/11 16:54, local time: 2019/8/25 12:28,

©2019 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://www.piclist.com/techref/microchip/dttwist.htm"> Scott Dattalos' Dual Tone Digital Twist for the PIC</A> 
Did you find what you needed? 
PICList 2019 contributors:
o List host: MIT, Site host massmind.org, Top posters @20190825 RussellMc, David Van Horn, Bob Blick, AB Pearce  UKRI STFC, Dwayne Reid, James Cameron, David C Brown, Jason White, Manu Abraham, Allen Mulvey, * Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. ongoing support is MOST appreciated! * Contributors: Richard Seriani, Sr. 
Welcome to www.piclist.com! 
.