Skip to content

Commit c322304

Browse files
committed
ajm aac: add resampling to float
1 parent 1a99ab7 commit c322304

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed

src/core/libraries/ajm/ajm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ u32 GetChannelMask(u32 num_channels) {
3434
case 8:
3535
return ORBIS_AJM_CHANNELMASK_7POINT1;
3636
default:
37-
UNREACHABLE();
37+
UNREACHABLE_MSG("Unexpected number of channels: {}", num_channels);
3838
}
3939
}
4040

src/core/libraries/ajm/ajm_aac.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,45 @@
55
#include "ajm_aac.h"
66
#include "ajm_result.h"
77

8+
#include <aacdecoder_lib.h>
89
// using this internal header to manually configure the decoder in RAW mode
910
#include "externals/aacdec/fdk-aac/libAACdec/src/aacdecoder.h"
1011

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>
1315

1416
namespace Libraries::Ajm {
1517

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+
1637
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+
}
1942

2043
AjmAacDecoder::~AjmAacDecoder() {
21-
aacDecoder_Close(m_decoder);
44+
if (m_decoder) {
45+
aacDecoder_Close(m_decoder);
46+
}
2247
}
2348

2449
TRANSPORT_TYPE TransportTypeFromConfigType(ConfigType config_type) {
@@ -98,7 +123,7 @@ AjmSidebandFormat AjmAacDecoder::GetFormat() const {
98123
.num_channels = static_cast<u32>(info->numChannels),
99124
.channel_mask = GetChannelMask(info->numChannels),
100125
.sampl_freq = static_cast<u32>(info->sampleRate),
101-
.sample_encoding = m_format, // AjmFormatEncoding
126+
.sample_encoding = m_format,
102127
.bitrate = static_cast<u32>(info->bitRate),
103128
};
104129
}
@@ -130,8 +155,7 @@ DecoderResult AjmAacDecoder::ProcessData(std::span<u8>& input, SparseOutputBuffe
130155
const UINT sizes[] = {static_cast<UINT>(input.size())};
131156
UINT valid = sizes[0];
132157
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);
135159

136160
switch (ret) {
137161
case AAC_DEC_OK:
@@ -167,16 +191,16 @@ DecoderResult AjmAacDecoder::ProcessData(std::span<u8>& input, SparseOutputBuffe
167191
gapless.init.total_samples != 0 ? gapless.current.total_samples : info->aacSamplesPerFrame;
168192

169193
size_t pcm_written = 0;
194+
auto pcm = GetOuputPcm(skip_samples * info->numChannels, max_samples * info->numChannels);
170195
switch (m_format) {
171196
case AjmFormatEncoding::S16:
172-
pcm_written = WriteOutputSamples<s16>(output, skip_samples * info->numChannels,
173-
max_samples * info->numChannels);
197+
pcm_written = output.Write(pcm);
174198
break;
175199
case AjmFormatEncoding::S32:
176200
UNREACHABLE_MSG("NOT IMPLEMENTED");
177201
break;
178202
case AjmFormatEncoding::Float:
179-
UNREACHABLE_MSG("NOT IMPLEMENTED");
203+
pcm_written = WriteOutputSamples<float>(output, pcm);
180204
break;
181205
default:
182206
UNREACHABLE();

src/core/libraries/ajm/ajm_aac.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,14 @@ struct AjmAacDecoder final : AjmCodec {
5252
};
5353

5454
template <class T>
55-
size_t WriteOutputSamples(SparseOutputBuffer& output, u32 skipped_pcm, u32 max_pcm) {
56-
std::span<T> pcm_data{reinterpret_cast<T*>(m_pcm_buffer.data()),
57-
m_pcm_buffer.size() / sizeof(T)};
58-
pcm_data = pcm_data.subspan(skipped_pcm);
59-
const auto pcm_size = std::min(u32(pcm_data.size()), max_pcm);
60-
return output.Write(pcm_data.subspan(0, pcm_size));
61-
}
55+
size_t WriteOutputSamples(SparseOutputBuffer& output, std::span<const s16> pcm);
56+
std::span<const s16> GetOuputPcm(u32 skipped_pcm, u32 max_pcm) const;
6257

6358
const AjmFormatEncoding m_format;
6459
const AjmAacCodecFlags m_flags;
6560
const u32 m_channels;
66-
std::vector<u8> m_pcm_buffer;
61+
std::vector<s16> m_pcm_buffer;
62+
std::vector<float> m_resample_buffer;
6763

6864
u32 m_skip_frames = 0;
6965
InitializeParameters m_init_params = {};

0 commit comments

Comments
 (0)