Added PCM stream to write data. Still plays with same ma_sound_start. Added some QoL for myself
This commit is contained in:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user