aboutsummaryrefslogtreecommitdiff
path: root/src/audio_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp9
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/audio_renderer.h3
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp5
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_list_processor.h8
-rw-r--r--src/audio_core/renderer/command/data_source/adpcm.cpp6
-rw-r--r--src/audio_core/renderer/command/data_source/decode.cpp106
-rw-r--r--src/audio_core/renderer/command/data_source/pcm_float.cpp6
-rw-r--r--src/audio_core/renderer/command/data_source/pcm_int16.cpp6
-rw-r--r--src/audio_core/renderer/system.cpp16
9 files changed, 86 insertions, 79 deletions
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp
index 3da342ea3..2e549bc6f 100644
--- a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp
+++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp
@@ -88,8 +88,13 @@ MailboxMessage AudioRenderer::Receive(Direction dir, bool block) {
return mailbox.Receive(dir, block);
}
-void AudioRenderer::SetCommandBuffer(s32 session_id, CommandBuffer& buffer) noexcept {
- command_buffers[session_id] = buffer;
+void AudioRenderer::SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit,
+ u64 applet_resource_user_id, bool reset) noexcept {
+ command_buffers[session_id].buffer = buffer;
+ command_buffers[session_id].size = size;
+ command_buffers[session_id].time_limit = time_limit;
+ command_buffers[session_id].applet_resource_user_id = applet_resource_user_id;
+ command_buffers[session_id].reset_buffer = reset;
}
u32 AudioRenderer::GetRemainCommandCount(s32 session_id) const noexcept {
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
index b225e10fb..3f5b7dca2 100644
--- a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
+++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
@@ -75,7 +75,8 @@ public:
void Send(Direction dir, MailboxMessage message);
MailboxMessage Receive(Direction dir, bool block = true);
- void SetCommandBuffer(s32 session_id, CommandBuffer& buffer) noexcept;
+ void SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit,
+ u64 applet_resource_user_id, bool reset) noexcept;
u32 GetRemainCommandCount(s32 session_id) const noexcept;
void ClearRemainCommandCount(s32 session_id) noexcept;
u64 GetRenderingStartTick(s32 session_id) const noexcept;
diff --git a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp
index acbc9100c..24e4d0496 100644
--- a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp
+++ b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp
@@ -37,11 +37,6 @@ u32 CommandListProcessor::GetRemainingCommandCount() const {
return command_count - processed_command_count;
}
-void CommandListProcessor::SetBuffer(const CpuAddr buffer, const u64 size) {
- commands = reinterpret_cast<u8*>(buffer + sizeof(Renderer::CommandListHeader));
- commands_buffer_size = size;
-}
-
Sink::SinkStream* CommandListProcessor::GetOutputSinkStream() const {
return stream;
}
diff --git a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h
index 9d6fe1851..4e5fb793e 100644
--- a/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h
+++ b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h
@@ -57,14 +57,6 @@ public:
u32 GetRemainingCommandCount() const;
/**
- * Set the command buffer.
- *
- * @param buffer - The buffer to use.
- * @param size - The size of the buffer.
- */
- void SetBuffer(CpuAddr buffer, u64 size);
-
- /**
* Get the stream for this command list.
*
* @return The stream associated with this command list.
diff --git a/src/audio_core/renderer/command/data_source/adpcm.cpp b/src/audio_core/renderer/command/data_source/adpcm.cpp
index 28e76fdcc..e7f82d3b3 100644
--- a/src/audio_core/renderer/command/data_source/adpcm.cpp
+++ b/src/audio_core/renderer/command/data_source/adpcm.cpp
@@ -20,6 +20,12 @@ void AdpcmDataSourceVersion1Command::Process(const AudioRenderer::CommandListPro
auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count,
processor.sample_count)};
+ for (auto& wave_buffer : wave_buffers) {
+ wave_buffer.loop_start_offset = wave_buffer.start_offset;
+ wave_buffer.loop_end_offset = wave_buffer.end_offset;
+ wave_buffer.loop_count = wave_buffer.loop ? -1 : 0;
+ }
+
DecodeFromWaveBuffersArgs args{
.sample_format{SampleFormat::Adpcm},
.output{out_buffer},
diff --git a/src/audio_core/renderer/command/data_source/decode.cpp b/src/audio_core/renderer/command/data_source/decode.cpp
index 762aec8ad..911dae3c1 100644
--- a/src/audio_core/renderer/command/data_source/decode.cpp
+++ b/src/audio_core/renderer/command/data_source/decode.cpp
@@ -123,11 +123,13 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
return 0;
}
- auto samples_to_process{
- std::min(req.end_offset - req.start_offset - req.offset, req.samples_to_read)};
+ auto start_pos{req.start_offset + req.offset};
+ auto samples_to_process{std::min(req.end_offset - start_pos, req.samples_to_read)};
+ if (samples_to_process == 0) {
+ return 0;
+ }
auto samples_to_read{samples_to_process};
- auto start_pos{req.start_offset + req.offset};
auto samples_remaining_in_frame{start_pos % SamplesPerFrame};
auto position_in_frame{(start_pos / SamplesPerFrame) * NibblesPerFrame +
samples_remaining_in_frame};
@@ -225,13 +227,24 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
* @param args - The wavebuffer data, and information for how to decode it.
*/
void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args) {
+ static constexpr auto EndWaveBuffer = [](auto& voice_state, auto& wavebuffer, auto& index,
+ auto& played_samples, auto& consumed) -> void {
+ voice_state.wave_buffer_valid[index] = false;
+ voice_state.loop_count = 0;
+
+ if (wavebuffer.stream_ended) {
+ played_samples = 0;
+ }
+
+ index = (index + 1) % MaxWaveBuffers;
+ consumed++;
+ };
auto& voice_state{*args.voice_state};
auto remaining_sample_count{args.sample_count};
auto fraction{voice_state.fraction};
- const auto sample_rate_ratio{
- (Common::FixedPoint<49, 15>(args.source_sample_rate) / args.target_sample_rate) *
- args.pitch};
+ const auto sample_rate_ratio{Common::FixedPoint<49, 15>(
+ (f32)args.source_sample_rate / (f32)args.target_sample_rate * (f32)args.pitch)};
const auto size_required{fraction + remaining_sample_count * sample_rate_ratio};
if (size_required < 0) {
@@ -298,22 +311,23 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf
auto end_offset{wavebuffer.end_offset};
if (wavebuffer.loop && voice_state.loop_count > 0 &&
- wavebuffer.loop_start_offset != 0 && wavebuffer.loop_end_offset != 0 &&
wavebuffer.loop_start_offset <= wavebuffer.loop_end_offset) {
start_offset = wavebuffer.loop_start_offset;
end_offset = wavebuffer.loop_end_offset;
}
- DecodeArg decode_arg{.buffer{wavebuffer.buffer},
- .buffer_size{wavebuffer.buffer_size},
- .start_offset{start_offset},
- .end_offset{end_offset},
- .channel_count{args.channel_count},
- .coefficients{},
- .adpcm_context{nullptr},
- .target_channel{args.channel},
- .offset{offset},
- .samples_to_read{samples_to_read - samples_read}};
+ DecodeArg decode_arg{
+ .buffer{wavebuffer.buffer},
+ .buffer_size{wavebuffer.buffer_size},
+ .start_offset{start_offset},
+ .end_offset{end_offset},
+ .channel_count{args.channel_count},
+ .coefficients{},
+ .adpcm_context{nullptr},
+ .target_channel{args.channel},
+ .offset{offset},
+ .samples_to_read{samples_to_read - samples_read},
+ };
s32 samples_decoded{0};
@@ -350,42 +364,30 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf
temp_buffer_pos += samples_decoded;
offset += samples_decoded;
- if (samples_decoded == 0 || offset >= end_offset - start_offset) {
- offset = 0;
- if (!wavebuffer.loop) {
- voice_state.wave_buffer_valid[wavebuffer_index] = false;
- voice_state.loop_count = 0;
-
- if (wavebuffer.stream_ended) {
- played_sample_count = 0;
- }
-
- wavebuffer_index = (wavebuffer_index + 1) % MaxWaveBuffers;
- wavebuffers_consumed++;
- } else {
- voice_state.loop_count++;
- if (wavebuffer.loop_count >= 0 &&
- (voice_state.loop_count > wavebuffer.loop_count || samples_decoded == 0)) {
- voice_state.wave_buffer_valid[wavebuffer_index] = false;
- voice_state.loop_count = 0;
-
- if (wavebuffer.stream_ended) {
- played_sample_count = 0;
- }
-
- wavebuffer_index = (wavebuffer_index + 1) % MaxWaveBuffers;
- wavebuffers_consumed++;
- }
-
- if (samples_decoded == 0) {
- is_buffer_starved = true;
- break;
- }
-
- if (args.IsVoicePlayedSampleCountResetAtLoopPointSupported) {
- played_sample_count = 0;
- }
+ if (samples_decoded && offset < end_offset - start_offset) {
+ continue;
+ }
+
+ offset = 0;
+ if (wavebuffer.loop) {
+ voice_state.loop_count++;
+ if (wavebuffer.loop_count >= 0 &&
+ (voice_state.loop_count > wavebuffer.loop_count || samples_decoded == 0)) {
+ EndWaveBuffer(voice_state, wavebuffer, wavebuffer_index, played_sample_count,
+ wavebuffers_consumed);
+ }
+
+ if (samples_decoded == 0) {
+ is_buffer_starved = true;
+ break;
+ }
+
+ if (args.IsVoicePlayedSampleCountResetAtLoopPointSupported) {
+ played_sample_count = 0;
}
+ } else {
+ EndWaveBuffer(voice_state, wavebuffer, wavebuffer_index, played_sample_count,
+ wavebuffers_consumed);
}
}
diff --git a/src/audio_core/renderer/command/data_source/pcm_float.cpp b/src/audio_core/renderer/command/data_source/pcm_float.cpp
index 5cc0797f4..d1f685656 100644
--- a/src/audio_core/renderer/command/data_source/pcm_float.cpp
+++ b/src/audio_core/renderer/command/data_source/pcm_float.cpp
@@ -21,6 +21,12 @@ void PcmFloatDataSourceVersion1Command::Process(
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
processor.sample_count);
+ for (auto& wave_buffer : wave_buffers) {
+ wave_buffer.loop_start_offset = wave_buffer.start_offset;
+ wave_buffer.loop_end_offset = wave_buffer.end_offset;
+ wave_buffer.loop_count = wave_buffer.loop ? -1 : 0;
+ }
+
DecodeFromWaveBuffersArgs args{
.sample_format{SampleFormat::PcmFloat},
.output{out_buffer},
diff --git a/src/audio_core/renderer/command/data_source/pcm_int16.cpp b/src/audio_core/renderer/command/data_source/pcm_int16.cpp
index 649993068..c89a5aaac 100644
--- a/src/audio_core/renderer/command/data_source/pcm_int16.cpp
+++ b/src/audio_core/renderer/command/data_source/pcm_int16.cpp
@@ -23,6 +23,12 @@ void PcmInt16DataSourceVersion1Command::Process(
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
processor.sample_count);
+ for (auto& wave_buffer : wave_buffers) {
+ wave_buffer.loop_start_offset = wave_buffer.start_offset;
+ wave_buffer.loop_end_offset = wave_buffer.end_offset;
+ wave_buffer.loop_count = wave_buffer.loop ? -1 : 0;
+ }
+
DecodeFromWaveBuffersArgs args{
.sample_format{SampleFormat::PcmInt16},
.output{out_buffer},
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 8f02754c5..d29754634 100644
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -609,17 +609,11 @@ void System::SendCommandToDsp() {
time_limit_percent = 70.0f;
}
- AudioRenderer::CommandBuffer command_buffer{
- .buffer{translated_addr},
- .size{command_size},
- .time_limit{
- static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 *
- (static_cast<f32>(render_time_limit_percent) / 100.0f))},
- .applet_resource_user_id{applet_resource_user_id},
- .reset_buffer{reset_command_buffers},
- };
-
- audio_renderer.SetCommandBuffer(session_id, command_buffer);
+ auto time_limit{
+ static_cast<u64>((time_limit_percent / 100) * 2'880'000.0 *
+ (static_cast<f32>(render_time_limit_percent) / 100.0f))};
+ audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit,
+ applet_resource_user_id, reset_command_buffers);
reset_command_buffers = false;
command_buffer_size = command_size;
if (remaining_command_count == 0) {