diff options
Diffstat (limited to 'src/audio_core/audio_renderer.cpp')
| -rw-r--r-- | src/audio_core/audio_renderer.cpp | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 6b0167acd..c187d8ac5 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -36,9 +36,9 @@ public: | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | void SetWaveIndex(std::size_t index); | 38 | void SetWaveIndex(std::size_t index); |
| 39 | std::vector<s16> DequeueSamples(std::size_t sample_count); | 39 | std::vector<s16> DequeueSamples(std::size_t sample_count, Memory::Memory& memory); |
| 40 | void UpdateState(); | 40 | void UpdateState(); |
| 41 | void RefreshBuffer(); | 41 | void RefreshBuffer(Memory::Memory& memory); |
| 42 | 42 | ||
| 43 | private: | 43 | private: |
| 44 | bool is_in_use{}; | 44 | bool is_in_use{}; |
| @@ -66,17 +66,18 @@ public: | |||
| 66 | return info; | 66 | return info; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void UpdateState(); | 69 | void UpdateState(Memory::Memory& memory); |
| 70 | 70 | ||
| 71 | private: | 71 | private: |
| 72 | EffectOutStatus out_status{}; | 72 | EffectOutStatus out_status{}; |
| 73 | EffectInStatus info{}; | 73 | EffectInStatus info{}; |
| 74 | }; | 74 | }; |
| 75 | AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params, | 75 | AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Memory::Memory& memory_, |
| 76 | AudioRendererParameter params, | ||
| 76 | std::shared_ptr<Kernel::WritableEvent> buffer_event, | 77 | std::shared_ptr<Kernel::WritableEvent> buffer_event, |
| 77 | std::size_t instance_number) | 78 | std::size_t instance_number) |
| 78 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), | 79 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), |
| 79 | effects(params.effect_count) { | 80 | effects(params.effect_count), memory{memory_} { |
| 80 | 81 | ||
| 81 | audio_out = std::make_unique<AudioCore::AudioOut>(); | 82 | audio_out = std::make_unique<AudioCore::AudioOut>(); |
| 82 | stream = audio_out->OpenStream(core_timing, STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, | 83 | stream = audio_out->OpenStream(core_timing, STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, |
| @@ -162,7 +163,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ | |||
| 162 | } | 163 | } |
| 163 | 164 | ||
| 164 | for (auto& effect : effects) { | 165 | for (auto& effect : effects) { |
| 165 | effect.UpdateState(); | 166 | effect.UpdateState(memory); |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | // Release previous buffers and queue next ones for playback | 169 | // Release previous buffers and queue next ones for playback |
| @@ -206,13 +207,14 @@ void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) { | |||
| 206 | is_refresh_pending = true; | 207 | is_refresh_pending = true; |
| 207 | } | 208 | } |
| 208 | 209 | ||
| 209 | std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count) { | 210 | std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count, |
| 211 | Memory::Memory& memory) { | ||
| 210 | if (!IsPlaying()) { | 212 | if (!IsPlaying()) { |
| 211 | return {}; | 213 | return {}; |
| 212 | } | 214 | } |
| 213 | 215 | ||
| 214 | if (is_refresh_pending) { | 216 | if (is_refresh_pending) { |
| 215 | RefreshBuffer(); | 217 | RefreshBuffer(memory); |
| 216 | } | 218 | } |
| 217 | 219 | ||
| 218 | const std::size_t max_size{samples.size() - offset}; | 220 | const std::size_t max_size{samples.size() - offset}; |
| @@ -256,10 +258,11 @@ void AudioRenderer::VoiceState::UpdateState() { | |||
| 256 | is_in_use = info.is_in_use; | 258 | is_in_use = info.is_in_use; |
| 257 | } | 259 | } |
| 258 | 260 | ||
| 259 | void AudioRenderer::VoiceState::RefreshBuffer() { | 261 | void AudioRenderer::VoiceState::RefreshBuffer(Memory::Memory& memory) { |
| 260 | std::vector<s16> new_samples(info.wave_buffer[wave_index].buffer_sz / sizeof(s16)); | 262 | const auto wave_buffer_address = info.wave_buffer[wave_index].buffer_addr; |
| 261 | Memory::ReadBlock(info.wave_buffer[wave_index].buffer_addr, new_samples.data(), | 263 | const auto wave_buffer_size = info.wave_buffer[wave_index].buffer_sz; |
| 262 | info.wave_buffer[wave_index].buffer_sz); | 264 | std::vector<s16> new_samples(wave_buffer_size / sizeof(s16)); |
| 265 | memory.ReadBlock(wave_buffer_address, new_samples.data(), wave_buffer_size); | ||
| 263 | 266 | ||
| 264 | switch (static_cast<Codec::PcmFormat>(info.sample_format)) { | 267 | switch (static_cast<Codec::PcmFormat>(info.sample_format)) { |
| 265 | case Codec::PcmFormat::Int16: { | 268 | case Codec::PcmFormat::Int16: { |
| @@ -269,7 +272,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() { | |||
| 269 | case Codec::PcmFormat::Adpcm: { | 272 | case Codec::PcmFormat::Adpcm: { |
| 270 | // Decode ADPCM to PCM16 | 273 | // Decode ADPCM to PCM16 |
| 271 | Codec::ADPCM_Coeff coeffs; | 274 | Codec::ADPCM_Coeff coeffs; |
| 272 | Memory::ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff)); | 275 | memory.ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff)); |
| 273 | new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()), | 276 | new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()), |
| 274 | new_samples.size() * sizeof(s16), coeffs, adpcm_state); | 277 | new_samples.size() * sizeof(s16), coeffs, adpcm_state); |
| 275 | break; | 278 | break; |
| @@ -307,18 +310,18 @@ void AudioRenderer::VoiceState::RefreshBuffer() { | |||
| 307 | is_refresh_pending = false; | 310 | is_refresh_pending = false; |
| 308 | } | 311 | } |
| 309 | 312 | ||
| 310 | void AudioRenderer::EffectState::UpdateState() { | 313 | void AudioRenderer::EffectState::UpdateState(Memory::Memory& memory) { |
| 311 | if (info.is_new) { | 314 | if (info.is_new) { |
| 312 | out_status.state = EffectStatus::New; | 315 | out_status.state = EffectStatus::New; |
| 313 | } else { | 316 | } else { |
| 314 | if (info.type == Effect::Aux) { | 317 | if (info.type == Effect::Aux) { |
| 315 | ASSERT_MSG(Memory::Read32(info.aux_info.return_buffer_info) == 0, | 318 | ASSERT_MSG(memory.Read32(info.aux_info.return_buffer_info) == 0, |
| 316 | "Aux buffers tried to update"); | 319 | "Aux buffers tried to update"); |
| 317 | ASSERT_MSG(Memory::Read32(info.aux_info.send_buffer_info) == 0, | 320 | ASSERT_MSG(memory.Read32(info.aux_info.send_buffer_info) == 0, |
| 318 | "Aux buffers tried to update"); | 321 | "Aux buffers tried to update"); |
| 319 | ASSERT_MSG(Memory::Read32(info.aux_info.return_buffer_base) == 0, | 322 | ASSERT_MSG(memory.Read32(info.aux_info.return_buffer_base) == 0, |
| 320 | "Aux buffers tried to update"); | 323 | "Aux buffers tried to update"); |
| 321 | ASSERT_MSG(Memory::Read32(info.aux_info.send_buffer_base) == 0, | 324 | ASSERT_MSG(memory.Read32(info.aux_info.send_buffer_base) == 0, |
| 322 | "Aux buffers tried to update"); | 325 | "Aux buffers tried to update"); |
| 323 | } | 326 | } |
| 324 | } | 327 | } |
| @@ -340,7 +343,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { | |||
| 340 | std::size_t offset{}; | 343 | std::size_t offset{}; |
| 341 | s64 samples_remaining{BUFFER_SIZE}; | 344 | s64 samples_remaining{BUFFER_SIZE}; |
| 342 | while (samples_remaining > 0) { | 345 | while (samples_remaining > 0) { |
| 343 | const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)}; | 346 | const std::vector<s16> samples{voice.DequeueSamples(samples_remaining, memory)}; |
| 344 | 347 | ||
| 345 | if (samples.empty()) { | 348 | if (samples.empty()) { |
| 346 | break; | 349 | break; |