CommandProcessingTimeEstimatorVersion3.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. using Ryujinx.Audio.Common;
  2. using Ryujinx.Audio.Renderer.Dsp.Command;
  3. using Ryujinx.Audio.Renderer.Parameter.Effect;
  4. using System;
  5. using System.Diagnostics;
  6. using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
  7. namespace Ryujinx.Audio.Renderer.Server
  8. {
  9. /// <summary>
  10. /// <see cref="ICommandProcessingTimeEstimator"/> version 3. (added with REV8)
  11. /// </summary>
  12. public class CommandProcessingTimeEstimatorVersion3 : ICommandProcessingTimeEstimator
  13. {
  14. protected uint SampleCount;
  15. protected uint BufferCount;
  16. public CommandProcessingTimeEstimatorVersion3(uint sampleCount, uint bufferCount)
  17. {
  18. SampleCount = sampleCount;
  19. BufferCount = bufferCount;
  20. }
  21. public uint Estimate(PerformanceCommand command)
  22. {
  23. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  24. if (SampleCount == 160)
  25. {
  26. return (uint)498.17f;
  27. }
  28. return (uint)489.42f;
  29. }
  30. public uint Estimate(ClearMixBufferCommand command)
  31. {
  32. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  33. float costPerBuffer = 440.68f;
  34. float baseCost = 0;
  35. if (SampleCount == 160)
  36. {
  37. costPerBuffer = 266.65f;
  38. }
  39. return (uint)(baseCost + costPerBuffer * BufferCount);
  40. }
  41. public uint Estimate(BiquadFilterCommand command)
  42. {
  43. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  44. if (SampleCount == 160)
  45. {
  46. return (uint)4173.2f;
  47. }
  48. return (uint)5585.1f;
  49. }
  50. public uint Estimate(MixRampGroupedCommand command)
  51. {
  52. float costPerSample = 6.4434f;
  53. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  54. if (SampleCount == 160)
  55. {
  56. costPerSample = 6.708f;
  57. }
  58. int volumeCount = 0;
  59. for (int i = 0; i < command.MixBufferCount; i++)
  60. {
  61. if (command.Volume0[i] != 0.0f || command.Volume1[i] != 0.0f)
  62. {
  63. volumeCount++;
  64. }
  65. }
  66. return (uint)(SampleCount * costPerSample * volumeCount);
  67. }
  68. public uint Estimate(MixRampCommand command)
  69. {
  70. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  71. if (SampleCount == 160)
  72. {
  73. return (uint)1968.7f;
  74. }
  75. return (uint)2459.4f;
  76. }
  77. public uint Estimate(DepopPrepareCommand command)
  78. {
  79. return 0;
  80. }
  81. public uint Estimate(VolumeRampCommand command)
  82. {
  83. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  84. if (SampleCount == 160)
  85. {
  86. return (uint)1425.3f;
  87. }
  88. return (uint)1700.0f;
  89. }
  90. public uint Estimate(PcmInt16DataSourceCommandVersion1 command)
  91. {
  92. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  93. float costPerSample = 710.143f;
  94. float baseCost = 7853.286f;
  95. if (SampleCount == 160)
  96. {
  97. costPerSample = 427.52f;
  98. baseCost = 6329.442f;
  99. }
  100. return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f))));
  101. }
  102. public uint Estimate(AdpcmDataSourceCommandVersion1 command)
  103. {
  104. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  105. float costPerSample = 3564.1f;
  106. float baseCost = 9736.702f;
  107. if (SampleCount == 160)
  108. {
  109. costPerSample = 2125.6f;
  110. baseCost = 7913.808f;
  111. }
  112. return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f))));
  113. }
  114. public uint Estimate(DepopForMixBuffersCommand command)
  115. {
  116. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  117. if (SampleCount == 160)
  118. {
  119. return (uint)739.64f;
  120. }
  121. return (uint)910.97f;
  122. }
  123. public uint Estimate(CopyMixBufferCommand command)
  124. {
  125. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  126. if (SampleCount == 160)
  127. {
  128. return (uint)842.59f;
  129. }
  130. return (uint)986.72f;
  131. }
  132. public uint Estimate(MixCommand command)
  133. {
  134. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  135. if (SampleCount == 160)
  136. {
  137. return (uint)1402.8f;
  138. }
  139. return (uint)1853.2f;
  140. }
  141. public virtual uint Estimate(DelayCommand command)
  142. {
  143. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  144. if (SampleCount == 160)
  145. {
  146. if (command.Enabled)
  147. {
  148. return command.Parameter.ChannelCount switch
  149. {
  150. 1 => (uint)8929.04f,
  151. 2 => (uint)25500.75f,
  152. 4 => (uint)47759.62f,
  153. 6 => (uint)82203.07f,
  154. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  155. };
  156. }
  157. return command.Parameter.ChannelCount switch
  158. {
  159. 1 => (uint)1295.20f,
  160. 2 => (uint)1213.60f,
  161. 4 => (uint)942.03f,
  162. 6 => (uint)1001.55f,
  163. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  164. };
  165. }
  166. if (command.Enabled)
  167. {
  168. return command.Parameter.ChannelCount switch
  169. {
  170. 1 => (uint)11941.05f,
  171. 2 => (uint)37197.37f,
  172. 4 => (uint)69749.84f,
  173. 6 => (uint)120042.40f,
  174. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  175. };
  176. }
  177. return command.Parameter.ChannelCount switch
  178. {
  179. 1 => (uint)997.67f,
  180. 2 => (uint)977.63f,
  181. 4 => (uint)792.30f,
  182. 6 => (uint)875.43f,
  183. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  184. };
  185. }
  186. public virtual uint Estimate(ReverbCommand command)
  187. {
  188. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  189. if (SampleCount == 160)
  190. {
  191. if (command.Enabled)
  192. {
  193. return command.Parameter.ChannelCount switch
  194. {
  195. 1 => (uint)81475.05f,
  196. 2 => (uint)84975.0f,
  197. 4 => (uint)91625.15f,
  198. 6 => (uint)95332.27f,
  199. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  200. };
  201. }
  202. return command.Parameter.ChannelCount switch
  203. {
  204. 1 => (uint)536.30f,
  205. 2 => (uint)588.70f,
  206. 4 => (uint)643.70f,
  207. 6 => (uint)706.0f,
  208. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  209. };
  210. }
  211. if (command.Enabled)
  212. {
  213. return command.Parameter.ChannelCount switch
  214. {
  215. 1 => (uint)120174.47f,
  216. 2 => (uint)25262.22f,
  217. 4 => (uint)135751.23f,
  218. 6 => (uint)141129.23f,
  219. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  220. };
  221. }
  222. return command.Parameter.ChannelCount switch
  223. {
  224. 1 => (uint)617.64f,
  225. 2 => (uint)659.54f,
  226. 4 => (uint)711.43f,
  227. 6 => (uint)778.07f,
  228. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  229. };
  230. }
  231. public virtual uint Estimate(Reverb3dCommand command)
  232. {
  233. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  234. if (SampleCount == 160)
  235. {
  236. if (command.Enabled)
  237. {
  238. return command.Parameter.ChannelCount switch
  239. {
  240. 1 => (uint)116754.0f,
  241. 2 => (uint)125912.05f,
  242. 4 => (uint)146336.03f,
  243. 6 => (uint)165812.66f,
  244. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  245. };
  246. }
  247. return command.Parameter.ChannelCount switch
  248. {
  249. 1 => (uint)734.0f,
  250. 2 => (uint)766.62f,
  251. 4 => (uint)797.46f,
  252. 6 => (uint)867.43f,
  253. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  254. };
  255. }
  256. if (command.Enabled)
  257. {
  258. return command.Parameter.ChannelCount switch
  259. {
  260. 1 => (uint)170292.34f,
  261. 2 => (uint)183875.63f,
  262. 4 => (uint)214696.19f,
  263. 6 => (uint)243846.77f,
  264. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  265. };
  266. }
  267. return command.Parameter.ChannelCount switch
  268. {
  269. 1 => (uint)508.47f,
  270. 2 => (uint)582.45f,
  271. 4 => (uint)626.42f,
  272. 6 => (uint)682.47f,
  273. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  274. };
  275. }
  276. public uint Estimate(AuxiliaryBufferCommand command)
  277. {
  278. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  279. if (SampleCount == 160)
  280. {
  281. if (command.Enabled)
  282. {
  283. return (uint)7182.14f;
  284. }
  285. return (uint)472.11f;
  286. }
  287. if (command.Enabled)
  288. {
  289. return (uint)9435.96f;
  290. }
  291. return (uint)462.62f;
  292. }
  293. public uint Estimate(VolumeCommand command)
  294. {
  295. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  296. if (SampleCount == 160)
  297. {
  298. return (uint)1311.1f;
  299. }
  300. return (uint)1713.6f;
  301. }
  302. public uint Estimate(CircularBufferSinkCommand command)
  303. {
  304. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  305. float costPerBuffer = 770.26f;
  306. float baseCost = 0f;
  307. if (SampleCount == 160)
  308. {
  309. costPerBuffer = 531.07f;
  310. }
  311. return (uint)(baseCost + costPerBuffer * command.InputCount);
  312. }
  313. public uint Estimate(DownMixSurroundToStereoCommand command)
  314. {
  315. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  316. if (SampleCount == 160)
  317. {
  318. return (uint)9949.7f;
  319. }
  320. return (uint)14679.0f;
  321. }
  322. public uint Estimate(UpsampleCommand command)
  323. {
  324. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  325. if (SampleCount == 160)
  326. {
  327. return (uint)312990.0f;
  328. }
  329. return (uint)0.0f;
  330. }
  331. public uint Estimate(DeviceSinkCommand command)
  332. {
  333. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  334. Debug.Assert(command.InputCount == 2 || command.InputCount == 6);
  335. if (command.InputCount == 2)
  336. {
  337. if (SampleCount == 160)
  338. {
  339. return (uint)8980.0f;
  340. }
  341. return (uint)9221.9f;
  342. }
  343. if (SampleCount == 160)
  344. {
  345. return (uint)9177.9f;
  346. }
  347. return (uint)9725.9f;
  348. }
  349. public uint Estimate(PcmFloatDataSourceCommandVersion1 command)
  350. {
  351. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  352. float costPerSample = 3490.9f;
  353. float baseCost = 10090.9f;
  354. if (SampleCount == 160)
  355. {
  356. costPerSample = 2310.4f;
  357. baseCost = 7845.25f;
  358. }
  359. return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f))));
  360. }
  361. public uint Estimate(DataSourceVersion2Command command)
  362. {
  363. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  364. (float baseCost, float costPerSample) = GetCostByFormat(SampleCount, command.SampleFormat, command.SrcQuality);
  365. return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / SampleCount) * (command.Pitch * 0.000030518f) - 1.0f)));
  366. }
  367. private static (float, float) GetCostByFormat(uint sampleCount, SampleFormat format, SampleRateConversionQuality quality)
  368. {
  369. Debug.Assert(sampleCount == 160 || sampleCount == 240);
  370. switch (format)
  371. {
  372. case SampleFormat.PcmInt16:
  373. switch (quality)
  374. {
  375. case SampleRateConversionQuality.Default:
  376. if (sampleCount == 160)
  377. {
  378. return (6329.44f, 427.52f);
  379. }
  380. return (7853.28f, 710.14f);
  381. case SampleRateConversionQuality.High:
  382. if (sampleCount == 160)
  383. {
  384. return (8049.42f, 371.88f);
  385. }
  386. return (10138.84f, 610.49f);
  387. case SampleRateConversionQuality.Low:
  388. if (sampleCount == 160)
  389. {
  390. return (5062.66f, 423.43f);
  391. }
  392. return (5810.96f, 676.72f);
  393. default:
  394. throw new NotImplementedException($"{format} {quality}");
  395. }
  396. case SampleFormat.PcmFloat:
  397. switch (quality)
  398. {
  399. case SampleRateConversionQuality.Default:
  400. if (sampleCount == 160)
  401. {
  402. return (7845.25f, 2310.4f);
  403. }
  404. return (10090.9f, 3490.9f);
  405. case SampleRateConversionQuality.High:
  406. if (sampleCount == 160)
  407. {
  408. return (9446.36f, 2308.91f);
  409. }
  410. return (12520.85f, 3480.61f);
  411. case SampleRateConversionQuality.Low:
  412. if (sampleCount == 160)
  413. {
  414. return (9446.36f, 2308.91f);
  415. }
  416. return (12520.85f, 3480.61f);
  417. default:
  418. throw new NotImplementedException($"{format} {quality}");
  419. }
  420. case SampleFormat.Adpcm:
  421. switch (quality)
  422. {
  423. case SampleRateConversionQuality.Default:
  424. if (sampleCount == 160)
  425. {
  426. return (7913.81f, 1827.66f);
  427. }
  428. return (9736.70f, 2756.37f);
  429. case SampleRateConversionQuality.High:
  430. if (sampleCount == 160)
  431. {
  432. return (9607.81f, 1829.29f);
  433. }
  434. return (12154.38f, 2731.31f);
  435. case SampleRateConversionQuality.Low:
  436. if (sampleCount == 160)
  437. {
  438. return (6517.48f, 1824.61f);
  439. }
  440. return (7929.44f, 2732.15f);
  441. default:
  442. throw new NotImplementedException($"{format} {quality}");
  443. }
  444. default:
  445. throw new NotImplementedException($"{format}");
  446. }
  447. }
  448. private uint EstimateLimiterCommandCommon(LimiterParameter parameter, bool enabled)
  449. {
  450. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  451. if (SampleCount == 160)
  452. {
  453. if (enabled)
  454. {
  455. return parameter.ChannelCount switch
  456. {
  457. 1 => (uint)21392.0f,
  458. 2 => (uint)26829.0f,
  459. 4 => (uint)32405.0f,
  460. 6 => (uint)52219.0f,
  461. _ => throw new NotImplementedException($"{parameter.ChannelCount}"),
  462. };
  463. }
  464. return parameter.ChannelCount switch
  465. {
  466. 1 => (uint)897.0f,
  467. 2 => (uint)931.55f,
  468. 4 => (uint)975.39f,
  469. 6 => (uint)1016.8f,
  470. _ => throw new NotImplementedException($"{parameter.ChannelCount}"),
  471. };
  472. }
  473. if (enabled)
  474. {
  475. return parameter.ChannelCount switch
  476. {
  477. 1 => (uint)30556.0f,
  478. 2 => (uint)39011.0f,
  479. 4 => (uint)48270.0f,
  480. 6 => (uint)76712.0f,
  481. _ => throw new NotImplementedException($"{parameter.ChannelCount}"),
  482. };
  483. }
  484. return parameter.ChannelCount switch
  485. {
  486. 1 => (uint)874.43f,
  487. 2 => (uint)921.55f,
  488. 4 => (uint)945.26f,
  489. 6 => (uint)992.26f,
  490. _ => throw new NotImplementedException($"{parameter.ChannelCount}"),
  491. };
  492. }
  493. public uint Estimate(LimiterCommandVersion1 command)
  494. {
  495. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  496. return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled);
  497. }
  498. public uint Estimate(LimiterCommandVersion2 command)
  499. {
  500. Debug.Assert(SampleCount == 160 || SampleCount == 240);
  501. if (!command.Parameter.StatisticsEnabled || !command.IsEffectEnabled)
  502. {
  503. return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled);
  504. }
  505. if (SampleCount == 160)
  506. {
  507. return command.Parameter.ChannelCount switch
  508. {
  509. 1 => (uint)23309.0f,
  510. 2 => (uint)29954.0f,
  511. 4 => (uint)35807.0f,
  512. 6 => (uint)58340.0f,
  513. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  514. };
  515. }
  516. return command.Parameter.ChannelCount switch
  517. {
  518. 1 => (uint)33526.0f,
  519. 2 => (uint)43549.0f,
  520. 4 => (uint)52190.0f,
  521. 6 => (uint)85527.0f,
  522. _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"),
  523. };
  524. }
  525. public virtual uint Estimate(MultiTapBiquadFilterCommand command)
  526. {
  527. return 0;
  528. }
  529. public virtual uint Estimate(CaptureBufferCommand command)
  530. {
  531. return 0;
  532. }
  533. public virtual uint Estimate(CompressorCommand command)
  534. {
  535. return 0;
  536. }
  537. public virtual uint Estimate(BiquadFilterAndMixCommand command)
  538. {
  539. return 0;
  540. }
  541. public virtual uint Estimate(MultiTapBiquadFilterAndMixCommand command)
  542. {
  543. return 0;
  544. }
  545. }
  546. }