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;
//! @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];
+3 -4
View File
@@ -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
View File
@@ -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;
+57 -2
View File
@@ -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()
+3 -3
View File
@@ -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;
}
}