Skip to content

Instantly share code, notes, and snippets.

@novelistparty
Last active May 15, 2016 19:31
Show Gist options
  • Save novelistparty/d43e5f7a515f1f927cc01476e0ec5e97 to your computer and use it in GitHub Desktop.
Save novelistparty/d43e5f7a515f1f927cc01476e0ec5e97 to your computer and use it in GitHub Desktop.
m-sequence output as wav file from LFSR
#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