mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-03 12:27:21 +12:00
Better DSP scheduling
This commit is contained in:
parent
f58354af06
commit
33eb096ef8
8 changed files with 44 additions and 27 deletions
|
@ -7,20 +7,30 @@
|
|||
#include "helpers.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "scheduler.hpp"
|
||||
|
||||
// The DSP core must have access to the DSP service to be able to trigger interrupts properly
|
||||
class DSPService;
|
||||
|
||||
namespace Audio {
|
||||
// There are 160 stereo samples in 1 audio frame, so 320 samples total
|
||||
static constexpr u64 samplesInFrame = 160;
|
||||
// 1 frame = 4096 DSP cycles = 8192 ARM11 cycles
|
||||
static constexpr u64 cyclesPerFrame = samplesInFrame * 8192;
|
||||
// For LLE DSP cores, we run the DSP for N cycles at a time, every N*2 arm11 cycles since the ARM11 runs twice as fast
|
||||
static constexpr u64 lleSlice = 16384;
|
||||
|
||||
class DSPCore {
|
||||
protected:
|
||||
Memory& mem;
|
||||
Scheduler& scheduler;
|
||||
DSPService& dspService;
|
||||
|
||||
MAKE_LOG_FUNCTION(log, dspLogger)
|
||||
|
||||
public:
|
||||
enum class Type { Null, Teakra };
|
||||
DSPCore(Memory& mem, DSPService& dspService) : mem(mem), dspService(dspService) {}
|
||||
DSPCore(Memory& mem, Scheduler& scheduler, DSPService& dspService) : mem(mem), scheduler(scheduler), dspService(dspService) {}
|
||||
|
||||
virtual void reset() = 0;
|
||||
virtual void runAudioFrame() = 0;
|
||||
|
@ -36,5 +46,5 @@ namespace Audio {
|
|||
virtual void setSemaphoreMask(u16 value) = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<DSPCore> makeDSPCore(DSPCore::Type type, Memory& mem, DSPService& dspService);
|
||||
std::unique_ptr<DSPCore> makeDSPCore(DSPCore::Type type, Memory& mem, Scheduler& scheduler, DSPService& dspService);
|
||||
} // namespace Audio
|
|
@ -20,7 +20,7 @@ namespace Audio {
|
|||
void resetAudioPipe();
|
||||
|
||||
public:
|
||||
NullDSP(Memory& mem, DSPService& dspService) : DSPCore(mem, dspService) {}
|
||||
NullDSP(Memory& mem, Scheduler& scheduler, DSPService& dspService) : DSPCore(mem, scheduler, dspService) {}
|
||||
|
||||
void reset() override;
|
||||
void runAudioFrame() override {}
|
||||
|
|
|
@ -65,14 +65,22 @@ namespace Audio {
|
|||
bool signalledData;
|
||||
bool signalledSemaphore;
|
||||
|
||||
// Run 1 slice of DSP instructions
|
||||
void runSlice() {
|
||||
if (running) {
|
||||
teakra.Run(Audio::lleSlice);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
TeakraDSP(Memory& mem, DSPService& dspService);
|
||||
TeakraDSP(Memory& mem, Scheduler& scheduler, DSPService& dspService);
|
||||
|
||||
void reset() override;
|
||||
|
||||
// Run 1 slice of DSP instructions and schedule the next audio frame
|
||||
void runAudioFrame() override {
|
||||
if (running) {
|
||||
teakra.Run(16384);
|
||||
}
|
||||
runSlice();
|
||||
scheduler.addEvent(Scheduler::EventType::RunDSP, scheduler.currentTimestamp + Audio::lleSlice * 2);
|
||||
}
|
||||
|
||||
u8* getDspMemory() override { return teakra.GetDspMemory().data(); }
|
||||
|
|
|
@ -50,7 +50,6 @@ struct Scheduler {
|
|||
// Clear any pending events
|
||||
events.clear();
|
||||
addEvent(Scheduler::EventType::VBlank, arm11Clock / 60);
|
||||
addEvent(Scheduler::EventType::RunDSP, 16384 * 2);
|
||||
|
||||
// Add a dummy event to always keep the scheduler non-empty
|
||||
addEvent(EventType::Panic, std::numeric_limits<u64>::max());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue