|
5 | 5 | #include "ajm_aac.h" |
6 | 6 | #include "ajm_result.h" |
7 | 7 |
|
| 8 | +#include <aacdecoder_lib.h> |
8 | 9 | // using this internal header to manually configure the decoder in RAW mode |
9 | 10 | #include "externals/aacdec/fdk-aac/libAACdec/src/aacdecoder.h" |
10 | 11 |
|
11 | | -#include <aacdecoder_lib.h> |
12 | | -#include <magic_enum/magic_enum.hpp> |
| 12 | +#include <algorithm> // std::transform |
| 13 | +#include <iterator> // std::back_inserter |
| 14 | +#include <limits> |
13 | 15 |
|
14 | 16 | namespace Libraries::Ajm { |
15 | 17 |
|
| 18 | +std::span<const s16> AjmAacDecoder::GetOuputPcm(u32 skipped_pcm, u32 max_pcm) const { |
| 19 | + const auto pcm_data = std::span(m_pcm_buffer).subspan(skipped_pcm); |
| 20 | + return pcm_data.subspan(0, std::min<u32>(pcm_data.size(), max_pcm)); |
| 21 | +} |
| 22 | + |
| 23 | +template <> |
| 24 | +size_t AjmAacDecoder::WriteOutputSamples<float>(SparseOutputBuffer& out, std::span<const s16> pcm) { |
| 25 | + if (pcm.empty()) { |
| 26 | + return 0; |
| 27 | + } |
| 28 | + |
| 29 | + m_resample_buffer.clear(); |
| 30 | + constexpr float inv_scale = 1.0f / std::numeric_limits<s16>::max(); |
| 31 | + std::transform(pcm.begin(), pcm.end(), std::back_inserter(m_resample_buffer), |
| 32 | + [](auto sample) { return float(sample) * inv_scale; }); |
| 33 | + |
| 34 | + return out.Write(std::span(m_resample_buffer)); |
| 35 | +} |
| 36 | + |
16 | 37 | AjmAacDecoder::AjmAacDecoder(AjmFormatEncoding format, AjmAacCodecFlags flags, u32 channels) |
17 | | - : m_format(format), m_flags(flags), m_channels(channels), m_pcm_buffer(2048 * 8), |
18 | | - m_skip_frames(True(flags & AjmAacCodecFlags::EnableNondelayOutput) ? 0 : 2) {} |
| 38 | + : m_format(format), m_flags(flags), m_channels(channels), m_pcm_buffer(1024 * 8), |
| 39 | + m_skip_frames(True(flags & AjmAacCodecFlags::EnableNondelayOutput) ? 0 : 2) { |
| 40 | + m_resample_buffer.reserve(m_pcm_buffer.size()); |
| 41 | +} |
19 | 42 |
|
20 | 43 | AjmAacDecoder::~AjmAacDecoder() { |
21 | | - aacDecoder_Close(m_decoder); |
| 44 | + if (m_decoder) { |
| 45 | + aacDecoder_Close(m_decoder); |
| 46 | + } |
22 | 47 | } |
23 | 48 |
|
24 | 49 | TRANSPORT_TYPE TransportTypeFromConfigType(ConfigType config_type) { |
@@ -98,7 +123,7 @@ AjmSidebandFormat AjmAacDecoder::GetFormat() const { |
98 | 123 | .num_channels = static_cast<u32>(info->numChannels), |
99 | 124 | .channel_mask = GetChannelMask(info->numChannels), |
100 | 125 | .sampl_freq = static_cast<u32>(info->sampleRate), |
101 | | - .sample_encoding = m_format, // AjmFormatEncoding |
| 126 | + .sample_encoding = m_format, |
102 | 127 | .bitrate = static_cast<u32>(info->bitRate), |
103 | 128 | }; |
104 | 129 | } |
@@ -130,8 +155,7 @@ DecoderResult AjmAacDecoder::ProcessData(std::span<u8>& input, SparseOutputBuffe |
130 | 155 | const UINT sizes[] = {static_cast<UINT>(input.size())}; |
131 | 156 | UINT valid = sizes[0]; |
132 | 157 | aacDecoder_Fill(m_decoder, buffers, sizes, &valid); |
133 | | - auto ret = aacDecoder_DecodeFrame(m_decoder, reinterpret_cast<s16*>(m_pcm_buffer.data()), |
134 | | - m_pcm_buffer.size() / 2, 0); |
| 158 | + auto ret = aacDecoder_DecodeFrame(m_decoder, m_pcm_buffer.data(), m_pcm_buffer.size(), 0); |
135 | 159 |
|
136 | 160 | switch (ret) { |
137 | 161 | case AAC_DEC_OK: |
@@ -167,16 +191,16 @@ DecoderResult AjmAacDecoder::ProcessData(std::span<u8>& input, SparseOutputBuffe |
167 | 191 | gapless.init.total_samples != 0 ? gapless.current.total_samples : info->aacSamplesPerFrame; |
168 | 192 |
|
169 | 193 | size_t pcm_written = 0; |
| 194 | + auto pcm = GetOuputPcm(skip_samples * info->numChannels, max_samples * info->numChannels); |
170 | 195 | switch (m_format) { |
171 | 196 | case AjmFormatEncoding::S16: |
172 | | - pcm_written = WriteOutputSamples<s16>(output, skip_samples * info->numChannels, |
173 | | - max_samples * info->numChannels); |
| 197 | + pcm_written = output.Write(pcm); |
174 | 198 | break; |
175 | 199 | case AjmFormatEncoding::S32: |
176 | 200 | UNREACHABLE_MSG("NOT IMPLEMENTED"); |
177 | 201 | break; |
178 | 202 | case AjmFormatEncoding::Float: |
179 | | - UNREACHABLE_MSG("NOT IMPLEMENTED"); |
| 203 | + pcm_written = WriteOutputSamples<float>(output, pcm); |
180 | 204 | break; |
181 | 205 | default: |
182 | 206 | UNREACHABLE(); |
|
0 commit comments