summaryrefslogtreecommitdiff
path: root/src/audio_core/codec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/codec.cpp')
-rw-r--r--src/audio_core/codec.cpp25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp
index 3e23323f1..c7efae753 100644
--- a/src/audio_core/codec.cpp
+++ b/src/audio_core/codec.cpp
@@ -15,22 +15,25 @@
15 15
16namespace Codec { 16namespace Codec {
17 17
18StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, const std::array<s16, 16>& adpcm_coeff, ADPCMState& state) { 18StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count,
19 const std::array<s16, 16>& adpcm_coeff, ADPCMState& state) {
19 // GC-ADPCM with scale factor and variable coefficients. 20 // GC-ADPCM with scale factor and variable coefficients.
20 // Frames are 8 bytes long containing 14 samples each. 21 // Frames are 8 bytes long containing 14 samples each.
21 // Samples are 4 bits (one nibble) long. 22 // Samples are 4 bits (one nibble) long.
22 23
23 constexpr size_t FRAME_LEN = 8; 24 constexpr size_t FRAME_LEN = 8;
24 constexpr size_t SAMPLES_PER_FRAME = 14; 25 constexpr size_t SAMPLES_PER_FRAME = 14;
25 constexpr std::array<int, 16> SIGNED_NIBBLES {{ 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 }}; 26 constexpr std::array<int, 16> SIGNED_NIBBLES{
27 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
26 28
27 const size_t ret_size = sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. 29 const size_t ret_size =
30 sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
28 StereoBuffer16 ret(ret_size); 31 StereoBuffer16 ret(ret_size);
29 32
30 int yn1 = state.yn1, 33 int yn1 = state.yn1, yn2 = state.yn2;
31 yn2 = state.yn2;
32 34
33 const size_t NUM_FRAMES = (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. 35 const size_t NUM_FRAMES =
36 (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
34 for (size_t framei = 0; framei < NUM_FRAMES; framei++) { 37 for (size_t framei = 0; framei < NUM_FRAMES; framei++) {
35 const int frame_header = data[framei * FRAME_LEN]; 38 const int frame_header = data[framei * FRAME_LEN];
36 const int scale = 1 << (frame_header & 0xF); 39 const int scale = 1 << (frame_header & 0xF);
@@ -43,7 +46,8 @@ StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, cons
43 // Decodes an audio sample. One nibble produces one sample. 46 // Decodes an audio sample. One nibble produces one sample.
44 const auto decode_sample = [&](const int nibble) -> s16 { 47 const auto decode_sample = [&](const int nibble) -> s16 {
45 const int xn = nibble * scale; 48 const int xn = nibble * scale;
46 // We first transform everything into 11 bit fixed point, perform the second order digital filter, then transform back. 49 // We first transform everything into 11 bit fixed point, perform the second order
50 // digital filter, then transform back.
47 // 0x400 == 0.5 in 11 bit fixed point. 51 // 0x400 == 0.5 in 11 bit fixed point.
48 // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2] 52 // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2]
49 int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11; 53 int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11;
@@ -82,7 +86,8 @@ static s16 SignExtendS8(u8 x) {
82 return static_cast<s16>(static_cast<s8>(x)); 86 return static_cast<s16>(static_cast<s8>(x));
83} 87}
84 88
85StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, const size_t sample_count) { 89StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
90 const size_t sample_count) {
86 ASSERT(num_channels == 1 || num_channels == 2); 91 ASSERT(num_channels == 1 || num_channels == 2);
87 92
88 StereoBuffer16 ret(sample_count); 93 StereoBuffer16 ret(sample_count);
@@ -101,7 +106,8 @@ StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, con
101 return ret; 106 return ret;
102} 107}
103 108
104StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, const size_t sample_count) { 109StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data,
110 const size_t sample_count) {
105 ASSERT(num_channels == 1 || num_channels == 2); 111 ASSERT(num_channels == 1 || num_channels == 2);
106 112
107 StereoBuffer16 ret(sample_count); 113 StereoBuffer16 ret(sample_count);
@@ -118,5 +124,4 @@ StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, co
118 124
119 return ret; 125 return ret;
120} 126}
121
122}; 127};