pureikyubu/src/audio.h
2023-08-02 23:43:02 +03:00

92 lines
1.9 KiB
C++

// AX audio mixer.
// To add sound to your OS, you need to implement this small interface.
#pragma once
#include <dsound.h>
namespace Flipper
{
enum class AudioSampleRate
{
Rate_32000 = 0,
Rate_48000,
};
enum class AxChannel
{
AudioDma = 0,
DvdAudio,
Max,
};
class AudioMixer;
class AudioRing
{
AudioMixer* mixer;
// Accumulate frameSize bytes in the circular buffer.
// When we have accumulated, lock the DirectSound buffer and emit frameSize bytes there.
// The frameSize size is not very large and not very small.
// It should not be longer than 1 PAL / NTSC video frame, but not less than 1/3 video frame.
static const size_t maxFrames = 16;
static const size_t frameSize = 0x1000; // Audio frame size
static const size_t ringSize = maxFrames * frameSize;
uint8_t* ringBuffer = nullptr;
size_t ringWritePtr = 0;
size_t ringReadPtr = 0;
size_t CurrentSize();
uint8_t FetchByte();
void EmitSound();
LPDIRECTSOUNDBUFFER DSBuffer = nullptr;
bool enabled = false;
size_t frameCounter = 0;
void DumpDSBuffer();
void DumpRing();
void WaitBufferOverflow(void);
size_t framesPerEmit = maxFrames / 2;
int bufferMode = DSBPLAY_LOOPING;
public:
AudioRing(AudioMixer* parentInst);
~AudioRing();
void Enable(bool enable);
bool IsEnabled() { return enabled; }
void SetSampleRate(AudioSampleRate value);
void PushBytes(uint8_t* sampleData, size_t sampleDataSize);
};
class AudioMixer
{
friend AudioRing;
AudioRing** Sources = nullptr;
static const size_t numSources = 2;
LPDIRECTSOUND8 lpds = nullptr;
LPDIRECTSOUNDBUFFER PrimaryBuffer = nullptr;
public:
AudioMixer(HWConfig* config);
~AudioMixer();
void Enable(AxChannel channel, bool enable);
bool IsEnabled(AxChannel channel);
void SetSampleRate(AxChannel channel, AudioSampleRate value);
void PushBytes(AxChannel channel, uint8_t* sampleData, size_t sampleDataSize);
};
}