reverb.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <numbers>
  4. #include <ranges>
  5. #include "audio_core/renderer/adsp/command_list_processor.h"
  6. #include "audio_core/renderer/command/effect/reverb.h"
  7. #include "common/polyfill_ranges.h"
  8. namespace AudioCore::AudioRenderer {
  9. constexpr std::array<f32, ReverbInfo::MaxDelayLines> FdnMaxDelayLineTimes = {
  10. 53.9532470703125f,
  11. 79.19256591796875f,
  12. 116.23876953125f,
  13. 170.61529541015625f,
  14. };
  15. constexpr std::array<f32, ReverbInfo::MaxDelayLines> DecayMaxDelayLineTimes = {
  16. 7.0f,
  17. 9.0f,
  18. 13.0f,
  19. 17.0f,
  20. };
  21. constexpr std::array<std::array<f32, ReverbInfo::MaxDelayTaps + 1>, ReverbInfo::NumEarlyModes>
  22. EarlyDelayTimes = {
  23. {{0.000000f, 3.500000f, 2.799988f, 3.899963f, 2.699951f, 13.399963f, 7.899963f, 8.399963f,
  24. 9.899963f, 12.000000f, 12.500000f},
  25. {0.000000f, 11.799988f, 5.500000f, 11.199951f, 10.399963f, 38.099976f, 22.199951f,
  26. 29.599976f, 21.199951f, 24.799988f, 40.000000f},
  27. {0.000000f, 41.500000f, 20.500000f, 41.299988f, 0.000000f, 29.500000f, 33.799988f,
  28. 45.199951f, 46.799988f, 0.000000f, 50.000000f},
  29. {33.099976f, 43.299988f, 22.799988f, 37.899963f, 14.899963f, 35.299988f, 17.899963f,
  30. 34.199951f, 0.000000f, 43.299988f, 50.000000f},
  31. {0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
  32. 0.000000f, 0.000000f, 0.000000f}},
  33. };
  34. constexpr std::array<std::array<f32, ReverbInfo::MaxDelayTaps>, ReverbInfo::NumEarlyModes>
  35. EarlyDelayGains = {{
  36. {0.699951f, 0.679993f, 0.699951f, 0.679993f, 0.699951f, 0.679993f, 0.699951f, 0.679993f,
  37. 0.679993f, 0.679993f},
  38. {0.699951f, 0.679993f, 0.699951f, 0.679993f, 0.699951f, 0.679993f, 0.679993f, 0.679993f,
  39. 0.679993f, 0.679993f},
  40. {0.500000f, 0.699951f, 0.699951f, 0.679993f, 0.500000f, 0.679993f, 0.679993f, 0.699951f,
  41. 0.679993f, 0.000000f},
  42. {0.929993f, 0.919983f, 0.869995f, 0.859985f, 0.939941f, 0.809998f, 0.799988f, 0.769958f,
  43. 0.759949f, 0.649963f},
  44. {0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
  45. 0.000000f, 0.000000f},
  46. }};
  47. constexpr std::array<std::array<f32, ReverbInfo::MaxDelayLines>, ReverbInfo::NumLateModes>
  48. FdnDelayTimes = {{
  49. {53.953247f, 79.192566f, 116.238770f, 130.615295f},
  50. {53.953247f, 79.192566f, 116.238770f, 170.615295f},
  51. {5.000000f, 10.000000f, 5.000000f, 10.000000f},
  52. {47.029968f, 71.000000f, 103.000000f, 170.000000f},
  53. {53.953247f, 79.192566f, 116.238770f, 170.615295f},
  54. }};
  55. constexpr std::array<std::array<f32, ReverbInfo::MaxDelayLines>, ReverbInfo::NumLateModes>
  56. DecayDelayTimes = {{
  57. {7.000000f, 9.000000f, 13.000000f, 17.000000f},
  58. {7.000000f, 9.000000f, 13.000000f, 17.000000f},
  59. {1.000000f, 1.000000f, 1.000000f, 1.000000f},
  60. {7.000000f, 7.000000f, 13.000000f, 9.000000f},
  61. {7.000000f, 9.000000f, 13.000000f, 17.000000f},
  62. }};
  63. /**
  64. * Update the ReverbInfo state according to the given parameters.
  65. *
  66. * @param params - Input parameters to update the state.
  67. * @param state - State to be updated.
  68. */
  69. static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& params,
  70. ReverbInfo::State& state) {
  71. const auto pow_10 = [](f32 val) -> f32 {
  72. return (val >= 0.0f) ? 1.0f : (val <= -5.3f) ? 0.0f : std::pow(10.0f, val);
  73. };
  74. const auto cos = [](f32 degrees) -> f32 {
  75. return std::cos(degrees * std::numbers::pi_v<f32> / 180.0f);
  76. };
  77. static bool unk_initialized{false};
  78. static Common::FixedPoint<50, 14> unk_value{};
  79. const auto sample_rate{Common::FixedPoint<50, 14>::from_base(params.sample_rate)};
  80. const auto pre_delay_time{Common::FixedPoint<50, 14>::from_base(params.pre_delay)};
  81. for (u32 i = 0; i < ReverbInfo::MaxDelayTaps; i++) {
  82. auto early_delay{
  83. ((pre_delay_time + EarlyDelayTimes[params.early_mode][i]) * sample_rate).to_int()};
  84. early_delay = std::min(early_delay, state.pre_delay_line.sample_count_max);
  85. state.early_delay_times[i] = early_delay + 1;
  86. state.early_gains[i] = Common::FixedPoint<50, 14>::from_base(params.early_gain) *
  87. EarlyDelayGains[params.early_mode][i];
  88. }
  89. if (params.channel_count == 2) {
  90. state.early_gains[4] * 0.5f;
  91. state.early_gains[5] * 0.5f;
  92. }
  93. auto pre_time{
  94. ((pre_delay_time + EarlyDelayTimes[params.early_mode][10]) * sample_rate).to_int()};
  95. state.pre_delay_time = std::min(pre_time, state.pre_delay_line.sample_count_max);
  96. if (!unk_initialized) {
  97. unk_value = cos((1280.0f / sample_rate).to_float());
  98. unk_initialized = true;
  99. }
  100. for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
  101. const auto fdn_delay{(FdnDelayTimes[params.late_mode][i] * sample_rate).to_int()};
  102. state.fdn_delay_lines[i].sample_count =
  103. std::min(fdn_delay, state.fdn_delay_lines[i].sample_count_max);
  104. state.fdn_delay_lines[i].buffer_end =
  105. &state.fdn_delay_lines[i].buffer[state.fdn_delay_lines[i].sample_count - 1];
  106. const auto decay_delay{(DecayDelayTimes[params.late_mode][i] * sample_rate).to_int()};
  107. state.decay_delay_lines[i].sample_count =
  108. std::min(decay_delay, state.decay_delay_lines[i].sample_count_max);
  109. state.decay_delay_lines[i].buffer_end =
  110. &state.decay_delay_lines[i].buffer[state.decay_delay_lines[i].sample_count - 1];
  111. state.decay_delay_lines[i].decay =
  112. 0.5999755859375f * (1.0f - Common::FixedPoint<50, 14>::from_base(params.colouration));
  113. auto a{(Common::FixedPoint<50, 14>(state.fdn_delay_lines[i].sample_count_max) +
  114. state.decay_delay_lines[i].sample_count_max) *
  115. -3};
  116. auto b{a / (Common::FixedPoint<50, 14>::from_base(params.decay_time) * sample_rate)};
  117. Common::FixedPoint<50, 14> c{0.0f};
  118. Common::FixedPoint<50, 14> d{0.0f};
  119. auto hf_decay_ratio{Common::FixedPoint<50, 14>::from_base(params.high_freq_decay_ratio)};
  120. if (hf_decay_ratio > 0.99493408203125f) {
  121. c = 0.0f;
  122. d = 1.0f;
  123. } else {
  124. const auto e{
  125. pow_10(((((1.0f / hf_decay_ratio) - 1.0f) * 2) / 100 * (b / 10)).to_float())};
  126. const auto f{1.0f - e};
  127. const auto g{2.0f - (unk_value * e * 2)};
  128. const auto h{std::sqrt(std::pow(g.to_float(), 2.0f) - (std::pow(f, 2.0f) * 4))};
  129. c = (g - h) / (f * 2.0f);
  130. d = 1.0f - c;
  131. }
  132. state.hf_decay_prev_gain[i] = c;
  133. state.hf_decay_gain[i] = pow_10((b / 1000).to_float()) * d * 0.70709228515625f;
  134. state.prev_feedback_output[i] = 0;
  135. }
  136. }
  137. /**
  138. * Initialize a new ReverbInfo state according to the given parameters.
  139. *
  140. * @param params - Input parameters to update the state.
  141. * @param state - State to be updated.
  142. * @param workbuffer - Game-supplied memory for the state. (Unused)
  143. * @param long_size_pre_delay_supported - Use a longer pre-delay time before reverb begins.
  144. */
  145. static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params,
  146. ReverbInfo::State& state, const CpuAddr workbuffer,
  147. const bool long_size_pre_delay_supported) {
  148. state = {};
  149. auto delay{Common::FixedPoint<50, 14>::from_base(params.sample_rate)};
  150. for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
  151. auto fdn_delay_time{(FdnMaxDelayLineTimes[i] * delay).to_uint_floor()};
  152. state.fdn_delay_lines[i].Initialize(fdn_delay_time, 1.0f);
  153. auto decay_delay_time{(DecayMaxDelayLineTimes[i] * delay).to_uint_floor()};
  154. state.decay_delay_lines[i].Initialize(decay_delay_time, 0.0f);
  155. }
  156. const auto pre_delay{long_size_pre_delay_supported ? 350.0f : 150.0f};
  157. const auto pre_delay_line{(pre_delay * delay).to_uint_floor()};
  158. state.pre_delay_line.Initialize(pre_delay_line, 1.0f);
  159. const auto center_delay_time{(5 * delay).to_uint_floor()};
  160. state.center_delay_line.Initialize(center_delay_time, 1.0f);
  161. UpdateReverbEffectParameter(params, state);
  162. for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
  163. std::ranges::fill(state.fdn_delay_lines[i].buffer, 0);
  164. std::ranges::fill(state.decay_delay_lines[i].buffer, 0);
  165. }
  166. std::ranges::fill(state.center_delay_line.buffer, 0);
  167. std::ranges::fill(state.pre_delay_line.buffer, 0);
  168. }
  169. /**
  170. * Pass-through the effect, copying input to output directly, with no reverb applied.
  171. *
  172. * @param inputs - Array of input mix buffers to copy.
  173. * @param outputs - Array of output mix buffers to receive copy.
  174. * @param channel_count - Number of channels in inputs and outputs.
  175. * @param sample_count - Number of samples within each channel.
  176. */
  177. static void ApplyReverbEffectBypass(std::span<std::span<const s32>> inputs,
  178. std::span<std::span<s32>> outputs, const u32 channel_count,
  179. const u32 sample_count) {
  180. for (u32 i = 0; i < channel_count; i++) {
  181. if (inputs[i].data() != outputs[i].data()) {
  182. std::memcpy(outputs[i].data(), inputs[i].data(), outputs[i].size_bytes());
  183. }
  184. }
  185. }
  186. /**
  187. * Tick the delay lines, reading and returning their current output, and writing a new decaying
  188. * sample (mix).
  189. *
  190. * @param decay - The decay line.
  191. * @param fdn - Feedback delay network.
  192. * @param mix - The new calculated sample to be written and decayed.
  193. * @return The next delayed and decayed sample.
  194. */
  195. static Common::FixedPoint<50, 14> Axfx2AllPassTick(ReverbInfo::ReverbDelayLine& decay,
  196. ReverbInfo::ReverbDelayLine& fdn,
  197. const Common::FixedPoint<50, 14> mix) {
  198. const auto val{decay.Read()};
  199. const auto mixed{mix - (val * decay.decay)};
  200. const auto out{decay.Tick(mixed) + (mixed * decay.decay)};
  201. fdn.Tick(out);
  202. return out;
  203. }
  204. /**
  205. * Impl. Apply a Reverb according to the current state, on the input mix buffers,
  206. * saving the results to the output mix buffers.
  207. *
  208. * @tparam NumChannels - Number of channels to process. 1-6.
  209. Inputs/outputs should have this many buffers.
  210. * @param params - Input parameters to update the state.
  211. * @param state - State to use, must be initialized (see InitializeReverbEffect).
  212. * @param inputs - Input mix buffers to perform the reverb on.
  213. * @param outputs - Output mix buffers to receive the reverbed samples.
  214. * @param sample_count - Number of samples to process.
  215. */
  216. template <size_t NumChannels>
  217. static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
  218. std::vector<std::span<const s32>>& inputs,
  219. std::vector<std::span<s32>>& outputs, const u32 sample_count) {
  220. constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
  221. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  222. };
  223. constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
  224. 0, 0, 1, 1, 0, 1, 0, 0, 1, 1,
  225. };
  226. constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
  227. 0, 0, 1, 1, 0, 1, 2, 2, 3, 3,
  228. };
  229. constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
  230. 0, 0, 1, 1, 2, 2, 4, 4, 5, 5,
  231. };
  232. std::span<const u8> tap_indexes{};
  233. if constexpr (NumChannels == 1) {
  234. tap_indexes = OutTapIndexes1Ch;
  235. } else if constexpr (NumChannels == 2) {
  236. tap_indexes = OutTapIndexes2Ch;
  237. } else if constexpr (NumChannels == 4) {
  238. tap_indexes = OutTapIndexes4Ch;
  239. } else if constexpr (NumChannels == 6) {
  240. tap_indexes = OutTapIndexes6Ch;
  241. }
  242. for (u32 sample_index = 0; sample_index < sample_count; sample_index++) {
  243. std::array<Common::FixedPoint<50, 14>, NumChannels> output_samples{};
  244. for (u32 early_tap = 0; early_tap < ReverbInfo::MaxDelayTaps; early_tap++) {
  245. const auto sample{state.pre_delay_line.TapOut(state.early_delay_times[early_tap]) *
  246. state.early_gains[early_tap]};
  247. output_samples[tap_indexes[early_tap]] += sample;
  248. if constexpr (NumChannels == 6) {
  249. output_samples[static_cast<u32>(Channels::LFE)] += sample;
  250. }
  251. }
  252. if constexpr (NumChannels == 6) {
  253. output_samples[static_cast<u32>(Channels::LFE)] *= 0.2f;
  254. }
  255. Common::FixedPoint<50, 14> input_sample{};
  256. for (u32 channel = 0; channel < NumChannels; channel++) {
  257. input_sample += inputs[channel][sample_index];
  258. }
  259. input_sample *= 64;
  260. input_sample *= Common::FixedPoint<50, 14>::from_base(params.base_gain);
  261. state.pre_delay_line.Write(input_sample);
  262. for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
  263. state.prev_feedback_output[i] =
  264. state.prev_feedback_output[i] * state.hf_decay_prev_gain[i] +
  265. state.fdn_delay_lines[i].Read() * state.hf_decay_gain[i];
  266. }
  267. Common::FixedPoint<50, 14> pre_delay_sample{
  268. state.pre_delay_line.Read() * Common::FixedPoint<50, 14>::from_base(params.late_gain)};
  269. std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> mix_matrix{
  270. state.prev_feedback_output[2] + state.prev_feedback_output[1] + pre_delay_sample,
  271. -state.prev_feedback_output[0] - state.prev_feedback_output[3] + pre_delay_sample,
  272. state.prev_feedback_output[0] - state.prev_feedback_output[3] + pre_delay_sample,
  273. state.prev_feedback_output[1] - state.prev_feedback_output[2] + pre_delay_sample,
  274. };
  275. std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> allpass_samples{};
  276. for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
  277. allpass_samples[i] = Axfx2AllPassTick(state.decay_delay_lines[i],
  278. state.fdn_delay_lines[i], mix_matrix[i]);
  279. }
  280. const auto dry_gain{Common::FixedPoint<50, 14>::from_base(params.dry_gain)};
  281. const auto wet_gain{Common::FixedPoint<50, 14>::from_base(params.wet_gain)};
  282. if constexpr (NumChannels == 6) {
  283. const std::array<Common::FixedPoint<50, 14>, MaxChannels> allpass_outputs{
  284. allpass_samples[0], allpass_samples[1], allpass_samples[2] - allpass_samples[3],
  285. allpass_samples[3], allpass_samples[2], allpass_samples[3],
  286. };
  287. for (u32 channel = 0; channel < NumChannels; channel++) {
  288. auto in_sample{inputs[channel][sample_index] * dry_gain};
  289. Common::FixedPoint<50, 14> allpass{};
  290. if (channel == static_cast<u32>(Channels::Center)) {
  291. allpass = state.center_delay_line.Tick(allpass_outputs[channel] * 0.5f);
  292. } else {
  293. allpass = allpass_outputs[channel];
  294. }
  295. auto out_sample{((output_samples[channel] + allpass) * wet_gain) / 64};
  296. outputs[channel][sample_index] = (in_sample + out_sample).to_int();
  297. }
  298. } else {
  299. for (u32 channel = 0; channel < NumChannels; channel++) {
  300. auto in_sample{inputs[channel][sample_index] * dry_gain};
  301. auto out_sample{((output_samples[channel] + allpass_samples[channel]) * wet_gain) /
  302. 64};
  303. outputs[channel][sample_index] = (in_sample + out_sample).to_int();
  304. }
  305. }
  306. }
  307. }
  308. /**
  309. * Apply a Reverb if enabled, according to the current state, on the input mix buffers,
  310. * saving the results to the output mix buffers.
  311. *
  312. * @param params - Input parameters to use.
  313. * @param state - State to use, must be initialized (see InitializeReverbEffect).
  314. * @param enabled - If enabled, delay will be applied, otherwise input is copied to output.
  315. * @param inputs - Input mix buffers to performan the reverb on.
  316. * @param outputs - Output mix buffers to receive the reverbed samples.
  317. * @param sample_count - Number of samples to process.
  318. */
  319. static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
  320. const bool enabled, std::vector<std::span<const s32>>& inputs,
  321. std::vector<std::span<s32>>& outputs, const u32 sample_count) {
  322. if (enabled) {
  323. switch (params.channel_count) {
  324. case 0:
  325. return;
  326. case 1:
  327. ApplyReverbEffect<1>(params, state, inputs, outputs, sample_count);
  328. break;
  329. case 2:
  330. ApplyReverbEffect<2>(params, state, inputs, outputs, sample_count);
  331. break;
  332. case 4:
  333. ApplyReverbEffect<4>(params, state, inputs, outputs, sample_count);
  334. break;
  335. case 6:
  336. ApplyReverbEffect<6>(params, state, inputs, outputs, sample_count);
  337. break;
  338. default:
  339. ApplyReverbEffectBypass(inputs, outputs, params.channel_count, sample_count);
  340. break;
  341. }
  342. } else {
  343. ApplyReverbEffectBypass(inputs, outputs, params.channel_count, sample_count);
  344. }
  345. }
  346. void ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
  347. std::string& string) {
  348. string += fmt::format(
  349. "ReverbCommand\n\tenabled {} long_size_pre_delay_supported {}\n\tinputs: ", effect_enabled,
  350. long_size_pre_delay_supported);
  351. for (u32 i = 0; i < MaxChannels; i++) {
  352. string += fmt::format("{:02X}, ", inputs[i]);
  353. }
  354. string += "\n\toutputs: ";
  355. for (u32 i = 0; i < MaxChannels; i++) {
  356. string += fmt::format("{:02X}, ", outputs[i]);
  357. }
  358. string += "\n";
  359. }
  360. void ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
  361. std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
  362. std::vector<std::span<s32>> output_buffers(parameter.channel_count);
  363. for (u32 i = 0; i < parameter.channel_count; i++) {
  364. input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
  365. processor.sample_count);
  366. output_buffers[i] = processor.mix_buffers.subspan(outputs[i] * processor.sample_count,
  367. processor.sample_count);
  368. }
  369. auto state_{reinterpret_cast<ReverbInfo::State*>(state)};
  370. if (effect_enabled) {
  371. if (parameter.state == ReverbInfo::ParameterState::Updating) {
  372. UpdateReverbEffectParameter(parameter, *state_);
  373. } else if (parameter.state == ReverbInfo::ParameterState::Initialized) {
  374. InitializeReverbEffect(parameter, *state_, workbuffer, long_size_pre_delay_supported);
  375. }
  376. }
  377. ApplyReverbEffect(parameter, *state_, effect_enabled, input_buffers, output_buffers,
  378. processor.sample_count);
  379. }
  380. bool ReverbCommand::Verify(const ADSP::CommandListProcessor& processor) {
  381. return true;
  382. }
  383. } // namespace AudioCore::AudioRenderer