Skip to content

Commit

Permalink
Another audio refactor, utilize implicit device pause state and strea…
Browse files Browse the repository at this point in the history
…m gain rather than own variables, cleaner code.
  • Loading branch information
coornio committed Nov 15, 2024
1 parent 44728db commit 7d7ac51
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 77 deletions.
46 changes: 46 additions & 0 deletions src/Assistants/BasicAudioSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,49 @@ void BasicAudioSpec::changeGlobalVolume(s32 delta) noexcept {

#pragma endregion
/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/

s32 AudioSpecBlock::getFrequency() const noexcept {
return mAudioSpec.freq;
}

s32 AudioSpecBlock::getStreamCount() const noexcept {
return static_cast<s32>(mAudioStreams.size());
}

bool AudioSpecBlock::isPaused(const u32 index) const noexcept {
const auto deviceID{ SDL_GetAudioStreamDevice(mAudioStreams[index]) };
return deviceID ? SDL_AudioDevicePaused(deviceID) : true;
}

f32 AudioSpecBlock::getSampleRate(const f32 framerate) const noexcept {
return framerate > Epsilon::f32 ? mAudioSpec.freq / framerate : 0.0f;
}

f32 AudioSpecBlock::getGain(const u32 index) const noexcept {
return SDL_GetAudioStreamGain(mAudioStreams[index]);
}

s32 AudioSpecBlock::getGainByte(const u32 index) const noexcept {
return static_cast<s32>(getGain(index) * 255.0f);
}

void AudioSpecBlock::pauseStream(const u32 index) noexcept {
SDL_PauseAudioStreamDevice(mAudioStreams[index]);
}

void AudioSpecBlock::resumeStream(const u32 index) noexcept {
SDL_ResumeAudioStreamDevice(mAudioStreams[index]);
}

void AudioSpecBlock::setGain(const u32 index, const f32 gain) noexcept {
SDL_SetAudioStreamGain(mAudioStreams[index], gain);
}

void AudioSpecBlock::addGain(const u32 index, const s32 gain) noexcept {
static constexpr f32 minF{ 1.0f / 255.0f };
setGain(index, std::clamp(getGain(index) + gain * minF, 0.0f, 1.0f));
}

void AudioSpecBlock::addGain(const u32 index, const f32 gain) noexcept {
setGain(index, std::clamp(getGain(index) + gain, 0.0f, 1.0f));
}
71 changes: 19 additions & 52 deletions src/Assistants/BasicAudioSpec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,72 +59,43 @@ class BasicAudioSpec final {
/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/

class AudioSpecBlock {

struct StreamBlock {
s32 volume{ 255 };
bool active{};
SDL_Unique<SDL_AudioStream> stream{};
};

SDL_AudioSpec mAudioSpec;
std::vector<StreamBlock>
std::vector<SDL_Unique<SDL_AudioStream>>
mAudioStreams;

public:
AudioSpecBlock(
const SDL_AudioFormat format, const s32 channels, const s32 frequency, const s32 streams,
const SDL_AudioDeviceID device = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK
) noexcept
) noexcept
: mAudioStreams(std::max(streams, 1))
{
mAudioSpec = { format, std::max(channels, 1), std::max(frequency, 1) };
for (auto& audioStream : mAudioStreams) {
audioStream.stream = SDL_OpenAudioDeviceStream(device, &mAudioSpec, nullptr, nullptr);
audioStream = SDL_OpenAudioDeviceStream(device, &mAudioSpec, nullptr, nullptr);
}
}
~AudioSpecBlock() = default;

AudioSpecBlock(const AudioSpecBlock&) = delete;
AudioSpecBlock& operator=(const AudioSpecBlock&) = delete;

auto getFrequency() const noexcept { return mAudioSpec.freq; }
auto getStreamCount() const noexcept { return static_cast<s32>(mAudioStreams.size()); }
s32 getFrequency() const noexcept;
s32 getStreamCount() const noexcept;

auto getSampleRate(const f32 framerate) const noexcept {
return framerate > Epsilon::f32 ? mAudioSpec.freq / framerate : 0.0f;
}
bool isPaused(const u32 index) const noexcept;

bool getStatus(const u32 index) noexcept {
if (index >= mAudioStreams.size()) { return false; }
return mAudioStreams[index].active;
}
auto getVolume(const u32 index) const noexcept {
if (index >= mAudioStreams.size()) { return -1; }
return mAudioStreams[index].volume;
}
auto getVolumeNorm(const u32 index) const noexcept {
if (index >= mAudioStreams.size()) { return -1.0f; }
return mAudioStreams[index].volume / 255.0f;
}
f32 getSampleRate(const f32 framerate) const noexcept;
f32 getGain(const u32 index) const noexcept;
s32 getGainByte(const u32 index) const noexcept;

void setStatus(const u32 index, const bool state) noexcept {
if (index >= mAudioStreams.size()) { return; }
if (state) {
mAudioStreams[index].active = \
SDL_ResumeAudioStreamDevice(mAudioStreams[index].stream);
} else {
mAudioStreams[index].active = false;
SDL_PauseAudioStreamDevice(mAudioStreams[index].stream);
}
}
void setVolume(const u32 index, const s32 value) noexcept {
if (index >= mAudioStreams.size()) { return; }
mAudioStreams[index].volume = std::clamp(value, 0, 255);
}
void changeVolume(const u32 index, const s32 delta) noexcept {
if (index >= mAudioStreams.size()) { return; }
mAudioStreams[index].volume = std::clamp(mAudioStreams[index].volume + delta, 0, 255);
}
void pauseStream(const u32 index) noexcept;
void resumeStream(const u32 index) noexcept;

void setGain(const u32 index, const f32 gain) noexcept;
void addGain(const u32 index, const s32 gain) noexcept;
void addGain(const u32 index, const f32 gain) noexcept;

/**
* @brief Pushes buffer of audio samples to SDL, accepts any span
Expand All @@ -133,25 +104,21 @@ class AudioSpecBlock {
*/
template <typename T>
void pushAudioData(const u32 index, const std::span<T> samplesBuffer) const {
if (index >= mAudioStreams.size()) { return; }

if (!mAudioStreams[index].stream) { return; }
if (!mAudioStreams[index].active) { return; }
if (isPaused(index)) { return; }

const auto streamVolume{ AudioSpecBlock::getVolumeNorm(index) };
const auto globalVolume{ BasicAudioSpec::getGlobalVolumeNorm() };

std::transform(
std::execution::unseq,
samplesBuffer.begin(),
samplesBuffer.end(),
samplesBuffer.data(),
[streamVolume, globalVolume](const T sample) noexcept {
return static_cast<T>(sample * streamVolume * globalVolume);
[globalVolume](const T sample) noexcept {
return static_cast<T>(sample * globalVolume);
}
);

SDL_PutAudioStreamData(mAudioStreams[index].stream.get(), samplesBuffer.data(),
SDL_PutAudioStreamData(mAudioStreams[index], samplesBuffer.data(),
static_cast<s32>(sizeof(T) * samplesBuffer.size())
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Assistants/LifetimeWrapperSDL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ class SDL_Unique {
SDL_Unique& operator=(T* ptr) noexcept { reset(ptr); return *this; }

void reset(T* ptr = nullptr) noexcept { mPtr.reset(ptr); }
T* release() noexcept { return mPtr.release(); }
T* release() noexcept { return mPtr.release(); }
T* get() const noexcept { return mPtr.get(); }

operator T* () noexcept { return mPtr.get(); }
operator T*() const noexcept { return mPtr.get(); }
operator bool() const noexcept { return static_cast<bool>(mPtr); }
};

Expand Down
2 changes: 1 addition & 1 deletion src/Systems/BYTEPUSHER/Cores/BYTEPUSHER_STANDARD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ BYTEPUSHER_STANDARD::BYTEPUSHER_STANDARD() {
mActiveCPF = 0x10000;
mFramerate = cRefreshRate;

ASB->setStatus(STREAM::CHANN0, true);
ASB->resumeStream(STREAM::CHANN0);
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/Systems/CHIP8/Cores/CHIP8_MODERN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ CHIP8_MODERN::CHIP8_MODERN() {
mFramerate = cRefreshRate;
mActiveCPF = Quirk.waitVblank ? cInstSpeedHi : cInstSpeedLo;

ASB->setStatus(STREAM::CHANN0, true);
ASB->setStatus(STREAM::CHANN1, true);
ASB->setStatus(STREAM::CHANN2, true);
ASB->setStatus(STREAM::BUZZER, true);
ASB->resumeStream(STREAM::CHANN0);
ASB->resumeStream(STREAM::CHANN1);
ASB->resumeStream(STREAM::CHANN2);
ASB->resumeStream(STREAM::BUZZER);
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/Systems/CHIP8/Cores/MEGACHIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ MEGACHIP::MEGACHIP()
setNewBlendAlgorithm(BlendMode::ALPHA_BLEND);
initializeFontColors();

ASB->setStatus(STREAM::CHANN0, true);
ASB->setStatus(STREAM::CHANN1, true);
ASB->setStatus(STREAM::CHANN2, true);
ASB->setStatus(STREAM::BUZZER, true);
ASB->resumeStream(STREAM::CHANN0);
ASB->resumeStream(STREAM::CHANN1);
ASB->resumeStream(STREAM::CHANN2);
ASB->resumeStream(STREAM::BUZZER);
}
}

Expand Down Expand Up @@ -593,8 +593,8 @@ void MEGACHIP::scrollBuffersRT() {
void MEGACHIP::instruction_0010() noexcept {
triggerInterrupt(Interrupt::FRAME);

ASB->setStatus(STREAM::CHANN1, true);
ASB->setStatus(STREAM::CHANN2, true);
ASB->resumeStream(STREAM::CHANN1);
ASB->resumeStream(STREAM::CHANN2);

resetAudioTrack();
flushAllVideoBuffers();
Expand All @@ -604,8 +604,8 @@ void MEGACHIP::scrollBuffersRT() {
void MEGACHIP::instruction_0011() noexcept {
triggerInterrupt(Interrupt::FRAME);

ASB->setStatus(STREAM::CHANN1, false);
ASB->setStatus(STREAM::CHANN2, false);
ASB->pauseStream(STREAM::CHANN1);
ASB->pauseStream(STREAM::CHANN2);

resetAudioTrack();
scrapAllVideoBuffers();
Expand Down
8 changes: 4 additions & 4 deletions src/Systems/CHIP8/Cores/SCHIP_LEGACY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ SCHIP_LEGACY::SCHIP_LEGACY()

prepDisplayArea(Resolution::LO);

ASB->setStatus(STREAM::CHANN0, true);
ASB->setStatus(STREAM::CHANN1, true);
ASB->setStatus(STREAM::CHANN2, true);
ASB->setStatus(STREAM::BUZZER, true);
ASB->resumeStream(STREAM::CHANN0);
ASB->resumeStream(STREAM::CHANN1);
ASB->resumeStream(STREAM::CHANN2);
ASB->resumeStream(STREAM::BUZZER);
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/Systems/CHIP8/Cores/SCHIP_MODERN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ SCHIP_MODERN::SCHIP_MODERN()
mFramerate = cRefreshRate;
mActiveCPF = cInstSpeedLo;

ASB->setStatus(STREAM::CHANN0, true);
ASB->setStatus(STREAM::CHANN1, true);
ASB->setStatus(STREAM::CHANN2, true);
ASB->setStatus(STREAM::BUZZER, true);
ASB->resumeStream(STREAM::CHANN0);
ASB->resumeStream(STREAM::CHANN1);
ASB->resumeStream(STREAM::CHANN2);
ASB->resumeStream(STREAM::BUZZER);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Systems/CHIP8/Cores/XOCHIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ XOCHIP::XOCHIP()
mFramerate = cRefreshRate;
mActiveCPF = cInstSpeedLo;

ASB->setStatus(STREAM::UNIQUE, true);
ASB->setStatus(STREAM::BUZZER, true);
ASB->resumeStream(STREAM::UNIQUE);
ASB->resumeStream(STREAM::BUZZER);
}
}

Expand Down

0 comments on commit 7d7ac51

Please sign in to comment.