source.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2016 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <queue>
  7. #include <vector>
  8. #include "audio_core/codec.h"
  9. #include "audio_core/hle/common.h"
  10. #include "audio_core/hle/dsp.h"
  11. #include "audio_core/hle/filter.h"
  12. #include "audio_core/interpolate.h"
  13. #include "common/common_types.h"
  14. namespace DSP {
  15. namespace HLE {
  16. /**
  17. * This module performs:
  18. * - Buffer management
  19. * - Decoding of buffers
  20. * - Buffer resampling and interpolation
  21. * - Per-source filtering (SimpleFilter, BiquadFilter)
  22. * - Per-source gain
  23. * - Other per-source processing
  24. */
  25. class Source final {
  26. public:
  27. explicit Source(size_t source_id_) : source_id(source_id_) {
  28. Reset();
  29. }
  30. /// Resets internal state.
  31. void Reset();
  32. /**
  33. * This is called once every audio frame. This performs per-source processing every frame.
  34. * @param config The new configuration we've got for this Source from the application.
  35. * @param adpcm_coeffs ADPCM coefficients to use if config tells us to use them (may contain
  36. * invalid values otherwise).
  37. * @return The current status of this Source. This is given back to the emulated application via
  38. * SharedMemory.
  39. */
  40. SourceStatus::Status Tick(SourceConfiguration::Configuration& config,
  41. const s16_le (&adpcm_coeffs)[16]);
  42. /**
  43. * Mix this source's output into dest, using the gains for the `intermediate_mix_id`-th
  44. * intermediate mixer.
  45. * @param dest The QuadFrame32 to mix into.
  46. * @param intermediate_mix_id The id of the intermediate mix whose gains we are using.
  47. */
  48. void MixInto(QuadFrame32& dest, size_t intermediate_mix_id) const;
  49. private:
  50. const size_t source_id;
  51. StereoFrame16 current_frame;
  52. using Format = SourceConfiguration::Configuration::Format;
  53. using InterpolationMode = SourceConfiguration::Configuration::InterpolationMode;
  54. using MonoOrStereo = SourceConfiguration::Configuration::MonoOrStereo;
  55. /// Internal representation of a buffer for our buffer queue
  56. struct Buffer {
  57. PAddr physical_address;
  58. u32 length;
  59. u8 adpcm_ps;
  60. std::array<u16, 2> adpcm_yn;
  61. bool adpcm_dirty;
  62. bool is_looping;
  63. u16 buffer_id;
  64. MonoOrStereo mono_or_stereo;
  65. Format format;
  66. bool from_queue;
  67. u32_dsp play_position; // = 0;
  68. bool has_played; // = false;
  69. };
  70. struct BufferOrder {
  71. bool operator()(const Buffer& a, const Buffer& b) const {
  72. // Lower buffer_id comes first.
  73. return a.buffer_id > b.buffer_id;
  74. }
  75. };
  76. struct {
  77. // State variables
  78. bool enabled = false;
  79. u16 sync = 0;
  80. // Mixing
  81. std::array<std::array<float, 4>, 3> gain = {};
  82. // Buffer queue
  83. std::priority_queue<Buffer, std::vector<Buffer>, BufferOrder> input_queue;
  84. MonoOrStereo mono_or_stereo = MonoOrStereo::Mono;
  85. Format format = Format::ADPCM;
  86. // Current buffer
  87. u32 current_sample_number = 0;
  88. u32 next_sample_number = 0;
  89. AudioInterp::StereoBuffer16 current_buffer;
  90. // buffer_id state
  91. bool buffer_update = false;
  92. u32 current_buffer_id = 0;
  93. // Decoding state
  94. std::array<s16, 16> adpcm_coeffs = {};
  95. Codec::ADPCMState adpcm_state = {};
  96. // Resampling state
  97. float rate_multiplier = 1.0;
  98. InterpolationMode interpolation_mode = InterpolationMode::Polyphase;
  99. AudioInterp::State interp_state = {};
  100. // Filter state
  101. SourceFilters filters;
  102. } state;
  103. // Internal functions
  104. /// INTERNAL: Update our internal state based on the current config.
  105. void ParseConfig(SourceConfiguration::Configuration& config, const s16_le (&adpcm_coeffs)[16]);
  106. /// INTERNAL: Generate the current audio output for this frame based on our internal state.
  107. void GenerateFrame();
  108. /// INTERNAL: Dequeues a buffer and does preprocessing on it (decoding, resampling). Puts it
  109. /// into current_buffer.
  110. bool DequeueBuffer();
  111. /// INTERNAL: Generates a SourceStatus::Status based on our internal state.
  112. SourceStatus::Status GetCurrentStatus();
  113. };
  114. } // namespace HLE
  115. } // namespace DSP