diff options
Diffstat (limited to 'src/audio_core/audio_renderer.cpp')
| -rw-r--r-- | src/audio_core/audio_renderer.cpp | 130 |
1 files changed, 63 insertions, 67 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 0757cd804..ccd5ca6cc 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -129,87 +129,85 @@ Stream::State AudioRenderer::GetStreamState() const { | |||
| 129 | 129 | ||
| 130 | ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params, | 130 | ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params, |
| 131 | std::vector<u8>& output_params) { | 131 | std::vector<u8>& output_params) { |
| 132 | { | 132 | std::scoped_lock lock{mutex}; |
| 133 | std::scoped_lock lock{mutex}; | 133 | InfoUpdater info_updater{input_params, output_params, behavior_info}; |
| 134 | InfoUpdater info_updater{input_params, output_params, behavior_info}; | ||
| 135 | 134 | ||
| 136 | if (!info_updater.UpdateBehaviorInfo(behavior_info)) { | 135 | if (!info_updater.UpdateBehaviorInfo(behavior_info)) { |
| 137 | LOG_ERROR(Audio, "Failed to update behavior info input parameters"); | 136 | LOG_ERROR(Audio, "Failed to update behavior info input parameters"); |
| 138 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 137 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 139 | } | 138 | } |
| 140 | 139 | ||
| 141 | if (!info_updater.UpdateMemoryPools(memory_pool_info)) { | 140 | if (!info_updater.UpdateMemoryPools(memory_pool_info)) { |
| 142 | LOG_ERROR(Audio, "Failed to update memory pool parameters"); | 141 | LOG_ERROR(Audio, "Failed to update memory pool parameters"); |
| 143 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 142 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | if (!info_updater.UpdateVoiceChannelResources(voice_context)) { | 145 | if (!info_updater.UpdateVoiceChannelResources(voice_context)) { |
| 147 | LOG_ERROR(Audio, "Failed to update voice channel resource parameters"); | 146 | LOG_ERROR(Audio, "Failed to update voice channel resource parameters"); |
| 148 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 147 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 149 | } | 148 | } |
| 150 | 149 | ||
| 151 | if (!info_updater.UpdateVoices(voice_context, memory_pool_info, 0)) { | 150 | if (!info_updater.UpdateVoices(voice_context, memory_pool_info, 0)) { |
| 152 | LOG_ERROR(Audio, "Failed to update voice parameters"); | 151 | LOG_ERROR(Audio, "Failed to update voice parameters"); |
| 153 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 152 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 154 | } | 153 | } |
| 155 | 154 | ||
| 156 | // TODO(ogniK): Deal with stopped audio renderer but updates still taking place | 155 | // TODO(ogniK): Deal with stopped audio renderer but updates still taking place |
| 157 | if (!info_updater.UpdateEffects(effect_context, true)) { | 156 | if (!info_updater.UpdateEffects(effect_context, true)) { |
| 158 | LOG_ERROR(Audio, "Failed to update effect parameters"); | 157 | LOG_ERROR(Audio, "Failed to update effect parameters"); |
| 158 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | ||
| 159 | } | ||
| 160 | |||
| 161 | if (behavior_info.IsSplitterSupported()) { | ||
| 162 | if (!info_updater.UpdateSplitterInfo(splitter_context)) { | ||
| 163 | LOG_ERROR(Audio, "Failed to update splitter parameters"); | ||
| 159 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 164 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 160 | } | 165 | } |
| 166 | } | ||
| 161 | 167 | ||
| 162 | if (behavior_info.IsSplitterSupported()) { | 168 | const auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count, |
| 163 | if (!info_updater.UpdateSplitterInfo(splitter_context)) { | 169 | splitter_context, effect_context); |
| 164 | LOG_ERROR(Audio, "Failed to update splitter parameters"); | ||
| 165 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | 170 | ||
| 169 | const auto mix_result = info_updater.UpdateMixes( | 171 | if (mix_result.IsError()) { |
| 170 | mix_context, worker_params.mix_buffer_count, splitter_context, effect_context); | 172 | LOG_ERROR(Audio, "Failed to update mix parameters"); |
| 173 | return mix_result; | ||
| 174 | } | ||
| 171 | 175 | ||
| 172 | if (mix_result.IsError()) { | 176 | // TODO(ogniK): Sinks |
| 173 | LOG_ERROR(Audio, "Failed to update mix parameters"); | 177 | if (!info_updater.UpdateSinks(sink_context)) { |
| 174 | return mix_result; | 178 | LOG_ERROR(Audio, "Failed to update sink parameters"); |
| 175 | } | 179 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 180 | } | ||
| 176 | 181 | ||
| 177 | // TODO(ogniK): Sinks | 182 | // TODO(ogniK): Performance buffer |
| 178 | if (!info_updater.UpdateSinks(sink_context)) { | 183 | if (!info_updater.UpdatePerformanceBuffer()) { |
| 179 | LOG_ERROR(Audio, "Failed to update sink parameters"); | 184 | LOG_ERROR(Audio, "Failed to update performance buffer parameters"); |
| 180 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 185 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 181 | } | 186 | } |
| 182 | 187 | ||
| 183 | // TODO(ogniK): Performance buffer | 188 | if (!info_updater.UpdateErrorInfo(behavior_info)) { |
| 184 | if (!info_updater.UpdatePerformanceBuffer()) { | 189 | LOG_ERROR(Audio, "Failed to update error info"); |
| 185 | LOG_ERROR(Audio, "Failed to update performance buffer parameters"); | 190 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 186 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 191 | } |
| 187 | } | ||
| 188 | 192 | ||
| 189 | if (!info_updater.UpdateErrorInfo(behavior_info)) { | 193 | if (behavior_info.IsElapsedFrameCountSupported()) { |
| 190 | LOG_ERROR(Audio, "Failed to update error info"); | 194 | if (!info_updater.UpdateRendererInfo(elapsed_frame_count)) { |
| 195 | LOG_ERROR(Audio, "Failed to update renderer info"); | ||
| 191 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 196 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 192 | } | 197 | } |
| 198 | } | ||
| 199 | // TODO(ogniK): Statistics | ||
| 193 | 200 | ||
| 194 | if (behavior_info.IsElapsedFrameCountSupported()) { | 201 | if (!info_updater.WriteOutputHeader()) { |
| 195 | if (!info_updater.UpdateRendererInfo(elapsed_frame_count)) { | 202 | LOG_ERROR(Audio, "Failed to write output header"); |
| 196 | LOG_ERROR(Audio, "Failed to update renderer info"); | 203 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 197 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 204 | } |
| 198 | } | ||
| 199 | } | ||
| 200 | // TODO(ogniK): Statistics | ||
| 201 | |||
| 202 | if (!info_updater.WriteOutputHeader()) { | ||
| 203 | LOG_ERROR(Audio, "Failed to write output header"); | ||
| 204 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | ||
| 205 | } | ||
| 206 | 205 | ||
| 207 | // TODO(ogniK): Check when all sections are implemented | 206 | // TODO(ogniK): Check when all sections are implemented |
| 208 | 207 | ||
| 209 | if (!info_updater.CheckConsumedSize()) { | 208 | if (!info_updater.CheckConsumedSize()) { |
| 210 | LOG_ERROR(Audio, "Audio buffers were not consumed!"); | 209 | LOG_ERROR(Audio, "Audio buffers were not consumed!"); |
| 211 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; | 210 | return AudioCommon::Audren::ERR_INVALID_PARAMETERS; |
| 212 | } | ||
| 213 | } | 211 | } |
| 214 | return ResultSuccess; | 212 | return ResultSuccess; |
| 215 | } | 213 | } |
| @@ -234,10 +232,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { | |||
| 234 | command_generator.PostCommand(); | 232 | command_generator.PostCommand(); |
| 235 | // Base sample size | 233 | // Base sample size |
| 236 | std::size_t BUFFER_SIZE{worker_params.sample_count}; | 234 | std::size_t BUFFER_SIZE{worker_params.sample_count}; |
| 237 | // Samples | 235 | // Samples, making sure to clear |
| 238 | std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels()); | 236 | std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels(), 0); |
| 239 | // Make sure to clear our samples | ||
| 240 | std::memset(buffer.data(), 0, buffer.size() * sizeof(s16)); | ||
| 241 | 237 | ||
| 242 | if (sink_context.InUse()) { | 238 | if (sink_context.InUse()) { |
| 243 | const auto stream_channel_count = stream->GetNumChannels(); | 239 | const auto stream_channel_count = stream->GetNumChannels(); |