Skip to content

Instantly share code, notes, and snippets.

@mjsyts
Last active December 18, 2022 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjsyts/2dc977fab6fb7690f3fe5e48ec21859a to your computer and use it in GitHub Desktop.
Save mjsyts/2dc977fab6fb7690f3fe5e48ec21859a to your computer and use it in GitHub Desktop.
//jsUtils.h
namespace jsUtils {
template<typename T> unsigned int getBit(T n, unsigned int pos){
return ((n >> pos) & 1);
}
template<typename T> T setBit(T number, unsigned int pos, unsigned int newBit){
number ^= (-(unsigned long)newBit ^ number) & (1UL << pos);
return number;
}
}
// LFSRNoise.cpp
#include "SC_PlugIn.hpp"
#include "LFSRNoise.hpp"
#include "jsUtils.h"
static InterfaceTable *ft;
LFSRNoise::LFSRNoise() {
// set the calculation function.
if (isAudioRateIn(FREQ)) {
set_calc_function<LFSRNoise,&LFSRNoise::next_a>();
} else {
set_calc_function<LFSRNoise,&LFSRNoise::next_k>();
}
// 2. initialize the unit generator state variables.
// initialize a constant for multiplying the frequency
this->mFreqMul = sampleDur();
this->mVal = -1;
// 3. calculate one sample of output.
if (isAudioRateIn(0)) {
next_a(1);
} else {
next_k(1);
}
}
float LFSRNoise::progressSeq(float frequency) {
size_t increment = static_cast<size_t>(frequency / sampleRate());
uint16_t val = this->mVal;
unsigned int pos = in0(FB_POS);
if (pos > this->MAX_POS) {
pos = this->MAX_POS;
}
else if (pos < this->MIN_POS) {
pos = this->MIN_POS;
};
for (int i = 0; i < increment; i++) {
unsigned int x = jsUtils::getBit(val, 0)^jsUtils::getBit(val, 1);
val >>= 1;
val = jsUtils::setBit(val, pos, x);
};
if (val == 0) {
val = -1;
};
this->mVal = val;
return calcOutVal();
}
void LFSRNoise::next_a(int nSamples) {
//pointer to output buffer
float *outbuf = out(0);
//pointer to input buffer
const float *frequency = in(FREQ);
for (int i = 0; i < nSamples; ++i) {
outbuf[i] = progressSeq(frequency[i]);
}
}
float LFSRNoise::calcOutVal()
{
if (jsUtils::getBit(this->mVal, 0) == 1) {
return 1.f;
}
else {
return -1.f;
};
}
void LFSRNoise::next_k(int nSamples) {
const float frequencyParam = in(FREQ)[0];
SlopeSignal<float> slopedFrequency =
makeSlope(frequencyParam, m_frequency_past);
float *outbuf = out(0);
for (int i = 0; i < nSamples; ++i) {
const float freq = slopedFrequency.consume();
outbuf[i] = progressSeq(freq);
}
m_frequency_past = slopedFrequency.value;
}
PluginLoad(LFSRNoise) {
// Plugin magic
ft = inTable;
registerUnit<LFSRNoise>(ft, "LFSRNoise", false);
}
// LFSRNoise.hpp
// m josiah sytsma
#pragma once
#include "SC_PlugIn.hpp"
#include <stdint.h>
class LFSRNoise : public SCUnit {
enum Inputs { FREQ, FB_POS };
uint16_t mVal; //value
uint16_t mFreqMul; //constant for multiplying freq
const unsigned int MAX_POS = 15;
const unsigned int MIN_POS = 0;
// Calc function
void next_a(int nSamples);
void next_k(int nSamples);
//step through lfsr process
float progressSeq(float frequency);
//get output value
float calcOutVal();
// State variables
float m_frequency_past{0.f};
public:
LFSRNoise();
};
LFSRNoise : UGen {
*ar { |freq=440, fbPos=0, mul=1.0, add=0.0|
^this.multiNew('audio', freq, fbPos).madd(mul, add);
}
*kr { |freq=440, fbPos=0, mul=1.0, add=0.0|
^this.multiNew('control', freq, fbPos).madd(mul, add);
}
}
class:: LFSRNoise
summary:: A linear feedback shift register noise generator.
related:: TODO
categories:: UGens>TODO
description::
A 16-bit linear feedback shift register noise generator. Like Classes/LFNoise0, Generates random values at a rate given by the nearest integer division of the sample rate by the code::freq:: argument.
classmethods::
method::ar, kr
argument::freq
Approximate rate at which to generate values.
argument::fbPos
Position of the bit to replace with the XOR result of the highest bits.
argument::mul
Output will be multiplied by this value.
argument::add
This value will be added to the output.
Examples::
code::
::
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment