summaryrefslogtreecommitdiffstats
path: root/src/audio_core/audio_renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/audio_renderer.cpp')
-rw-r--r--src/audio_core/audio_renderer.cpp76
1 files changed, 58 insertions, 18 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 397b107f5..83b75e61f 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -3,9 +3,12 @@
// Refer to the license.txt file included.
#include "audio_core/algorithm/interpolate.h"
+#include "audio_core/audio_out.h"
#include "audio_core/audio_renderer.h"
+#include "audio_core/codec.h"
#include "common/assert.h"
#include "common/logging/log.h"
+#include "core/hle/kernel/event.h"
#include "core/memory.h"
namespace AudioCore {
@@ -13,20 +16,57 @@ namespace AudioCore {
constexpr u32 STREAM_SAMPLE_RATE{48000};
constexpr u32 STREAM_NUM_CHANNELS{2};
+class AudioRenderer::VoiceState {
+public:
+ bool IsPlaying() const {
+ return is_in_use && info.play_state == PlayState::Started;
+ }
+
+ const VoiceOutStatus& GetOutStatus() const {
+ return out_status;
+ }
+
+ const VoiceInfo& GetInfo() const {
+ return info;
+ }
+
+ VoiceInfo& Info() {
+ return info;
+ }
+
+ void SetWaveIndex(std::size_t index);
+ std::vector<s16> DequeueSamples(std::size_t sample_count);
+ void UpdateState();
+ void RefreshBuffer();
+
+private:
+ bool is_in_use{};
+ bool is_refresh_pending{};
+ std::size_t wave_index{};
+ std::size_t offset{};
+ Codec::ADPCMState adpcm_state{};
+ InterpolationState interp_state{};
+ std::vector<s16> samples;
+ VoiceOutStatus out_status{};
+ VoiceInfo info{};
+};
+
AudioRenderer::AudioRenderer(AudioRendererParameter params,
Kernel::SharedPtr<Kernel::Event> buffer_event)
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) {
- audio_core = std::make_unique<AudioCore::AudioOut>();
- stream = audio_core->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer",
- [=]() { buffer_event->Signal(); });
- audio_core->StartStream(stream);
+ audio_out = std::make_unique<AudioCore::AudioOut>();
+ stream = audio_out->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer",
+ [=]() { buffer_event->Signal(); });
+ audio_out->StartStream(stream);
QueueMixedBuffer(0);
QueueMixedBuffer(1);
QueueMixedBuffer(2);
}
+AudioRenderer::~AudioRenderer() = default;
+
u32 AudioRenderer::GetSampleRate() const {
return worker_params.sample_rate;
}
@@ -52,8 +92,8 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
memory_pool_count * sizeof(MemoryPoolInfo));
// Copy VoiceInfo structs
- size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size +
- config.voice_resource_size};
+ std::size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size +
+ config.voice_resource_size};
for (auto& voice : voices) {
std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo));
offset += sizeof(VoiceInfo);
@@ -72,7 +112,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
// Update memory pool state
std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
- for (size_t index = 0; index < memory_pool.size(); ++index) {
+ for (std::size_t index = 0; index < memory_pool.size(); ++index) {
if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) {
memory_pool[index].state = MemoryPoolStates::Attached;
} else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) {
@@ -93,7 +133,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
response_data.memory_pools_size);
// Copy output voice status
- size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
+ std::size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
for (const auto& voice : voices) {
std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(),
sizeof(VoiceOutStatus));
@@ -103,12 +143,12 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
return output_params;
}
-void AudioRenderer::VoiceState::SetWaveIndex(size_t index) {
+void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) {
wave_index = index & 3;
is_refresh_pending = true;
}
-std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) {
+std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count) {
if (!IsPlaying()) {
return {};
}
@@ -117,9 +157,9 @@ std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count)
RefreshBuffer();
}
- const size_t max_size{samples.size() - offset};
- const size_t dequeue_offset{offset};
- size_t size{sample_count * STREAM_NUM_CHANNELS};
+ const std::size_t max_size{samples.size() - offset};
+ const std::size_t dequeue_offset{offset};
+ std::size_t size{sample_count * STREAM_NUM_CHANNELS};
if (size > max_size) {
size = max_size;
}
@@ -184,7 +224,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
case 1:
// 1 channel is upsampled to 2 channel
samples.resize(new_samples.size() * 2);
- for (size_t index = 0; index < new_samples.size(); ++index) {
+ for (std::size_t index = 0; index < new_samples.size(); ++index) {
samples[index * 2] = new_samples[index];
samples[index * 2 + 1] = new_samples[index];
}
@@ -210,7 +250,7 @@ static constexpr s16 ClampToS16(s32 value) {
}
void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
- constexpr size_t BUFFER_SIZE{512};
+ constexpr std::size_t BUFFER_SIZE{512};
std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
for (auto& voice : voices) {
@@ -218,7 +258,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
continue;
}
- size_t offset{};
+ std::size_t offset{};
s64 samples_remaining{BUFFER_SIZE};
while (samples_remaining > 0) {
const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)};
@@ -236,11 +276,11 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
}
}
}
- audio_core->QueueBuffer(stream, tag, std::move(buffer));
+ audio_out->QueueBuffer(stream, tag, std::move(buffer));
}
void AudioRenderer::ReleaseAndQueueBuffers() {
- const auto released_buffers{audio_core->GetTagsAndReleaseBuffers(stream, 2)};
+ const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream, 2)};
for (const auto& tag : released_buffers) {
QueueMixedBuffer(tag);
}