diff options
| author | LAGonauta <lagonauta@gmail.com> | 2017-08-09 16:57:26 -0300 |
|---|---|---|
| committer | LAGonauta <lagonauta@gmail.com> | 2019-02-13 22:52:40 -0200 |
| commit | df631f0d75bd6422aca4b69854671ba1c561b077 (patch) | |
| tree | b7096e96ac15beae5ddf2f8baf912f096ef3e1be /Source/Core/AudioCommon/SurroundDecoder.cpp | |
| parent | 7b9375875ce67d15aa579dde6069e3bd98370758 (diff) | |
Swapped FFDShow's DPL2 decoder by FreeSurround
Added class in AudioCommon for the surround decoder
Diffstat (limited to 'Source/Core/AudioCommon/SurroundDecoder.cpp')
| -rw-r--r-- | Source/Core/AudioCommon/SurroundDecoder.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/Source/Core/AudioCommon/SurroundDecoder.cpp b/Source/Core/AudioCommon/SurroundDecoder.cpp new file mode 100644 index 0000000000..8ded0ca5e8 --- /dev/null +++ b/Source/Core/AudioCommon/SurroundDecoder.cpp @@ -0,0 +1,93 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include <FreeSurround/FreeSurroundDecoder.h> +#include <limits> + +#include "AudioCommon/SurroundDecoder.h" + +namespace AudioCommon +{ +constexpr size_t STEREO_CHANNELS = 2; +constexpr size_t SURROUND_CHANNELS = 6; + +SurroundDecoder::SurroundDecoder(u32 sample_rate, u32 frame_block_size) + : m_sample_rate(sample_rate), m_frame_block_size(frame_block_size) +{ + m_fsdecoder = std::make_unique<DPL2FSDecoder>(); + m_fsdecoder->Init(cs_5point1, m_frame_block_size, m_sample_rate); +} + +SurroundDecoder::~SurroundDecoder() = default; + +void SurroundDecoder::Clear() +{ + m_fsdecoder->flush(); + m_decoded_fifo.clear(); +} + +// Currently only 6 channels are supported. +size_t SurroundDecoder::QueryFramesNeededForSurroundOutput(const size_t output_frames) const +{ + if (m_decoded_fifo.size() < output_frames * SURROUND_CHANNELS) + { + // Output stereo frames needed to have at least the desired number of surround frames + size_t frames_needed = output_frames - m_decoded_fifo.size() / SURROUND_CHANNELS; + return frames_needed + m_frame_block_size - frames_needed % m_frame_block_size; + } + + return 0; +} + +// Receive and decode samples +void SurroundDecoder::PutFrames(const short* in, const size_t num_frames_in) +{ + // Maybe check if it is really power-of-2? + s64 remaining_frames = static_cast<s64>(num_frames_in); + size_t frame_index = 0; + + while (remaining_frames > 0) + { + // Convert to float + for (size_t i = 0, end = m_frame_block_size * STEREO_CHANNELS; i < end; ++i) + { + m_float_conversion_buffer[i] = in[i + frame_index * STEREO_CHANNELS] / + static_cast<float>(std::numeric_limits<short>::max()); + } + + // Decode + const float* dpl2_fs = m_fsdecoder->decode(m_float_conversion_buffer.data()); + + // Add to ring buffer and fix channel mapping + // Maybe modify FreeSurround to output the correct mapping? + // FreeSurround: + // FL | FC | FR | BL | BR | LFE + // Most backends: + // FL | FR | FC | LFE | BL | BR + for (size_t i = 0; i < m_frame_block_size; ++i) + { + m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 0]); // LEFTFRONT + m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 2]); // RIGHTFRONT + m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 1]); // CENTREFRONT + m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 5]); // sub/lfe + m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 3]); // LEFTREAR + m_decoded_fifo.push(dpl2_fs[i * SURROUND_CHANNELS + 4]); // RIGHTREAR + } + + remaining_frames = remaining_frames - static_cast<int>(m_frame_block_size); + frame_index = frame_index + m_frame_block_size; + } +} + +void SurroundDecoder::ReceiveFrames(float* out, const size_t num_frames_out) +{ + // Copy to output array with desired num_frames_out + for (size_t i = 0, num_samples_output = num_frames_out * SURROUND_CHANNELS; + i < num_samples_output; ++i) + { + out[i] = m_decoded_fifo.pop_front(); + } +} + +} // namespace AudioCommon |
