Created
June 27, 2021 16:43
-
-
Save Xenakios/b1d7a00fdb0639d2af8fa9d99ad143f9 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
class StarGateReverb | |
{ | |
public: | |
StarGateReverb() | |
{ | |
for (int i = 0; i < dram.size(); ++i) | |
dram[i] = 0; | |
for (int i = 0; i < delayTaps.size(); ++i) | |
{ | |
delayTaps[i] = 0; | |
gainCeiling[i] = 0; | |
} | |
auto coeffs = juce::dsp::IIR::Coefficients<float>::makeFirstOrderHighPass(44100.0, 25.0f); | |
juce::dsp::ProcessSpec spec; | |
spec.maximumBlockSize = 1; | |
spec.numChannels = 1; | |
spec.sampleRate = 44100; | |
for (int i = 0; i < 4; ++i) | |
{ | |
hpFilters[i].coefficients = coeffs; | |
hpFilters[i].prepare(spec); | |
} | |
} | |
std::pair<float,float> processSample(float in_left, float in_right) | |
{ | |
in_left = (in_left + in_right) * 0.5f; | |
//in_left = hpFilters[3].processSample(in_left); | |
dram[delayTaps[0]] = juce::jmap<float>(in_left + feedbackStored, -1.0f, 1.0, 0, 65535); | |
gainBaseAddr = (decayTime << 5) | (program << 8); | |
preDelay_high = preDelay >> 3; | |
preDelay_low = preDelay << 5; | |
preDelay_low = preDelay_low >> 5; | |
delayBaseAddr = (preDelay_low << 6) | (program << 9) | (preDelay_high << 12); | |
//calculate write tap (=test tap) | |
//calculate address row | |
result = nROW; | |
bit6 = result << 1; | |
bit6 = bit6 >> 7; | |
MSB = result; | |
MSB = MSB >> 7; | |
delayCarryOut = result >> 8; | |
rowDelay = result << 2; | |
rowDelay = (rowDelay >> 1) | bit6 | (MSB << 7); | |
//calculate address column | |
result = nCOLUMN + delayCarryOut; | |
colDelay = result << 2; | |
colDelay = colDelay >> 2; | |
//store address | |
delayTaps[0] = (rowDelay)+(colDelay * 256); | |
//calculate gain value | |
gainAddress = gainBaseAddr + 7; | |
gainOut = U78[gainAddress]; | |
//store gain value | |
gainCeiling[0] = gainOut; //only needed for testing purposes | |
//calculate feedback taps | |
dly_mod_addr = delayModBaseAddr + 7; | |
dly_addr = delayBaseAddr + 16; | |
gainModContAddress = gainModContBaseAddr + 8; | |
gainAddress = gainBaseAddr + 8; | |
for (int d = 0; d < 15; d++) | |
{ | |
result = U79[dly_mod_addr + d] + nROW; | |
bit6 = result << 1; | |
bit6 = bit6 >> 7; | |
MSB = result; | |
MSB = MSB >> 7; | |
delayCarryOut = result >> 8; | |
rowDelay = result << 2; | |
rowDelay = (rowDelay >> 1) | bit6 | (MSB << 7); | |
result = U69[dly_addr + d * 2] + nCOLUMN + delayCarryOut; | |
colDelay = result << 2; | |
colDelay = colDelay >> 2; | |
delayTaps[1 + d] = (rowDelay)+(colDelay * 256); | |
gainModContOut = U76[gainModContAddress + d]; | |
nGainModEnable = gainModContOut >> 3; | |
gainModContOut = gainModContOut << 5; | |
gainModContOut = gainModContOut >> 5; | |
gainModAddress = gainModContOut | gainModBaseAddr; | |
gainModOut = U77[gainModAddress]; | |
gainOut = U78[gainAddress + d]; | |
gainOut = gainOut; | |
if (gainModOut < gainOut && nGainModEnable == 0) | |
{ | |
gainCeiling[1 + d] = gainModOut; | |
} | |
else | |
{ | |
gainCeiling[1 + d] = gainOut; | |
} | |
} | |
//calculate output taps | |
gainAddress = gainBaseAddr + 23; | |
dly_mod_addr = delayBaseAddr + 45; | |
dly_addr = delayBaseAddr + 46; | |
for (int d = 0; d < 8; d++) | |
{ | |
result = U69[dly_mod_addr + d * 2] + nROW; | |
bit6 = result << 1; | |
bit6 = bit6 >> 7; | |
MSB = result; | |
MSB = MSB >> 7; | |
delayCarryOut = result >> 8; | |
rowDelay = result << 2; | |
rowDelay = (rowDelay >> 1) | bit6 | (MSB << 7); | |
result = U69[dly_addr + d * 2] + nCOLUMN + delayCarryOut; | |
colDelay = result << 2; | |
colDelay = colDelay >> 2; | |
delayTaps[16 + d] = (rowDelay)+(colDelay * 256); | |
gainOut = U78[gainAddress + d]; | |
gainCeiling[16 + d] = gainOut; | |
} | |
//mod rate counter | |
modClockOut = modClockOut + 1; | |
if (modClockOut == 16) | |
{ | |
modRateCount = rateLvl | (program << 4); | |
modClockOut = U71[modRateCount]; | |
} | |
modCarry = (modClockOut + 1) >> 4; | |
//increment write address & wraparound if >16bit | |
writeAddressCount = writeAddressCount - 1; | |
if (writeAddressCount < 0) | |
{ | |
writeAddressCount = 16383; | |
} | |
nROW = writeAddressCount; | |
nCOLUMN = writeAddressCount >> 8; | |
MCCK = modCarry; | |
if (MCCK == 1) | |
{ | |
modCount = modCount + 1; | |
if (modCount > 8191) | |
{ | |
modCount = 0; | |
} | |
gainModContBaseAddr = (modCount >> 6) << 5; | |
gainModBaseAddr = modCount << 7; | |
gainModBaseAddr = gainModBaseAddr >> 4; | |
delayModCount = modCount >> 6; | |
delayModBaseAddr = delayModCount << 5; | |
} | |
float out_left = 0.0f; | |
float out_right = 0.0f; | |
for (int i = 0; i < 4; ++i) | |
{ | |
out_left += juce::jmap((float)dram[delayTaps[16 + i]] * ((float)gainCeiling[16 + i] / 256.0f), 0.0f, 65535.0f, -1.0f, 1.0f); | |
out_right += juce::jmap((float)dram[delayTaps[20 + i]] * ((float)gainCeiling[20 + i] / 256.0f), 0.0f, 65535.0f, -1.0f, 1.0f); | |
} | |
out_left = hpFilters[0].processSample(out_left); | |
out_right = hpFilters[1].processSample(out_right); | |
feedbackStored = 0.0f; | |
for (int i = 1; i < 16; ++i) | |
{ | |
float gain = (float)gainCeiling[i] / 256.0f; | |
feedbackStored += juce::jmap((float)dram[delayTaps[i]] * gain, 0.0f, 65535.0f, -1.0f, 1.0f); | |
} | |
feedbackStored *= 0.05; | |
//feedbackStored = hpFilters[2].processSample(feedbackStored); | |
return { out_left,out_right }; | |
} | |
__uint8_t program = 7; // program from low to high (3,2,0,1,5,4,6,7) | |
__uint8_t preDelay = 1; // predelay from low to high (3,2,0,1,5,4,6,7,11,10,8,9,13,12,14,15) | |
__uint8_t decayTime = 7; // decay times from low to high (3,2,0,1,5,4,6,7) | |
__uint8_t rateLvl = 0; // 0-15 for testing | |
std::array<__uint16_t, 16384> dram; | |
std::array<__uint16_t, 24> delayTaps; | |
std::array<__uint8_t, 24> gainCeiling; | |
__uint16_t gainBaseAddr = 0; | |
__uint16_t gainAddress = 0; | |
__uint8_t gainOut = 0; | |
__uint8_t preDelay_low = 0; | |
__uint8_t preDelay_high = 0; | |
__uint16_t delayBaseAddr = 0; | |
__uint16_t dly_addr = 0; | |
__uint16_t result = 0; | |
__uint8_t bit6 = 0; | |
__uint8_t MSB = 0; | |
__uint8_t delayCarryOut = 0; | |
__uint8_t rowDelay = 0; | |
__uint8_t colDelay = 0; | |
__uint16_t writeAddressCount = 16383; | |
__uint8_t nROW = 255; | |
__uint8_t nCOLUMN = 255; | |
__uint8_t modRateCount = 0; | |
__uint8_t modClockOut = 0; | |
__uint8_t modCarry = 0; | |
__uint8_t MCCK = 0; | |
__uint16_t modCount = 0; | |
__uint8_t delayModCount = 0; | |
__uint16_t gainModContBaseAddr = 0; | |
__uint16_t gainModBaseAddr = 0; | |
__uint16_t gainModContAddress = 0; | |
__uint16_t gainModAddress = 0; | |
__uint8_t gainModOut = 0; | |
__uint8_t gainModContOut = 0; | |
__uint8_t nGainModEnable = 1; | |
__uint16_t delayModBaseAddr = 0; | |
__uint16_t dly_mod_addr = 0; | |
float feedbackStored = 0.0f; | |
juce::dsp::IIR::Filter<float> hpFilters[4]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment