mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-08 12:10:34 +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;
|
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];
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user