Last active
May 15, 2016 19:31
-
-
Save novelistparty/d43e5f7a515f1f927cc01476e0ec5e97 to your computer and use it in GitHub Desktop.
m-sequence output as wav file from LFSR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
/* | |
Run with: | |
make msequence_16_4taps && ./msequence_16_4taps 4847 2 | sox -q -t .raw -r 44100 -c 1 -b 16 -e signed-integer - output.wav | |
Uses code from Wikipedia article "Pseudorandom binary sequence" | |
Feedback taps from tabulated values at: | |
http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm | |
More values: | |
15 Stages, 4 taps: | |
[15, 14, 9, 8] | |
[15, 14, 9, 3] | |
[15, 14, 9, 2] | |
[15, 14, 8, 5] | |
[15, 14, 8, 4] | |
31 stages, 6 taps: | |
[31, 30, 29, 28, 18, 6] | |
[31, 30, 29, 28, 17, 9] | |
[31, 30, 29, 28, 17, 7] | |
[31, 30, 29, 28, 16, 8] | |
[31, 30, 29, 28, 14, 6] | |
[31, 30, 29, 28, 14, 3] | |
*/ | |
void print_binary(uint16_t c) { | |
for (size_t i = 8 * sizeof(c); i-- > 0; ) { | |
fprintf(stderr, "%d", (c >> i) & 1); | |
} | |
fprintf(stderr, "\n"); | |
} | |
int main(int argc, char* argv[]) { | |
if (argc < 3) { | |
fprintf(stderr, "%s: Error, provide a seed value and symbol length\n", argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
uint16_t start = atoi(argv[1]); | |
uint16_t symbol_length = atoi(argv[2]); | |
if (symbol_length < 2) { | |
fprintf(stderr, "Error: Minimum symbol length is 2. Setting it to 2. (\"%hd\" was entered)\n", symbol_length); | |
symbol_length = 2; | |
} | |
/* Data for symbol output */ | |
int16_t * symbol_one = malloc(sizeof(int16_t) * symbol_length); | |
int16_t * symbol_zero = malloc(sizeof(int16_t) * symbol_length); | |
for (size_t i = 0; i < symbol_length; i++) { | |
symbol_one[i] = 0x7FFF; | |
symbol_zero[i] = -0x7FFF; | |
} | |
/* Linear Feedback Shift Register */ | |
uint16_t a = start; | |
fprintf(stderr, "First in sequence: "); | |
print_binary(a); | |
for(size_t i = 1;; i++) { | |
uint16_t newbit = ((((a >> 15) | |
^ (a >> 14) | |
^ (a >> 9) | |
^ (a >> 3)) | |
& 1)); | |
a = ((a << 1) | newbit) & 0xffff; | |
/* print_binary(a); */ | |
if (0x1 == newbit) { | |
fwrite(symbol_one, sizeof(int16_t), symbol_length, stdout); | |
} else { | |
fwrite(symbol_zero, sizeof(int16_t), symbol_length, stdout); | |
} | |
if (a == start) { | |
fprintf(stderr, "m-sequency repetition period is %zu\n", i); | |
break; | |
} | |
if (i > 0xfffff) { | |
fprintf(stderr, "Max Count Reached.\n"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
fflush(stdout); | |
fclose(stdout); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment