effect_context.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {}
  78. EffectI3dl2Reverb::~EffectI3dl2Reverb() = default;
  79. void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
  80. auto& params = GetParams();
  81. const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data());
  82. if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
  83. UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels);
  84. return;
  85. }
  86. const auto last_status = params.status;
  87. mix_id = in_params.mix_id;
  88. processing_order = in_params.processing_order;
  89. params = *reverb_params;
  90. if (!ValidChannelCountForEffect(reverb_params->channel_count)) {
  91. params.channel_count = params.max_channels;
  92. }
  93. enabled = in_params.is_enabled;
  94. if (last_status != ParameterStatus::Updated) {
  95. params.status = last_status;
  96. }
  97. if (in_params.is_new || skipped) {
  98. usage = UsageState::Initialized;
  99. params.status = ParameterStatus::Initialized;
  100. skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
  101. }
  102. }
  103. void EffectI3dl2Reverb::UpdateForCommandGeneration() {
  104. if (enabled) {
  105. usage = UsageState::Running;
  106. } else {
  107. usage = UsageState::Stopped;
  108. }
  109. GetParams().status = ParameterStatus::Updated;
  110. }
  111. EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {}
  112. EffectBiquadFilter::~EffectBiquadFilter() = default;
  113. void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) {
  114. auto& params = GetParams();
  115. const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data());
  116. mix_id = in_params.mix_id;
  117. processing_order = in_params.processing_order;
  118. params = *biquad_params;
  119. enabled = in_params.is_enabled;
  120. }
  121. void EffectBiquadFilter::UpdateForCommandGeneration() {
  122. if (enabled) {
  123. usage = UsageState::Running;
  124. } else {
  125. usage = UsageState::Stopped;
  126. }
  127. GetParams().status = ParameterStatus::Updated;
  128. }
  129. EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {}
  130. EffectAuxInfo::~EffectAuxInfo() = default;
  131. void EffectAuxInfo::Update(EffectInfo::InParams& in_params) {
  132. const auto* aux_params = reinterpret_cast<AuxInfo*>(in_params.raw.data());
  133. mix_id = in_params.mix_id;
  134. processing_order = in_params.processing_order;
  135. GetParams() = *aux_params;
  136. enabled = in_params.is_enabled;
  137. if (in_params.is_new || skipped) {
  138. skipped = aux_params->send_buffer_info == 0 || aux_params->return_buffer_info == 0;
  139. if (skipped) {
  140. return;
  141. }
  142. // There's two AuxInfos which are an identical size, the first one is managed by the cpu,
  143. // the second is managed by the dsp. All we care about is managing the DSP one
  144. send_info = aux_params->send_buffer_info + sizeof(AuxInfoDSP);
  145. send_buffer = aux_params->send_buffer_info + (sizeof(AuxInfoDSP) * 2);
  146. recv_info = aux_params->return_buffer_info + sizeof(AuxInfoDSP);
  147. recv_buffer = aux_params->return_buffer_info + (sizeof(AuxInfoDSP) * 2);
  148. }
  149. }
  150. void EffectAuxInfo::UpdateForCommandGeneration() {
  151. if (enabled) {
  152. usage = UsageState::Running;
  153. } else {
  154. usage = UsageState::Stopped;
  155. }
  156. }
  157. VAddr EffectAuxInfo::GetSendInfo() const {
  158. return send_info;
  159. }
  160. VAddr EffectAuxInfo::GetSendBuffer() const {
  161. return send_buffer;
  162. }
  163. VAddr EffectAuxInfo::GetRecvInfo() const {
  164. return recv_info;
  165. }
  166. VAddr EffectAuxInfo::GetRecvBuffer() const {
  167. return recv_buffer;
  168. }
  169. EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {}
  170. EffectDelay::~EffectDelay() = default;
  171. void EffectDelay::Update(EffectInfo::InParams& in_params) {
  172. const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data());
  173. auto& params = GetParams();
  174. if (!ValidChannelCountForEffect(delay_params->max_channels)) {
  175. return;
  176. }
  177. const auto last_status = params.status;
  178. mix_id = in_params.mix_id;
  179. processing_order = in_params.processing_order;
  180. params = *delay_params;
  181. if (!ValidChannelCountForEffect(delay_params->channels)) {
  182. params.channels = params.max_channels;
  183. }
  184. enabled = in_params.is_enabled;
  185. if (last_status != ParameterStatus::Updated) {
  186. params.status = last_status;
  187. }
  188. if (in_params.is_new || skipped) {
  189. usage = UsageState::Initialized;
  190. params.status = ParameterStatus::Initialized;
  191. skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
  192. }
  193. }
  194. void EffectDelay::UpdateForCommandGeneration() {
  195. if (enabled) {
  196. usage = UsageState::Running;
  197. } else {
  198. usage = UsageState::Stopped;
  199. }
  200. GetParams().status = ParameterStatus::Updated;
  201. }
  202. EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {}
  203. EffectBufferMixer::~EffectBufferMixer() = default;
  204. void EffectBufferMixer::Update(EffectInfo::InParams& in_params) {
  205. mix_id = in_params.mix_id;
  206. processing_order = in_params.processing_order;
  207. GetParams() = *reinterpret_cast<BufferMixerParams*>(in_params.raw.data());
  208. enabled = in_params.is_enabled;
  209. }
  210. void EffectBufferMixer::UpdateForCommandGeneration() {
  211. if (enabled) {
  212. usage = UsageState::Running;
  213. } else {
  214. usage = UsageState::Stopped;
  215. }
  216. }
  217. EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {}
  218. EffectReverb::~EffectReverb() = default;
  219. void EffectReverb::Update(EffectInfo::InParams& in_params) {
  220. const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data());
  221. auto& params = GetParams();
  222. if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
  223. return;
  224. }
  225. const auto last_status = params.status;
  226. mix_id = in_params.mix_id;
  227. processing_order = in_params.processing_order;
  228. params = *reverb_params;
  229. if (!ValidChannelCountForEffect(reverb_params->channels)) {
  230. params.channels = params.max_channels;
  231. }
  232. enabled = in_params.is_enabled;
  233. if (last_status != ParameterStatus::Updated) {
  234. params.status = last_status;
  235. }
  236. if (in_params.is_new || skipped) {
  237. usage = UsageState::Initialized;
  238. params.status = ParameterStatus::Initialized;
  239. skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
  240. }
  241. }
  242. void EffectReverb::UpdateForCommandGeneration() {
  243. if (enabled) {
  244. usage = UsageState::Running;
  245. } else {
  246. usage = UsageState::Stopped;
  247. }
  248. GetParams().status = ParameterStatus::Updated;
  249. }
  250. } // namespace AudioCore