mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-05-03 18:54:48 +12:00
Start decoding ADPCM
This commit is contained in:
parent
000dc09a30
commit
ea6e111938
2 changed files with 149 additions and 6 deletions
|
@ -1,6 +1,9 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
#include "audio/dsp_core.hpp"
|
||||
|
@ -39,17 +42,40 @@ namespace Audio {
|
|||
return this->bufferID > other.bufferID;
|
||||
}
|
||||
};
|
||||
// Buffer of decoded PCM16 samples. TODO: Are there better alternatives to use over deque?
|
||||
using SampleBuffer = std::deque<std::array<s16, 2>>;
|
||||
|
||||
using BufferQueue = std::priority_queue<Buffer>;
|
||||
BufferQueue buffers;
|
||||
|
||||
std::array<float, 3> gain0, gain1, gain2;
|
||||
u16 syncCount;
|
||||
bool enabled;
|
||||
bool enabled; // Is the source enabled?
|
||||
|
||||
BufferQueue buffers;
|
||||
// ADPCM decoding info:
|
||||
// An array of fixed point S5.11 coefficients. These provide "weights" for the history samples
|
||||
// The system describing how an ADPCM output sample is generated is
|
||||
// y[n] = x[n] + 0.5 + coeff1 * y[n-1] + coeff2 * y[n-2]
|
||||
// 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
|
||||
|
||||
SampleBuffer currentSamples;
|
||||
int index = 0; // Index of the voice in [0, 23] for debugging
|
||||
|
||||
void reset();
|
||||
// Pop a buffer from the buffer queue and return it
|
||||
Buffer popBuffer() {
|
||||
assert(!buffers.empty());
|
||||
|
||||
Buffer ret = buffers.top();
|
||||
buffers.pop();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DSPSource() { reset(); }
|
||||
};
|
||||
|
||||
|
@ -72,6 +98,7 @@ namespace Audio {
|
|||
using QuadFrame = Frame<T, 4>;
|
||||
|
||||
using Source = Audio::DSPSource;
|
||||
using SampleBuffer = Source::SampleBuffer;
|
||||
private:
|
||||
enum class DSPState : u32 {
|
||||
Off,
|
||||
|
@ -130,10 +157,13 @@ namespace Audio {
|
|||
}
|
||||
}
|
||||
|
||||
void updateSourceConfig(Source& source, HLE::SourceConfiguration::Configuration& config);
|
||||
void updateSourceConfig(Source& source, HLE::SourceConfiguration::Configuration& config, s16_le* adpcmCoefficients);
|
||||
void generateFrame(StereoFrame<s16>& frame);
|
||||
void outputFrame();
|
||||
void dumpBuffer(const Source::Buffer& buffer);
|
||||
// Decode an entire buffer worth of audio
|
||||
void decodeBuffer(DSPSource& source);
|
||||
SampleBuffer decodeADPCM(const u8* data, usize sampleCount, Source& source);
|
||||
|
||||
public:
|
||||
HLE_DSP(Memory& mem, Scheduler& scheduler, DSPService& dspService);
|
||||
~HLE_DSP() override {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue