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