Finishing all voices

Starting echos
(random sound generator)
This commit is contained in:
Melefo
2021-02-05 16:39:14 +01:00
parent 96fe1a5e33
commit bdd0f2375d
5 changed files with 83 additions and 15 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ namespace ComSquare::APU
std::shared_ptr<MemoryMap> _map; std::shared_ptr<MemoryMap> _map;
//! @brief Total size of the buffer containing samples //! @brief Total size of the buffer containing samples
static constexpr int32_t bufferSize = 0x20000; static constexpr int32_t bufferSize = 0x10000;
//! @brief Buffer containing samples to be played //! @brief Buffer containing samples to be played
int16_t _soundBuffer[bufferSize]; int16_t _soundBuffer[bufferSize];
+3 -4
View File
@@ -8,11 +8,10 @@
namespace ComSquare::APU::DSP namespace ComSquare::APU::DSP
{ {
DSP::DSP(int16_t *buffer, int32_t size, std::weak_ptr<MemoryMap> map) : _map(map) DSP::DSP(int16_t *buffer, uint32_t size, std::weak_ptr<MemoryMap> map) : _map(map)
{ {
this->_state.buffer = buffer; this->_state.buffer = buffer;
this->_state.bufferStart = buffer; this->_state.bufferSize = size;
this->_state.bufferEnd = buffer + size;
} }
uint8_t DSP::read(uint24_t addr) const uint8_t DSP::read(uint24_t addr) const
@@ -796,6 +795,6 @@ namespace ComSquare::APU::DSP
int32_t DSP::getSamplesCount() const int32_t DSP::getSamplesCount() const
{ {
return this->_state.buffer - this->_state.bufferStart; return this->_state.bufferOffset;
} }
} }
+19 -5
View File
@@ -46,12 +46,20 @@ namespace ComSquare::APU::DSP
std::array<uint8_t, 8> FIR; std::array<uint8_t, 8> FIR;
//! @brief Echo data start register (ESA) //! @brief Echo data start register (ESA)
uint8_t data; uint8_t data;
//! @brief Offset position after data start
uint16_t offset;
//! @brief Echo delay size register (EDL) //! @brief Echo delay size register (EDL)
uint8_t delay; uint8_t delay;
//! @brief Echo enabled (5th bit FLG) //! @brief Echo enabled (5th bit FLG)
bool enabled = true; bool enabled = true;
//! @brief Last sound produced for each voice in each channel //! @brief Last sound produced for each voice in each channel
std::array<std::array<int16_t, 8>, 2> history; std::array<std::array<int16_t, 8>, 2> history;
//! @brief Current position inside history
uint8_t historyOffset;
//! @brief Address of the current echo
uint16_t address;
//! @brief Current of value of the echo
uint8_t value;
//! @brief Current sound to echo //! @brief Current sound to echo
std::array<uint16_t, 2> input; std::array<uint16_t, 2> input;
//! @brief Current sound echoed produced //! @brief Current sound echoed produced
@@ -123,6 +131,8 @@ namespace ComSquare::APU::DSP
uint8_t gain; uint8_t gain;
//! @brief envelope associated with this voice //! @brief envelope associated with this voice
uint8_t envx; uint8_t envx;
//! @brief Wave height associated with this voice
uint8_t outx;
//! @brief Sample end register (ENDX) //! @brief Sample end register (ENDX)
bool endx : 1; bool endx : 1;
@@ -176,10 +186,10 @@ namespace ComSquare::APU::DSP
uint8_t voice = 0; uint8_t voice = 0;
//! @brief Current buffer of samples //! @brief Current buffer of samples
int16_t *buffer; int16_t *buffer;
//! @brief Limit of the buffer //! @brief Size of buffer
int16_t *bufferEnd; uint32_t bufferSize;
//! @brief Beginning of the buffer //! @brief Current position in the buffer of samples
int16_t *bufferStart; uint32_t bufferOffset;
}; };
struct Timer { struct Timer {
@@ -404,6 +414,10 @@ namespace ComSquare::APU::DSP
int32_t interpolate(const Voice &voice); int32_t interpolate(const Voice &voice);
void runEnvelope(Voice &voice); void runEnvelope(Voice &voice);
int32_t loadFIR(bool channel, int fir);
void loadEcho(bool channel);
int16_t outputEcho(bool channel);
void timerTick(); void timerTick();
bool timerPoll(uint32_t rate); bool timerPoll(uint32_t rate);
@@ -414,7 +428,7 @@ namespace ComSquare::APU::DSP
uint8_t _readRAM(uint24_t addr); uint8_t _readRAM(uint24_t addr);
void _writeRAM(uint24_t addr, uint8_t data); void _writeRAM(uint24_t addr, uint8_t data);
public: public:
DSP(int16_t *buffer, int32_t size, std::weak_ptr<MemoryMap> map); DSP(int16_t *buffer, uint32_t size, std::weak_ptr<MemoryMap> map);
DSP(const DSP &) = default; DSP(const DSP &) = default;
DSP &operator=(const DSP &) = default; DSP &operator=(const DSP &) = default;
~DSP() = default; ~DSP() = default;
+57 -2
View File
@@ -6,34 +6,89 @@
namespace ComSquare::APU::DSP namespace ComSquare::APU::DSP
{ {
int32_t DSP::loadFIR(bool channel, int fir)
{
int32_t sample = this->_echo.history[channel][this->_echo.historyOffset + fir + 1];
return (sample * this->_echo.FIR[fir]) >> 6;
}
void DSP::loadEcho(bool channel)
{
uint16_t address = this->_echo.address + channel * 2;
uint8_t low = this->_readRAM(address++);
uint8_t high = this->_readRAM(address);
int16_t echo = (high << 8) + low;
this->_echo.history[channel][this->_echo.historyOffset] = echo >> 1;
}
int16_t DSP::outputEcho(bool channel)
{
int16_t master = this->_master.output[channel] * this->_master.volume[channel] >> 7;
int16_t echo = this->_echo.input[channel] * this->_echo.input[channel] >> 7;
return master + echo;
}
void DSP::echo22() void DSP::echo22()
{ {
this->_echo.historyOffset += 1;
this->_echo.address = (this->_echo.value << 8) + this->_echo.offset;
this->loadEcho(0);
this->_echo.input[0] = this->loadFIR(0, 0);
this->_echo.input[1] = this->loadFIR(1, 0);
} }
void DSP::echo23() void DSP::echo23()
{ {
this->loadEcho(1);
this->_echo.input[0] += this->loadFIR(0, 1) + this->loadFIR(0, 2);
this->_echo.input[1] += this->loadFIR(1, 1) + this->loadFIR(1, 2);
} }
void DSP::echo24() void DSP::echo24()
{ {
this->_echo.input[0] += this->loadFIR(0, 3) + this->loadFIR(0, 4) + this->loadFIR(0, 5);
this->_echo.input[1] += this->loadFIR(1, 3) + this->loadFIR(1, 4) + this->loadFIR(1, 5);
} }
void DSP::echo25() void DSP::echo25()
{ {
this->_echo.input[0] += this->loadFIR(0, 6) + this->loadFIR(0, 7);
this->_echo.input[1] += this->loadFIR(1, 6) + this->loadFIR(1, 7);
} }
void DSP::echo26() void DSP::echo26()
{ {
this->_master.output[0] = this->outputEcho(0);
this->_echo.output[0] += this->_echo.input[0] * this->_echo.feedback >> 7;
this->_echo.output[1] += this->_echo.input[1] * this->_echo.feedback >> 7;
} }
void DSP::echo27() void DSP::echo27()
{ {
int16_t outputLeft = this->_master.output[0];
int16_t outputRight = this->outputEcho(1);
this->_master.output[0] = 0;
this->_master.output[1] = 0;
if (this->_master.mute) {
outputLeft = 0;
outputRight = 0;
}
srand(time(NULL));
this->_state.buffer[this->_state.bufferOffset] = outputLeft + (INT16_MIN + rand() % (INT16_MAX + 1 - INT16_MIN));
this->_state.buffer[this->_state.bufferOffset + 1] = outputRight + (INT16_MIN + rand() % (INT16_MAX + 1 - INT16_MIN));
this->_state.bufferOffset += 2;
if (this->_state.bufferOffset >= this->_state.bufferSize)
this->_state.bufferOffset = 0;
} }
void DSP::echo28() void DSP::echo28()
+3 -3
View File
@@ -141,16 +141,16 @@ namespace ComSquare::APU::DSP
void DSP::voice7(Voice &voice) void DSP::voice7(Voice &voice)
{ {
this->_latch.envx = voice.envx;
} }
void DSP::voice8(Voice &voice) void DSP::voice8(Voice &voice)
{ {
voice.outx = this->_latch.outx;
} }
void DSP::voice9(Voice &voice) void DSP::voice9(Voice &voice)
{ {
voice.envx = this->_latch.envx;
} }
} }