Added PCM stream to write data. Still plays with same ma_sound_start. Added some QoL for myself

This commit is contained in:
2025-09-27 07:09:34 +03:00
parent 5291b08330
commit d996910515
3 changed files with 38 additions and 3 deletions

View File

@@ -42,6 +42,9 @@ public:
void SetVolume(float value); void SetVolume(float value);
const float GetVolume(); const float GetVolume();
// For StreamedRawPCM
void WriteToRingBuffer(uint8_t *data, uint32_t length);
private: private:
Sound(class Engine *engine, std::function<void(Sound *)> setupFunction, Sound(class Engine *engine, std::function<void(Sound *)> setupFunction,
SoundType type, std::string additionalErrorMessage = ""); SoundType type, std::string additionalErrorMessage = "");
@@ -110,6 +113,8 @@ private:
ma_result maResponse; ma_result maResponse;
ma_decoder maStero; ma_decoder maStero;
ma_uint64 listenerCounter = 0; ma_uint64 listenerCounter = 0;
ma_format PCMFormat = ma_format_f32;
ma_uint8 frameSize;
friend class Listener; friend class Listener;
friend class Sound; friend class Sound;
}; };

View File

@@ -10,6 +10,7 @@ Engine::Engine(uint32_t sampleRate, uint32_t channels) {
maConfig = ma_engine_config_init(); maConfig = ma_engine_config_init();
maConfig.sampleRate = sampleRate; maConfig.sampleRate = sampleRate;
maConfig.channels = channels; maConfig.channels = channels;
frameSize = ma_get_bytes_per_sample(PCMFormat) * channels;
ThrowOnRuntimeError("Failed to init miniaudio engine", ThrowOnRuntimeError("Failed to init miniaudio engine",
ma_engine_init(&maConfig, &maEngine)); ma_engine_init(&maConfig, &maEngine));
@@ -27,9 +28,10 @@ SoundContainer Engine::CreateSound(int bufferLengthInSeconds) {
[length = bufferLengthInSeconds, channels = GetChannelCount(), [length = bufferLengthInSeconds, channels = GetChannelCount(),
sampleRate = GetSampleRate()](Sound *sound) { sampleRate = GetSampleRate()](Sound *sound) {
ma_result result = ma_pcm_rb_init( ma_result result = ma_pcm_rb_init(
ma_format_s32, channels, sampleRate * channels * length, nullptr, sound->baseEngine->PCMFormat, channels, sampleRate * length,
nullptr, &sound->maRingBuffer); nullptr, nullptr, &sound->maRingBuffer);
ThrowOnRuntimeError("Failed to create a new ring buffer!", result); ThrowOnRuntimeError("Failed to create a new ring buffer!", result);
sound->maConfig.pDataSource = &sound->maRingBuffer;
}, },
Sound::SoundType::StreamedRawPCM, Sound::SoundType::StreamedRawPCM,
"Failed to create the sound from ring buffer: ")); "Failed to create the sound from ring buffer: "));
@@ -42,7 +44,8 @@ SoundContainer Engine::CreateSound(uint8_t *data, int length) {
[data, length, channels = GetChannelCount(), [data, length, channels = GetChannelCount(),
sampleRate = GetSampleRate()](Sound *sound) { sampleRate = GetSampleRate()](Sound *sound) {
ma_audio_buffer_config config = ma_audio_buffer_config_init( ma_audio_buffer_config config = ma_audio_buffer_config_init(
ma_format_s32, channels, length / (4 * channels), data, nullptr); sound->baseEngine->PCMFormat, channels,
length / sound->baseEngine->frameSize, data, nullptr);
ma_result result = ma_result result =
ma_audio_buffer_init_copy(&config, &sound->maAudioBuffer); ma_audio_buffer_init_copy(&config, &sound->maAudioBuffer);

View File

@@ -1,5 +1,8 @@
#include "ChargeAudio.hpp" #include "ChargeAudio.hpp"
#include <Corrade/Utility/Debug.h>
#include <cassert>
#include <cstring>
#include <functional> #include <functional>
using namespace ChargeAudio; using namespace ChargeAudio;
@@ -94,6 +97,30 @@ const Magnum::Vector3 Sound::GetPosition() {
void Sound::SetVolume(float value) { ma_sound_set_volume(&maSound, value); } void Sound::SetVolume(float value) { ma_sound_set_volume(&maSound, value); }
const float Sound::GetVolume() { return ma_sound_get_volume(&maSound); } const float Sound::GetVolume() { return ma_sound_get_volume(&maSound); }
// StreamedRawPCM
void Sound::WriteToRingBuffer(uint8_t *data, uint32_t length) {
uint8_t *dataPosition = data;
void *writePosition;
uint32_t framesToWrite = length / baseEngine->frameSize, framesWritten = 0,
framesAvailable = 0;
while (framesWritten < framesToWrite) {
framesAvailable = framesToWrite - framesWritten;
// Sometimes this can fail. Actually terrifying.
ThrowOnRuntimeError("PCM ring buffer could not allocate... Oh no",
ma_pcm_rb_acquire_write(&maRingBuffer, &framesAvailable,
&writePosition));
memcpy(writePosition, dataPosition,
(framesAvailable * baseEngine->frameSize) - 8);
ma_pcm_rb_commit_write(&maRingBuffer, framesAvailable);
framesWritten += framesAvailable;
dataPosition += framesAvailable * baseEngine->frameSize;
}
}
// STATICs // STATICs
void Sound::onSoundFinish(void *customData, ma_sound *) { void Sound::onSoundFinish(void *customData, ma_sound *) {
auto sound = static_cast<Sound *>(customData); auto sound = static_cast<Sound *>(customData);