Files
ComSquare/sources/APU/DSP/Envelope.cpp
Melefo b0fb1e3351 new MemoryMap architecture
starting to working of voices and so on BRR, Envelopes, Gauss and Timers as they use each others
2021-02-04 00:06:39 +01:00

78 lines
2.2 KiB
C++

//
// Created by melefo on 2/3/21.
//
#include "DSP.hpp"
namespace ComSquare::APU::DSP
{
void DSP::runEnvelope(Voice &voice)
{
int32_t envelope = voice.envelope;
if (voice.envelopeMode == Envelope::Release) {
envelope -= 0x08;
if (envelope < 0)
envelope = 0;
voice.envelope = envelope;
return;
}
int32_t rate;
int32_t mode;
int32_t data = voice.adsr2;
if (this->_latch.adsr1 & 0b10000000) {
if (voice.envelopeMode >= Envelope::Decay) {
envelope -= 1;
envelope -= envelope >> 8;
rate = data & 0b11111;
if (voice.envelopeMode == Envelope::Decay)
rate = ((this->_latch.adsr1 >> 3) & 0x0E) + 0x10;
}
else {
rate = ((this->_latch.adsr1 & 0b1111) << 1) + 1;
if (rate < 0b11111)
envelope += 0x20;
else
envelope += 0x400;
}
}
else {
data = voice.gain;
mode = data >> 5;
if (mode < 4) {
envelope = data << 4;
rate = 0b11111;
}
else {
rate = data & 0b11111;
if (mode == 4)
envelope -= 0x20;
else if (mode < 6) {
envelope -= 1;
envelope -= envelope >> 8;
}
else {
envelope += 0x20;
if (mode > 6 && voice.hiddenEnvelope >= 0x600)
envelope += 0x08 - 0x20;
}
}
}
if (envelope >> 8 == (data >> 5) && voice.envelopeMode == Envelope::Decay)
voice.envelopeMode = Envelope::Sustain;
voice.hiddenEnvelope = envelope;
if (static_cast<uint32_t>(envelope) > 0x7FF) {
if (envelope < 0)
envelope = 0;
else
envelope = 0x7FF;
if (voice.envelopeMode == Envelope::Attack)
voice.envelopeMode = Envelope::Decay;
}
if (this->timerPoll(rate))
voice.envelope = envelope;
}
}