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
28char * 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
40int pn( void ) ;
41
42/* Print out values of a sample binary PN sequence. */
43
44int 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
63int 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}