1 /*+============================================================================ 2 | 3 | LEGAL 4 | 5 | PN Version 1.0 - A Program for generating pseudonoise sequences. 6 | Copyright (C) 1986-2024 by Sean Erik O'Connor. All Rights Reserved. 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see <http://www.gnu.org/licenses/>. 20 | 21 | The author's address is seanerikoconnor!AT!gmail!DOT!com 22 | with !DOT! replaced by . and the !AT! replaced by @ 23 | 24 +============================================================================*/ 25 26 #include <stdio.h> 27 28 char * legalNotice = 29 { 30 "\n" 31 "PN Version 1.0 - A Program for generating pseudonoise sequences.\n" 32 "Copyright (C) 1986-2024 by Sean Erik O'Connor. All Rights Reserved.\n" 33 "\n" 34 "PN comes with ABSOLUTELY NO WARRANTY; for details see the\n" 35 "GNU General Public License. This is free software, and you are welcome\n" 36 "to redistribute it under certain conditions; see the GNU General Public License\n" 37 "for details.\n\n" 38 } ; 39 40 int pn( void ) ; 41 42 /* Print out values of a sample binary PN sequence. */ 43 44 int main( int argc, char * argv[] ) 45 { 46 int i ; 47 48 /* Show the legal notice first. */ 49 printf( "%s", legalNotice ) ; 50 51 /* Print out PN sequence values. */ 52 for (i = 1 ; i <= 15 ; ++i) 53 { 54 printf( "pn %3d = %3d\n", i, pn() ) ; 55 } 56 57 return 0 ; 58 } 59 60 61 /* Compute the bits of a binary PN sequence. */ 62 63 int pn( void ) 64 { 65 static unsigned int shiftRegister = 1 ; /* Initial state of shift register, */ 66 /* a = 1, a = ... = a = 0 */ 67 /* 0 1 3 */ 68 69 unsigned int m = 4 ; /* Period of PN sequence = 2^m - 1 = 15 */ 70 71 unsigned int primPoly = 0x13 ; /* Primitive polynomial coefficients, */ 72 /* x^4 + x + 1 = 10011 (binary) = 13 hex */ 73 74 unsigned int mask = (1 << (m-1)) ; /* Selects the mth bit. */ 75 76 unsigned int multiplier = 77 (primPoly ^ (1 << m)) ; /* Feedback multiplier, corresponding to */ 78 /* the taps f ... f on the shift register, */ 79 /* 3 0 */ 80 /* equal to the primitive polynomial */ 81 /* coefficients with highest degree term */ 82 /* omitted. */ 83 84 unsigned int feedback ; /* Feedback bit. */ 85 unsigned int bit ; /* Bit 0 or 1 of the PN sequence. */ 86 unsigned int product ; /* Bitwise product. */ 87 unsigned int i ; 88 89 product = shiftRegister & multiplier ; /* Modulo 2 multiplication of feedback */ 90 /* taps times shift register contents */ 91 /* in parallel. */ 92 93 /* Sum up the product bits modulo 2 to get the feedback bit. */ 94 for (i = 1, feedback = 0 ; i <= m ; ++i) 95 { 96 feedback ^= (1 & product) ; /* Add first bit of the product into */ 97 /* the running sum of the feedback. */ 98 99 product >>= 1 ; /* Shift to expose next bit of the product. */ 100 } 101 102 bit = shiftRegister & 1 ; /* Save the zeroth (PN sequence) bit of */ 103 /* of the shift register. */ 104 105 shiftRegister >>= 1 ; /* Shift the shift register contents. */ 106 107 if (feedback) /* Add feedback (if any) to the shift register */ 108 { /* contents. */ 109 shiftRegister ^= mask ; 110 } 111 112 return( bit ) ; /* Return the PN sequence bit. */ 113 }