Audio device pt 2

This commit is contained in:
wheremyfoodat 2025-02-09 04:06:44 +02:00
parent 486e2ea5cb
commit 4b7fedb65c
4 changed files with 41 additions and 42 deletions

View file

@ -8,17 +8,17 @@
class AudioDeviceInterface {
protected:
using Samples = Common::RingBuffer<s16, 0x2000 * 2>;
using RenderBatchCallback = usize (*)(const s16*, usize);
Samples* samples = nullptr;
const AudioDeviceConfig& audioSettings;
// Store the last stereo sample we output. We play this when underruning to avoid pops.
std::array<s16, 2> lastStereoSample{};
public:
AudioDeviceInterface(Samples* samples, const AudioDeviceConfig& audioSettings) : samples(samples), audioSettings(audioSettings) {}
// Store the last stereo sample we output. We play this when underruning to avoid pops.
// TODO: Make this protected again before merging!!!
std::array<s16, 2> lastStereoSample{};
bool running = false;
Samples* getSamples() { return samples; }
@ -28,4 +28,7 @@ class AudioDeviceInterface {
virtual void start() = 0;
virtual void stop() = 0;
// Only used for audio devices that render multiple audio frames in one go, eg the libretro audio device.
virtual void renderBatch(RenderBatchCallback callback) {}
};

View file

@ -1,7 +1,5 @@
#pragma once
#include <atomic>
#include <string>
#include <vector>
#include <cstring>
#include "audio/audio_device.hpp"
@ -28,6 +26,35 @@ class LibretroAudioDevice : public AudioDeviceInterface {
void start() override { running = true; }
void stop() override { running = false; };
void renderBatch(RenderBatchCallback callback) override {
if (running) {
static constexpr int frameCount = 547;
static constexpr int channelCount = 2;
static s16 audioBuffer[frameCount * channelCount];
usize samplesWritten = 0;
samplesWritten += samples->pop(audioBuffer, frameCount * channelCount);
// Get the last sample for underrun handling
if (samplesWritten != 0) {
std::memcpy(&lastStereoSample[0], &audioBuffer[(samplesWritten - 1) * 2], sizeof(lastStereoSample));
}
// If underruning, copy the last output sample
{
s16* pointer = &audioBuffer[samplesWritten * 2];
s16 l = lastStereoSample[0];
s16 r = lastStereoSample[1];
for (usize i = samplesWritten; i < frameCount; i++) {
*pointer++ = l;
*pointer++ = r;
}
}
callback(audioBuffer, sizeof(audioBuffer) / (2 * sizeof(s16)));
}
}
bool isInitialized() const { return initialized; }
bool isRunning() const { return running; }
};

View file

@ -60,7 +60,7 @@ class Emulator {
static constexpr u32 width = 400;
static constexpr u32 height = 240 * 2; // * 2 because 2 screens
ROMType romType = ROMType::None;
bool running = false; // Is the emulator running a game?
bool running = false; // Is the emulator running a game?
private:
#ifdef PANDA3DS_ENABLE_HTTP_SERVER