mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-23 23:08:16 +00:00
Finishing all voices
Starting echos (random sound generator)
This commit is contained in:
+1
-1
@@ -144,7 +144,7 @@ namespace ComSquare::APU
|
||||
std::shared_ptr<MemoryMap> _map;
|
||||
|
||||
//! @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
|
||||
int16_t _soundBuffer[bufferSize];
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
|
||||
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.bufferStart = buffer;
|
||||
this->_state.bufferEnd = buffer + size;
|
||||
this->_state.bufferSize = size;
|
||||
}
|
||||
|
||||
uint8_t DSP::read(uint24_t addr) const
|
||||
@@ -796,6 +795,6 @@ namespace ComSquare::APU::DSP
|
||||
|
||||
int32_t DSP::getSamplesCount() const
|
||||
{
|
||||
return this->_state.buffer - this->_state.bufferStart;
|
||||
return this->_state.bufferOffset;
|
||||
}
|
||||
}
|
||||
+19
-5
@@ -46,12 +46,20 @@ namespace ComSquare::APU::DSP
|
||||
std::array<uint8_t, 8> FIR;
|
||||
//! @brief Echo data start register (ESA)
|
||||
uint8_t data;
|
||||
//! @brief Offset position after data start
|
||||
uint16_t offset;
|
||||
//! @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<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
|
||||
std::array<uint16_t, 2> input;
|
||||
//! @brief Current sound echoed produced
|
||||
@@ -123,6 +131,8 @@ namespace ComSquare::APU::DSP
|
||||
uint8_t gain;
|
||||
//! @brief envelope associated with this voice
|
||||
uint8_t envx;
|
||||
//! @brief Wave height associated with this voice
|
||||
uint8_t outx;
|
||||
//! @brief Sample end register (ENDX)
|
||||
bool endx : 1;
|
||||
|
||||
@@ -176,10 +186,10 @@ namespace ComSquare::APU::DSP
|
||||
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 Size of buffer
|
||||
uint32_t bufferSize;
|
||||
//! @brief Current position in the buffer of samples
|
||||
uint32_t bufferOffset;
|
||||
};
|
||||
|
||||
struct Timer {
|
||||
@@ -404,6 +414,10 @@ namespace ComSquare::APU::DSP
|
||||
int32_t interpolate(const Voice &voice);
|
||||
void runEnvelope(Voice &voice);
|
||||
|
||||
int32_t loadFIR(bool channel, int fir);
|
||||
void loadEcho(bool channel);
|
||||
int16_t outputEcho(bool channel);
|
||||
|
||||
void timerTick();
|
||||
bool timerPoll(uint32_t rate);
|
||||
|
||||
@@ -414,7 +428,7 @@ namespace ComSquare::APU::DSP
|
||||
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<MemoryMap> map);
|
||||
DSP(int16_t *buffer, uint32_t size, std::weak_ptr<MemoryMap> map);
|
||||
DSP(const DSP &) = default;
|
||||
DSP &operator=(const DSP &) = default;
|
||||
~DSP() = default;
|
||||
|
||||
@@ -6,34 +6,89 @@
|
||||
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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()
|
||||
|
||||
@@ -141,16 +141,16 @@ namespace ComSquare::APU::DSP
|
||||
|
||||
void DSP::voice7(Voice &voice)
|
||||
{
|
||||
|
||||
this->_latch.envx = voice.envx;
|
||||
}
|
||||
|
||||
void DSP::voice8(Voice &voice)
|
||||
{
|
||||
|
||||
voice.outx = this->_latch.outx;
|
||||
}
|
||||
|
||||
void DSP::voice9(Voice &voice)
|
||||
{
|
||||
|
||||
voice.envx = this->_latch.envx;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user