Skip to content

Commit fbdcf2c

Browse files
georgemoralisXcedf
authored andcommitted
m4aac decoder
1 parent beb9c86 commit fbdcf2c

File tree

4 files changed

+111
-0
lines changed

4 files changed

+111
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ set(AJM_LIB src/core/libraries/ajm/ajm.cpp
298298
src/core/libraries/ajm/ajm_instance.h
299299
src/core/libraries/ajm/ajm_mp3.cpp
300300
src/core/libraries/ajm/ajm_mp3.h
301+
src/core/libraries/ajm/ajm_m4aac.cpp
302+
src/core/libraries/ajm/ajm_m4aac.h
301303
)
302304

303305
set(AUDIO_LIB src/core/libraries/audio/audioin.cpp

src/core/libraries/ajm/ajm_instance.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "core/libraries/ajm/ajm_at9.h"
55
#include "core/libraries/ajm/ajm_instance.h"
6+
#include "core/libraries/ajm/ajm_m4aac.h"
67
#include "core/libraries/ajm/ajm_mp3.h"
78

89
#include <magic_enum/magic_enum.hpp>
@@ -47,6 +48,11 @@ AjmInstance::AjmInstance(AjmCodecType codec_type, AjmInstanceFlags flags) : m_fl
4748
AjmMp3CodecFlags(flags.codec));
4849
break;
4950
}
51+
case AjmCodecType::M4aacDec: {
52+
m_codec = std::make_unique<AjmM4aacDecoder>(AjmFormatEncoding(flags.format),
53+
AjmM4aacCodecFlags(flags.codec));
54+
break;
55+
}
5056
default:
5157
UNREACHABLE_MSG("Unimplemented codec type {}", magic_enum::enum_name(codec_type));
5258
}

src/core/libraries/ajm/ajm_m4aac.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#include "common/assert.h"
5+
#include "core/libraries/ajm/ajm_error.h"
6+
#include "core/libraries/ajm/ajm_m4aac.h"
7+
#include "core/libraries/error_codes.h"
8+
9+
extern "C" {
10+
#include <libavcodec/avcodec.h>
11+
#include <libavutil/opt.h>
12+
#include <libswresample/swresample.h>
13+
}
14+
15+
#include "common/support/avdec.h"
16+
17+
namespace Libraries::Ajm {
18+
AjmM4aacDecoder::AjmM4aacDecoder(AjmFormatEncoding format, AjmM4aacCodecFlags flags)
19+
: m_format(format), m_flags(flags), m_codec(avcodec_find_decoder(AV_CODEC_ID_AAC)),
20+
m_codec_context(avcodec_alloc_context3(m_codec)), m_parser(av_parser_init(m_codec->id)) {
21+
int ret = avcodec_open2(m_codec_context, m_codec, nullptr);
22+
ASSERT_MSG(ret >= 0, "Could not open m_codec");
23+
}
24+
AjmM4aacDecoder::~AjmM4aacDecoder() {
25+
swr_free(&m_swr_context);
26+
av_parser_close(m_parser);
27+
avcodec_free_context(&m_codec_context);
28+
}
29+
void AjmM4aacDecoder::Reset() {}
30+
void AjmM4aacDecoder::GetInfo(void* out_info) const {}
31+
AjmSidebandFormat AjmM4aacDecoder::GetFormat() const {
32+
return AjmSidebandFormat();
33+
}
34+
u32 AjmM4aacDecoder::GetNextFrameSize(const AjmInstanceGapless& gapless) const {
35+
return u32();
36+
}
37+
std::tuple<u32, u32> AjmM4aacDecoder::ProcessData(std::span<u8>& input, SparseOutputBuffer& output,
38+
AjmInstanceGapless& gapless) {
39+
return std::tuple<u32, u32>();
40+
}
41+
AVFrame* AjmM4aacDecoder::ConvertAudioFrame(AVFrame* frame) {
42+
return nullptr;
43+
}
44+
} // namespace Libraries::Ajm

src/core/libraries/ajm/ajm_m4aac.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#pragma once
5+
6+
#include "common/types.h"
7+
#include "core/libraries/ajm/ajm_instance.h"
8+
9+
extern "C" {
10+
#include <libavcodec/avcodec.h>
11+
struct SwrContext;
12+
}
13+
14+
namespace Libraries::Ajm {
15+
16+
enum AjmM4aacCodecFlags : u32 {
17+
SbrDecode = 1 << 0,
18+
NodelayOutput = 1 << 8,
19+
InterleaveOrderExtlExtrLsRs = 1 << 16,
20+
InterleaveOrderLsRsExtlExtr = 1 << 24
21+
};
22+
DECLARE_ENUM_FLAG_OPERATORS(AjmM4aacCodecFlags)
23+
24+
class AjmM4aacDecoder : public AjmCodec {
25+
public:
26+
explicit AjmM4aacDecoder(AjmFormatEncoding format, AjmM4aacCodecFlags flags);
27+
~AjmM4aacDecoder() override;
28+
29+
void Reset() override;
30+
void Initialize(const void* buffer, u32 buffer_size) override {}
31+
void GetInfo(void* out_info) const override;
32+
AjmSidebandFormat GetFormat() const override;
33+
u32 GetNextFrameSize(const AjmInstanceGapless& gapless) const override;
34+
std::tuple<u32, u32> ProcessData(std::span<u8>& input, SparseOutputBuffer& output,
35+
AjmInstanceGapless& gapless) override;
36+
37+
private:
38+
template <class T>
39+
size_t WriteOutputPCM(AVFrame* frame, SparseOutputBuffer& output, u32 skipped_samples,
40+
u32 max_pcm) {
41+
std::span<T> pcm_data(reinterpret_cast<T*>(frame->data[0]),
42+
frame->nb_samples * frame->ch_layout.nb_channels);
43+
pcm_data = pcm_data.subspan(skipped_samples * frame->ch_layout.nb_channels);
44+
return output.Write(pcm_data.subspan(0, std::min(u32(pcm_data.size()), max_pcm)));
45+
}
46+
47+
AVFrame* ConvertAudioFrame(AVFrame* frame);
48+
49+
const AjmFormatEncoding m_format;
50+
const AjmM4aacCodecFlags m_flags;
51+
const AVCodec* m_codec = nullptr;
52+
AVCodecContext* m_codec_context = nullptr;
53+
AVCodecParserContext* m_parser = nullptr;
54+
SwrContext* m_swr_context = nullptr;
55+
std::optional<u32> m_header;
56+
u32 m_frame_samples = 0;
57+
};
58+
59+
} // namespace Libraries::Ajm

0 commit comments

Comments
 (0)