SurroundDecoder.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2017 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "AudioCommon/SurroundDecoder.h"
  4. #include <FreeSurround/FreeSurroundDecoder.h>
  5. #include <limits>
  6. namespace AudioCommon
  7. {
  8. constexpr size_t STEREO_CHANNELS = 2;
  9. constexpr size_t SURROUND_CHANNELS = 6;
  10. SurroundDecoder::SurroundDecoder(u32 sample_rate, u32 frame_block_size)
  11. : m_sample_rate(sample_rate), m_frame_block_size(frame_block_size)
  12. {
  13. m_fsdecoder = std::make_unique<DPL2FSDecoder>();
  14. m_fsdecoder->Init(cs_5point1, m_frame_block_size, m_sample_rate);
  15. }
  16. SurroundDecoder::~SurroundDecoder() = default;
  17. void SurroundDecoder::Clear()
  18. {
  19. m_fsdecoder->flush();
  20. m_decoded_fifo.clear();
  21. }
  22. // Currently only 6 channels are supported.
  23. size_t SurroundDecoder::QueryFramesNeededForSurroundOutput(const size_t output_frames) const
  24. {
  25. if (m_decoded_fifo.size() < output_frames * SURROUND_CHANNELS)
  26. {
  27. // Output stereo frames needed to have at least the desired number of surround frames
  28. size_t frames_needed = output_frames - m_decoded_fifo.size() / SURROUND_CHANNELS;
  29. return frames_needed + m_frame_block_size - frames_needed % m_frame_block_size;
  30. }
  31. return 0;
  32. }
  33. // Receive and decode samples
  34. void SurroundDecoder::PutFrames(const short* in, const size_t num_frames_in)
  35. {
  36. // Maybe check if it is really power-of-2?
  37. s64 remaining_frames = static_cast<s64>(num_frames_in);
  38. size_t frame_index = 0;
  39. while (remaining_frames > 0)
  40. {
  41. // Convert to float
  42. for (size_t i = 0, end = m_frame_block_size * STEREO_CHANNELS; i < end; ++i)
  43. {
  44. m_float_conversion_buffer[i] = in[i + frame_index * STEREO_CHANNELS] /
  45. static_cast<float>(std::numeric_limits<short>::max());
  46. }
  47. // Decode
  48. const float* dpl2_fs = m_fsdecoder->decode(m_float_conversion_buffer.data());
  49. // Add to ring buffer and fix channel mapping
  50. // Maybe modify FreeSurround to output the correct mapping?
  51. // FreeSurround:
  52. // FL | FC | FR | BL | BR | LFE
  53. // Most backends:
  54. // FL | FR | FC | LFE | BL | BR
  55. for (size_t i = 0; i < m_frame_block_size; ++i)
  56. {
  57. m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 0]); // LEFTFRONT
  58. m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 2]); // RIGHTFRONT
  59. m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 1]); // CENTREFRONT
  60. m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 5]); // sub/lfe
  61. m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 3]); // LEFTREAR
  62. m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 4]); // RIGHTREAR
  63. }
  64. remaining_frames = remaining_frames - static_cast<int>(m_frame_block_size);
  65. frame_index = frame_index + m_frame_block_size;
  66. }
  67. }
  68. void SurroundDecoder::ReceiveFrames(float* out, const size_t num_frames_out)
  69. {
  70. // Copy to output array with desired num_frames_out
  71. for (size_t i = 0, num_samples_output = num_frames_out * SURROUND_CHANNELS;
  72. i < num_samples_output; ++i)
  73. {
  74. out[i] = m_decoded_fifo.pop_front();
  75. }
  76. }
  77. } // namespace AudioCommon