CommandProcessingTimeEstimatorVersion3.cs 24 KB

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