diff --git a/sources/APU/DSP/BRR.cpp b/sources/APU/DSP/BRR.cpp index 683c590..27fa942 100644 --- a/sources/APU/DSP/BRR.cpp +++ b/sources/APU/DSP/BRR.cpp @@ -7,60 +7,60 @@ namespace ComSquare::APU::DSP { - void DSP::decodeBRR(Voice &voice) - { - int32_t value = this->_brr.value << 8 | this->_readRAM(voice.brrAddress + voice.brrOffset + 1); + void DSP::decodeBRR(Voice &voice) + { + int32_t value = this->_brr.value << 8 | this->_readRAM(voice.brrAddress + voice.brrOffset + 1); - int32_t filter = this->_brr.header >> 2 & 0b11; - int32_t range = this->_brr.header >> 4 & 0b1111; + int32_t filter = this->_brr.header >> 2 & 0b11; + int32_t range = this->_brr.header >> 4 & 0b1111; - for (int i = 0; i < 4; i++) { - int32_t sample = value >> 12; - value <<= 4; + for (int i = 0; i < 4; i++) { + int32_t sample = value >> 12; + value <<= 4; - if (range <= 12) { - sample <<= range; - sample >>= 1; - } - else - sample &= ~0x7FF; + if (range <= 12) { + sample <<= range; + sample >>= 1; + } + else + sample &= ~0x7FF; - int offset = voice.sampleOffset; - int lastSample; - int afterLastSample; + int offset = voice.sampleOffset; + int lastSample; + int afterLastSample; - if (--offset < 0) - offset = 11; - lastSample = voice.samples[offset]; - if (--offset < 0) - offset = 11; - afterLastSample = voice.samples[offset]; + if (--offset < 0) + offset = 11; + lastSample = voice.samples[offset]; + if (--offset < 0) + offset = 11; + afterLastSample = voice.samples[offset]; - switch (filter) { - case 0: - break; - case 1: - sample += lastSample; - sample += (lastSample) >> 4; - break; - case 2: - sample += lastSample << 1; - sample += -((lastSample << 1) + lastSample) >> 5; - sample -= afterLastSample; - sample += afterLastSample >> 4; - break; - case 3: - sample += lastSample << 1; - sample += -(lastSample + (lastSample << 2) + (lastSample << 3)) >> 6; - sample -= afterLastSample; - sample += ((afterLastSample << 1) + afterLastSample) >> 4; - break; - } - sample = std::clamp(sample, 0, 16); - sample <<= 1; - voice.samples[voice.sampleOffset] = sample; - if (++voice.sampleOffset >= 12) - voice.sampleOffset = 0; - } - } + switch (filter) { + case 0: + break; + case 1: + sample += lastSample; + sample += (lastSample) >> 4; + break; + case 2: + sample += lastSample << 1; + sample += -((lastSample << 1) + lastSample) >> 5; + sample -= afterLastSample; + sample += afterLastSample >> 4; + break; + case 3: + sample += lastSample << 1; + sample += -(lastSample + (lastSample << 2) + (lastSample << 3)) >> 6; + sample -= afterLastSample; + sample += ((afterLastSample << 1) + afterLastSample) >> 4; + break; + } + sample = std::clamp(sample, 0, 16); + sample <<= 1; + voice.samples[voice.sampleOffset] = sample; + if (++voice.sampleOffset >= 12) + voice.sampleOffset = 0; + } + } } \ No newline at end of file diff --git a/sources/APU/DSP/DSP.cpp b/sources/APU/DSP/DSP.cpp index 710d343..2321ae7 100644 --- a/sources/APU/DSP/DSP.cpp +++ b/sources/APU/DSP/DSP.cpp @@ -8,12 +8,12 @@ namespace ComSquare::APU::DSP { - DSP::DSP(int16_t *buffer, int32_t size, std::weak_ptr map) : _map(map) - { - this->_state.buffer = buffer; - this->_state.bufferStart = buffer; - this->_state.bufferEnd = buffer + size; - } + DSP::DSP(int16_t *buffer, int32_t size, std::weak_ptr map) : _map(map) + { + this->_state.buffer = buffer; + this->_state.bufferStart = buffer; + this->_state.bufferEnd = buffer + size; + } uint8_t DSP::read(uint24_t addr) const { @@ -187,13 +187,13 @@ namespace ComSquare::APU::DSP return kof; } case 0x6C: { - uint8_t flg = 0; - flg += this->_master.reset << 7; - flg += this->_master.mute << 6; - flg += this->_echo.enabled << 5; - flg += this->_noise.clock; - return flg; - } + uint8_t flg = 0; + flg += this->_master.reset << 7; + flg += this->_master.mute << 6; + flg += this->_echo.enabled << 5; + flg += this->_noise.clock; + return flg; + } case 0x7C: { uint8_t endx = 0; @@ -496,18 +496,18 @@ namespace ComSquare::APU::DSP break; case 0x4C: for (int i = 0; i < 8; i++) { - this->_voices[i].kon |= data << i; - } + this->_voices[i].kon |= data << i; + } break; case 0x5C: for (int i = 0; i < 8; i++) this->_voices[i].kof |= data << i; break; case 0x6C: - this->_master.reset = data >> 7; - this->_master.mute = (data >> 6) & 0b1; - this->_echo.enabled = (data >> 5) & 0b1; - this->_noise.clock = data & 0b1111; + this->_master.reset = data >> 7; + this->_master.mute = (data >> 6) & 0b1; + this->_echo.enabled = (data >> 5) & 0b1; + this->_noise.clock = data & 0b1111; break; case 0x7C: for (int i = 0; i < 8; i++) @@ -568,197 +568,197 @@ namespace ComSquare::APU::DSP throw InvalidAddress("DSP Registers write", addr); } } - uint8_t DSP::_readRAM(uint24_t addr) { - switch (addr) { - case 0x0000 ... 0x00EF: - return this->_map.lock()->Page0.read(addr); - case 0x0100 ... 0x01FF: - return this->_map.lock()->Page1.read(addr - 0x0100); - case 0x0200 ... 0xFFBF: - return this->_map.lock()->Memory.read(addr - 0x200); - case 0xFFC0 ... 0xFFFF: - return this->_map.lock()->IPL.read(addr - 0xFFC0); - default: - throw InvalidAddress("DSP read", addr); - } - } + uint8_t DSP::_readRAM(uint24_t addr) { + switch (addr) { + case 0x0000 ... 0x00EF: + return this->_map.lock()->Page0.read(addr); + case 0x0100 ... 0x01FF: + return this->_map.lock()->Page1.read(addr - 0x0100); + case 0x0200 ... 0xFFBF: + return this->_map.lock()->Memory.read(addr - 0x200); + case 0xFFC0 ... 0xFFFF: + return this->_map.lock()->IPL.read(addr - 0xFFC0); + default: + throw InvalidAddress("DSP read", addr); + } + } - void DSP::_writeRAM(uint24_t addr, uint8_t data) { - switch (addr) { - case 0x0000 ... 0x00EF: - this->_map.lock()->Page0.write(addr, data); - break; - case 0x0100 ... 0x01FF: - this->_map.lock()->Page1.write(addr - 0x0100, data); - break; - case 0x0200 ... 0xFFBF: - this->_map.lock()->Memory.write(addr - 0x200, data); - break; - case 0xFFC0 ... 0xFFFF: - this->_map.lock()->IPL.write(addr - 0xFFC0, data); - break; - default: - throw InvalidAddress("DSP write", addr); - } - } + void DSP::_writeRAM(uint24_t addr, uint8_t data) { + switch (addr) { + case 0x0000 ... 0x00EF: + this->_map.lock()->Page0.write(addr, data); + break; + case 0x0100 ... 0x01FF: + this->_map.lock()->Page1.write(addr - 0x0100, data); + break; + case 0x0200 ... 0xFFBF: + this->_map.lock()->Memory.write(addr - 0x200, data); + break; + case 0xFFC0 ... 0xFFFF: + this->_map.lock()->IPL.write(addr - 0xFFC0, data); + break; + default: + throw InvalidAddress("DSP write", addr); + } + } void DSP::update() - { - switch (this->_state.voice) { - case 0: - this->voice5(this->_voices[0]); - this->voice2(this->_voices[1]); - break; - case 1: - this->voice6(this->_voices[0]); - this->voice3(this->_voices[1]); - break; - case 2: - this->voice7(this->_voices[0]); - this->voice4(this->_voices[1]); - this->voice1(this->_voices[3]); - break; - case 3: - this->voice8(this->_voices[0]); - this->voice5(this->_voices[1]); - this->voice2(this->_voices[2]); - break; - case 4: - this->voice9(this->_voices[0]); - this->voice6(this->_voices[1]); - this->voice3(this->_voices[2]); - break; - case 5: - this->voice7(this->_voices[1]); - this->voice4(this->_voices[2]); - this->voice1(this->_voices[4]); - break; - case 6: - this->voice8(this->_voices[1]); - this->voice5(this->_voices[2]); - this->voice2(this->_voices[3]); - break; - case 7: - this->voice9(this->_voices[1]); - this->voice6(this->_voices[2]); - this->voice3(this->_voices[3]); - break; - case 8: - this->voice7(this->_voices[2]); - this->voice4(this->_voices[3]); - this->voice1(this->_voices[5]); - break; - case 9: - this->voice8(this->_voices[2]); - this->voice5(this->_voices[3]); - this->voice2(this->_voices[4]); - break; - case 10: - this->voice9(this->_voices[2]); - this->voice6(this->_voices[3]); - this->voice3(this->_voices[4]); - break; - case 11: - this->voice7(this->_voices[3]); - this->voice4(this->_voices[4]); - this->voice1(this->_voices[6]); - break; - case 12: - this->voice8(this->_voices[3]); - this->voice5(this->_voices[4]); - this->voice2(this->_voices[5]); - break; - case 13: - this->voice9(this->_voices[3]); - this->voice6(this->_voices[4]); - this->voice3(this->_voices[5]); - break; - case 14: - this->voice7(this->_voices[4]); - this->voice4(this->_voices[5]); - this->voice1(this->_voices[7]); - break; - case 15: - this->voice8(this->_voices[4]); - this->voice5(this->_voices[5]); - this->voice2(this->_voices[6]); - break; - case 16: - this->voice9(this->_voices[4]); - this->voice6(this->_voices[5]); - this->voice3(this->_voices[6]); - break; - case 17: - this->voice1(this->_voices[0]); - this->voice7(this->_voices[5]); - this->voice4(this->_voices[6]); - break; - case 18: - this->voice8(this->_voices[5]); - this->voice5(this->_voices[6]); - this->voice2(this->_voices[7]); - break; - case 19: - this->voice9(this->_voices[5]); - this->voice6(this->_voices[6]); - this->voice3(this->_voices[7]); - break; - case 20: - this->voice1(this->_voices[1]); - this->voice7(this->_voices[6]); - this->voice4(this->_voices[7]); - break; - case 21: - this->voice8(this->_voices[6]); - this->voice5(this->_voices[7]); - this->voice2(this->_voices[0]); - break; - case 22: - this->voice3a(this->_voices[0]); - this->voice9(this->_voices[6]); - this->voice6(this->_voices[7]); - echo22(); - break; - case 23: - this->voice7(this->_voices[7]); - echo23(); - break; - case 24: - this->voice8(this->_voices[7]); - echo24(); - break; - case 25: - this->voice3b(this->_voices[0]); - this->voice9(this->_voices[7]); - echo25(); - break; - case 26: - echo26(); - break; - case 27: - this->misc27(); - this->echo27(); - break; - case 28: - this->misc28(); - this->echo28(); - break; - case 29: - this->misc29(); - this->echo29(); - break; - case 30: - this->misc30(); - this->voice3c(this->_voices[0]); - this->echo30(); - break; - case 31: - this->voice4(this->_voices[0]); - this->voice1(this->_voices[2]); - break; - } - this->_state.voice = (this->_state.voice + 1) % 32; - } + { + switch (this->_state.voice) { + case 0: + this->voice5(this->_voices[0]); + this->voice2(this->_voices[1]); + break; + case 1: + this->voice6(this->_voices[0]); + this->voice3(this->_voices[1]); + break; + case 2: + this->voice7(this->_voices[0]); + this->voice4(this->_voices[1]); + this->voice1(this->_voices[3]); + break; + case 3: + this->voice8(this->_voices[0]); + this->voice5(this->_voices[1]); + this->voice2(this->_voices[2]); + break; + case 4: + this->voice9(this->_voices[0]); + this->voice6(this->_voices[1]); + this->voice3(this->_voices[2]); + break; + case 5: + this->voice7(this->_voices[1]); + this->voice4(this->_voices[2]); + this->voice1(this->_voices[4]); + break; + case 6: + this->voice8(this->_voices[1]); + this->voice5(this->_voices[2]); + this->voice2(this->_voices[3]); + break; + case 7: + this->voice9(this->_voices[1]); + this->voice6(this->_voices[2]); + this->voice3(this->_voices[3]); + break; + case 8: + this->voice7(this->_voices[2]); + this->voice4(this->_voices[3]); + this->voice1(this->_voices[5]); + break; + case 9: + this->voice8(this->_voices[2]); + this->voice5(this->_voices[3]); + this->voice2(this->_voices[4]); + break; + case 10: + this->voice9(this->_voices[2]); + this->voice6(this->_voices[3]); + this->voice3(this->_voices[4]); + break; + case 11: + this->voice7(this->_voices[3]); + this->voice4(this->_voices[4]); + this->voice1(this->_voices[6]); + break; + case 12: + this->voice8(this->_voices[3]); + this->voice5(this->_voices[4]); + this->voice2(this->_voices[5]); + break; + case 13: + this->voice9(this->_voices[3]); + this->voice6(this->_voices[4]); + this->voice3(this->_voices[5]); + break; + case 14: + this->voice7(this->_voices[4]); + this->voice4(this->_voices[5]); + this->voice1(this->_voices[7]); + break; + case 15: + this->voice8(this->_voices[4]); + this->voice5(this->_voices[5]); + this->voice2(this->_voices[6]); + break; + case 16: + this->voice9(this->_voices[4]); + this->voice6(this->_voices[5]); + this->voice3(this->_voices[6]); + break; + case 17: + this->voice1(this->_voices[0]); + this->voice7(this->_voices[5]); + this->voice4(this->_voices[6]); + break; + case 18: + this->voice8(this->_voices[5]); + this->voice5(this->_voices[6]); + this->voice2(this->_voices[7]); + break; + case 19: + this->voice9(this->_voices[5]); + this->voice6(this->_voices[6]); + this->voice3(this->_voices[7]); + break; + case 20: + this->voice1(this->_voices[1]); + this->voice7(this->_voices[6]); + this->voice4(this->_voices[7]); + break; + case 21: + this->voice8(this->_voices[6]); + this->voice5(this->_voices[7]); + this->voice2(this->_voices[0]); + break; + case 22: + this->voice3a(this->_voices[0]); + this->voice9(this->_voices[6]); + this->voice6(this->_voices[7]); + echo22(); + break; + case 23: + this->voice7(this->_voices[7]); + echo23(); + break; + case 24: + this->voice8(this->_voices[7]); + echo24(); + break; + case 25: + this->voice3b(this->_voices[0]); + this->voice9(this->_voices[7]); + echo25(); + break; + case 26: + echo26(); + break; + case 27: + this->misc27(); + this->echo27(); + break; + case 28: + this->misc28(); + this->echo28(); + break; + case 29: + this->misc29(); + this->echo29(); + break; + case 30: + this->misc30(); + this->voice3c(this->_voices[0]); + this->echo30(); + break; + case 31: + this->voice4(this->_voices[0]); + this->voice1(this->_voices[2]); + break; + } + this->_state.voice = (this->_state.voice + 1) % 32; + } uint24_t DSP::getSize() const { return 0x7F; @@ -769,33 +769,33 @@ namespace ComSquare::APU::DSP return this->_voices; } - const Master &DSP::getMaster() const - { - return this->_master; - } + const Master &DSP::getMaster() const + { + return this->_master; + } - const Echo &DSP::getEcho() const - { - return this->_echo; - } + const Echo &DSP::getEcho() const + { + return this->_echo; + } - const Noise &DSP::getNoise() const - { - return this->_noise; - } + const Noise &DSP::getNoise() const + { + return this->_noise; + } - const BRR &DSP::getBrr() const - { - return this->_brr; - } + const BRR &DSP::getBrr() const + { + return this->_brr; + } - const Latch &DSP::getLatch() const - { - return this->_latch; - } + const Latch &DSP::getLatch() const + { + return this->_latch; + } - int32_t DSP::getSamplesCount() const - { - return this->_state.buffer - this->_state.bufferStart; - } + int32_t DSP::getSamplesCount() const + { + return this->_state.buffer - this->_state.bufferStart; + } } \ No newline at end of file diff --git a/sources/APU/DSP/DSP.hpp b/sources/APU/DSP/DSP.hpp index 67cadc0..4ea52f4 100644 --- a/sources/APU/DSP/DSP.hpp +++ b/sources/APU/DSP/DSP.hpp @@ -11,202 +11,202 @@ namespace ComSquare::APU { - class APU; - struct MemoryMap; + class APU; + struct MemoryMap; } namespace ComSquare::APU::DSP { - enum Envelope : uint { - Release, - Attack, - Decay, - Sustain - }; + enum Envelope : uint { + Release, + Attack, + Decay, + Sustain + }; - struct Master { - //! @brief Main Volume register (MVOL) - std::array volume; - //! @brief Mutes all channel (6th bit FLG) - bool mute : 1; - //! @brief Soft reset DSP (7th bit FLG) - bool reset : 1; - //! @brief Current sound produced - std::array output; - //! @brief Not used register - uint8_t unused; - }; + struct Master { + //! @brief Main Volume register (MVOL) + std::array volume; + //! @brief Mutes all channel (6th bit FLG) + bool mute : 1; + //! @brief Soft reset DSP (7th bit FLG) + bool reset : 1; + //! @brief Current sound produced + std::array output; + //! @brief Not used register + uint8_t unused; + }; - struct Echo { - //! @brief Echo Volume register (EVOL) - std::array volume; - //! @brief Echo feedback register (EFB) - uint8_t feedback; - //! @brief Echo FIR filter coefficients (COEF) - std::array FIR; - //! @brief Echo data start register (ESA) - uint8_t data; - //! @brief Echo delay size register (EDL) - uint8_t delay; - //! @brief Echo enabled (5th bit FLG) - bool enabled = true; - //! @brief Last sound produced for each voice in each channel - std::array, 2> history; - //! @brief Current sound to echo - std::array input; - //! @brief Current sound echoed produced - std::array output; - }; + struct Echo { + //! @brief Echo Volume register (EVOL) + std::array volume; + //! @brief Echo feedback register (EFB) + uint8_t feedback; + //! @brief Echo FIR filter coefficients (COEF) + std::array FIR; + //! @brief Echo data start register (ESA) + uint8_t data; + //! @brief Echo delay size register (EDL) + uint8_t delay; + //! @brief Echo enabled (5th bit FLG) + bool enabled = true; + //! @brief Last sound produced for each voice in each channel + std::array, 2> history; + //! @brief Current sound to echo + std::array input; + //! @brief Current sound echoed produced + std::array output; + }; - struct Noise { - //! @brief Frequency of white noise (the first 4 bits FLG) - uint8_t clock : 5; - //! @brief Linear feedback shift register used to shift final output - uint16_t lfsr = 0x4000; - }; + struct Noise { + //! @brief Frequency of white noise (the first 4 bits FLG) + uint8_t clock : 5; + //! @brief Linear feedback shift register used to shift final output + uint16_t lfsr = 0x4000; + }; - struct BRR { - //! @brief Offset pointing to sample directory in external RAM (DIR) - uint8_t offset; - //! @brief Address of the offset - uint8_t offsetAddr; - //! @brief Current address of the BRR in APU's RAM - uint16_t address; - //! @brief Next address of the BRR in APU's RAM - uint16_t nextAddress; - //! @brief Current value inside BRR - uint8_t value; - //! @brief Current header of BRR - uint8_t header; - //! @brief Current value of Voice ADSR1 loaded - uint8_t source; - }; + struct BRR { + //! @brief Offset pointing to sample directory in external RAM (DIR) + uint8_t offset; + //! @brief Address of the offset + uint8_t offsetAddr; + //! @brief Current address of the BRR in APU's RAM + uint16_t address; + //! @brief Next address of the BRR in APU's RAM + uint16_t nextAddress; + //! @brief Current value inside BRR + uint8_t value; + //! @brief Current header of BRR + uint8_t header; + //! @brief Current value of Voice ADSR1 loaded + uint8_t source; + }; - struct Latch { - //! @brief Current voice's adsr1 in use - uint8_t adsr1; - //! @brief Envelope value register (ENVX) - uint8_t envx; - //! @brief Wave height register (OUTX) - uint8_t outx; - //! @brief Current voice's pitch in use - uint16_t pitch; - //! @brief Output currently being modified - uint16_t output; - }; + struct Latch { + //! @brief Current voice's adsr1 in use + uint8_t adsr1; + //! @brief Envelope value register (ENVX) + uint8_t envx; + //! @brief Wave height register (OUTX) + uint8_t outx; + //! @brief Current voice's pitch in use + uint16_t pitch; + //! @brief Output currently being modified + uint16_t output; + }; - struct Voice { - //! @brief Volume register (VOL) - std::array volume; - //! @brief Pitch register (P) - union { - struct { - //! @brief Lower 8 bits of pitch register - uint8_t pitchL; - //! @brief Higher 8 bits of pitch register - uint8_t pitchH; - }; - uint16_t pitch; - }; - //! @brief Source number register (SRCN) - uint8_t srcn; - union { - struct { - //! @brief Envelope register (ADSR) - uint8_t adsr1; - //! @brief Envelope controllers register (ADSR) - uint8_t adsr2; - }; - uint16_t adsr; - }; - //! @brief Gain register (GAIN) - uint8_t gain; - //! @brief envelope associated with this voice - uint8_t envx; - //! @brief Sample end register (ENDX) - bool endx : 1; + struct Voice { + //! @brief Volume register (VOL) + std::array volume; + //! @brief Pitch register (P) + union { + struct { + //! @brief Lower 8 bits of pitch register + uint8_t pitchL; + //! @brief Higher 8 bits of pitch register + uint8_t pitchH; + }; + uint16_t pitch; + }; + //! @brief Source number register (SRCN) + uint8_t srcn; + union { + struct { + //! @brief Envelope register (ADSR) + uint8_t adsr1; + //! @brief Envelope controllers register (ADSR) + uint8_t adsr2; + }; + uint16_t adsr; + }; + //! @brief Gain register (GAIN) + uint8_t gain; + //! @brief envelope associated with this voice + uint8_t envx; + //! @brief Sample end register (ENDX) + bool endx : 1; - //! @brief Key On register (KON) - bool kon : 1; - //! @brief Key Off register (KOF) - bool kof : 1; - //! @brief Pitch modulation register (PMON) - bool pmon : 1; - //! @brief Noise enable register (NON) - bool non : 1; - //! @brief Echo enable register (EON) - bool eon : 1; + //! @brief Key On register (KON) + bool kon : 1; + //! @brief Key Off register (KOF) + bool kof : 1; + //! @brief Pitch modulation register (PMON) + bool pmon : 1; + //! @brief Noise enable register (NON) + bool non : 1; + //! @brief Echo enable register (EON) + bool eon : 1; - //! @brief Check if voice is in setup phase - uint8_t konDelay; - //! @brief Check if the output will be echoed - bool echo; - //! @brief Check if this voice will be looped - bool loop; - //! @brief Current BRR associated with this voice - uint16_t brrAddress; - //! @brief Current Offset in the BRR block - uint8_t brrOffset = 1; - //! @brief Previous modulation - bool prevPmon : 1; - //! @brief temporary NON register value - bool tempNon : 1; - //! @brief temporary Key On register value - bool tempKon : 1; - //! @brief temporary Key Off register value - bool tempKof : 1; - //! @brief all samples Decoded from BRR - std::array samples; - //! @brief Offset of current sample in samples buffer - uint8_t sampleOffset; - //! @brief Current envelope level - uint16_t envelope; - //! @brief Second envelope level used to make "special" waveforms - uint16_t hiddenEnvelope; - //! @brief current envelope Mode - Envelope envelopeMode; - //! @brief Relative fractional position in sample - uint16_t gaussOffset; - }; + //! @brief Check if voice is in setup phase + uint8_t konDelay; + //! @brief Check if the output will be echoed + bool echo; + //! @brief Check if this voice will be looped + bool loop; + //! @brief Current BRR associated with this voice + uint16_t brrAddress; + //! @brief Current Offset in the BRR block + uint8_t brrOffset = 1; + //! @brief Previous modulation + bool prevPmon : 1; + //! @brief temporary NON register value + bool tempNon : 1; + //! @brief temporary Key On register value + bool tempKon : 1; + //! @brief temporary Key Off register value + bool tempKof : 1; + //! @brief all samples Decoded from BRR + std::array samples; + //! @brief Offset of current sample in samples buffer + uint8_t sampleOffset; + //! @brief Current envelope level + uint16_t envelope; + //! @brief Second envelope level used to make "special" waveforms + uint16_t hiddenEnvelope; + //! @brief current envelope Mode + Envelope envelopeMode; + //! @brief Relative fractional position in sample + uint16_t gaussOffset; + }; - //! @brief Current state of the DSP - struct State - { - //! @brief Current voice modification to do - uint8_t voice = 0; - //! @brief Current buffer of samples - int16_t *buffer; - //! @brief Limit of the buffer - int16_t *bufferEnd; - //! @brief Beginning of the buffer - int16_t *bufferStart; - }; + //! @brief Current state of the DSP + struct State + { + //! @brief Current voice modification to do + uint8_t voice = 0; + //! @brief Current buffer of samples + int16_t *buffer; + //! @brief Limit of the buffer + int16_t *bufferEnd; + //! @brief Beginning of the buffer + int16_t *bufferStart; + }; - struct Timer { - //! @brief Ticks remaining in the timer - uint16_t counter; - //! @brief output every samples - bool sample = true; - }; + struct Timer { + //! @brief Ticks remaining in the timer + uint16_t counter; + //! @brief output every samples + bool sample = true; + }; /*//! @brief All the registers of the DSP struct Registers { - //! @brief Main Volume register - std::array mVol; //master.volume + //! @brief Main Volume register + std::array mVol; //master.volume - //! @brief Echo Volume register - std::array eVol; //echo.volume + //! @brief Echo Volume register + std::array eVol; //echo.volume //! @brief Flags register union { - struct { - uint8_t noiseClock : 5; //noise.frequency - bool ecen : 1; //echo.readonly - bool mute : 1; //master.mute - bool reset : 1; //master.reset - }; - uint8_t flg; - }; + struct { + uint8_t noiseClock : 5; //noise.frequency + bool ecen : 1; //echo.readonly + bool mute : 1; //master.mute + bool reset : 1; //master.reset + }; + uint8_t flg; + }; //! @brief Echo feedback register uint8_t efb; //echo.feedback @@ -223,28 +223,28 @@ namespace ComSquare::APU::DSP uint8_t edl; //echo.delay }; - struct BRR { - //! @brief BRR Header - union { - struct { - //! @brief Shift value range - unsigned range : 4; - //! @brief Decompression filter - unsigned filter : 2; - //! @brief Flag if the sample loops - bool loop : 1; - //! @brief Stop the sample (or restart from loop point) - bool end : 1; - }; - uint8_t head; - }; - //! @brief Sample data inside BRR - uint64_t block; - }; + struct BRR { + //! @brief BRR Header + union { + struct { + //! @brief Shift value range + unsigned range : 4; + //! @brief Decompression filter + unsigned filter : 2; + //! @brief Flag if the sample loops + bool loop : 1; + //! @brief Stop the sample (or restart from loop point) + bool end : 1; + }; + uint8_t head; + }; + //! @brief Sample data inside BRR + uint64_t block; + }; - struct Voice { - //! @brief Volume register - std::array volume; //voice.volume + struct Voice { + //! @brief Volume register + std::array volume; //voice.volume union { struct { @@ -256,26 +256,26 @@ namespace ComSquare::APU::DSP uint16_t pitch; //voice.pitch }; - //! @brief Source number register - uint8_t srcn; //voice.source + //! @brief Source number register + uint8_t srcn; //voice.source - union { - struct { - //! @brief Envelope register - uint8_t adsr1; //voice.adsr0 - //! @brief Envelope controllers register - uint8_t adsr2; //voice.adsr1 - }; - uint16_t envelope; - }; + union { + struct { + //! @brief Envelope register + uint8_t adsr1; //voice.adsr0 + //! @brief Envelope controllers register + uint8_t adsr2; //voice.adsr1 + }; + uint16_t envelope; + }; - //! @brief Gain register - uint8_t gain; //voice.gain + //! @brief Gain register + uint8_t gain; //voice.gain - //! @brief Envelope value register - uint8_t envx; //latch.envx - //! @brief Wave height register - uint8_t outx; //latch.outx + //! @brief Envelope value register + uint8_t envx; //latch.envx + //! @brief Wave height register + uint8_t outx; //latch.outx //! @brief Key On register bool kon : 1; //voice.keyon @@ -299,120 +299,120 @@ namespace ComSquare::APU::DSP bool latchEon : 1; //voice._echo }; - struct Latch - { - uint8_t adsr0; - uint16_t pitch; - uint16_t output; - };*/ + struct Latch + { + uint8_t adsr0; + uint16_t pitch; + uint16_t output; + };*/ class DSP { private: - //! @brief Number of samples per counter event - std::array _rateModulus = { - 0, 2048, 1536, 1280, 1024, 768, - 640, 512, 384, 320, 256, 192, - 160, 128, 96, 80, 64, 48, - 40, 32, 24, 20, 16, 12, - 10, 8, 6, 5, 4, 3, - 2, 1 - }; + //! @brief Number of samples per counter event + std::array _rateModulus = { + 0, 2048, 1536, 1280, 1024, 768, + 640, 512, 384, 320, 256, 192, + 160, 128, 96, 80, 64, 48, + 40, 32, 24, 20, 16, 12, + 10, 8, 6, 5, 4, 3, + 2, 1 + }; - //! @brief Counter offset - std::array _counterOffset = { - 0, 0, 1040, 536, 0, 1040, - 536, 0, 1040, 536, 0, 1040, - 536, 0, 1040, 536, 0, 1040, - 536, 0, 1040, 536, 0, 1040, - 536, 0, 1040, 536, 0, 1040, - 0,0 - }; + //! @brief Counter offset + std::array _counterOffset = { + 0, 0, 1040, 536, 0, 1040, + 536, 0, 1040, 536, 0, 1040, + 536, 0, 1040, 536, 0, 1040, + 536, 0, 1040, 536, 0, 1040, + 536, 0, 1040, 536, 0, 1040, + 0,0 + }; //! @brief Gaussian table used for making waves std::array _gauss = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, - 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, - 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, - 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, - 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, - 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, - 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, - 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, - 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, - 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, - 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, - 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, - 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, - 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, - 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, - 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, - 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, - 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, - 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, - 969, 974, 978, 983, 988, 992, 997, 1001, 1005, 1010, 1014, 1019, 1023, 1027, 1032, 1036, - 1040, 1045, 1049, 1053, 1057, 1061, 1066, 1070, 1074, 1078, 1082, 1086, 1090, 1094, 1098, 1102, - 1106, 1109, 1113, 1117, 1121, 1125, 1128, 1132, 1136, 1139, 1143, 1146, 1150, 1153, 1157, 1160, - 1164, 1167, 1170, 1174, 1177, 1180, 1183, 1186, 1190, 1193, 1196, 1199, 1202, 1205, 1207, 1210, - 1213, 1216, 1219, 1221, 1224, 1227, 1229, 1232, 1234, 1237, 1239, 1241, 1244, 1246, 1248, 1251, - 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1270, 1272, 1274, 1275, 1277, 1279, 1280, - 1282, 1283, 1284, 1286, 1287, 1288, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1297, 1298, - 1299, 1300, 1300, 1301, 1302, 1302, 1303, 1303, 1303, 1304, 1304, 1304, 1304, 1304, 1305, 1305 - }; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, + 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, + 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, + 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, + 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, + 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, + 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, + 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, + 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, + 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, + 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, + 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, + 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, + 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, + 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, + 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, + 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, + 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, + 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, + 969, 974, 978, 983, 988, 992, 997, 1001, 1005, 1010, 1014, 1019, 1023, 1027, 1032, 1036, + 1040, 1045, 1049, 1053, 1057, 1061, 1066, 1070, 1074, 1078, 1082, 1086, 1090, 1094, 1098, 1102, + 1106, 1109, 1113, 1117, 1121, 1125, 1128, 1132, 1136, 1139, 1143, 1146, 1150, 1153, 1157, 1160, + 1164, 1167, 1170, 1174, 1177, 1180, 1183, 1186, 1190, 1193, 1196, 1199, 1202, 1205, 1207, 1210, + 1213, 1216, 1219, 1221, 1224, 1227, 1229, 1232, 1234, 1237, 1239, 1241, 1244, 1246, 1248, 1251, + 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1270, 1272, 1274, 1275, 1277, 1279, 1280, + 1282, 1283, 1284, 1286, 1287, 1288, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1297, 1298, + 1299, 1300, 1300, 1301, 1302, 1302, 1303, 1303, 1303, 1304, 1304, 1304, 1304, 1304, 1305, 1305 + }; - //! @brief 8x voices of sample used to make sound - std::array _voices {}; - Master _master {}; - Echo _echo {}; - Noise _noise {}; - BRR _brr {}; - Latch _latch {}; - State _state {}; - Timer _timer {}; + //! @brief 8x voices of sample used to make sound + std::array _voices {}; + Master _master {}; + Echo _echo {}; + Noise _noise {}; + BRR _brr {}; + Latch _latch {}; + State _state {}; + Timer _timer {}; - void voiceOutput(Voice &voice, bool channel); - void voice1(Voice &voice); - void voice2(Voice &voice); - void voice3(Voice &voice); - void voice3a(Voice &voice); - void voice3b(Voice &voice); - void voice3c(Voice &voice); - void voice4(Voice &voice); - void voice5(Voice &voice); - void voice6(Voice &voice); - void voice7(Voice &voice); - void voice8(Voice &voice); - void voice9(Voice &voice); - void echo22(); - void echo23(); - void echo24(); - void echo25(); - void echo26(); - void echo27(); - void echo28(); - void echo29(); - void echo30(); - void misc27(); - void misc28(); - void misc29(); - void misc30(); + void voiceOutput(Voice &voice, bool channel); + void voice1(Voice &voice); + void voice2(Voice &voice); + void voice3(Voice &voice); + void voice3a(Voice &voice); + void voice3b(Voice &voice); + void voice3c(Voice &voice); + void voice4(Voice &voice); + void voice5(Voice &voice); + void voice6(Voice &voice); + void voice7(Voice &voice); + void voice8(Voice &voice); + void voice9(Voice &voice); + void echo22(); + void echo23(); + void echo24(); + void echo25(); + void echo26(); + void echo27(); + void echo28(); + void echo29(); + void echo30(); + void misc27(); + void misc28(); + void misc29(); + void misc30(); - int32_t interpolate(const Voice &voice); - void runEnvelope(Voice &voice); + int32_t interpolate(const Voice &voice); + void runEnvelope(Voice &voice); - void timerTick(); - bool timerPoll(uint32_t rate); + void timerTick(); + bool timerPoll(uint32_t rate); - void decodeBRR(Voice &voice); + void decodeBRR(Voice &voice); - std::weak_ptr _map; + std::weak_ptr _map; - uint8_t _readRAM(uint24_t addr); - void _writeRAM(uint24_t addr, uint8_t data); + uint8_t _readRAM(uint24_t addr); + void _writeRAM(uint24_t addr, uint8_t data); public: DSP(int16_t *buffer, int32_t size, std::weak_ptr map); DSP(const DSP &) = default; @@ -421,11 +421,11 @@ namespace ComSquare::APU::DSP //! @brief Return all 8 voices from DSP const std::array &getVoices() const; - const Master &getMaster() const; - const Echo &getEcho() const; - const Noise &getNoise() const; - const BRR &getBrr() const; - const Latch &getLatch() const; + const Master &getMaster() const; + const Echo &getEcho() const; + const Noise &getNoise() const; + const BRR &getBrr() const; + const Latch &getLatch() const; //! @brief Read from the internal DSP register. //! @param addr The address to read from. The address 0x0 should refer to the first byte of the register. @@ -440,8 +440,8 @@ namespace ComSquare::APU::DSP //! @brief Get the name of this accessor (used for debug purpose) std::string getName() const; - //! @brief Execute current voice transformation - void update(); + //! @brief Execute current voice transformation + void update(); //! @brief Get the component of this accessor (used for debug purpose) Component getComponent() const; @@ -449,8 +449,8 @@ namespace ComSquare::APU::DSP //! @brief Get the size of the data. This size can be lower than the mapped data. //! @return The number of bytes inside this memory. uint24_t getSize() const; - //! @brief Return the number of samples written - int32_t getSamplesCount() const; + //! @brief Return the number of samples written + int32_t getSamplesCount() const; }; } diff --git a/sources/APU/DSP/Echo.cpp b/sources/APU/DSP/Echo.cpp index ed2b365..5b4d999 100644 --- a/sources/APU/DSP/Echo.cpp +++ b/sources/APU/DSP/Echo.cpp @@ -6,68 +6,68 @@ namespace ComSquare::APU::DSP { - void DSP::echo22() - { + void DSP::echo22() + { - } + } - void DSP::echo23() - { + void DSP::echo23() + { - } + } - void DSP::echo24() - { + void DSP::echo24() + { - } + } - void DSP::echo25() - { + void DSP::echo25() + { - } + } - void DSP::echo26() - { + void DSP::echo26() + { - } + } - void DSP::echo27() - { + void DSP::echo27() + { - } + } - void DSP::echo28() - { + void DSP::echo28() + { - } + } - void DSP::echo29() - { + void DSP::echo29() + { - } + } - void DSP::echo30() - { + void DSP::echo30() + { - } + } - void DSP::misc27() - { + void DSP::misc27() + { - } + } - void DSP::misc28() - { + void DSP::misc28() + { - } + } - void DSP::misc29() - { + void DSP::misc29() + { - } + } - void DSP::misc30() - { + void DSP::misc30() + { - } + } } \ No newline at end of file diff --git a/sources/APU/DSP/Envelope.cpp b/sources/APU/DSP/Envelope.cpp index 47f4aae..ca8b506 100644 --- a/sources/APU/DSP/Envelope.cpp +++ b/sources/APU/DSP/Envelope.cpp @@ -6,73 +6,73 @@ namespace ComSquare::APU::DSP { - void DSP::runEnvelope(Voice &voice) - { - int32_t envelope = voice.envelope; + 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; - } + 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; - } - } - } + 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(envelope) > 0x7FF) { - if (envelope < 0) - envelope = 0; - else - envelope = 0x7FF; - if (voice.envelopeMode == Envelope::Attack) - voice.envelopeMode = Envelope::Decay; - } + if (envelope >> 8 == (data >> 5) && voice.envelopeMode == Envelope::Decay) + voice.envelopeMode = Envelope::Sustain; + voice.hiddenEnvelope = envelope; + if (static_cast(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; - } + if (this->timerPoll(rate)) + voice.envelope = envelope; + } } \ No newline at end of file diff --git a/sources/APU/DSP/Gauss.cpp b/sources/APU/DSP/Gauss.cpp index c6ad58a..0b8003a 100644 --- a/sources/APU/DSP/Gauss.cpp +++ b/sources/APU/DSP/Gauss.cpp @@ -8,23 +8,23 @@ namespace ComSquare::APU::DSP { - int32_t DSP::interpolate(const Voice &voice) - { - int32_t interpolated; - uint8_t offset = voice.gaussOffset >> 4; - int forward = 255 - offset; - int reverse = offset; + int32_t DSP::interpolate(const Voice &voice) + { + int32_t interpolated; + uint8_t offset = voice.gaussOffset >> 4; + int forward = 255 - offset; + int reverse = offset; - offset = (voice.sampleOffset + (voice.gaussOffset >> 12)) % 12; - interpolated = this->_gauss[forward] * voice.samples[offset++] >> 11; - offset %= 12; - interpolated += this->_gauss[forward + 256] * voice.samples[offset++] >> 11; - offset %= 12; - interpolated += this->_gauss[reverse + 256] * voice.samples[offset++] >> 11; - offset %= 12; - interpolated = static_cast(interpolated); - interpolated += this->_gauss[reverse] * voice.samples[offset] >> 11; + offset = (voice.sampleOffset + (voice.gaussOffset >> 12)) % 12; + interpolated = this->_gauss[forward] * voice.samples[offset++] >> 11; + offset %= 12; + interpolated += this->_gauss[forward + 256] * voice.samples[offset++] >> 11; + offset %= 12; + interpolated += this->_gauss[reverse + 256] * voice.samples[offset++] >> 11; + offset %= 12; + interpolated = static_cast(interpolated); + interpolated += this->_gauss[reverse] * voice.samples[offset] >> 11; - return std::clamp(interpolated, 0, 16) & ~1; - } + return std::clamp(interpolated, 0, 16) & ~1; + } } \ No newline at end of file diff --git a/sources/APU/DSP/Timer.cpp b/sources/APU/DSP/Timer.cpp index 9e85488..1b060d4 100644 --- a/sources/APU/DSP/Timer.cpp +++ b/sources/APU/DSP/Timer.cpp @@ -6,17 +6,17 @@ namespace ComSquare::APU::DSP { - void DSP::timerTick() - { - if (!this->_timer.counter) - this->_timer.counter = 0x7800; - this->_timer.counter -= 1; - } + void DSP::timerTick() + { + if (!this->_timer.counter) + this->_timer.counter = 0x7800; + this->_timer.counter -= 1; + } - bool DSP::timerPoll(uint32_t rate) - { - if (!rate) - return false; - return (this->_timer.counter + this->_counterOffset[rate]) % this->_rateModulus[rate] == 0; - } + bool DSP::timerPoll(uint32_t rate) + { + if (!rate) + return false; + return (this->_timer.counter + this->_counterOffset[rate]) % this->_rateModulus[rate] == 0; + } } \ No newline at end of file diff --git a/sources/APU/DSP/Voice.cpp b/sources/APU/DSP/Voice.cpp index 680642d..eccc7a2 100644 --- a/sources/APU/DSP/Voice.cpp +++ b/sources/APU/DSP/Voice.cpp @@ -8,149 +8,149 @@ namespace ComSquare::APU::DSP { - void DSP::voiceOutput(Voice &voice, bool channel) - { - int out = this->_latch.output * voice.volume[channel] >> 7; + void DSP::voiceOutput(Voice &voice, bool channel) + { + int out = this->_latch.output * voice.volume[channel] >> 7; - this->_master.output[channel] += out; - if (!voice.echo) - return; - this->_echo.volume[channel] += out; - } + this->_master.output[channel] += out; + if (!voice.echo) + return; + this->_echo.volume[channel] += out; + } - void DSP::voice1(Voice &voice) - { - this->_brr.address = (this->_brr.offsetAddr << 8) + (this->_brr.source << 2); - this->_brr.source = voice.srcn; - } + void DSP::voice1(Voice &voice) + { + this->_brr.address = (this->_brr.offsetAddr << 8) + (this->_brr.source << 2); + this->_brr.source = voice.srcn; + } - void DSP::voice2(Voice &voice) - { - uint16_t addr = this->_brr.address; + void DSP::voice2(Voice &voice) + { + uint16_t addr = this->_brr.address; - if (!voice.konDelay) - addr += 2; - this->_brr.nextAddress = this->_readRAM(addr++); - this->_brr.nextAddress += this->_readRAM(addr++) << 8; - this->_latch.adsr1 = voice.adsr1; - this->_latch.pitch = voice.pitch & 0xFF; - } + if (!voice.konDelay) + addr += 2; + this->_brr.nextAddress = this->_readRAM(addr++); + this->_brr.nextAddress += this->_readRAM(addr++) << 8; + this->_latch.adsr1 = voice.adsr1; + this->_latch.pitch = voice.pitch & 0xFF; + } - void DSP::voice3(Voice &voice) - { - this->voice3a(voice); - this->voice3b(voice); - this->voice3c(voice); - } + void DSP::voice3(Voice &voice) + { + this->voice3a(voice); + this->voice3b(voice); + this->voice3c(voice); + } - void DSP::voice3a(Voice &voice) - { - this->_latch.pitch |= (voice.pitchH & 0x3F) << 8; - } + void DSP::voice3a(Voice &voice) + { + this->_latch.pitch |= (voice.pitchH & 0x3F) << 8; + } - void DSP::voice3b(Voice &voice) - { - this->_brr.header = this->_readRAM(this->_brr.address); - this->_brr.value = this->_readRAM(this->_brr.address + voice.brrOffset); - } + void DSP::voice3b(Voice &voice) + { + this->_brr.header = this->_readRAM(this->_brr.address); + this->_brr.value = this->_readRAM(this->_brr.address + voice.brrOffset); + } - void DSP::voice3c(Voice &voice) - { - if (voice.prevPmon) - this->_latch.pitch += (this->_latch.output >> 5) * this->_latch.pitch >> 10; + void DSP::voice3c(Voice &voice) + { + if (voice.prevPmon) + this->_latch.pitch += (this->_latch.output >> 5) * this->_latch.pitch >> 10; - if (voice.konDelay) { - if (voice.konDelay == 5) { - voice.brrAddress = this->_brr.nextAddress; - voice.brrOffset = 1; - voice.sampleOffset = 0; - this->_brr.header = 0; - } + if (voice.konDelay) { + if (voice.konDelay == 5) { + voice.brrAddress = this->_brr.nextAddress; + voice.brrOffset = 1; + voice.sampleOffset = 0; + this->_brr.header = 0; + } - voice.envelope = 0; - voice.hiddenEnvelope = 0; - voice.gaussOffset = 0; - voice.konDelay -= 1; - if (voice.konDelay & 3) - voice.gaussOffset = 0x4000; - this->_latch.pitch = 0; - } + voice.envelope = 0; + voice.hiddenEnvelope = 0; + voice.gaussOffset = 0; + voice.konDelay -= 1; + if (voice.konDelay & 3) + voice.gaussOffset = 0x4000; + this->_latch.pitch = 0; + } - int32_t interpolated = this->interpolate(voice); + int32_t interpolated = this->interpolate(voice); - if (voice.tempNon) - interpolated = this->_noise.lfsr << 1; + if (voice.tempNon) + interpolated = this->_noise.lfsr << 1; - this->_latch.output = interpolated * voice.envelope >> 11 & ~1; - voice.envx = voice.envelope >> 4; + this->_latch.output = interpolated * voice.envelope >> 11 & ~1; + voice.envx = voice.envelope >> 4; - if (this->_master.reset || (this->_brr.header & 3) == 1) { - voice.envelope = 0; - voice.envelopeMode = Envelope::Release; - } + if (this->_master.reset || (this->_brr.header & 3) == 1) { + voice.envelope = 0; + voice.envelopeMode = Envelope::Release; + } - if (this->_timer.sample) - { - if (voice.tempKof) - voice.envelopeMode = Envelope::Release; - if (voice.tempKon) { - voice.konDelay = 5; - voice.envelopeMode = Envelope::Attack; - } - } + if (this->_timer.sample) + { + if (voice.tempKof) + voice.envelopeMode = Envelope::Release; + if (voice.tempKon) { + voice.konDelay = 5; + voice.envelopeMode = Envelope::Attack; + } + } - if (!voice.konDelay) - this->runEnvelope(voice); - } + if (!voice.konDelay) + this->runEnvelope(voice); + } - void DSP::voice4(Voice &voice) - { - voice.loop = false; - if (voice.gaussOffset >= 0x4000) { - this->decodeBRR(voice); - voice.brrOffset += 2; - if (voice.brrOffset >= 9) { - voice.brrOffset = voice.brrAddress + 9; - if (this->_brr.header & 0b1) { - voice.brrAddress = this->_brr.nextAddress; - voice.loop = true; - } - voice.brrOffset = 1; - } - } + void DSP::voice4(Voice &voice) + { + voice.loop = false; + if (voice.gaussOffset >= 0x4000) { + this->decodeBRR(voice); + voice.brrOffset += 2; + if (voice.brrOffset >= 9) { + voice.brrOffset = voice.brrAddress + 9; + if (this->_brr.header & 0b1) { + voice.brrAddress = this->_brr.nextAddress; + voice.loop = true; + } + voice.brrOffset = 1; + } + } - voice.gaussOffset = (voice.gaussOffset & 0x3FFF) + this->_latch.pitch; - if (voice.gaussOffset > 0x7FFF) - voice.gaussOffset = 0x7FFF; - this->voiceOutput(voice, 0); - } + voice.gaussOffset = (voice.gaussOffset & 0x3FFF) + this->_latch.pitch; + if (voice.gaussOffset > 0x7FFF) + voice.gaussOffset = 0x7FFF; + this->voiceOutput(voice, 0); + } - void DSP::voice5(Voice &voice) - { - this->voiceOutput(voice, 1); + void DSP::voice5(Voice &voice) + { + this->voiceOutput(voice, 1); - voice.endx |= voice.loop; - if (voice.konDelay == 5) - voice.endx &= ~voice.endx; - } + voice.endx |= voice.loop; + if (voice.konDelay == 5) + voice.endx &= ~voice.endx; + } - void DSP::voice6(Voice &) - { - this->_latch.outx = this->_latch.output >> 8; - } + void DSP::voice6(Voice &) + { + this->_latch.outx = this->_latch.output >> 8; + } - void DSP::voice7(Voice &voice) - { + void DSP::voice7(Voice &voice) + { - } + } - void DSP::voice8(Voice &voice) - { + void DSP::voice8(Voice &voice) + { - } + } - void DSP::voice9(Voice &voice) - { + void DSP::voice9(Voice &voice) + { - } + } } \ No newline at end of file