|
|
@ -51,9 +51,30 @@ private: |
|
|
VoiceInfo info{}; |
|
|
VoiceInfo info{}; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class AudioRenderer::EffectState { |
|
|
|
|
|
public: |
|
|
|
|
|
const EffectOutStatus& GetOutStatus() const { |
|
|
|
|
|
return out_status; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const EffectInStatus& GetInfo() const { |
|
|
|
|
|
info; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
EffectInStatus& Info() { |
|
|
|
|
|
return info; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void UpdateState(); |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
EffectOutStatus out_status{}; |
|
|
|
|
|
EffectInStatus info{}; |
|
|
|
|
|
}; |
|
|
AudioRenderer::AudioRenderer(AudioRendererParameter params, |
|
|
AudioRenderer::AudioRenderer(AudioRendererParameter params, |
|
|
Kernel::SharedPtr<Kernel::Event> buffer_event) |
|
|
Kernel::SharedPtr<Kernel::Event> buffer_event) |
|
|
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) { |
|
|
|
|
|
|
|
|
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), |
|
|
|
|
|
effects(params.effect_count) { |
|
|
|
|
|
|
|
|
audio_out = std::make_unique<AudioCore::AudioOut>(); |
|
|
audio_out = std::make_unique<AudioCore::AudioOut>(); |
|
|
stream = audio_out->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer", |
|
|
stream = audio_out->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer", |
|
|
@ -96,11 +117,29 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ |
|
|
memory_pool_count * sizeof(MemoryPoolInfo)); |
|
|
memory_pool_count * sizeof(MemoryPoolInfo)); |
|
|
|
|
|
|
|
|
// Copy VoiceInfo structs
|
|
|
// Copy VoiceInfo structs
|
|
|
std::size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size + |
|
|
|
|
|
config.voice_resource_size}; |
|
|
|
|
|
|
|
|
std::size_t voice_offset{sizeof(UpdateDataHeader) + config.behavior_size + |
|
|
|
|
|
config.memory_pools_size + config.voice_resource_size}; |
|
|
for (auto& voice : voices) { |
|
|
for (auto& voice : voices) { |
|
|
std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo)); |
|
|
|
|
|
offset += sizeof(VoiceInfo); |
|
|
|
|
|
|
|
|
std::memcpy(&voice.Info(), input_params.data() + voice_offset, sizeof(VoiceInfo)); |
|
|
|
|
|
voice_offset += sizeof(VoiceInfo); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::size_t effect_offset{sizeof(UpdateDataHeader) + config.behavior_size + |
|
|
|
|
|
config.memory_pools_size + config.voice_resource_size + |
|
|
|
|
|
config.voices_size}; |
|
|
|
|
|
for (auto& effect : effects) { |
|
|
|
|
|
std::memcpy(&effect.Info(), input_params.data() + effect_offset, sizeof(EffectInStatus)); |
|
|
|
|
|
effect_offset += sizeof(EffectInStatus); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Update memory pool state
|
|
|
|
|
|
std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); |
|
|
|
|
|
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) { |
|
|
|
|
|
memory_pool[index].state = MemoryPoolStates::Detached; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Update voices
|
|
|
// Update voices
|
|
|
@ -114,14 +153,8 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Update memory pool state
|
|
|
|
|
|
std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); |
|
|
|
|
|
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) { |
|
|
|
|
|
memory_pool[index].state = MemoryPoolStates::Detached; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for (auto& effect : effects) { |
|
|
|
|
|
effect.UpdateState(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Release previous buffers and queue next ones for playback
|
|
|
// Release previous buffers and queue next ones for playback
|
|
|
@ -144,6 +177,14 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ |
|
|
voice_out_status_offset += sizeof(VoiceOutStatus); |
|
|
voice_out_status_offset += sizeof(VoiceOutStatus); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::size_t effect_out_status_offset{ |
|
|
|
|
|
sizeof(UpdateDataHeader) + response_data.memory_pools_size + response_data.voices_size + |
|
|
|
|
|
response_data.voice_resource_size}; |
|
|
|
|
|
for (const auto& effect : effects) { |
|
|
|
|
|
std::memcpy(output_params.data() + effect_out_status_offset, &effect.GetOutStatus(), |
|
|
|
|
|
sizeof(EffectOutStatus)); |
|
|
|
|
|
effect_out_status_offset += sizeof(EffectOutStatus); |
|
|
|
|
|
} |
|
|
return output_params; |
|
|
return output_params; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -249,6 +290,23 @@ void AudioRenderer::VoiceState::RefreshBuffer() { |
|
|
is_refresh_pending = false; |
|
|
is_refresh_pending = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AudioRenderer::EffectState::UpdateState() { |
|
|
|
|
|
if (info.is_new) { |
|
|
|
|
|
out_status.state = EffectStatus::New; |
|
|
|
|
|
} else { |
|
|
|
|
|
if (info.type == Effect::Aux) { |
|
|
|
|
|
ASSERT_MSG(Memory::Read32(info.aux_info.return_buffer_info) == 0, |
|
|
|
|
|
"Aux buffers tried to update"); |
|
|
|
|
|
ASSERT_MSG(Memory::Read32(info.aux_info.send_buffer_info) == 0, |
|
|
|
|
|
"Aux buffers tried to update"); |
|
|
|
|
|
ASSERT_MSG(Memory::Read32(info.aux_info.return_buffer_base) == 0, |
|
|
|
|
|
"Aux buffers tried to update"); |
|
|
|
|
|
ASSERT_MSG(Memory::Read32(info.aux_info.send_buffer_base) == 0, |
|
|
|
|
|
"Aux buffers tried to update"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static constexpr s16 ClampToS16(s32 value) { |
|
|
static constexpr s16 ClampToS16(s32 value) { |
|
|
return static_cast<s16>(std::clamp(value, -32768, 32767)); |
|
|
return static_cast<s16>(std::clamp(value, -32768, 32767)); |
|
|
} |
|
|
} |
|
|
|