2 * Copyright (c) 2007-2008 Ian Caulfield
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/attributes.h"
27 static void mlp_filter_channel(int32_t *state
, const int32_t *coeff
,
28 int firorder
, int iirorder
,
29 unsigned int filter_shift
, int32_t mask
,
30 int blocksize
, int32_t *sample_buffer
)
32 int32_t *firbuf
= state
;
33 int32_t *iirbuf
= state
+ MAX_BLOCKSIZE
+ MAX_FIR_ORDER
;
34 const int32_t *fircoeff
= coeff
;
35 const int32_t *iircoeff
= coeff
+ MAX_FIR_ORDER
;
38 for (i
= 0; i
< blocksize
; i
++) {
39 int32_t residual
= *sample_buffer
;
44 for (order
= 0; order
< firorder
; order
++)
45 accum
+= (int64_t) firbuf
[order
] * fircoeff
[order
];
46 for (order
= 0; order
< iirorder
; order
++)
47 accum
+= (int64_t) iirbuf
[order
] * iircoeff
[order
];
49 accum
= accum
>> filter_shift
;
50 result
= (accum
+ residual
) & mask
;
53 *--iirbuf
= result
- accum
;
55 *sample_buffer
= result
;
56 sample_buffer
+= MAX_CHANNELS
;
60 void ff_mlp_rematrix_channel(int32_t *samples
,
61 const int32_t *coeffs
,
62 const uint8_t *bypassed_lsbs
,
63 const int8_t *noise_buffer
,
68 int matrix_noise_shift
,
69 int access_unit_size_pow2
,
72 unsigned int src_ch
, i
;
73 int index2
= 2 * index
+ 1;
74 for (i
= 0; i
< blockpos
; i
++) {
77 for (src_ch
= 0; src_ch
<= maxchan
; src_ch
++)
78 accum
+= (int64_t) samples
[src_ch
] * coeffs
[src_ch
];
80 if (matrix_noise_shift
) {
81 index
&= access_unit_size_pow2
- 1;
82 accum
+= noise_buffer
[index
] << (matrix_noise_shift
+ 7);
86 samples
[dest_ch
] = ((accum
>> 14) & mask
) + *bypassed_lsbs
;
87 bypassed_lsbs
+= MAX_CHANNELS
;
88 samples
+= MAX_CHANNELS
;
92 static int32_t (*mlp_select_pack_output(uint8_t *ch_assign
,
94 uint8_t max_matrix_channel
,
95 int is32
))(int32_t, uint16_t, int32_t (*)[], void *, uint8_t*, int8_t *, uint8_t, int)
97 return ff_mlp_pack_output
;
100 int32_t ff_mlp_pack_output(int32_t lossless_check_data
,
102 int32_t (*sample_buffer
)[MAX_CHANNELS
],
105 int8_t *output_shift
,
106 uint8_t max_matrix_channel
,
109 unsigned int i
, out_ch
= 0;
110 int32_t *data_32
= data
;
111 int16_t *data_16
= data
;
113 for (i
= 0; i
< blockpos
; i
++) {
114 for (out_ch
= 0; out_ch
<= max_matrix_channel
; out_ch
++) {
115 int mat_ch
= ch_assign
[out_ch
];
116 int32_t sample
= sample_buffer
[i
][mat_ch
]
117 << output_shift
[mat_ch
];
118 lossless_check_data
^= (sample
& 0xffffff) << mat_ch
;
120 *data_32
++ = sample
<< 8;
122 *data_16
++ = sample
>> 8;
125 return lossless_check_data
;
128 av_cold
void ff_mlpdsp_init(MLPDSPContext
*c
)
130 c
->mlp_filter_channel
= mlp_filter_channel
;
131 c
->mlp_rematrix_channel
= ff_mlp_rematrix_channel
;
132 c
->mlp_select_pack_output
= mlp_select_pack_output
;
133 c
->mlp_pack_output
= ff_mlp_pack_output
;
135 ff_mlpdsp_init_arm(c
);
137 ff_mlpdsp_init_x86(c
);