mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-18 03:31:31 +12:00
Format
This commit is contained in:
parent
26c07717aa
commit
e9e041813f
2 changed files with 19 additions and 18 deletions
|
@ -21,7 +21,7 @@ namespace Audio {
|
||||||
u32 paddr; // Physical address of the buffer
|
u32 paddr; // Physical address of the buffer
|
||||||
u32 sampleCount; // Total number of samples
|
u32 sampleCount; // Total number of samples
|
||||||
u8 adpcmScale; // ADPCM predictor/scale
|
u8 adpcmScale; // ADPCM predictor/scale
|
||||||
u8 pad1; // Unknown
|
u8 pad1; // Unknown
|
||||||
|
|
||||||
std::array<s16, 2> previousSamples; // ADPCM y[n-1] and y[n-2]
|
std::array<s16, 2> previousSamples; // ADPCM y[n-1] and y[n-2]
|
||||||
bool adpcmDirty;
|
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
|
// 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
|
// And coeff1/coeff2 are the coefficients from this array that are used for weighing the history samples
|
||||||
std::array<s16, 16> adpcmCoefficients;
|
std::array<s16, 16> adpcmCoefficients;
|
||||||
s16 history1; // y[n-1], the previous output sample
|
s16 history1; // y[n-1], the previous output sample
|
||||||
s16 history2; // y[n-2], the previous previous output sample
|
s16 history2; // y[n-2], the previous previous output sample
|
||||||
|
|
||||||
SampleBuffer currentSamples;
|
SampleBuffer currentSamples;
|
||||||
int index = 0; // Index of the voice in [0, 23] for debugging
|
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
|
// Pop a buffer from the buffer queue and return it
|
||||||
Buffer popBuffer() {
|
Buffer popBuffer() {
|
||||||
assert(!buffers.empty());
|
assert(!buffers.empty());
|
||||||
|
|
||||||
Buffer ret = buffers.top();
|
Buffer ret = buffers.top();
|
||||||
buffers.pop();
|
buffers.pop();
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ namespace Audio {
|
||||||
|
|
||||||
template <typename T, usize channelCount>
|
template <typename T, usize channelCount>
|
||||||
using Frame = std::array<Sample<T, channelCount>, 160>;
|
using Frame = std::array<Sample<T, channelCount>, 160>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using MonoFrame = Frame<T, 1>;
|
using MonoFrame = Frame<T, 1>;
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ namespace Audio {
|
||||||
|
|
||||||
using Source = Audio::DSPSource;
|
using Source = Audio::DSPSource;
|
||||||
using SampleBuffer = Source::SampleBuffer;
|
using SampleBuffer = Source::SampleBuffer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class DSPState : u32 {
|
enum class DSPState : u32 {
|
||||||
Off,
|
Off,
|
||||||
|
@ -118,7 +119,7 @@ namespace Audio {
|
||||||
SourceType sourceType = SourceType::Stereo;
|
SourceType sourceType = SourceType::Stereo;
|
||||||
|
|
||||||
void resetAudioPipe();
|
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
|
// 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
|
// Accounting for whether one of the frame counters has wrapped around
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace Audio {
|
||||||
outputFrame();
|
outputFrame();
|
||||||
scheduler.addEvent(Scheduler::EventType::RunDSP, scheduler.currentTimestamp + Audio::cyclesPerFrame);
|
scheduler.addEvent(Scheduler::EventType::RunDSP, scheduler.currentTimestamp + Audio::cyclesPerFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 HLE_DSP::recvData(u32 regId) {
|
u16 HLE_DSP::recvData(u32 regId) {
|
||||||
if (regId != 0) {
|
if (regId != 0) {
|
||||||
Helpers::panic("Audio: invalid register in HLE frontend");
|
Helpers::panic("Audio: invalid register in HLE frontend");
|
||||||
|
@ -141,14 +141,11 @@ namespace Audio {
|
||||||
// TODO: Other initialization stuff here
|
// TODO: Other initialization stuff here
|
||||||
dspState = DSPState::On;
|
dspState = DSPState::On;
|
||||||
resetAudioPipe();
|
resetAudioPipe();
|
||||||
|
|
||||||
dspService.triggerPipeEvent(DSPPipeType::Audio);
|
dspService.triggerPipeEvent(DSPPipeType::Audio);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StateChange::Shutdown:
|
case StateChange::Shutdown: dspState = DSPState::Off; break;
|
||||||
dspState = DSPState::Off;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: Helpers::panic("Unimplemented DSP audio pipe state change %d", state);
|
default: Helpers::panic("Unimplemented DSP audio pipe state change %d", state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,11 +213,13 @@ namespace Audio {
|
||||||
|
|
||||||
// Generate audio
|
// Generate audio
|
||||||
if (source.enabled && !source.buffers.empty()) {
|
if (source.enabled && !source.buffers.empty()) {
|
||||||
|
static int aaaa = 0;
|
||||||
const auto& buffer = source.buffers.top();
|
const auto& buffer = source.buffers.top();
|
||||||
const u8* data = getPointerPhys<u8>(buffer.paddr);
|
const u8* data = getPointerPhys<u8>(buffer.paddr);
|
||||||
|
|
||||||
if (data != nullptr) {
|
if (data != nullptr) {
|
||||||
// TODO
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +264,7 @@ namespace Audio {
|
||||||
config.partialResetFlag = 0;
|
config.partialResetFlag = 0;
|
||||||
source.buffers = {};
|
source.buffers = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should we check bufferQueueDirty here too?
|
// TODO: Should we check bufferQueueDirty here too?
|
||||||
if (config.formatDirty || config.embeddedBufferDirty) {
|
if (config.formatDirty || config.embeddedBufferDirty) {
|
||||||
sampleFormat = config.format;
|
sampleFormat = config.format;
|
||||||
|
@ -341,14 +340,15 @@ namespace Audio {
|
||||||
|
|
||||||
HLE_DSP::SampleBuffer HLE_DSP::decodeADPCM(const u8* data, usize sampleCount, Source& source) {
|
HLE_DSP::SampleBuffer HLE_DSP::decodeADPCM(const u8* data, usize sampleCount, Source& source) {
|
||||||
static constexpr uint samplesPerBlock = 14;
|
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;
|
static constexpr usize blockSize = sizeof(u8) + samplesPerBlock / 2;
|
||||||
|
|
||||||
// How many ADPCM blocks we'll be consuming. It's sampleCount / samplesPerBlock, rounded up.
|
// How many ADPCM blocks we'll be consuming. It's sampleCount / samplesPerBlock, rounded up.
|
||||||
const usize blockCount = (sampleCount + (samplesPerBlock - 1)) / samplesPerBlock;
|
const usize blockCount = (sampleCount + (samplesPerBlock - 1)) / samplesPerBlock;
|
||||||
const usize outputSize = sampleCount + (sampleCount & 1); // Bump the output size to a multiple of 2
|
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);
|
SampleBuffer decodedSamples(outputSize);
|
||||||
|
|
||||||
s16 history1 = source.history1;
|
s16 history1 = source.history1;
|
||||||
|
@ -371,8 +371,8 @@ namespace Audio {
|
||||||
// So each byte of ADPCM data ends up generating 2 stereo samples
|
// So each byte of ADPCM data ends up generating 2 stereo samples
|
||||||
for (uint sampleIndex = 0; sampleIndex < samplesPerBlock && outputCount < sampleCount; sampleIndex += 2) {
|
for (uint sampleIndex = 0; sampleIndex < samplesPerBlock && outputCount < sampleCount; sampleIndex += 2) {
|
||||||
const auto decode = [&](s32 nibble) -> s16 {
|
const auto decode = [&](s32 nibble) -> s16 {
|
||||||
static constexpr s32 ONE = 0x800; // 1.0 in S5.11 fixed point
|
static constexpr s32 ONE = 0x800; // 1.0 in S5.11 fixed point
|
||||||
static constexpr s32 HALF = ONE / 2; // 0.5 similarly
|
static constexpr s32 HALF = ONE / 2; // 0.5 similarly
|
||||||
|
|
||||||
// Sign extend our nibble from s4 to s32
|
// Sign extend our nibble from s4 to s32
|
||||||
nibble = (nibble << 28) >> 28;
|
nibble = (nibble << 28) >> 28;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue