Added RawPCM data that doesn't use ring buffer(for non-streaming), and proper deallocation

This commit is contained in:
2025-09-21 03:41:40 +03:00
parent 090317b394
commit 64a5d19464
3 changed files with 40 additions and 3 deletions

View File

@@ -17,7 +17,7 @@ typedef Containers::Pointer<class Listener> ListenerContainer;
class Sound { class Sound {
public: public:
enum class SoundState { Idle, Playing, Paused, Finished }; enum class SoundState { Idle, Playing, Paused, Finished };
enum class SoundType { FromFile, RawPCM }; enum class SoundType { FromFile, StreamedRawPCM, RawPCM };
// No copying // No copying
Sound(const Sound &) = delete; Sound(const Sound &) = delete;
Sound &operator=(const Sound &) = delete; Sound &operator=(const Sound &) = delete;
@@ -51,6 +51,7 @@ private:
ma_sound maSound; ma_sound maSound;
ma_sound_config maConfig; ma_sound_config maConfig;
ma_pcm_rb maRingBuffer; ma_pcm_rb maRingBuffer;
ma_audio_buffer maAudioBuffer;
SoundState state = SoundState::Idle; SoundState state = SoundState::Idle;
SoundType type; SoundType type;
@@ -93,6 +94,7 @@ public:
// Creating tools // Creating tools
SoundContainer CreateSound(int bufferLengthInSeconds); SoundContainer CreateSound(int bufferLengthInSeconds);
SoundContainer CreateSound(uint8_t *data, int length);
SoundContainer CreateSound(std::string filepath, bool streamFile = false); SoundContainer CreateSound(std::string filepath, bool streamFile = false);
ListenerContainer CreateListener(); ListenerContainer CreateListener();

View File

@@ -25,6 +25,7 @@ Engine::~Engine() { ma_engine_uninit(&maEngine); }
uint32_t Engine::GetSampleRate() { return maEngine.sampleRate; } uint32_t Engine::GetSampleRate() { return maEngine.sampleRate; }
uint32_t Engine::GetChannelCount() { return ma_engine_get_channels(&maEngine); } uint32_t Engine::GetChannelCount() { return ma_engine_get_channels(&maEngine); }
// Use case: Stream of PCM data
SoundContainer Engine::CreateSound(int bufferLengthInSeconds) { SoundContainer Engine::CreateSound(int bufferLengthInSeconds) {
return SoundContainer(new Sound( return SoundContainer(new Sound(
this, this,
@@ -40,7 +41,32 @@ SoundContainer Engine::CreateSound(int bufferLengthInSeconds) {
"Check STDERR for more info."); "Check STDERR for more info.");
} }
}, },
Sound::SoundType::RawPCM, "Failed to create the sound from the data: ")); Sound::SoundType::StreamedRawPCM,
"Failed to create the sound from ring buffer: "));
}
// Use case: 1 time set up and use audio
SoundContainer Engine::CreateSound(uint8_t *data, int length) {
return SoundContainer(new Sound(
this,
[data, length, channels = GetChannelCount(),
sampleRate = GetSampleRate()](Sound *sound) {
ma_audio_buffer_config config = ma_audio_buffer_config_init(
ma_format_s32, channels, length / (4 * channels), data, nullptr);
ma_result result =
ma_audio_buffer_init_copy(&config, &sound->maAudioBuffer);
if (result != MA_SUCCESS) {
Utility::Error{} << "Failed to create a new audio buffer!" << " ("
<< result << ")";
throw new std::runtime_error("Failed to create a new audio buffer! "
"Check STDERR for more info.");
}
sound->maConfig.pDataSource = &sound->maAudioBuffer;
},
Sound::SoundType::RawPCM,
"Failed to create the sound from the PCM data: "));
} }
SoundContainer Engine::CreateSound(const std::string filepath, SoundContainer Engine::CreateSound(const std::string filepath,

View File

@@ -24,7 +24,16 @@ Sound::Sound(Engine *engine, std::function<void(Sound *)> setupFunction,
} }
Sound::~Sound() { Sound::~Sound() {
switch (type) {
case Sound::SoundType::RawPCM:
ma_audio_buffer_uninit_and_free(&maAudioBuffer);
break;
case Sound::SoundType::StreamedRawPCM:
ma_pcm_rb_uninit(&maRingBuffer); ma_pcm_rb_uninit(&maRingBuffer);
break;
default:
break;
}
ma_sound_uninit(&maSound); ma_sound_uninit(&maSound);
} }