command_generator.cpp 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <numbers>
  6. #include "audio_core/algorithm/interpolate.h"
  7. #include "audio_core/command_generator.h"
  8. #include "audio_core/effect_context.h"
  9. #include "audio_core/mix_context.h"
  10. #include "audio_core/voice_context.h"
  11. #include "common/common_types.h"
  12. #include "core/memory.h"
  13. namespace AudioCore {
  14. namespace {
  15. constexpr std::size_t MIX_BUFFER_SIZE = 0x3f00;
  16. constexpr std::size_t SCALED_MIX_BUFFER_SIZE = MIX_BUFFER_SIZE << 15ULL;
  17. using DelayLineTimes = std::array<f32, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT>;
  18. constexpr DelayLineTimes FDN_MIN_DELAY_LINE_TIMES{5.0f, 6.0f, 13.0f, 14.0f};
  19. constexpr DelayLineTimes FDN_MAX_DELAY_LINE_TIMES{45.704f, 82.782f, 149.94f, 271.58f};
  20. constexpr DelayLineTimes DECAY0_MAX_DELAY_LINE_TIMES{17.0f, 13.0f, 9.0f, 7.0f};
  21. constexpr DelayLineTimes DECAY1_MAX_DELAY_LINE_TIMES{19.0f, 11.0f, 10.0f, 6.0f};
  22. constexpr std::array<f32, AudioCommon::I3DL2REVERB_TAPS> EARLY_TAP_TIMES{
  23. 0.017136f, 0.059154f, 0.161733f, 0.390186f, 0.425262f, 0.455411f, 0.689737f,
  24. 0.745910f, 0.833844f, 0.859502f, 0.000000f, 0.075024f, 0.168788f, 0.299901f,
  25. 0.337443f, 0.371903f, 0.599011f, 0.716741f, 0.817859f, 0.851664f};
  26. constexpr std::array<f32, AudioCommon::I3DL2REVERB_TAPS> EARLY_GAIN{
  27. 0.67096f, 0.61027f, 1.0f, 0.35680f, 0.68361f, 0.65978f, 0.51939f,
  28. 0.24712f, 0.45945f, 0.45021f, 0.64196f, 0.54879f, 0.92925f, 0.38270f,
  29. 0.72867f, 0.69794f, 0.5464f, 0.24563f, 0.45214f, 0.44042f};
  30. template <std::size_t N>
  31. void ApplyMix(std::span<s32> output, std::span<const s32> input, s32 gain, s32 sample_count) {
  32. for (std::size_t i = 0; i < static_cast<std::size_t>(sample_count); i += N) {
  33. for (std::size_t j = 0; j < N; j++) {
  34. output[i + j] +=
  35. static_cast<s32>((static_cast<s64>(input[i + j]) * gain + 0x4000) >> 15);
  36. }
  37. }
  38. }
  39. s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, float gain, float delta,
  40. s32 sample_count) {
  41. // XC2 passes in NaN mix volumes, causing further issues as we handle everything as s32 rather
  42. // than float, so the NaN propogation is lost. As the samples get further modified for
  43. // volume etc, they can get out of NaN range, so a later heuristic for catching this is
  44. // more difficult. Handle it here by setting these samples to silence.
  45. if (std::isnan(gain)) {
  46. gain = 0.0f;
  47. delta = 0.0f;
  48. }
  49. s32 x = 0;
  50. for (s32 i = 0; i < sample_count; i++) {
  51. x = static_cast<s32>(static_cast<float>(input[i]) * gain);
  52. output[i] += x;
  53. gain += delta;
  54. }
  55. return x;
  56. }
  57. void ApplyGain(std::span<s32> output, std::span<const s32> input, s32 gain, s32 delta,
  58. s32 sample_count) {
  59. for (s32 i = 0; i < sample_count; i++) {
  60. output[i] = static_cast<s32>((static_cast<s64>(input[i]) * gain + 0x4000) >> 15);
  61. gain += delta;
  62. }
  63. }
  64. void ApplyGainWithoutDelta(std::span<s32> output, std::span<const s32> input, s32 gain,
  65. s32 sample_count) {
  66. for (s32 i = 0; i < sample_count; i++) {
  67. output[i] = static_cast<s32>((static_cast<s64>(input[i]) * gain + 0x4000) >> 15);
  68. }
  69. }
  70. s32 ApplyMixDepop(std::span<s32> output, s32 first_sample, s32 delta, s32 sample_count) {
  71. const bool positive = first_sample > 0;
  72. auto final_sample = std::abs(first_sample);
  73. for (s32 i = 0; i < sample_count; i++) {
  74. final_sample = static_cast<s32>((static_cast<s64>(final_sample) * delta) >> 15);
  75. if (positive) {
  76. output[i] += final_sample;
  77. } else {
  78. output[i] -= final_sample;
  79. }
  80. }
  81. if (positive) {
  82. return final_sample;
  83. } else {
  84. return -final_sample;
  85. }
  86. }
  87. float Pow10(float x) {
  88. if (x >= 0.0f) {
  89. return 1.0f;
  90. } else if (x <= -5.3f) {
  91. return 0.0f;
  92. }
  93. return std::pow(10.0f, x);
  94. }
  95. float SinD(float degrees) {
  96. return std::sin(degrees * std::numbers::pi_v<float> / 180.0f);
  97. }
  98. float CosD(float degrees) {
  99. return std::cos(degrees * std::numbers::pi_v<float> / 180.0f);
  100. }
  101. float ToFloat(s32 sample) {
  102. return static_cast<float>(sample) / 65536.f;
  103. }
  104. s32 ToS32(float sample) {
  105. constexpr auto min = -8388608.0f;
  106. constexpr auto max = 8388607.f;
  107. float rescaled_sample = sample * 65536.0f;
  108. if (rescaled_sample < min) {
  109. rescaled_sample = min;
  110. }
  111. if (rescaled_sample > max) {
  112. rescaled_sample = max;
  113. }
  114. return static_cast<s32>(rescaled_sample);
  115. }
  116. constexpr std::array<u8, 20> REVERB_TAP_INDEX_1CH{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  117. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  118. constexpr std::array<u8, 20> REVERB_TAP_INDEX_2CH{0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
  119. 1, 1, 1, 0, 0, 0, 0, 1, 1, 1};
  120. constexpr std::array<u8, 20> REVERB_TAP_INDEX_4CH{0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
  121. 1, 1, 1, 0, 0, 0, 0, 3, 3, 3};
  122. constexpr std::array<u8, 20> REVERB_TAP_INDEX_6CH{4, 0, 0, 1, 1, 1, 1, 2, 2, 2,
  123. 1, 1, 1, 0, 0, 0, 0, 3, 3, 3};
  124. template <std::size_t CHANNEL_COUNT>
  125. void ApplyReverbGeneric(
  126. I3dl2ReverbState& state,
  127. const std::array<std::span<const s32>, AudioCommon::MAX_CHANNEL_COUNT>& input,
  128. const std::array<std::span<s32>, AudioCommon::MAX_CHANNEL_COUNT>& output, s32 sample_count) {
  129. auto GetTapLookup = []() {
  130. if constexpr (CHANNEL_COUNT == 1) {
  131. return REVERB_TAP_INDEX_1CH;
  132. } else if constexpr (CHANNEL_COUNT == 2) {
  133. return REVERB_TAP_INDEX_2CH;
  134. } else if constexpr (CHANNEL_COUNT == 4) {
  135. return REVERB_TAP_INDEX_4CH;
  136. } else if constexpr (CHANNEL_COUNT == 6) {
  137. return REVERB_TAP_INDEX_6CH;
  138. }
  139. };
  140. const auto& tap_index_lut = GetTapLookup();
  141. for (s32 sample = 0; sample < sample_count; sample++) {
  142. std::array<f32, CHANNEL_COUNT> out_samples{};
  143. std::array<f32, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> fsamp{};
  144. std::array<f32, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> mixed{};
  145. std::array<f32, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> osamp{};
  146. // Mix everything into a single sample
  147. s32 temp_mixed_sample = 0;
  148. for (std::size_t i = 0; i < CHANNEL_COUNT; i++) {
  149. temp_mixed_sample += input[i][sample];
  150. }
  151. const auto current_sample = ToFloat(temp_mixed_sample);
  152. const auto early_tap = state.early_delay_line.TapOut(state.early_to_late_taps);
  153. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_TAPS; i++) {
  154. const auto tapped_samp =
  155. state.early_delay_line.TapOut(state.early_tap_steps[i]) * EARLY_GAIN[i];
  156. out_samples[tap_index_lut[i]] += tapped_samp;
  157. if constexpr (CHANNEL_COUNT == 6) {
  158. // handle lfe
  159. out_samples[5] += tapped_samp;
  160. }
  161. }
  162. state.lowpass_0 = current_sample * state.lowpass_2 + state.lowpass_0 * state.lowpass_1;
  163. state.early_delay_line.Tick(state.lowpass_0);
  164. for (std::size_t i = 0; i < CHANNEL_COUNT; i++) {
  165. out_samples[i] *= state.early_gain;
  166. }
  167. // Two channel seems to apply a latet gain, we require to save this
  168. f32 filter{};
  169. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT; i++) {
  170. filter = state.fdn_delay_line[i].GetOutputSample();
  171. const auto computed = filter * state.lpf_coefficients[0][i] + state.shelf_filter[i];
  172. state.shelf_filter[i] =
  173. filter * state.lpf_coefficients[1][i] + computed * state.lpf_coefficients[2][i];
  174. fsamp[i] = computed;
  175. }
  176. // Mixing matrix
  177. mixed[0] = fsamp[1] + fsamp[2];
  178. mixed[1] = -fsamp[0] - fsamp[3];
  179. mixed[2] = fsamp[0] - fsamp[3];
  180. mixed[3] = fsamp[1] - fsamp[2];
  181. if constexpr (CHANNEL_COUNT == 2) {
  182. for (auto& mix : mixed) {
  183. mix *= (filter * state.late_gain);
  184. }
  185. }
  186. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT; i++) {
  187. const auto late = early_tap * state.late_gain;
  188. osamp[i] = state.decay_delay_line0[i].Tick(late + mixed[i]);
  189. osamp[i] = state.decay_delay_line1[i].Tick(osamp[i]);
  190. state.fdn_delay_line[i].Tick(osamp[i]);
  191. }
  192. if constexpr (CHANNEL_COUNT == 1) {
  193. output[0][sample] = ToS32(state.dry_gain * ToFloat(input[0][sample]) +
  194. (out_samples[0] + osamp[0] + osamp[1]));
  195. } else if constexpr (CHANNEL_COUNT == 2 || CHANNEL_COUNT == 4) {
  196. for (std::size_t i = 0; i < CHANNEL_COUNT; i++) {
  197. output[i][sample] =
  198. ToS32(state.dry_gain * ToFloat(input[i][sample]) + (out_samples[i] + osamp[i]));
  199. }
  200. } else if constexpr (CHANNEL_COUNT == 6) {
  201. const auto temp_center = state.center_delay_line.Tick(0.5f * (osamp[2] - osamp[3]));
  202. for (std::size_t i = 0; i < 4; i++) {
  203. output[i][sample] =
  204. ToS32(state.dry_gain * ToFloat(input[i][sample]) + (out_samples[i] + osamp[i]));
  205. }
  206. output[4][sample] =
  207. ToS32(state.dry_gain * ToFloat(input[4][sample]) + (out_samples[4] + temp_center));
  208. output[5][sample] =
  209. ToS32(state.dry_gain * ToFloat(input[5][sample]) + (out_samples[5] + osamp[3]));
  210. }
  211. }
  212. }
  213. } // namespace
  214. CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
  215. VoiceContext& voice_context_, MixContext& mix_context_,
  216. SplitterContext& splitter_context_,
  217. EffectContext& effect_context_, Core::Memory::Memory& memory_)
  218. : worker_params(worker_params_), voice_context(voice_context_), mix_context(mix_context_),
  219. splitter_context(splitter_context_), effect_context(effect_context_), memory(memory_),
  220. mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) *
  221. worker_params.sample_count),
  222. sample_buffer(MIX_BUFFER_SIZE),
  223. depop_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) *
  224. worker_params.sample_count) {}
  225. CommandGenerator::~CommandGenerator() = default;
  226. void CommandGenerator::ClearMixBuffers() {
  227. std::fill(mix_buffer.begin(), mix_buffer.end(), 0);
  228. std::fill(sample_buffer.begin(), sample_buffer.end(), 0);
  229. // std::fill(depop_buffer.begin(), depop_buffer.end(), 0);
  230. }
  231. void CommandGenerator::GenerateVoiceCommands() {
  232. if (dumping_frame) {
  233. LOG_DEBUG(Audio, "(DSP_TRACE) GenerateVoiceCommands");
  234. }
  235. // Grab all our voices
  236. const auto voice_count = voice_context.GetVoiceCount();
  237. for (std::size_t i = 0; i < voice_count; i++) {
  238. auto& voice_info = voice_context.GetSortedInfo(i);
  239. // Update voices and check if we should queue them
  240. if (voice_info.ShouldSkip() || !voice_info.UpdateForCommandGeneration(voice_context)) {
  241. continue;
  242. }
  243. // Queue our voice
  244. GenerateVoiceCommand(voice_info);
  245. }
  246. // Update our splitters
  247. splitter_context.UpdateInternalState();
  248. }
  249. void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
  250. auto& in_params = voice_info.GetInParams();
  251. const auto channel_count = in_params.channel_count;
  252. for (s32 channel = 0; channel < channel_count; channel++) {
  253. const auto resource_id = in_params.voice_channel_resource_id[channel];
  254. auto& dsp_state = voice_context.GetDspSharedState(resource_id);
  255. auto& channel_resource = voice_context.GetChannelResource(resource_id);
  256. // Decode our samples for our channel
  257. GenerateDataSourceCommand(voice_info, dsp_state, channel);
  258. if (in_params.should_depop) {
  259. in_params.last_volume = 0.0f;
  260. } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER ||
  261. in_params.mix_id != AudioCommon::NO_MIX) {
  262. // Apply a biquad filter if needed
  263. GenerateBiquadFilterCommandForVoice(voice_info, dsp_state,
  264. worker_params.mix_buffer_count, channel);
  265. // Base voice volume ramping
  266. GenerateVolumeRampCommand(in_params.last_volume, in_params.volume, channel,
  267. in_params.node_id);
  268. in_params.last_volume = in_params.volume;
  269. if (in_params.mix_id != AudioCommon::NO_MIX) {
  270. // If we're using a mix id
  271. auto& mix_info = mix_context.GetInfo(in_params.mix_id);
  272. const auto& dest_mix_params = mix_info.GetInParams();
  273. // Voice Mixing
  274. GenerateVoiceMixCommand(
  275. channel_resource.GetCurrentMixVolume(), channel_resource.GetLastMixVolume(),
  276. dsp_state, dest_mix_params.buffer_offset, dest_mix_params.buffer_count,
  277. worker_params.mix_buffer_count + channel, in_params.node_id);
  278. // Update last mix volumes
  279. channel_resource.UpdateLastMixVolumes();
  280. } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER) {
  281. s32 base = channel;
  282. while (auto* destination_data =
  283. GetDestinationData(in_params.splitter_info_id, base)) {
  284. base += channel_count;
  285. if (!destination_data->IsConfigured()) {
  286. continue;
  287. }
  288. if (destination_data->GetMixId() >= static_cast<int>(mix_context.GetCount())) {
  289. continue;
  290. }
  291. const auto& mix_info = mix_context.GetInfo(destination_data->GetMixId());
  292. const auto& dest_mix_params = mix_info.GetInParams();
  293. GenerateVoiceMixCommand(
  294. destination_data->CurrentMixVolumes(), destination_data->LastMixVolumes(),
  295. dsp_state, dest_mix_params.buffer_offset, dest_mix_params.buffer_count,
  296. worker_params.mix_buffer_count + channel, in_params.node_id);
  297. destination_data->MarkDirty();
  298. }
  299. }
  300. // Update biquad filter enabled states
  301. for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) {
  302. in_params.was_biquad_filter_enabled[i] = in_params.biquad_filter[i].enabled;
  303. }
  304. }
  305. }
  306. }
  307. void CommandGenerator::GenerateSubMixCommands() {
  308. const auto mix_count = mix_context.GetCount();
  309. for (std::size_t i = 0; i < mix_count; i++) {
  310. auto& mix_info = mix_context.GetSortedInfo(i);
  311. const auto& in_params = mix_info.GetInParams();
  312. if (!in_params.in_use || in_params.mix_id == AudioCommon::FINAL_MIX) {
  313. continue;
  314. }
  315. GenerateSubMixCommand(mix_info);
  316. }
  317. }
  318. void CommandGenerator::GenerateFinalMixCommands() {
  319. GenerateFinalMixCommand();
  320. }
  321. void CommandGenerator::PreCommand() {
  322. if (!dumping_frame) {
  323. return;
  324. }
  325. for (std::size_t i = 0; i < splitter_context.GetInfoCount(); i++) {
  326. const auto& base = splitter_context.GetInfo(i);
  327. std::string graph = fmt::format("b[{}]", i);
  328. const auto* head = base.GetHead();
  329. while (head != nullptr) {
  330. graph += fmt::format("->{}", head->GetMixId());
  331. head = head->GetNextDestination();
  332. }
  333. LOG_DEBUG(Audio, "(DSP_TRACE) SplitterGraph splitter_info={}, {}", i, graph);
  334. }
  335. }
  336. void CommandGenerator::PostCommand() {
  337. if (!dumping_frame) {
  338. return;
  339. }
  340. dumping_frame = false;
  341. }
  342. void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
  343. s32 channel) {
  344. const auto& in_params = voice_info.GetInParams();
  345. const auto depop = in_params.should_depop;
  346. if (depop) {
  347. if (in_params.mix_id != AudioCommon::NO_MIX) {
  348. auto& mix_info = mix_context.GetInfo(in_params.mix_id);
  349. const auto& mix_in = mix_info.GetInParams();
  350. GenerateDepopPrepareCommand(dsp_state, mix_in.buffer_count, mix_in.buffer_offset);
  351. } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER) {
  352. s32 index{};
  353. while (const auto* destination =
  354. GetDestinationData(in_params.splitter_info_id, index++)) {
  355. if (!destination->IsConfigured()) {
  356. continue;
  357. }
  358. auto& mix_info = mix_context.GetInfo(destination->GetMixId());
  359. const auto& mix_in = mix_info.GetInParams();
  360. GenerateDepopPrepareCommand(dsp_state, mix_in.buffer_count, mix_in.buffer_offset);
  361. }
  362. }
  363. } else {
  364. switch (in_params.sample_format) {
  365. case SampleFormat::Pcm8:
  366. case SampleFormat::Pcm16:
  367. case SampleFormat::Pcm32:
  368. case SampleFormat::PcmFloat:
  369. DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel,
  370. worker_params.sample_rate, worker_params.sample_count,
  371. in_params.node_id);
  372. break;
  373. case SampleFormat::Adpcm:
  374. ASSERT(channel == 0 && in_params.channel_count == 1);
  375. DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(0), dsp_state, 0,
  376. worker_params.sample_rate, worker_params.sample_count,
  377. in_params.node_id);
  378. break;
  379. default:
  380. ASSERT_MSG(false, "Unimplemented sample format={}", in_params.sample_format);
  381. }
  382. }
  383. }
  384. void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info,
  385. VoiceState& dsp_state,
  386. [[maybe_unused]] s32 mix_buffer_count,
  387. [[maybe_unused]] s32 channel) {
  388. for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) {
  389. const auto& in_params = voice_info.GetInParams();
  390. auto& biquad_filter = in_params.biquad_filter[i];
  391. // Check if biquad filter is actually used
  392. if (!biquad_filter.enabled) {
  393. continue;
  394. }
  395. // Reinitialize our biquad filter state if it was enabled previously
  396. if (!in_params.was_biquad_filter_enabled[i]) {
  397. dsp_state.biquad_filter_state.fill(0);
  398. }
  399. // Generate biquad filter
  400. // GenerateBiquadFilterCommand(mix_buffer_count, biquad_filter,
  401. // dsp_state.biquad_filter_state,
  402. // mix_buffer_count + channel, mix_buffer_count + channel,
  403. // worker_params.sample_count, voice_info.GetInParams().node_id);
  404. }
  405. }
  406. void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buffer_id,
  407. const BiquadFilterParameter& params,
  408. std::array<s64, 2>& state,
  409. std::size_t input_offset,
  410. std::size_t output_offset, s32 sample_count,
  411. s32 node_id) {
  412. if (dumping_frame) {
  413. LOG_DEBUG(Audio,
  414. "(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, "
  415. "input_mix_buffer={}, output_mix_buffer={}",
  416. node_id, input_offset, output_offset);
  417. }
  418. std::span<const s32> input = GetMixBuffer(input_offset);
  419. std::span<s32> output = GetMixBuffer(output_offset);
  420. // Biquad filter parameters
  421. const auto [n0, n1, n2] = params.numerator;
  422. const auto [d0, d1] = params.denominator;
  423. // Biquad filter states
  424. auto [s0, s1] = state;
  425. constexpr s64 int32_min = std::numeric_limits<s32>::min();
  426. constexpr s64 int32_max = std::numeric_limits<s32>::max();
  427. for (int i = 0; i < sample_count; ++i) {
  428. const auto sample = static_cast<s64>(input[i]);
  429. const auto f = (sample * n0 + s0 + 0x4000) >> 15;
  430. const auto y = std::clamp(f, int32_min, int32_max);
  431. s0 = sample * n1 + y * d0 + s1;
  432. s1 = sample * n2 + y * d1;
  433. output[i] = static_cast<s32>(y);
  434. }
  435. state = {s0, s1};
  436. }
  437. void CommandGenerator::GenerateDepopPrepareCommand(VoiceState& dsp_state,
  438. std::size_t mix_buffer_count,
  439. std::size_t mix_buffer_offset) {
  440. for (std::size_t i = 0; i < mix_buffer_count; i++) {
  441. auto& sample = dsp_state.previous_samples[i];
  442. if (sample != 0) {
  443. depop_buffer[mix_buffer_offset + i] += sample;
  444. sample = 0;
  445. }
  446. }
  447. }
  448. void CommandGenerator::GenerateDepopForMixBuffersCommand(std::size_t mix_buffer_count,
  449. std::size_t mix_buffer_offset,
  450. s32 sample_rate) {
  451. const std::size_t end_offset =
  452. std::min(mix_buffer_offset + mix_buffer_count, GetTotalMixBufferCount());
  453. const s32 delta = sample_rate == 48000 ? 0x7B29 : 0x78CB;
  454. for (std::size_t i = mix_buffer_offset; i < end_offset; i++) {
  455. if (depop_buffer[i] == 0) {
  456. continue;
  457. }
  458. depop_buffer[i] =
  459. ApplyMixDepop(GetMixBuffer(i), depop_buffer[i], delta, worker_params.sample_count);
  460. }
  461. }
  462. void CommandGenerator::GenerateEffectCommand(ServerMixInfo& mix_info) {
  463. const std::size_t effect_count = effect_context.GetCount();
  464. const auto buffer_offset = mix_info.GetInParams().buffer_offset;
  465. for (std::size_t i = 0; i < effect_count; i++) {
  466. const auto index = mix_info.GetEffectOrder(i);
  467. if (index == AudioCommon::NO_EFFECT_ORDER) {
  468. break;
  469. }
  470. auto* info = effect_context.GetInfo(index);
  471. const auto type = info->GetType();
  472. // TODO(ogniK): Finish remaining effects
  473. switch (type) {
  474. case EffectType::Aux:
  475. GenerateAuxCommand(buffer_offset, info, info->IsEnabled());
  476. break;
  477. case EffectType::I3dl2Reverb:
  478. GenerateI3dl2ReverbEffectCommand(buffer_offset, info, info->IsEnabled());
  479. break;
  480. case EffectType::BiquadFilter:
  481. GenerateBiquadFilterEffectCommand(buffer_offset, info, info->IsEnabled());
  482. break;
  483. default:
  484. break;
  485. }
  486. info->UpdateForCommandGeneration();
  487. }
  488. }
  489. void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, EffectBase* info,
  490. bool enabled) {
  491. auto* reverb = dynamic_cast<EffectI3dl2Reverb*>(info);
  492. const auto& params = reverb->GetParams();
  493. auto& state = reverb->GetState();
  494. const auto channel_count = params.channel_count;
  495. if (channel_count != 1 && channel_count != 2 && channel_count != 4 && channel_count != 6) {
  496. return;
  497. }
  498. std::array<std::span<const s32>, AudioCommon::MAX_CHANNEL_COUNT> input{};
  499. std::array<std::span<s32>, AudioCommon::MAX_CHANNEL_COUNT> output{};
  500. const auto status = params.status;
  501. for (s32 i = 0; i < channel_count; i++) {
  502. input[i] = GetMixBuffer(mix_buffer_offset + params.input[i]);
  503. output[i] = GetMixBuffer(mix_buffer_offset + params.output[i]);
  504. }
  505. if (enabled) {
  506. if (status == ParameterStatus::Initialized) {
  507. InitializeI3dl2Reverb(reverb->GetParams(), state, info->GetWorkBuffer());
  508. } else if (status == ParameterStatus::Updating) {
  509. UpdateI3dl2Reverb(reverb->GetParams(), state, false);
  510. }
  511. }
  512. if (enabled) {
  513. switch (channel_count) {
  514. case 1:
  515. ApplyReverbGeneric<1>(state, input, output, worker_params.sample_count);
  516. break;
  517. case 2:
  518. ApplyReverbGeneric<2>(state, input, output, worker_params.sample_count);
  519. break;
  520. case 4:
  521. ApplyReverbGeneric<4>(state, input, output, worker_params.sample_count);
  522. break;
  523. case 6:
  524. ApplyReverbGeneric<6>(state, input, output, worker_params.sample_count);
  525. break;
  526. }
  527. } else {
  528. for (s32 i = 0; i < channel_count; i++) {
  529. // Only copy if the buffer input and output do not match!
  530. if ((mix_buffer_offset + params.input[i]) != (mix_buffer_offset + params.output[i])) {
  531. std::memcpy(output[i].data(), input[i].data(),
  532. worker_params.sample_count * sizeof(s32));
  533. }
  534. }
  535. }
  536. }
  537. void CommandGenerator::GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset, EffectBase* info,
  538. bool enabled) {
  539. if (!enabled) {
  540. return;
  541. }
  542. const auto& params = dynamic_cast<EffectBiquadFilter*>(info)->GetParams();
  543. const auto channel_count = params.channel_count;
  544. for (s32 i = 0; i < channel_count; i++) {
  545. // TODO(ogniK): Actually implement biquad filter
  546. if (params.input[i] != params.output[i]) {
  547. std::span<const s32> input = GetMixBuffer(mix_buffer_offset + params.input[i]);
  548. std::span<s32> output = GetMixBuffer(mix_buffer_offset + params.output[i]);
  549. ApplyMix<1>(output, input, 32768, worker_params.sample_count);
  550. }
  551. }
  552. }
  553. void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled) {
  554. auto* aux = dynamic_cast<EffectAuxInfo*>(info);
  555. const auto& params = aux->GetParams();
  556. if (aux->GetSendBuffer() != 0 && aux->GetRecvBuffer() != 0) {
  557. const auto max_channels = params.count;
  558. u32 offset{};
  559. for (u32 channel = 0; channel < max_channels; channel++) {
  560. u32 write_count = 0;
  561. if (channel == (max_channels - 1)) {
  562. write_count = offset + worker_params.sample_count;
  563. }
  564. const auto input_index = params.input_mix_buffers[channel] + mix_buffer_offset;
  565. const auto output_index = params.output_mix_buffers[channel] + mix_buffer_offset;
  566. if (enabled) {
  567. AuxInfoDSP send_info{};
  568. AuxInfoDSP recv_info{};
  569. memory.ReadBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP));
  570. memory.ReadBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
  571. WriteAuxBuffer(send_info, aux->GetSendBuffer(), params.sample_count,
  572. GetMixBuffer(input_index), worker_params.sample_count, offset,
  573. write_count);
  574. memory.WriteBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP));
  575. const auto samples_read = ReadAuxBuffer(
  576. recv_info, aux->GetRecvBuffer(), params.sample_count,
  577. GetMixBuffer(output_index), worker_params.sample_count, offset, write_count);
  578. memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
  579. if (samples_read != static_cast<int>(worker_params.sample_count) &&
  580. samples_read <= params.sample_count) {
  581. std::memset(GetMixBuffer(output_index).data(), 0,
  582. params.sample_count - samples_read);
  583. }
  584. } else {
  585. AuxInfoDSP empty{};
  586. memory.WriteBlock(aux->GetSendInfo(), &empty, sizeof(AuxInfoDSP));
  587. memory.WriteBlock(aux->GetRecvInfo(), &empty, sizeof(AuxInfoDSP));
  588. if (output_index != input_index) {
  589. std::memcpy(GetMixBuffer(output_index).data(), GetMixBuffer(input_index).data(),
  590. worker_params.sample_count * sizeof(s32));
  591. }
  592. }
  593. offset += worker_params.sample_count;
  594. }
  595. }
  596. }
  597. ServerSplitterDestinationData* CommandGenerator::GetDestinationData(s32 splitter_id, s32 index) {
  598. if (splitter_id == AudioCommon::NO_SPLITTER) {
  599. return nullptr;
  600. }
  601. return splitter_context.GetDestinationData(splitter_id, index);
  602. }
  603. s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples,
  604. std::span<const s32> data, u32 sample_count, u32 write_offset,
  605. u32 write_count) {
  606. if (max_samples == 0) {
  607. return 0;
  608. }
  609. u32 offset = dsp_info.write_offset + write_offset;
  610. if (send_buffer == 0 || offset > max_samples) {
  611. return 0;
  612. }
  613. s32 data_offset{};
  614. u32 remaining = sample_count;
  615. while (remaining > 0) {
  616. // Get position in buffer
  617. const auto base = send_buffer + (offset * sizeof(u32));
  618. const auto samples_to_grab = std::min(max_samples - offset, remaining);
  619. // Write to output
  620. memory.WriteBlock(base, (data.data() + data_offset), samples_to_grab * sizeof(u32));
  621. offset = (offset + samples_to_grab) % max_samples;
  622. remaining -= samples_to_grab;
  623. data_offset += samples_to_grab;
  624. }
  625. if (write_count != 0) {
  626. dsp_info.write_offset = (dsp_info.write_offset + write_count) % max_samples;
  627. }
  628. return sample_count;
  629. }
  630. s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u32 max_samples,
  631. std::span<s32> out_data, u32 sample_count, u32 read_offset,
  632. u32 read_count) {
  633. if (max_samples == 0) {
  634. return 0;
  635. }
  636. u32 offset = recv_info.read_offset + read_offset;
  637. if (recv_buffer == 0 || offset > max_samples) {
  638. return 0;
  639. }
  640. u32 remaining = sample_count;
  641. s32 data_offset{};
  642. while (remaining > 0) {
  643. const auto base = recv_buffer + (offset * sizeof(u32));
  644. const auto samples_to_grab = std::min(max_samples - offset, remaining);
  645. std::vector<s32> buffer(samples_to_grab);
  646. memory.ReadBlock(base, buffer.data(), buffer.size() * sizeof(u32));
  647. std::memcpy(out_data.data() + data_offset, buffer.data(), buffer.size() * sizeof(u32));
  648. offset = (offset + samples_to_grab) % max_samples;
  649. remaining -= samples_to_grab;
  650. data_offset += samples_to_grab;
  651. }
  652. if (read_count != 0) {
  653. recv_info.read_offset = (recv_info.read_offset + read_count) % max_samples;
  654. }
  655. return sample_count;
  656. }
  657. void CommandGenerator::InitializeI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbState& state,
  658. std::vector<u8>& work_buffer) {
  659. // Reset state
  660. state.lowpass_0 = 0.0f;
  661. state.lowpass_1 = 0.0f;
  662. state.lowpass_2 = 0.0f;
  663. state.early_delay_line.Reset();
  664. state.early_tap_steps.fill(0);
  665. state.early_gain = 0.0f;
  666. state.late_gain = 0.0f;
  667. state.early_to_late_taps = 0;
  668. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT; i++) {
  669. state.fdn_delay_line[i].Reset();
  670. state.decay_delay_line0[i].Reset();
  671. state.decay_delay_line1[i].Reset();
  672. }
  673. state.last_reverb_echo = 0.0f;
  674. state.center_delay_line.Reset();
  675. for (auto& coef : state.lpf_coefficients) {
  676. coef.fill(0.0f);
  677. }
  678. state.shelf_filter.fill(0.0f);
  679. state.dry_gain = 0.0f;
  680. const auto sample_rate = info.sample_rate / 1000;
  681. f32* work_buffer_ptr = reinterpret_cast<f32*>(work_buffer.data());
  682. s32 delay_samples{};
  683. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT; i++) {
  684. delay_samples =
  685. AudioCommon::CalculateDelaySamples(sample_rate, FDN_MAX_DELAY_LINE_TIMES[i]);
  686. state.fdn_delay_line[i].Initialize(delay_samples, work_buffer_ptr);
  687. work_buffer_ptr += delay_samples + 1;
  688. delay_samples =
  689. AudioCommon::CalculateDelaySamples(sample_rate, DECAY0_MAX_DELAY_LINE_TIMES[i]);
  690. state.decay_delay_line0[i].Initialize(delay_samples, 0.0f, work_buffer_ptr);
  691. work_buffer_ptr += delay_samples + 1;
  692. delay_samples =
  693. AudioCommon::CalculateDelaySamples(sample_rate, DECAY1_MAX_DELAY_LINE_TIMES[i]);
  694. state.decay_delay_line1[i].Initialize(delay_samples, 0.0f, work_buffer_ptr);
  695. work_buffer_ptr += delay_samples + 1;
  696. }
  697. delay_samples = AudioCommon::CalculateDelaySamples(sample_rate, 5.0f);
  698. state.center_delay_line.Initialize(delay_samples, work_buffer_ptr);
  699. work_buffer_ptr += delay_samples + 1;
  700. delay_samples = AudioCommon::CalculateDelaySamples(sample_rate, 400.0f);
  701. state.early_delay_line.Initialize(delay_samples, work_buffer_ptr);
  702. UpdateI3dl2Reverb(info, state, true);
  703. }
  704. void CommandGenerator::UpdateI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbState& state,
  705. bool should_clear) {
  706. state.dry_gain = info.dry_gain;
  707. state.shelf_filter.fill(0.0f);
  708. state.lowpass_0 = 0.0f;
  709. state.early_gain = Pow10(std::min(info.room + info.reflection, 5000.0f) / 2000.0f);
  710. state.late_gain = Pow10(std::min(info.room + info.reverb, 5000.0f) / 2000.0f);
  711. const auto sample_rate = info.sample_rate / 1000;
  712. const f32 hf_gain = Pow10(info.room_hf / 2000.0f);
  713. if (hf_gain >= 1.0f) {
  714. state.lowpass_2 = 1.0f;
  715. state.lowpass_1 = 0.0f;
  716. } else {
  717. const auto a = 1.0f - hf_gain;
  718. const auto b = 2.0f * (2.0f - hf_gain * CosD(256.0f * info.hf_reference /
  719. static_cast<f32>(info.sample_rate)));
  720. const auto c = std::sqrt(b * b - 4.0f * a * a);
  721. state.lowpass_1 = (b - c) / (2.0f * a);
  722. state.lowpass_2 = 1.0f - state.lowpass_1;
  723. }
  724. state.early_to_late_taps = AudioCommon::CalculateDelaySamples(
  725. sample_rate, 1000.0f * (info.reflection_delay + info.reverb_delay));
  726. state.last_reverb_echo = 0.6f * info.diffusion * 0.01f;
  727. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT; i++) {
  728. const auto length =
  729. FDN_MIN_DELAY_LINE_TIMES[i] +
  730. (info.density / 100.0f) * (FDN_MAX_DELAY_LINE_TIMES[i] - FDN_MIN_DELAY_LINE_TIMES[i]);
  731. state.fdn_delay_line[i].SetDelay(AudioCommon::CalculateDelaySamples(sample_rate, length));
  732. const auto delay_sample_counts = state.fdn_delay_line[i].GetDelay() +
  733. state.decay_delay_line0[i].GetDelay() +
  734. state.decay_delay_line1[i].GetDelay();
  735. float a = (-60.0f * static_cast<f32>(delay_sample_counts)) /
  736. (info.decay_time * static_cast<f32>(info.sample_rate));
  737. float b = a / info.hf_decay_ratio;
  738. float c = CosD(128.0f * 0.5f * info.hf_reference / static_cast<f32>(info.sample_rate)) /
  739. SinD(128.0f * 0.5f * info.hf_reference / static_cast<f32>(info.sample_rate));
  740. float d = Pow10((b - a) / 40.0f);
  741. float e = Pow10((b + a) / 40.0f) * 0.7071f;
  742. state.lpf_coefficients[0][i] = e * ((d * c) + 1.0f) / (c + d);
  743. state.lpf_coefficients[1][i] = e * (1.0f - (d * c)) / (c + d);
  744. state.lpf_coefficients[2][i] = (c - d) / (c + d);
  745. state.decay_delay_line0[i].SetCoefficient(state.last_reverb_echo);
  746. state.decay_delay_line1[i].SetCoefficient(-0.9f * state.last_reverb_echo);
  747. }
  748. if (should_clear) {
  749. for (std::size_t i = 0; i < AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT; i++) {
  750. state.fdn_delay_line[i].Clear();
  751. state.decay_delay_line0[i].Clear();
  752. state.decay_delay_line1[i].Clear();
  753. }
  754. state.early_delay_line.Clear();
  755. state.center_delay_line.Clear();
  756. }
  757. const auto max_early_delay = state.early_delay_line.GetMaxDelay();
  758. const auto reflection_time = 1000.0f * (0.9998f * info.reverb_delay + 0.02f);
  759. for (std::size_t tap = 0; tap < AudioCommon::I3DL2REVERB_TAPS; tap++) {
  760. const auto length = AudioCommon::CalculateDelaySamples(
  761. sample_rate, 1000.0f * info.reflection_delay + reflection_time * EARLY_TAP_TIMES[tap]);
  762. state.early_tap_steps[tap] = std::min(length, max_early_delay);
  763. }
  764. }
  765. void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float current_volume,
  766. s32 channel, s32 node_id) {
  767. const auto last = static_cast<s32>(last_volume * 32768.0f);
  768. const auto current = static_cast<s32>(current_volume * 32768.0f);
  769. const auto delta = static_cast<s32>((static_cast<float>(current) - static_cast<float>(last)) /
  770. static_cast<float>(worker_params.sample_count));
  771. if (dumping_frame) {
  772. LOG_DEBUG(Audio,
  773. "(DSP_TRACE) GenerateVolumeRampCommand node_id={}, input={}, output={}, "
  774. "last_volume={}, current_volume={}",
  775. node_id, GetMixChannelBufferOffset(channel), GetMixChannelBufferOffset(channel),
  776. last_volume, current_volume);
  777. }
  778. // Apply generic gain on samples
  779. ApplyGain(GetChannelMixBuffer(channel), GetChannelMixBuffer(channel), last, delta,
  780. worker_params.sample_count);
  781. }
  782. void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes,
  783. const MixVolumeBuffer& last_mix_volumes,
  784. VoiceState& dsp_state, s32 mix_buffer_offset,
  785. s32 mix_buffer_count, s32 voice_index, s32 node_id) {
  786. // Loop all our mix buffers
  787. for (s32 i = 0; i < mix_buffer_count; i++) {
  788. if (last_mix_volumes[i] != 0.0f || mix_volumes[i] != 0.0f) {
  789. const auto delta = static_cast<float>((mix_volumes[i] - last_mix_volumes[i])) /
  790. static_cast<float>(worker_params.sample_count);
  791. if (dumping_frame) {
  792. LOG_DEBUG(Audio,
  793. "(DSP_TRACE) GenerateVoiceMixCommand node_id={}, input={}, "
  794. "output={}, last_volume={}, current_volume={}",
  795. node_id, voice_index, mix_buffer_offset + i, last_mix_volumes[i],
  796. mix_volumes[i]);
  797. }
  798. dsp_state.previous_samples[i] =
  799. ApplyMixRamp(GetMixBuffer(mix_buffer_offset + i), GetMixBuffer(voice_index),
  800. last_mix_volumes[i], delta, worker_params.sample_count);
  801. } else {
  802. dsp_state.previous_samples[i] = 0;
  803. }
  804. }
  805. }
  806. void CommandGenerator::GenerateSubMixCommand(ServerMixInfo& mix_info) {
  807. if (dumping_frame) {
  808. LOG_DEBUG(Audio, "(DSP_TRACE) GenerateSubMixCommand");
  809. }
  810. const auto& in_params = mix_info.GetInParams();
  811. GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset,
  812. in_params.sample_rate);
  813. GenerateEffectCommand(mix_info);
  814. GenerateMixCommands(mix_info);
  815. }
  816. void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) {
  817. if (!mix_info.HasAnyConnection()) {
  818. return;
  819. }
  820. const auto& in_params = mix_info.GetInParams();
  821. if (in_params.dest_mix_id != AudioCommon::NO_MIX) {
  822. const auto& dest_mix = mix_context.GetInfo(in_params.dest_mix_id);
  823. const auto& dest_in_params = dest_mix.GetInParams();
  824. const auto buffer_count = in_params.buffer_count;
  825. for (s32 i = 0; i < buffer_count; i++) {
  826. for (s32 j = 0; j < dest_in_params.buffer_count; j++) {
  827. const auto mixed_volume = in_params.volume * in_params.mix_volume[i][j];
  828. if (mixed_volume != 0.0f) {
  829. GenerateMixCommand(dest_in_params.buffer_offset + j,
  830. in_params.buffer_offset + i, mixed_volume,
  831. in_params.node_id);
  832. }
  833. }
  834. }
  835. } else if (in_params.splitter_id != AudioCommon::NO_SPLITTER) {
  836. s32 base{};
  837. while (const auto* destination_data = GetDestinationData(in_params.splitter_id, base++)) {
  838. if (!destination_data->IsConfigured()) {
  839. continue;
  840. }
  841. const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId());
  842. const auto& dest_in_params = dest_mix.GetInParams();
  843. const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset;
  844. for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count);
  845. i++) {
  846. const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i);
  847. if (mixed_volume != 0.0f) {
  848. GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume,
  849. in_params.node_id);
  850. }
  851. }
  852. }
  853. }
  854. }
  855. void CommandGenerator::GenerateMixCommand(std::size_t output_offset, std::size_t input_offset,
  856. float volume, s32 node_id) {
  857. if (dumping_frame) {
  858. LOG_DEBUG(Audio,
  859. "(DSP_TRACE) GenerateMixCommand node_id={}, input={}, output={}, volume={}",
  860. node_id, input_offset, output_offset, volume);
  861. }
  862. std::span<s32> output = GetMixBuffer(output_offset);
  863. std::span<const s32> input = GetMixBuffer(input_offset);
  864. const s32 gain = static_cast<s32>(volume * 32768.0f);
  865. // Mix with loop unrolling
  866. if (worker_params.sample_count % 4 == 0) {
  867. ApplyMix<4>(output, input, gain, worker_params.sample_count);
  868. } else if (worker_params.sample_count % 2 == 0) {
  869. ApplyMix<2>(output, input, gain, worker_params.sample_count);
  870. } else {
  871. ApplyMix<1>(output, input, gain, worker_params.sample_count);
  872. }
  873. }
  874. void CommandGenerator::GenerateFinalMixCommand() {
  875. if (dumping_frame) {
  876. LOG_DEBUG(Audio, "(DSP_TRACE) GenerateFinalMixCommand");
  877. }
  878. auto& mix_info = mix_context.GetFinalMixInfo();
  879. const auto& in_params = mix_info.GetInParams();
  880. GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset,
  881. in_params.sample_rate);
  882. GenerateEffectCommand(mix_info);
  883. for (s32 i = 0; i < in_params.buffer_count; i++) {
  884. const s32 gain = static_cast<s32>(in_params.volume * 32768.0f);
  885. if (dumping_frame) {
  886. LOG_DEBUG(
  887. Audio,
  888. "(DSP_TRACE) ApplyGainWithoutDelta node_id={}, input={}, output={}, volume={}",
  889. in_params.node_id, in_params.buffer_offset + i, in_params.buffer_offset + i,
  890. in_params.volume);
  891. }
  892. ApplyGainWithoutDelta(GetMixBuffer(in_params.buffer_offset + i),
  893. GetMixBuffer(in_params.buffer_offset + i), gain,
  894. worker_params.sample_count);
  895. }
  896. }
  897. template <typename T>
  898. s32 CommandGenerator::DecodePcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
  899. s32 sample_start_offset, s32 sample_end_offset, s32 sample_count,
  900. s32 channel, std::size_t mix_offset) {
  901. const auto& in_params = voice_info.GetInParams();
  902. const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
  903. if (wave_buffer.buffer_address == 0) {
  904. return 0;
  905. }
  906. if (wave_buffer.buffer_size == 0) {
  907. return 0;
  908. }
  909. if (sample_end_offset < sample_start_offset) {
  910. return 0;
  911. }
  912. const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset;
  913. const auto start_offset =
  914. ((dsp_state.offset + sample_start_offset) * in_params.channel_count) * sizeof(T);
  915. const auto buffer_pos = wave_buffer.buffer_address + start_offset;
  916. const auto samples_processed = std::min(sample_count, samples_remaining);
  917. const auto channel_count = in_params.channel_count;
  918. std::vector<T> buffer(samples_processed * channel_count);
  919. memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(T));
  920. if constexpr (std::is_floating_point_v<T>) {
  921. for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
  922. sample_buffer[mix_offset + i] = static_cast<s32>(buffer[i * channel_count + channel] *
  923. std::numeric_limits<s16>::max());
  924. }
  925. } else if constexpr (sizeof(T) == 1) {
  926. for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
  927. sample_buffer[mix_offset + i] =
  928. static_cast<s32>(static_cast<f32>(buffer[i * channel_count + channel] /
  929. std::numeric_limits<s8>::max()) *
  930. std::numeric_limits<s16>::max());
  931. }
  932. } else if constexpr (sizeof(T) == 2) {
  933. for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
  934. sample_buffer[mix_offset + i] = buffer[i * channel_count + channel];
  935. }
  936. } else {
  937. for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
  938. sample_buffer[mix_offset + i] =
  939. static_cast<s32>(static_cast<f32>(buffer[i * channel_count + channel] /
  940. std::numeric_limits<s32>::max()) *
  941. std::numeric_limits<s16>::max());
  942. }
  943. }
  944. return samples_processed;
  945. }
  946. s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
  947. s32 sample_start_offset, s32 sample_end_offset, s32 sample_count,
  948. [[maybe_unused]] s32 channel, std::size_t mix_offset) {
  949. const auto& in_params = voice_info.GetInParams();
  950. const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
  951. if (wave_buffer.buffer_address == 0) {
  952. return 0;
  953. }
  954. if (wave_buffer.buffer_size == 0) {
  955. return 0;
  956. }
  957. if (sample_end_offset < sample_start_offset) {
  958. return 0;
  959. }
  960. static constexpr std::array<int, 16> SIGNED_NIBBLES{
  961. 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
  962. };
  963. constexpr std::size_t FRAME_LEN = 8;
  964. constexpr std::size_t NIBBLES_PER_SAMPLE = 16;
  965. constexpr std::size_t SAMPLES_PER_FRAME = 14;
  966. auto frame_header = dsp_state.context.header;
  967. s32 idx = (frame_header >> 4) & 0xf;
  968. s32 scale = frame_header & 0xf;
  969. s16 yn1 = dsp_state.context.yn1;
  970. s16 yn2 = dsp_state.context.yn2;
  971. Codec::ADPCM_Coeff coeffs;
  972. memory.ReadBlock(in_params.additional_params_address, coeffs.data(),
  973. sizeof(Codec::ADPCM_Coeff));
  974. s32 coef1 = coeffs[idx * 2];
  975. s32 coef2 = coeffs[idx * 2 + 1];
  976. const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset;
  977. const auto samples_processed = std::min(sample_count, samples_remaining);
  978. const auto sample_pos = dsp_state.offset + sample_start_offset;
  979. const auto samples_remaining_in_frame = sample_pos % SAMPLES_PER_FRAME;
  980. auto position_in_frame = ((sample_pos / SAMPLES_PER_FRAME) * NIBBLES_PER_SAMPLE) +
  981. samples_remaining_in_frame + (samples_remaining_in_frame != 0 ? 2 : 0);
  982. const auto decode_sample = [&](const int nibble) -> s16 {
  983. const int xn = nibble * (1 << scale);
  984. // We first transform everything into 11 bit fixed point, perform the second order
  985. // digital filter, then transform back.
  986. // 0x400 == 0.5 in 11 bit fixed point.
  987. // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2]
  988. int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11;
  989. // Clamp to output range.
  990. val = std::clamp<s32>(val, -32768, 32767);
  991. // Advance output feedback.
  992. yn2 = yn1;
  993. yn1 = static_cast<s16>(val);
  994. return yn1;
  995. };
  996. std::size_t buffer_offset{};
  997. std::vector<u8> buffer(
  998. std::max((samples_processed / FRAME_LEN) * SAMPLES_PER_FRAME, FRAME_LEN));
  999. memory.ReadBlock(wave_buffer.buffer_address + (position_in_frame / 2), buffer.data(),
  1000. buffer.size());
  1001. std::size_t cur_mix_offset = mix_offset;
  1002. auto remaining_samples = samples_processed;
  1003. while (remaining_samples > 0) {
  1004. if (position_in_frame % NIBBLES_PER_SAMPLE == 0) {
  1005. // Read header
  1006. frame_header = buffer[buffer_offset++];
  1007. idx = (frame_header >> 4) & 0xf;
  1008. scale = frame_header & 0xf;
  1009. coef1 = coeffs[idx * 2];
  1010. coef2 = coeffs[idx * 2 + 1];
  1011. position_in_frame += 2;
  1012. // Decode entire frame
  1013. if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) {
  1014. for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
  1015. // Sample 1
  1016. const s32 s0 = SIGNED_NIBBLES[buffer[buffer_offset] >> 4];
  1017. const s32 s1 = SIGNED_NIBBLES[buffer[buffer_offset++] & 0xf];
  1018. const s16 sample_1 = decode_sample(s0);
  1019. const s16 sample_2 = decode_sample(s1);
  1020. sample_buffer[cur_mix_offset++] = sample_1;
  1021. sample_buffer[cur_mix_offset++] = sample_2;
  1022. }
  1023. remaining_samples -= static_cast<int>(SAMPLES_PER_FRAME);
  1024. position_in_frame += SAMPLES_PER_FRAME;
  1025. continue;
  1026. }
  1027. }
  1028. // Decode mid frame
  1029. s32 current_nibble = buffer[buffer_offset];
  1030. if (position_in_frame++ & 0x1) {
  1031. current_nibble &= 0xf;
  1032. buffer_offset++;
  1033. } else {
  1034. current_nibble >>= 4;
  1035. }
  1036. const s16 sample = decode_sample(SIGNED_NIBBLES[current_nibble]);
  1037. sample_buffer[cur_mix_offset++] = sample;
  1038. remaining_samples--;
  1039. }
  1040. dsp_state.context.header = frame_header;
  1041. dsp_state.context.yn1 = yn1;
  1042. dsp_state.context.yn2 = yn2;
  1043. return samples_processed;
  1044. }
  1045. std::span<s32> CommandGenerator::GetMixBuffer(std::size_t index) {
  1046. return std::span<s32>(mix_buffer.data() + (index * worker_params.sample_count),
  1047. worker_params.sample_count);
  1048. }
  1049. std::span<const s32> CommandGenerator::GetMixBuffer(std::size_t index) const {
  1050. return std::span<const s32>(mix_buffer.data() + (index * worker_params.sample_count),
  1051. worker_params.sample_count);
  1052. }
  1053. std::size_t CommandGenerator::GetMixChannelBufferOffset(s32 channel) const {
  1054. return worker_params.mix_buffer_count + channel;
  1055. }
  1056. std::size_t CommandGenerator::GetTotalMixBufferCount() const {
  1057. return worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT;
  1058. }
  1059. std::span<s32> CommandGenerator::GetChannelMixBuffer(s32 channel) {
  1060. return GetMixBuffer(worker_params.mix_buffer_count + channel);
  1061. }
  1062. std::span<const s32> CommandGenerator::GetChannelMixBuffer(s32 channel) const {
  1063. return GetMixBuffer(worker_params.mix_buffer_count + channel);
  1064. }
  1065. void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, std::span<s32> output,
  1066. VoiceState& dsp_state, s32 channel,
  1067. s32 target_sample_rate, s32 sample_count,
  1068. s32 node_id) {
  1069. const auto& in_params = voice_info.GetInParams();
  1070. if (dumping_frame) {
  1071. LOG_DEBUG(Audio,
  1072. "(DSP_TRACE) DecodeFromWaveBuffers, node_id={}, channel={}, "
  1073. "format={}, sample_count={}, sample_rate={}, mix_id={}, splitter_id={}",
  1074. node_id, channel, in_params.sample_format, sample_count, in_params.sample_rate,
  1075. in_params.mix_id, in_params.splitter_info_id);
  1076. }
  1077. ASSERT_OR_EXECUTE(output.data() != nullptr, { return; });
  1078. const auto resample_rate = static_cast<s32>(
  1079. static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) *
  1080. static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f)));
  1081. if (dsp_state.fraction + sample_count * resample_rate >
  1082. static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) {
  1083. return;
  1084. }
  1085. auto min_required_samples =
  1086. std::min(static_cast<s32>(SCALED_MIX_BUFFER_SIZE) - dsp_state.fraction, resample_rate);
  1087. if (min_required_samples >= sample_count) {
  1088. min_required_samples = sample_count;
  1089. }
  1090. std::size_t temp_mix_offset{};
  1091. s32 samples_output{};
  1092. auto samples_remaining = sample_count;
  1093. while (samples_remaining > 0) {
  1094. const auto samples_to_output = std::min(samples_remaining, min_required_samples);
  1095. const auto samples_to_read = (samples_to_output * resample_rate + dsp_state.fraction) >> 15;
  1096. if (!in_params.behavior_flags.is_pitch_and_src_skipped) {
  1097. // Append sample histtory for resampler
  1098. for (std::size_t i = 0; i < AudioCommon::MAX_SAMPLE_HISTORY; i++) {
  1099. sample_buffer[temp_mix_offset + i] = dsp_state.sample_history[i];
  1100. }
  1101. temp_mix_offset += 4;
  1102. }
  1103. s32 samples_read{};
  1104. while (samples_read < samples_to_read) {
  1105. const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
  1106. // No more data can be read
  1107. if (!dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index]) {
  1108. break;
  1109. }
  1110. if (in_params.sample_format == SampleFormat::Adpcm && dsp_state.offset == 0 &&
  1111. wave_buffer.context_address != 0 && wave_buffer.context_size != 0) {
  1112. memory.ReadBlock(wave_buffer.context_address, &dsp_state.context,
  1113. sizeof(ADPCMContext));
  1114. }
  1115. s32 samples_offset_start;
  1116. s32 samples_offset_end;
  1117. if (dsp_state.loop_count > 0 && wave_buffer.loop_start_sample != 0 &&
  1118. wave_buffer.loop_end_sample != 0 &&
  1119. wave_buffer.loop_start_sample <= wave_buffer.loop_end_sample) {
  1120. samples_offset_start = wave_buffer.loop_start_sample;
  1121. samples_offset_end = wave_buffer.loop_end_sample;
  1122. } else {
  1123. samples_offset_start = wave_buffer.start_sample_offset;
  1124. samples_offset_end = wave_buffer.end_sample_offset;
  1125. }
  1126. s32 samples_decoded{0};
  1127. switch (in_params.sample_format) {
  1128. case SampleFormat::Pcm8:
  1129. samples_decoded =
  1130. DecodePcm<s8>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
  1131. samples_to_read - samples_read, channel, temp_mix_offset);
  1132. break;
  1133. case SampleFormat::Pcm16:
  1134. samples_decoded =
  1135. DecodePcm<s16>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
  1136. samples_to_read - samples_read, channel, temp_mix_offset);
  1137. break;
  1138. case SampleFormat::Pcm32:
  1139. samples_decoded =
  1140. DecodePcm<s32>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
  1141. samples_to_read - samples_read, channel, temp_mix_offset);
  1142. break;
  1143. case SampleFormat::PcmFloat:
  1144. samples_decoded =
  1145. DecodePcm<f32>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
  1146. samples_to_read - samples_read, channel, temp_mix_offset);
  1147. break;
  1148. case SampleFormat::Adpcm:
  1149. samples_decoded =
  1150. DecodeAdpcm(voice_info, dsp_state, samples_offset_start, samples_offset_end,
  1151. samples_to_read - samples_read, channel, temp_mix_offset);
  1152. break;
  1153. default:
  1154. ASSERT_MSG(false, "Unimplemented sample format={}", in_params.sample_format);
  1155. }
  1156. temp_mix_offset += samples_decoded;
  1157. samples_read += samples_decoded;
  1158. dsp_state.offset += samples_decoded;
  1159. dsp_state.played_sample_count += samples_decoded;
  1160. if (dsp_state.offset >= (samples_offset_end - samples_offset_start) ||
  1161. samples_decoded == 0) {
  1162. // Reset our sample offset
  1163. dsp_state.offset = 0;
  1164. if (wave_buffer.is_looping) {
  1165. dsp_state.loop_count++;
  1166. if (wave_buffer.loop_count > 0 &&
  1167. (dsp_state.loop_count > wave_buffer.loop_count || samples_decoded == 0)) {
  1168. // End of our buffer
  1169. voice_info.SetWaveBufferCompleted(dsp_state, wave_buffer);
  1170. }
  1171. if (samples_decoded == 0) {
  1172. break;
  1173. }
  1174. if (in_params.behavior_flags.is_played_samples_reset_at_loop_point.Value()) {
  1175. dsp_state.played_sample_count = 0;
  1176. }
  1177. } else {
  1178. // Update our wave buffer states
  1179. voice_info.SetWaveBufferCompleted(dsp_state, wave_buffer);
  1180. }
  1181. }
  1182. }
  1183. if (in_params.behavior_flags.is_pitch_and_src_skipped.Value()) {
  1184. // No need to resample
  1185. std::memcpy(output.data() + samples_output, sample_buffer.data(),
  1186. samples_read * sizeof(s32));
  1187. } else {
  1188. std::fill(sample_buffer.begin() + temp_mix_offset,
  1189. sample_buffer.begin() + temp_mix_offset + (samples_to_read - samples_read),
  1190. 0);
  1191. AudioCore::Resample(output.data() + samples_output, sample_buffer.data(), resample_rate,
  1192. dsp_state.fraction, samples_to_output);
  1193. // Resample
  1194. for (std::size_t i = 0; i < AudioCommon::MAX_SAMPLE_HISTORY; i++) {
  1195. dsp_state.sample_history[i] = sample_buffer[samples_to_read + i];
  1196. }
  1197. }
  1198. samples_remaining -= samples_to_output;
  1199. samples_output += samples_to_output;
  1200. }
  1201. }
  1202. } // namespace AudioCore