Skip to content

Commit ee12070

Browse files
committed
[AT3P] PQF implementation
M=16 perfect reconstruction polyphase quadrature analysis filter bank
1 parent f018c66 commit ee12070

12 files changed

+407
-888
lines changed

src/atrac/atrac3plus_pqf/atrac3plus_pqf.c

+50-88
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include <math.h>
2929

3030
#include "atrac3plus_pqf.h"
31-
#include "atrac3plus_pqf_prototype.h"
31+
#include "atrac3plus_pqf_data.h"
3232

3333
/*
3434
* Number of subbands to split input signal
@@ -44,111 +44,84 @@
4444
#define PROTO_SZ 384
4545

4646
#define FRAME_SZ ((SUBBANDS_NUM * SUBBAND_SIZE))
47-
#define EXTRA_SZ ((PROTO_SZ - SUBBANDS_NUM))
47+
#define OVERLAP_SZ ((PROTO_SZ - SUBBANDS_NUM))
4848

49-
const uint16_t at3plus_pqf_frame_sz = FRAME_SZ;
50-
const uint16_t at3plus_pqf_proto_sz = PROTO_SZ;
5149

52-
static float C[PROTO_SZ];
53-
static float M[256];
50+
static float fir[PROTO_SZ];
51+
52+
static void dct4(float* out, const float* x, int N, float scale) {
53+
for (int k = 0; k < N; k++) {
54+
double sum = 0;
55+
for (int n = 0; n < N; n++) {
56+
sum += ((double)x[n] * cosl((M_PI/(double)N) * ((double)n + 0.5) * ((double)k + 0.5)));
57+
}
58+
out[N - 1 - k] = sum * scale;
59+
}
60+
}
5461

5562
struct at3plus_pqf_a_ctx {
56-
float buf[FRAME_SZ + EXTRA_SZ];
63+
float buf[FRAME_SZ + OVERLAP_SZ];
5764
};
5865

5966
static void init(void)
6067
{
61-
int i;
62-
int j;
63-
const float* const t = at3plus_pqf_prototype;
6468
static int inited = 0;
6569

6670
if (inited)
6771
return;
68-
inited = 1;
6972

70-
for (i = 0; i < 16; i++) {
71-
for (j = 0; j < 16; j++) {
72-
M[i*16 + j] = (float)cos(((2 * i + 1) * j & 127) * M_PI / 32);
73-
}
74-
}
73+
inited = 1;
7574

76-
for (i = 0; i < 6; i++) {
77-
for (j = 0; j < 32; j++) {
78-
if (i & 1) {
79-
C[j * 12 + i] = 1.489 * t[j * 2 + 64 * i];
80-
C[j * 12 + 6 + i] = 1.489 * t[j * 2 + 1 + 64 * i];
81-
} else {
82-
C[j * 12 + i] = -1.489 * t[j * 2 + 64 * i];
83-
C[j * 12 + 6 + i] = -1.489 * t[j * 2 + 1 + 64 * i];
84-
}
75+
for (int i = 0; i < 16; i++) {
76+
for (int j = 0; j < ATRAC3P_PQF_FIR_LEN; j++) {
77+
if (i >= 8) {
78+
fir[j + 96 + (i - 8) * 12] = ff_ipqf_coeffs1[j][i];
79+
fir[j + 288 + (i - 8) * 12] = ff_ipqf_coeffs2[j][i];
80+
} else {
81+
fir[j + 192 + i * 12] = ff_ipqf_coeffs2[j][i];
82+
fir[j + 0 + i * 12] = ff_ipqf_coeffs1[j][i];
83+
}
8584
}
8685
}
8786
}
8887

89-
static void vectoring(const float* x, float* y)
88+
static void vectoring(const float* const x, float* y)
9089
{
91-
int i;
92-
int j;
93-
const float* c = C;
94-
95-
for ( i = 0; i < SUBBANDS_NUM * 2; i++, c += 12, x += 1, y += 1 ) {
96-
y[0] = 0;
97-
for (j = 0; j < 12; j++) {
98-
y[0] += c[j] * x[j * 32];
90+
for (int i = 0; i < 32; i++) {
91+
y[i] = 0;
92+
for (int j = 0; j < ATRAC3P_PQF_FIR_LEN; j++) {
93+
y[i] += fir[i * 12 + j] * x[j * 32 + i];
9994
}
10095
}
10196
}
10297

103-
static void matrixing(const float* mi, const float* y, float* samples )
104-
{
105-
int i;
106-
for (i = 0; i < SUBBANDS_NUM; i++, mi += 16, samples += SUBBAND_SIZE) {
107-
samples[0] = y[8] + mi[ 1] * (y[7]+y[9])
108-
+ mi[ 2] * (y[6]+y[10]) + mi[ 3] * (y[5]+y[11])
109-
+ mi[ 4] * (y[4]+y[12]) + mi[ 5] * (y[3]+y[13])
110-
+ mi[ 6] * (y[2]+y[14]) + mi[ 7] * (y[ 1]+y[15])
111-
+ mi[ 8] * (y[ 0]+y[16])
112-
+ mi[15] * (y[23]-y[25]) + mi[14] * (y[22]-y[26])
113-
+ mi[13] * (y[21]-y[27]) + mi[12] * (y[20]-y[28])
114-
+ mi[11] * (y[19]-y[29]) + mi[10] * (y[18]-y[30])
115-
+ mi[ 9] * (y[17]-y[31]);
116-
}
117-
}
118-
119-
static void a_init(at3plus_pqf_a_ctx_t ctx)
98+
static void matrixing(const float* y, float* samples )
12099
{
121-
float y[SUBBANDS_NUM * 2];
122-
float out[FRAME_SZ];
123-
float* x;
124-
int n, i;
125-
126-
float* buf = ctx->buf;
127-
init();
100+
float yy[SUBBANDS_NUM];
101+
float res[SUBBANDS_NUM];
128102

129-
memcpy ( buf + FRAME_SZ, buf, EXTRA_SZ * sizeof(*buf) );
130-
x = buf + FRAME_SZ;
131-
132-
for ( n = 0; n < SUBBAND_SIZE; n++ ) {
133-
x -= SUBBANDS_NUM;
103+
for (int i = 0; i < 8; i++) {
104+
yy[i] = y[i + 8] + y[7 - i];
105+
yy[i + 8] = y[i + 16] + y[31 - i];
106+
}
134107

135-
for (i = 0; i < SUBBANDS_NUM; i++)
136-
x[i] = 0.0;
108+
dct4(res, yy, SUBBANDS_NUM, 128.0 * 512.0);
137109

138-
vectoring(x, y);
139-
matrixing (M, y, &out[n]);
110+
for (int i = 0; i < SUBBANDS_NUM; i++) {
111+
samples[i * SUBBAND_SIZE] = res[SUBBANDS_NUM - 1 - i];
140112
}
141113
}
142114

143115
at3plus_pqf_a_ctx_t at3plus_pqf_create_a_ctx()
144116
{
145-
int i = 0;
146117
at3plus_pqf_a_ctx_t ctx = (at3plus_pqf_a_ctx_t)malloc(sizeof(struct at3plus_pqf_a_ctx));
147-
for (i = 0; i < FRAME_SZ + EXTRA_SZ; i++) {
118+
119+
for (int i = 0; i < FRAME_SZ + OVERLAP_SZ; i++) {
148120
ctx->buf[i] = 0.0;
149121
}
150122

151-
a_init(ctx);
123+
init();
124+
152125
return ctx;
153126
}
154127

@@ -160,29 +133,18 @@ void at3plus_pqf_free_a_ctx(at3plus_pqf_a_ctx_t ctx)
160133
void at3plus_pqf_do_analyse(at3plus_pqf_a_ctx_t ctx, const float* in, float* out)
161134
{
162135
float y[SUBBANDS_NUM * 2];
163-
float* x;
164-
const float* pcm;
165-
int n, i;
166136

167-
float* buf = ctx->buf;
137+
float* const buf = ctx->buf;
168138

169-
memcpy(buf + FRAME_SZ, buf, EXTRA_SZ * sizeof(float));
170-
x = buf + FRAME_SZ;
139+
const float* x = buf;
171140

172-
pcm = in + (SUBBANDS_NUM - 1);
141+
memcpy(buf + OVERLAP_SZ, in, sizeof(in[0]) * FRAME_SZ);
173142

174-
for (n = 0; n < SUBBAND_SIZE; n++, pcm += SUBBANDS_NUM * 2) {
175-
x -= SUBBANDS_NUM;
176-
for (i = 0; i < SUBBANDS_NUM; i++) {
177-
x[i] = *pcm--;
178-
}
143+
for (int i = 0; i < SUBBAND_SIZE; i++) {
179144
vectoring(x, y);
180-
matrixing (M, y, &out[n]);
145+
matrixing (y, &out[i]);
146+
x += SUBBANDS_NUM;
181147
}
182-
}
183148

184-
const float* at3plus_pqf_get_proto(void)
185-
{
186-
return at3plus_pqf_prototype;
149+
memcpy(buf, buf + FRAME_SZ, sizeof(buf[0]) * OVERLAP_SZ);
187150
}
188-

src/atrac/atrac3plus_pqf/atrac3plus_pqf.h

-6
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,10 @@ typedef struct at3plus_pqf_a_ctx *at3plus_pqf_a_ctx_t;
2727
extern "C" {
2828
#endif
2929

30-
extern const uint16_t at3plus_pqf_frame_sz;
31-
extern const uint16_t at3plus_pqf_proto_sz;
32-
3330
at3plus_pqf_a_ctx_t at3plus_pqf_create_a_ctx(void);
3431
void at3plus_pqf_free_a_ctx(at3plus_pqf_a_ctx_t ctx);
3532
void at3plus_pqf_do_analyse(at3plus_pqf_a_ctx_t ctx, const float* in, float* out);
3633

37-
// Debug functions
38-
const float* at3plus_pqf_get_proto(void);
39-
4034
#ifdef __cplusplus
4135
}
4236
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* This file is part of AtracDEnc.
3+
*
4+
* AtracDEnc is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* AtracDEnc is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with AtracDEnc; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#ifndef ATRAC3PLUSPQFDATA_H
20+
#define ATRAC3PLUSPQFDATA_H
21+
22+
#define ATRAC3P_PQF_FIR_LEN 12
23+
24+
/*
25+
* Borrowed from FFmpeg
26+
*/
27+
28+
/* First half of the 384-tap IPQF filtering coefficients. */
29+
static const float ff_ipqf_coeffs1[ATRAC3P_PQF_FIR_LEN][16] = {
30+
{ -5.8336207e-7, -8.0604229e-7, -4.2005411e-7, -4.4400572e-8,
31+
3.226247e-8, 3.530856e-8, 1.2660377e-8, 0.000010516783,
32+
-0.000011838618, 6.005389e-7, 0.0000014333754, 0.0000023108685,
33+
0.0000032569742, 0.0000046192422, 0.0000063894258, 0.0000070302972 },
34+
{ -0.0000091622824, -0.000010502935, -0.0000079212787, -0.0000041712024,
35+
-0.0000026336629, -0.0000015432918, -5.7168614e-7, 0.0000018111954,
36+
0.000023530851, 0.00002780562, 0.000032302323, 0.000036968919,
37+
0.000041575615, 0.000045337845, 0.000046043948, 0.000048585582 },
38+
{ -0.000064464548, -0.000068306952, -0.000073081472, -0.00007612785,
39+
-0.000074850752, -0.000070208509, -0.000062285151, -0.000058270442,
40+
-0.000056296329, -0.000049888811, -0.000035615325, -0.000018532943,
41+
0.0000016657353, 0.00002610587, 0.000053397067, 0.00008079566 },
42+
{ -0.00054488552, -0.00052537228, -0.00049731287, -0.00045778,
43+
-0.00040612387, -0.00034301577, -0.00026866337, -0.00018248901,
44+
-0.000084307925, 0.000025081157, 0.00014135583, 0.00026649953,
45+
0.00039945057, 0.00053928449, 0.00068422867, 0.00083093712 },
46+
{ -0.0014771431, -0.001283227, -0.0010566821, -0.00079780724,
47+
-0.00050782406, -0.00018855913, 0.00015771533, 0.00052769453,
48+
0.00091862219, 0.001326357, 0.0017469483, 0.0021754825,
49+
0.0026067684, 0.0030352892, 0.0034549395, 0.0038591374 },
50+
{ -0.0022995141, -0.001443546, -0.00049266568, 0.00055068987,
51+
0.001682895, 0.0028992873, 0.0041943151, 0.0055614738,
52+
0.0069935122, 0.0084823566, 0.010018963, 0.011593862,
53+
0.013196872, 0.014817309, 0.016444042, 0.018065533 },
54+
{ -0.034426283, -0.034281436, -0.033992987, -0.033563249,
55+
-0.032995768, -0.032295227, -0.031467363, -0.030518902,
56+
-0.02945766, -0.028291954, -0.027031265, -0.025685543,
57+
-0.024265358, -0.022781773, -0.021246184, -0.019670162 },
58+
{ -0.0030586775, -0.0037203205, -0.0042847847, -0.0047529764,
59+
-0.0051268316, -0.0054091476, -0.0056034233, -0.005714261,
60+
-0.0057445862, -0.0057025906, -0.0055920109, -0.0054194843,
61+
-0.0051914565, -0.0049146507, -0.0045959447, -0.0042418269 },
62+
{ -0.0016376863, -0.0017651899, -0.0018608454, -0.0019252141,
63+
-0.0019593791, -0.0019653172, -0.0019450618, -0.0018990048,
64+
-0.00183808, -0.0017501717, -0.0016481078, -0.0015320742,
65+
-0.0014046903, -0.0012685474, -0.001125814, -0.00097943726 },
66+
{ -0.00055432378, -0.00055472925, -0.00054783461, -0.00053276919,
67+
-0.00051135791, -0.00048466062, -0.00045358928, -0.00042499689,
68+
-0.00036942671, -0.0003392619, -0.00030001783, -0.00025986304,
69+
-0.0002197204, -0.00018116167, -0.00014691355, -0.00011279432 },
70+
{ -0.000064147389, -0.00006174868, -0.000054267788, -0.000047133824,
71+
-0.000042927582, -0.000039477309, -0.000036340745, -0.000029687517,
72+
-0.000049787737, -0.000041577889, -0.000033864744, -0.000026534748,
73+
-0.000019841305, -0.000014789486, -0.000013131184, -0.0000099198869 },
74+
{ -0.0000062990207, -0.0000072701259, -0.000011984052, -0.000017348082,
75+
-0.000019907106, -0.000021348773, -0.000021961965, -0.000012203576,
76+
-0.000010840992, 4.6299544e-7, 5.2588763e-7, 2.7792686e-7,
77+
-2.3649704e-7, -0.0000010897784, -9.171448e-7, -5.22682e-7 }
78+
};
79+
80+
/* Second half of the 384-tap IPQF filtering coefficients. */
81+
static const float ff_ipqf_coeffs2[ATRAC3P_PQF_FIR_LEN][16] = {
82+
{ 5.22682e-7, 9.171448e-7, 0.0000010897784, 2.3649704e-7,
83+
-2.7792686e-7, -5.2588763e-7, -4.6299544e-7, 0.000010840992,
84+
-0.000012203576, -0.000021961965, -0.000021348773, -0.000019907106,
85+
-0.000017348082, -0.000011984052, -0.0000072701259, -0.0000062990207 },
86+
{ 0.0000099198869, 0.000013131184, 0.000014789486, 0.000019841305,
87+
0.000026534748, 0.000033864744, 0.000041577889, 0.000049787737,
88+
-0.000029687517, -0.000036340745, -0.000039477309, -0.000042927582,
89+
-0.000047133824, -0.000054267788, -0.00006174868, -0.000064147389 },
90+
{ 0.00011279432, 0.00014691355, 0.00018116167, 0.0002197204,
91+
0.00025986304, 0.00030001783, 0.0003392619, 0.00036942671,
92+
-0.00042499689, -0.00045358928, -0.00048466062, -0.00051135791,
93+
-0.00053276919, -0.00054783461, -0.00055472925, -0.00055432378 },
94+
{ 0.00097943726, 0.001125814, 0.0012685474, 0.0014046903,
95+
0.0015320742, 0.0016481078, 0.0017501717, 0.00183808,
96+
-0.0018990048, -0.0019450618, -0.0019653172, -0.0019593791,
97+
-0.0019252141, -0.0018608454, -0.0017651899, -0.0016376863 },
98+
{ 0.0042418269, 0.0045959447, 0.0049146507, 0.0051914565,
99+
0.0054194843, 0.0055920109, 0.0057025906, 0.0057445862,
100+
-0.005714261, -0.0056034233, -0.0054091476, -0.0051268316,
101+
-0.0047529764, -0.0042847847, -0.0037203205, -0.0030586775 },
102+
{ 0.019670162, 0.021246184, 0.022781773, 0.024265358,
103+
0.025685543, 0.027031265, 0.028291954, 0.02945766,
104+
-0.030518902, -0.031467363, -0.032295227, -0.032995768,
105+
-0.033563249, -0.033992987, -0.034281436, -0.034426283 },
106+
{ -0.018065533, -0.016444042, -0.014817309, -0.013196872,
107+
-0.011593862, -0.010018963, -0.0084823566, -0.0069935122,
108+
0.0055614738, 0.0041943151, 0.0028992873, 0.001682895,
109+
0.00055068987, -0.00049266568, -0.001443546, -0.0022995141 },
110+
{ -0.0038591374, -0.0034549395, -0.0030352892, -0.0026067684,
111+
-0.0021754825, -0.0017469483, -0.001326357, -0.00091862219,
112+
0.00052769453, 0.00015771533, -0.00018855913, -0.00050782406,
113+
-0.00079780724, -0.0010566821, -0.001283227, -0.0014771431 },
114+
{ -0.00083093712, -0.00068422867, -0.00053928449, -0.00039945057,
115+
-0.00026649953, -0.00014135583, -0.000025081157, 0.000084307925,
116+
-0.00018248901, -0.00026866337, -0.00034301577, -0.00040612387,
117+
-0.00045778, -0.00049731287, -0.00052537228, -0.00054488552 },
118+
{ -0.00008079566, -0.000053397067, -0.00002610587, -0.0000016657353,
119+
0.000018532943, 0.000035615325, 0.000049888811, 0.000056296329,
120+
-0.000058270442, -0.000062285151, -0.000070208509, -0.000074850752,
121+
-0.00007612785, -0.000073081472, -0.000068306952, -0.000064464548 },
122+
{ -0.000048585582, -0.000046043948, -0.000045337845, -0.000041575615,
123+
-0.000036968919, -0.000032302323, -0.00002780562, -0.000023530851,
124+
0.0000018111954, -5.7168614e-7, -0.0000015432918, -0.0000026336629,
125+
-0.0000041712024, -0.0000079212787, -0.000010502935, -0.0000091622824 },
126+
{ -0.0000070302972, -0.0000063894258, -0.0000046192422, -0.0000032569742,
127+
-0.0000023108685, -0.0000014333754, -6.005389e-7, 0.000011838618,
128+
0.000010516783, 1.2660377e-8, 3.530856e-8, 3.226247e-8,
129+
-4.4400572e-8, -4.2005411e-7, -8.0604229e-7, -5.8336207e-7 }
130+
};
131+
132+
#endif

0 commit comments

Comments
 (0)