audio_renderer.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright 2018 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "audio_core/algorithm/interpolate.h"
  5. #include "audio_core/audio_out.h"
  6. #include "audio_core/audio_renderer.h"
  7. #include "audio_core/codec.h"
  8. #include "audio_core/common.h"
  9. #include "common/assert.h"
  10. #include "common/logging/log.h"
  11. #include "core/core.h"
  12. #include "core/hle/kernel/writable_event.h"
  13. #include "core/memory.h"
  14. namespace AudioCore {
  15. constexpr u32 STREAM_SAMPLE_RATE{48000};
  16. constexpr u32 STREAM_NUM_CHANNELS{2};
  17. class AudioRenderer::VoiceState {
  18. public:
  19. bool IsPlaying() const {
  20. return is_in_use && info.play_state == PlayState::Started;
  21. }
  22. const VoiceOutStatus& GetOutStatus() const {
  23. return out_status;
  24. }
  25. const VoiceInfo& GetInfo() const {
  26. return info;
  27. }
  28. VoiceInfo& GetInfo() {
  29. return info;
  30. }
  31. void SetWaveIndex(std::size_t index);
  32. std::vector<s16> DequeueSamples(std::size_t sample_count, Core::Memory::Memory& memory);
  33. void UpdateState();
  34. void RefreshBuffer(Core::Memory::Memory& memory);
  35. private:
  36. bool is_in_use{};
  37. bool is_refresh_pending{};
  38. std::size_t wave_index{};
  39. std::size_t offset{};
  40. Codec::ADPCMState adpcm_state{};
  41. InterpolationState interp_state{};
  42. std::vector<s16> samples;
  43. VoiceOutStatus out_status{};
  44. VoiceInfo info{};
  45. };
  46. class AudioRenderer::EffectState {
  47. public:
  48. const EffectOutStatus& GetOutStatus() const {
  49. return out_status;
  50. }
  51. const EffectInStatus& GetInfo() const {
  52. return info;
  53. }
  54. EffectInStatus& GetInfo() {
  55. return info;
  56. }
  57. void UpdateState(Core::Memory::Memory& memory);
  58. private:
  59. EffectOutStatus out_status{};
  60. EffectInStatus info{};
  61. };
  62. AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
  63. AudioRendererParameter params,
  64. std::shared_ptr<Kernel::WritableEvent> buffer_event,
  65. std::size_t instance_number)
  66. : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
  67. effects(params.effect_count), memory{memory_} {
  68. behavior_info.SetUserRevision(params.revision);
  69. audio_out = std::make_unique<AudioCore::AudioOut>();
  70. stream = audio_out->OpenStream(core_timing, STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS,
  71. fmt::format("AudioRenderer-Instance{}", instance_number),
  72. [=]() { buffer_event->Signal(); });
  73. audio_out->StartStream(stream);
  74. QueueMixedBuffer(0);
  75. QueueMixedBuffer(1);
  76. QueueMixedBuffer(2);
  77. }
  78. AudioRenderer::~AudioRenderer() = default;
  79. u32 AudioRenderer::GetSampleRate() const {
  80. return worker_params.sample_rate;
  81. }
  82. u32 AudioRenderer::GetSampleCount() const {
  83. return worker_params.sample_count;
  84. }
  85. u32 AudioRenderer::GetMixBufferCount() const {
  86. return worker_params.mix_buffer_count;
  87. }
  88. Stream::State AudioRenderer::GetStreamState() const {
  89. return stream->GetState();
  90. }
  91. ResultVal<std::vector<u8>> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) {
  92. // Copy UpdateDataHeader struct
  93. UpdateDataHeader config{};
  94. std::memcpy(&config, input_params.data(), sizeof(UpdateDataHeader));
  95. u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4);
  96. if (!behavior_info.UpdateInput(input_params, sizeof(UpdateDataHeader))) {
  97. LOG_ERROR(Audio, "Failed to update behavior info input parameters");
  98. return Audren::ERR_INVALID_PARAMETERS;
  99. }
  100. // Copy MemoryPoolInfo structs
  101. std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count);
  102. std::memcpy(mem_pool_info.data(),
  103. input_params.data() + sizeof(UpdateDataHeader) + config.behavior_size,
  104. memory_pool_count * sizeof(MemoryPoolInfo));
  105. // Copy VoiceInfo structs
  106. std::size_t voice_offset{sizeof(UpdateDataHeader) + config.behavior_size +
  107. config.memory_pools_size + config.voice_resource_size};
  108. for (auto& voice : voices) {
  109. std::memcpy(&voice.GetInfo(), input_params.data() + voice_offset, sizeof(VoiceInfo));
  110. voice_offset += sizeof(VoiceInfo);
  111. }
  112. std::size_t effect_offset{sizeof(UpdateDataHeader) + config.behavior_size +
  113. config.memory_pools_size + config.voice_resource_size +
  114. config.voices_size};
  115. for (auto& effect : effects) {
  116. std::memcpy(&effect.GetInfo(), input_params.data() + effect_offset, sizeof(EffectInStatus));
  117. effect_offset += sizeof(EffectInStatus);
  118. }
  119. // Update memory pool state
  120. std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
  121. for (std::size_t index = 0; index < memory_pool.size(); ++index) {
  122. if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) {
  123. memory_pool[index].state = MemoryPoolStates::Attached;
  124. } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) {
  125. memory_pool[index].state = MemoryPoolStates::Detached;
  126. }
  127. }
  128. // Update voices
  129. for (auto& voice : voices) {
  130. voice.UpdateState();
  131. if (!voice.GetInfo().is_in_use) {
  132. continue;
  133. }
  134. if (voice.GetInfo().is_new) {
  135. voice.SetWaveIndex(voice.GetInfo().wave_buffer_head);
  136. }
  137. }
  138. for (auto& effect : effects) {
  139. effect.UpdateState(memory);
  140. }
  141. // Release previous buffers and queue next ones for playback
  142. ReleaseAndQueueBuffers();
  143. // Copy output header
  144. UpdateDataHeader response_data{worker_params};
  145. std::vector<u8> output_params(response_data.total_size);
  146. if (behavior_info.IsElapsedFrameCountSupported()) {
  147. response_data.frame_count = 0x10;
  148. response_data.total_size += 0x10;
  149. }
  150. std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader));
  151. // Copy output memory pool entries
  152. std::memcpy(output_params.data() + sizeof(UpdateDataHeader), memory_pool.data(),
  153. response_data.memory_pools_size);
  154. // Copy output voice status
  155. std::size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
  156. for (const auto& voice : voices) {
  157. std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(),
  158. sizeof(VoiceOutStatus));
  159. voice_out_status_offset += sizeof(VoiceOutStatus);
  160. }
  161. std::size_t effect_out_status_offset{
  162. sizeof(UpdateDataHeader) + response_data.memory_pools_size + response_data.voices_size +
  163. response_data.voice_resource_size};
  164. for (const auto& effect : effects) {
  165. std::memcpy(output_params.data() + effect_out_status_offset, &effect.GetOutStatus(),
  166. sizeof(EffectOutStatus));
  167. effect_out_status_offset += sizeof(EffectOutStatus);
  168. }
  169. // Update behavior info output
  170. const std::size_t behavior_out_status_offset{
  171. sizeof(UpdateDataHeader) + response_data.memory_pools_size + response_data.voices_size +
  172. response_data.effects_size + response_data.sinks_size +
  173. response_data.performance_manager_size};
  174. if (!behavior_info.UpdateOutput(output_params, behavior_out_status_offset)) {
  175. LOG_ERROR(Audio, "Failed to update behavior info output parameters");
  176. return Audren::ERR_INVALID_PARAMETERS;
  177. }
  178. return MakeResult(output_params);
  179. }
  180. void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) {
  181. wave_index = index & 3;
  182. is_refresh_pending = true;
  183. }
  184. std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count,
  185. Core::Memory::Memory& memory) {
  186. if (!IsPlaying()) {
  187. return {};
  188. }
  189. if (is_refresh_pending) {
  190. RefreshBuffer(memory);
  191. }
  192. const std::size_t max_size{samples.size() - offset};
  193. const std::size_t dequeue_offset{offset};
  194. std::size_t size{sample_count * STREAM_NUM_CHANNELS};
  195. if (size > max_size) {
  196. size = max_size;
  197. }
  198. out_status.played_sample_count += size / STREAM_NUM_CHANNELS;
  199. offset += size;
  200. const auto& wave_buffer{info.wave_buffer[wave_index]};
  201. if (offset == samples.size()) {
  202. offset = 0;
  203. if (!wave_buffer.is_looping && wave_buffer.buffer_sz) {
  204. SetWaveIndex(wave_index + 1);
  205. }
  206. if (wave_buffer.buffer_sz) {
  207. out_status.wave_buffer_consumed++;
  208. }
  209. if (wave_buffer.end_of_stream || wave_buffer.buffer_sz == 0) {
  210. info.play_state = PlayState::Paused;
  211. }
  212. }
  213. return {samples.begin() + dequeue_offset, samples.begin() + dequeue_offset + size};
  214. }
  215. void AudioRenderer::VoiceState::UpdateState() {
  216. if (is_in_use && !info.is_in_use) {
  217. // No longer in use, reset state
  218. is_refresh_pending = true;
  219. wave_index = 0;
  220. offset = 0;
  221. out_status = {};
  222. }
  223. is_in_use = info.is_in_use;
  224. }
  225. void AudioRenderer::VoiceState::RefreshBuffer(Core::Memory::Memory& memory) {
  226. const auto wave_buffer_address = info.wave_buffer[wave_index].buffer_addr;
  227. const auto wave_buffer_size = info.wave_buffer[wave_index].buffer_sz;
  228. std::vector<s16> new_samples(wave_buffer_size / sizeof(s16));
  229. memory.ReadBlock(wave_buffer_address, new_samples.data(), wave_buffer_size);
  230. switch (static_cast<Codec::PcmFormat>(info.sample_format)) {
  231. case Codec::PcmFormat::Int16: {
  232. // PCM16 is played as-is
  233. break;
  234. }
  235. case Codec::PcmFormat::Adpcm: {
  236. // Decode ADPCM to PCM16
  237. Codec::ADPCM_Coeff coeffs;
  238. memory.ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff));
  239. new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()),
  240. new_samples.size() * sizeof(s16), coeffs, adpcm_state);
  241. break;
  242. }
  243. default:
  244. UNIMPLEMENTED_MSG("Unimplemented sample_format={}", info.sample_format);
  245. break;
  246. }
  247. switch (info.channel_count) {
  248. case 1:
  249. // 1 channel is upsampled to 2 channel
  250. samples.resize(new_samples.size() * 2);
  251. for (std::size_t index = 0; index < new_samples.size(); ++index) {
  252. samples[index * 2] = new_samples[index];
  253. samples[index * 2 + 1] = new_samples[index];
  254. }
  255. break;
  256. case 2: {
  257. // 2 channel is played as is
  258. samples = std::move(new_samples);
  259. break;
  260. }
  261. default:
  262. UNIMPLEMENTED_MSG("Unimplemented channel_count={}", info.channel_count);
  263. break;
  264. }
  265. // Only interpolate when necessary, expensive.
  266. if (GetInfo().sample_rate != STREAM_SAMPLE_RATE) {
  267. samples = Interpolate(interp_state, std::move(samples), GetInfo().sample_rate,
  268. STREAM_SAMPLE_RATE);
  269. }
  270. is_refresh_pending = false;
  271. }
  272. void AudioRenderer::EffectState::UpdateState(Core::Memory::Memory& memory) {
  273. if (info.is_new) {
  274. out_status.state = EffectStatus::New;
  275. } else {
  276. if (info.type == Effect::Aux) {
  277. ASSERT_MSG(memory.Read32(info.aux_info.return_buffer_info) == 0,
  278. "Aux buffers tried to update");
  279. ASSERT_MSG(memory.Read32(info.aux_info.send_buffer_info) == 0,
  280. "Aux buffers tried to update");
  281. ASSERT_MSG(memory.Read32(info.aux_info.return_buffer_base) == 0,
  282. "Aux buffers tried to update");
  283. ASSERT_MSG(memory.Read32(info.aux_info.send_buffer_base) == 0,
  284. "Aux buffers tried to update");
  285. }
  286. }
  287. }
  288. static constexpr s16 ClampToS16(s32 value) {
  289. return static_cast<s16>(std::clamp(value, -32768, 32767));
  290. }
  291. void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
  292. constexpr std::size_t BUFFER_SIZE{512};
  293. std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
  294. for (auto& voice : voices) {
  295. if (!voice.IsPlaying()) {
  296. continue;
  297. }
  298. std::size_t offset{};
  299. s64 samples_remaining{BUFFER_SIZE};
  300. while (samples_remaining > 0) {
  301. const std::vector<s16> samples{voice.DequeueSamples(samples_remaining, memory)};
  302. if (samples.empty()) {
  303. break;
  304. }
  305. samples_remaining -= samples.size() / stream->GetNumChannels();
  306. for (const auto& sample : samples) {
  307. const s32 buffer_sample{buffer[offset]};
  308. buffer[offset++] =
  309. ClampToS16(buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume));
  310. }
  311. }
  312. }
  313. audio_out->QueueBuffer(stream, tag, std::move(buffer));
  314. }
  315. void AudioRenderer::ReleaseAndQueueBuffers() {
  316. const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream, 2)};
  317. for (const auto& tag : released_buffers) {
  318. QueueMixedBuffer(tag);
  319. }
  320. }
  321. } // namespace AudioCore