/*+============================================================================ | | LEGAL | | PN Version 1.0 - A Program for generating pseudonoise sequences. | Copyright (C) 1986-2017 by Sean Erik O'Connor. All Rights Reserved. | | This program is free software: you can redistribute it and/or modify | it under the terms of the GNU General Public License as published by | the Free Software Foundation, either version 3 of the License, or | (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with this program. If not, see <http://www.gnu.org/licenses/>. | | The author's address is artificer!AT!seanerikoconnor!DOT!freeservers!DOT!com | with !DOT! replaced by . and the !AT! replaced by @ | +============================================================================*/ #include <stdio.h> char * legalNotice = { "\n" "PN Version 1.0 - A Program for generating pseudonoise sequences.\n" "Copyright (C) 1986-2017 by Sean Erik O'Connor. All Rights Reserved.\n" "\n" "PN comes with ABSOLUTELY NO WARRANTY; for details see the\n" "GNU General Public License. This is free software, and you are welcome\n" "to redistribute it under certain conditions; see the GNU General Public License\n" "for details.\n\n" } ; int pn( void ) ; /* Print out values of a sample binary PN sequence. */ int main( int argc, char * argv[] ) { int i ; /* Show the legal notice first. */ printf( "%s", legalNotice ) ; /* Print out PN sequence values. */ for (i = 1 ; i <= 15 ; ++i) { printf( "pn %3d = %3d\n", i, pn() ) ; } return 0 ; } /* Compute the bits of a binary PN sequence. */ int pn( void ) { static unsigned int shiftRegister = 1 ; /* Initial state of shift register, */ /* a = 1, a = ... = a = 0 */ /* 0 1 3 */ unsigned int m = 4 ; /* Period of PN sequence = 2^m - 1 = 15 */ unsigned int primPoly = 0x13 ; /* Primitive polynomial coefficients, */ /* x^4 + x + 1 = 10011 (binary) = 13 hex */ unsigned int mask = (1 << (m-1)) ; /* Selects the mth bit. */ unsigned int multiplier = (primPoly ^ (1 << m)) ; /* Feedback multiplier, corresponding to */ /* the taps f ... f on the shift register, */ /* 3 0 */ /* equal to the primitive polynomial */ /* coefficients with highest degree term */ /* omitted. */ unsigned int feedback ; /* Feedback bit. */ unsigned int bit ; /* Bit 0 or 1 of the PN sequence. */ unsigned int product ; /* Bitwise product. */ unsigned int i ; product = shiftRegister & multiplier ; /* Modulo 2 multiplication of feedback */ /* taps times shift register contents */ /* in parallel. */ /* Sum up the product bits modulo 2 to get the feedback bit. */ for (i = 1, feedback = 0 ; i <= m ; ++i) { feedback ^= (1 & product) ; /* Add first bit of the product into */ /* the running sum of the feedback. */ product >>= 1 ; /* Shift to expose next bit of the product. */ } bit = shiftRegister & 1 ; /* Save the zeroth (PN sequence) bit of */ /* of the shift register. */ shiftRegister >>= 1 ; /* Shift the shift register contents. */ if (feedback) /* Add feedback (if any) to the shift register */ { /* contents. */ shiftRegister ^= mask ; } return( bit ) ; /* Return the PN sequence bit. */ }