effect_context.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include "audio_core/effect_context.h"
  6. namespace AudioCore {
  7. namespace {
  8. bool ValidChannelCountForEffect(s32 channel_count) {
  9. return channel_count == 1 || channel_count == 2 || channel_count == 4 || channel_count == 6;
  10. }
  11. } // namespace
  12. EffectContext::EffectContext(std::size_t effect_count_) : effect_count(effect_count_) {
  13. effects.reserve(effect_count);
  14. std::generate_n(std::back_inserter(effects), effect_count,
  15. [] { return std::make_unique<EffectStubbed>(); });
  16. }
  17. EffectContext::~EffectContext() = default;
  18. std::size_t EffectContext::GetCount() const {
  19. return effect_count;
  20. }
  21. EffectBase* EffectContext::GetInfo(std::size_t i) {
  22. return effects.at(i).get();
  23. }
  24. EffectBase* EffectContext::RetargetEffect(std::size_t i, EffectType effect) {
  25. switch (effect) {
  26. case EffectType::Invalid:
  27. effects[i] = std::make_unique<EffectStubbed>();
  28. break;
  29. case EffectType::BufferMixer:
  30. effects[i] = std::make_unique<EffectBufferMixer>();
  31. break;
  32. case EffectType::Aux:
  33. effects[i] = std::make_unique<EffectAuxInfo>();
  34. break;
  35. case EffectType::Delay:
  36. effects[i] = std::make_unique<EffectDelay>();
  37. break;
  38. case EffectType::Reverb:
  39. effects[i] = std::make_unique<EffectReverb>();
  40. break;
  41. case EffectType::I3dl2Reverb:
  42. effects[i] = std::make_unique<EffectI3dl2Reverb>();
  43. break;
  44. case EffectType::BiquadFilter:
  45. effects[i] = std::make_unique<EffectBiquadFilter>();
  46. break;
  47. default:
  48. UNREACHABLE_MSG("Unimplemented effect {}", effect);
  49. effects[i] = std::make_unique<EffectStubbed>();
  50. }
  51. return GetInfo(i);
  52. }
  53. const EffectBase* EffectContext::GetInfo(std::size_t i) const {
  54. return effects.at(i).get();
  55. }
  56. EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {}
  57. EffectStubbed::~EffectStubbed() = default;
  58. void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {}
  59. void EffectStubbed::UpdateForCommandGeneration() {}
  60. EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {}
  61. EffectBase::~EffectBase() = default;
  62. UsageState EffectBase::GetUsage() const {
  63. return usage;
  64. }
  65. EffectType EffectBase::GetType() const {
  66. return effect_type;
  67. }
  68. bool EffectBase::IsEnabled() const {
  69. return enabled;
  70. }
  71. s32 EffectBase::GetMixID() const {
  72. return mix_id;
  73. }
  74. s32 EffectBase::GetProcessingOrder() const {
  75. return processing_order;
  76. }
  77. std::vector<u8>& EffectBase::GetWorkBuffer() {
  78. return work_buffer;
  79. }
  80. const std::vector<u8>& EffectBase::GetWorkBuffer() const {
  81. return work_buffer;
  82. }
  83. EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {}
  84. EffectI3dl2Reverb::~EffectI3dl2Reverb() = default;
  85. void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
  86. auto& params = GetParams();
  87. const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data());
  88. if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
  89. UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels);
  90. return;
  91. }
  92. const auto last_status = params.status;
  93. mix_id = in_params.mix_id;
  94. processing_order = in_params.processing_order;
  95. params = *reverb_params;
  96. if (!ValidChannelCountForEffect(reverb_params->channel_count)) {
  97. params.channel_count = params.max_channels;
  98. }
  99. enabled = in_params.is_enabled;
  100. if (last_status != ParameterStatus::Updated) {
  101. params.status = last_status;
  102. }
  103. if (in_params.is_new || skipped) {
  104. usage = UsageState::Initialized;
  105. params.status = ParameterStatus::Initialized;
  106. skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
  107. if (!skipped) {
  108. auto& cur_work_buffer = GetWorkBuffer();
  109. // Has two buffers internally
  110. cur_work_buffer.resize(in_params.buffer_size * 2);
  111. std::fill(cur_work_buffer.begin(), cur_work_buffer.end(), 0);
  112. }
  113. }
  114. }
  115. void EffectI3dl2Reverb::UpdateForCommandGeneration() {
  116. if (enabled) {
  117. usage = UsageState::Running;
  118. } else {
  119. usage = UsageState::Stopped;
  120. }
  121. GetParams().status = ParameterStatus::Updated;
  122. }
  123. I3dl2ReverbState& EffectI3dl2Reverb::GetState() {
  124. return state;
  125. }
  126. const I3dl2ReverbState& EffectI3dl2Reverb::GetState() const {
  127. return state;
  128. }
  129. EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {}
  130. EffectBiquadFilter::~EffectBiquadFilter() = default;
  131. void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) {
  132. auto& params = GetParams();
  133. const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data());
  134. mix_id = in_params.mix_id;
  135. processing_order = in_params.processing_order;
  136. params = *biquad_params;
  137. enabled = in_params.is_enabled;
  138. }
  139. void EffectBiquadFilter::UpdateForCommandGeneration() {
  140. if (enabled) {
  141. usage = UsageState::Running;
  142. } else {
  143. usage = UsageState::Stopped;
  144. }
  145. GetParams().status = ParameterStatus::Updated;
  146. }
  147. EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {}
  148. EffectAuxInfo::~EffectAuxInfo() = default;
  149. void EffectAuxInfo::Update(EffectInfo::InParams& in_params) {
  150. const auto* aux_params = reinterpret_cast<AuxInfo*>(in_params.raw.data());
  151. mix_id = in_params.mix_id;
  152. processing_order = in_params.processing_order;
  153. GetParams() = *aux_params;
  154. enabled = in_params.is_enabled;
  155. if (in_params.is_new || skipped) {
  156. skipped = aux_params->send_buffer_info == 0 || aux_params->return_buffer_info == 0;
  157. if (skipped) {
  158. return;
  159. }
  160. // There's two AuxInfos which are an identical size, the first one is managed by the cpu,
  161. // the second is managed by the dsp. All we care about is managing the DSP one
  162. send_info = aux_params->send_buffer_info + sizeof(AuxInfoDSP);
  163. send_buffer = aux_params->send_buffer_info + (sizeof(AuxInfoDSP) * 2);
  164. recv_info = aux_params->return_buffer_info + sizeof(AuxInfoDSP);
  165. recv_buffer = aux_params->return_buffer_info + (sizeof(AuxInfoDSP) * 2);
  166. }
  167. }
  168. void EffectAuxInfo::UpdateForCommandGeneration() {
  169. if (enabled) {
  170. usage = UsageState::Running;
  171. } else {
  172. usage = UsageState::Stopped;
  173. }
  174. }
  175. VAddr EffectAuxInfo::GetSendInfo() const {
  176. return send_info;
  177. }
  178. VAddr EffectAuxInfo::GetSendBuffer() const {
  179. return send_buffer;
  180. }
  181. VAddr EffectAuxInfo::GetRecvInfo() const {
  182. return recv_info;
  183. }
  184. VAddr EffectAuxInfo::GetRecvBuffer() const {
  185. return recv_buffer;
  186. }
  187. EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {}
  188. EffectDelay::~EffectDelay() = default;
  189. void EffectDelay::Update(EffectInfo::InParams& in_params) {
  190. const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data());
  191. auto& params = GetParams();
  192. if (!ValidChannelCountForEffect(delay_params->max_channels)) {
  193. return;
  194. }
  195. const auto last_status = params.status;
  196. mix_id = in_params.mix_id;
  197. processing_order = in_params.processing_order;
  198. params = *delay_params;
  199. if (!ValidChannelCountForEffect(delay_params->channels)) {
  200. params.channels = params.max_channels;
  201. }
  202. enabled = in_params.is_enabled;
  203. if (last_status != ParameterStatus::Updated) {
  204. params.status = last_status;
  205. }
  206. if (in_params.is_new || skipped) {
  207. usage = UsageState::Initialized;
  208. params.status = ParameterStatus::Initialized;
  209. skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
  210. }
  211. }
  212. void EffectDelay::UpdateForCommandGeneration() {
  213. if (enabled) {
  214. usage = UsageState::Running;
  215. } else {
  216. usage = UsageState::Stopped;
  217. }
  218. GetParams().status = ParameterStatus::Updated;
  219. }
  220. EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {}
  221. EffectBufferMixer::~EffectBufferMixer() = default;
  222. void EffectBufferMixer::Update(EffectInfo::InParams& in_params) {
  223. mix_id = in_params.mix_id;
  224. processing_order = in_params.processing_order;
  225. GetParams() = *reinterpret_cast<BufferMixerParams*>(in_params.raw.data());
  226. enabled = in_params.is_enabled;
  227. }
  228. void EffectBufferMixer::UpdateForCommandGeneration() {
  229. if (enabled) {
  230. usage = UsageState::Running;
  231. } else {
  232. usage = UsageState::Stopped;
  233. }
  234. }
  235. EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {}
  236. EffectReverb::~EffectReverb() = default;
  237. void EffectReverb::Update(EffectInfo::InParams& in_params) {
  238. const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data());
  239. auto& params = GetParams();
  240. if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
  241. return;
  242. }
  243. const auto last_status = params.status;
  244. mix_id = in_params.mix_id;
  245. processing_order = in_params.processing_order;
  246. params = *reverb_params;
  247. if (!ValidChannelCountForEffect(reverb_params->channels)) {
  248. params.channels = params.max_channels;
  249. }
  250. enabled = in_params.is_enabled;
  251. if (last_status != ParameterStatus::Updated) {
  252. params.status = last_status;
  253. }
  254. if (in_params.is_new || skipped) {
  255. usage = UsageState::Initialized;
  256. params.status = ParameterStatus::Initialized;
  257. skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
  258. }
  259. }
  260. void EffectReverb::UpdateForCommandGeneration() {
  261. if (enabled) {
  262. usage = UsageState::Running;
  263. } else {
  264. usage = UsageState::Stopped;
  265. }
  266. GetParams().status = ParameterStatus::Updated;
  267. }
  268. } // namespace AudioCore