command_generator.cpp 58 KB

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