This commit is contained in:
wheremyfoodat 2024-04-27 00:37:45 +03:00
parent 26c07717aa
commit e9e041813f
2 changed files with 19 additions and 18 deletions

View file

@ -21,7 +21,7 @@ namespace Audio {
u32 paddr; // Physical address of the buffer
u32 sampleCount; // Total number of samples
u8 adpcmScale; // ADPCM predictor/scale
u8 pad1; // Unknown
u8 pad1; // Unknown
std::array<s16, 2> previousSamples; // ADPCM y[n-1] and y[n-2]
bool adpcmDirty;
@ -59,8 +59,8 @@ namespace Audio {
// Where y[n] is the output sample we're generating, x[n] is the ADPCM "differential" of the current sample
// And coeff1/coeff2 are the coefficients from this array that are used for weighing the history samples
std::array<s16, 16> adpcmCoefficients;
s16 history1; // y[n-1], the previous output sample
s16 history2; // y[n-2], the previous previous output sample
s16 history1; // y[n-1], the previous output sample
s16 history2; // y[n-2], the previous previous output sample
SampleBuffer currentSamples;
int index = 0; // Index of the voice in [0, 23] for debugging
@ -69,7 +69,7 @@ namespace Audio {
// Pop a buffer from the buffer queue and return it
Buffer popBuffer() {
assert(!buffers.empty());
Buffer ret = buffers.top();
buffers.pop();
@ -87,7 +87,7 @@ namespace Audio {
template <typename T, usize channelCount>
using Frame = std::array<Sample<T, channelCount>, 160>;
template <typename T>
using MonoFrame = Frame<T, 1>;
@ -99,6 +99,7 @@ namespace Audio {
using Source = Audio::DSPSource;
using SampleBuffer = Source::SampleBuffer;
private:
enum class DSPState : u32 {
Off,
@ -118,7 +119,7 @@ namespace Audio {
SourceType sourceType = SourceType::Stereo;
void resetAudioPipe();
bool loaded = false; // Have we loaded a component?
bool loaded = false; // Have we loaded a component?
// Get the index for the current region we'll be reading. Returns the region with the highest frame counter
// Accounting for whether one of the frame counters has wrapped around

View file

@ -107,7 +107,7 @@ namespace Audio {
outputFrame();
scheduler.addEvent(Scheduler::EventType::RunDSP, scheduler.currentTimestamp + Audio::cyclesPerFrame);
}
u16 HLE_DSP::recvData(u32 regId) {
if (regId != 0) {
Helpers::panic("Audio: invalid register in HLE frontend");
@ -141,14 +141,11 @@ namespace Audio {
// TODO: Other initialization stuff here
dspState = DSPState::On;
resetAudioPipe();
dspService.triggerPipeEvent(DSPPipeType::Audio);
break;
case StateChange::Shutdown:
dspState = DSPState::Off;
break;
case StateChange::Shutdown: dspState = DSPState::Off; break;
default: Helpers::panic("Unimplemented DSP audio pipe state change %d", state);
}
}
@ -216,11 +213,13 @@ namespace Audio {
// Generate audio
if (source.enabled && !source.buffers.empty()) {
static int aaaa = 0;
const auto& buffer = source.buffers.top();
const u8* data = getPointerPhys<u8>(buffer.paddr);
if (data != nullptr) {
// TODO
}
}
}
@ -265,7 +264,7 @@ namespace Audio {
config.partialResetFlag = 0;
source.buffers = {};
}
// TODO: Should we check bufferQueueDirty here too?
if (config.formatDirty || config.embeddedBufferDirty) {
sampleFormat = config.format;
@ -341,14 +340,15 @@ namespace Audio {
HLE_DSP::SampleBuffer HLE_DSP::decodeADPCM(const u8* data, usize sampleCount, Source& source) {
static constexpr uint samplesPerBlock = 14;
// An ADPCM block is comprised of a single header which contains the scale and predictor value for the block, and then 14 4bpp samples (hence the / 2)
// An ADPCM block is comprised of a single header which contains the scale and predictor value for the block, and then 14 4bpp samples (hence
// the / 2)
static constexpr usize blockSize = sizeof(u8) + samplesPerBlock / 2;
// How many ADPCM blocks we'll be consuming. It's sampleCount / samplesPerBlock, rounded up.
const usize blockCount = (sampleCount + (samplesPerBlock - 1)) / samplesPerBlock;
const usize outputSize = sampleCount + (sampleCount & 1); // Bump the output size to a multiple of 2
usize outputCount = 0; // How many stereo samples have we output thus far?
usize outputCount = 0; // How many stereo samples have we output thus far?
SampleBuffer decodedSamples(outputSize);
s16 history1 = source.history1;
@ -371,8 +371,8 @@ namespace Audio {
// So each byte of ADPCM data ends up generating 2 stereo samples
for (uint sampleIndex = 0; sampleIndex < samplesPerBlock && outputCount < sampleCount; sampleIndex += 2) {
const auto decode = [&](s32 nibble) -> s16 {
static constexpr s32 ONE = 0x800; // 1.0 in S5.11 fixed point
static constexpr s32 HALF = ONE / 2; // 0.5 similarly
static constexpr s32 ONE = 0x800; // 1.0 in S5.11 fixed point
static constexpr s32 HALF = ONE / 2; // 0.5 similarly
// Sign extend our nibble from s4 to s32
nibble = (nibble << 28) >> 28;