1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * WavPack lossless audio encoder
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#define BITSTREAM_WRITER_LE
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
24cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
25cabdff1aSopenharmony_ci#include "libavutil/opt.h"
26cabdff1aSopenharmony_ci#include "avcodec.h"
27cabdff1aSopenharmony_ci#include "codec_internal.h"
28cabdff1aSopenharmony_ci#include "encode.h"
29cabdff1aSopenharmony_ci#include "internal.h"
30cabdff1aSopenharmony_ci#include "put_bits.h"
31cabdff1aSopenharmony_ci#include "bytestream.h"
32cabdff1aSopenharmony_ci#include "wavpackenc.h"
33cabdff1aSopenharmony_ci#include "wavpack.h"
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_ci#define UPDATE_WEIGHT(weight, delta, source, result) \
36cabdff1aSopenharmony_ci    if ((source) && (result)) { \
37cabdff1aSopenharmony_ci        int32_t s = (int32_t) ((source) ^ (result)) >> 31; \
38cabdff1aSopenharmony_ci        weight = ((delta) ^ s) + ((weight) - s); \
39cabdff1aSopenharmony_ci    }
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_ci#define APPLY_WEIGHT_F(weight, sample) ((((((sample) & 0xffff) * (weight)) >> 9) + \
42cabdff1aSopenharmony_ci    ((((sample) & ~0xffff) >> 9) * (weight)) + 1) >> 1)
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_ci#define APPLY_WEIGHT_I(weight, sample) (((weight) * (sample) + 512) >> 10)
45cabdff1aSopenharmony_ci
46cabdff1aSopenharmony_ci#define APPLY_WEIGHT(weight, sample) ((sample) != (short) (sample) ? \
47cabdff1aSopenharmony_ci    APPLY_WEIGHT_F(weight, sample) : APPLY_WEIGHT_I (weight, sample))
48cabdff1aSopenharmony_ci
49cabdff1aSopenharmony_ci#define CLEAR(destin) memset(&destin, 0, sizeof(destin));
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci#define SHIFT_LSB       13
52cabdff1aSopenharmony_ci#define SHIFT_MASK      (0x1FU << SHIFT_LSB)
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci#define MAG_LSB         18
55cabdff1aSopenharmony_ci#define MAG_MASK        (0x1FU << MAG_LSB)
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_ci#define SRATE_LSB       23
58cabdff1aSopenharmony_ci#define SRATE_MASK      (0xFU << SRATE_LSB)
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci#define EXTRA_TRY_DELTAS     1
61cabdff1aSopenharmony_ci#define EXTRA_ADJUST_DELTAS  2
62cabdff1aSopenharmony_ci#define EXTRA_SORT_FIRST     4
63cabdff1aSopenharmony_ci#define EXTRA_BRANCHES       8
64cabdff1aSopenharmony_ci#define EXTRA_SORT_LAST     16
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_citypedef struct WavPackExtraInfo {
67cabdff1aSopenharmony_ci    struct Decorr dps[MAX_TERMS];
68cabdff1aSopenharmony_ci    int nterms, log_limit, gt16bit;
69cabdff1aSopenharmony_ci    uint32_t best_bits;
70cabdff1aSopenharmony_ci} WavPackExtraInfo;
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_citypedef struct WavPackWords {
73cabdff1aSopenharmony_ci    int pend_data, holding_one, zeros_acc;
74cabdff1aSopenharmony_ci    int holding_zero, pend_count;
75cabdff1aSopenharmony_ci    WvChannel c[2];
76cabdff1aSopenharmony_ci} WavPackWords;
77cabdff1aSopenharmony_ci
78cabdff1aSopenharmony_citypedef struct WavPackEncodeContext {
79cabdff1aSopenharmony_ci    AVClass *class;
80cabdff1aSopenharmony_ci    AVCodecContext *avctx;
81cabdff1aSopenharmony_ci    PutBitContext pb;
82cabdff1aSopenharmony_ci    int block_samples;
83cabdff1aSopenharmony_ci    int buffer_size;
84cabdff1aSopenharmony_ci    int sample_index;
85cabdff1aSopenharmony_ci    int stereo, stereo_in;
86cabdff1aSopenharmony_ci    int ch_offset;
87cabdff1aSopenharmony_ci
88cabdff1aSopenharmony_ci    int32_t *samples[2];
89cabdff1aSopenharmony_ci    int samples_size[2];
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci    int32_t *sampleptrs[MAX_TERMS+2][2];
92cabdff1aSopenharmony_ci    int sampleptrs_size[MAX_TERMS+2][2];
93cabdff1aSopenharmony_ci
94cabdff1aSopenharmony_ci    int32_t *temp_buffer[2][2];
95cabdff1aSopenharmony_ci    int temp_buffer_size[2][2];
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_ci    int32_t *best_buffer[2];
98cabdff1aSopenharmony_ci    int best_buffer_size[2];
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci    int32_t *js_left, *js_right;
101cabdff1aSopenharmony_ci    int js_left_size, js_right_size;
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci    int32_t *orig_l, *orig_r;
104cabdff1aSopenharmony_ci    int orig_l_size, orig_r_size;
105cabdff1aSopenharmony_ci
106cabdff1aSopenharmony_ci    unsigned extra_flags;
107cabdff1aSopenharmony_ci    int optimize_mono;
108cabdff1aSopenharmony_ci    int decorr_filter;
109cabdff1aSopenharmony_ci    int joint;
110cabdff1aSopenharmony_ci    int num_branches;
111cabdff1aSopenharmony_ci
112cabdff1aSopenharmony_ci    uint32_t flags;
113cabdff1aSopenharmony_ci    uint32_t crc_x;
114cabdff1aSopenharmony_ci    WavPackWords w;
115cabdff1aSopenharmony_ci
116cabdff1aSopenharmony_ci    uint8_t int32_sent_bits, int32_zeros, int32_ones, int32_dups;
117cabdff1aSopenharmony_ci    uint8_t float_flags, float_shift, float_max_exp, max_exp;
118cabdff1aSopenharmony_ci    int32_t shifted_ones, shifted_zeros, shifted_both;
119cabdff1aSopenharmony_ci    int32_t false_zeros, neg_zeros, ordata;
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    int num_terms, shift, joint_stereo, false_stereo;
122cabdff1aSopenharmony_ci    int num_decorrs, num_passes, best_decorr, mask_decorr;
123cabdff1aSopenharmony_ci    struct Decorr decorr_passes[MAX_TERMS];
124cabdff1aSopenharmony_ci    const WavPackDecorrSpec *decorr_specs;
125cabdff1aSopenharmony_ci    float delta_decay;
126cabdff1aSopenharmony_ci} WavPackEncodeContext;
127cabdff1aSopenharmony_ci
128cabdff1aSopenharmony_cistatic av_cold int wavpack_encode_init(AVCodecContext *avctx)
129cabdff1aSopenharmony_ci{
130cabdff1aSopenharmony_ci    WavPackEncodeContext *s = avctx->priv_data;
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    s->avctx = avctx;
133cabdff1aSopenharmony_ci
134cabdff1aSopenharmony_ci    if (avctx->ch_layout.nb_channels > 255) {
135cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d\n", avctx->ch_layout.nb_channels);
136cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
137cabdff1aSopenharmony_ci    }
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_ci    if (!avctx->frame_size) {
140cabdff1aSopenharmony_ci        int block_samples;
141cabdff1aSopenharmony_ci        if (!(avctx->sample_rate & 1))
142cabdff1aSopenharmony_ci            block_samples = avctx->sample_rate / 2;
143cabdff1aSopenharmony_ci        else
144cabdff1aSopenharmony_ci            block_samples = avctx->sample_rate;
145cabdff1aSopenharmony_ci
146cabdff1aSopenharmony_ci        while (block_samples * avctx->ch_layout.nb_channels > WV_MAX_SAMPLES)
147cabdff1aSopenharmony_ci            block_samples /= 2;
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ci        while (block_samples * avctx->ch_layout.nb_channels < 40000)
150cabdff1aSopenharmony_ci            block_samples *= 2;
151cabdff1aSopenharmony_ci        avctx->frame_size = block_samples;
152cabdff1aSopenharmony_ci    } else if (avctx->frame_size && (avctx->frame_size < 128 ||
153cabdff1aSopenharmony_ci                              avctx->frame_size > WV_MAX_SAMPLES)) {
154cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n", avctx->frame_size);
155cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
156cabdff1aSopenharmony_ci    }
157cabdff1aSopenharmony_ci
158cabdff1aSopenharmony_ci    if (avctx->compression_level != FF_COMPRESSION_DEFAULT) {
159cabdff1aSopenharmony_ci        if (avctx->compression_level >= 3) {
160cabdff1aSopenharmony_ci            s->decorr_filter = 3;
161cabdff1aSopenharmony_ci            s->num_passes = 9;
162cabdff1aSopenharmony_ci            if      (avctx->compression_level >= 8) {
163cabdff1aSopenharmony_ci                s->num_branches = 4;
164cabdff1aSopenharmony_ci                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_SORT_LAST|EXTRA_BRANCHES;
165cabdff1aSopenharmony_ci            } else if (avctx->compression_level >= 7) {
166cabdff1aSopenharmony_ci                s->num_branches = 3;
167cabdff1aSopenharmony_ci                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
168cabdff1aSopenharmony_ci            } else if (avctx->compression_level >= 6) {
169cabdff1aSopenharmony_ci                s->num_branches = 2;
170cabdff1aSopenharmony_ci                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
171cabdff1aSopenharmony_ci            } else if (avctx->compression_level >= 5) {
172cabdff1aSopenharmony_ci                s->num_branches = 1;
173cabdff1aSopenharmony_ci                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
174cabdff1aSopenharmony_ci            } else if (avctx->compression_level >= 4) {
175cabdff1aSopenharmony_ci                s->num_branches = 1;
176cabdff1aSopenharmony_ci                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_BRANCHES;
177cabdff1aSopenharmony_ci            }
178cabdff1aSopenharmony_ci        } else if (avctx->compression_level == 2) {
179cabdff1aSopenharmony_ci            s->decorr_filter = 2;
180cabdff1aSopenharmony_ci            s->num_passes = 4;
181cabdff1aSopenharmony_ci        } else if (avctx->compression_level == 1) {
182cabdff1aSopenharmony_ci            s->decorr_filter = 1;
183cabdff1aSopenharmony_ci            s->num_passes = 2;
184cabdff1aSopenharmony_ci        } else if (avctx->compression_level < 1) {
185cabdff1aSopenharmony_ci            s->decorr_filter = 0;
186cabdff1aSopenharmony_ci            s->num_passes = 0;
187cabdff1aSopenharmony_ci        }
188cabdff1aSopenharmony_ci    }
189cabdff1aSopenharmony_ci
190cabdff1aSopenharmony_ci    s->num_decorrs = decorr_filter_sizes[s->decorr_filter];
191cabdff1aSopenharmony_ci    s->decorr_specs = decorr_filters[s->decorr_filter];
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci    s->delta_decay = 2.0;
194cabdff1aSopenharmony_ci
195cabdff1aSopenharmony_ci    return 0;
196cabdff1aSopenharmony_ci}
197cabdff1aSopenharmony_ci
198cabdff1aSopenharmony_cistatic void shift_mono(int32_t *samples, int nb_samples, int shift)
199cabdff1aSopenharmony_ci{
200cabdff1aSopenharmony_ci    int i;
201cabdff1aSopenharmony_ci    for (i = 0; i < nb_samples; i++)
202cabdff1aSopenharmony_ci        samples[i] >>= shift;
203cabdff1aSopenharmony_ci}
204cabdff1aSopenharmony_ci
205cabdff1aSopenharmony_cistatic void shift_stereo(int32_t *left, int32_t *right,
206cabdff1aSopenharmony_ci                         int nb_samples, int shift)
207cabdff1aSopenharmony_ci{
208cabdff1aSopenharmony_ci    int i;
209cabdff1aSopenharmony_ci    for (i = 0; i < nb_samples; i++) {
210cabdff1aSopenharmony_ci        left [i] >>= shift;
211cabdff1aSopenharmony_ci        right[i] >>= shift;
212cabdff1aSopenharmony_ci    }
213cabdff1aSopenharmony_ci}
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci#define FLOAT_SHIFT_ONES 1
216cabdff1aSopenharmony_ci#define FLOAT_SHIFT_SAME 2
217cabdff1aSopenharmony_ci#define FLOAT_SHIFT_SENT 4
218cabdff1aSopenharmony_ci#define FLOAT_ZEROS_SENT 8
219cabdff1aSopenharmony_ci#define FLOAT_NEG_ZEROS  0x10
220cabdff1aSopenharmony_ci#define FLOAT_EXCEPTIONS 0x20
221cabdff1aSopenharmony_ci
222cabdff1aSopenharmony_ci#define get_mantissa(f)     ((f) & 0x7fffff)
223cabdff1aSopenharmony_ci#define get_exponent(f)     (((f) >> 23) & 0xff)
224cabdff1aSopenharmony_ci#define get_sign(f)         (((f) >> 31) & 0x1)
225cabdff1aSopenharmony_ci
226cabdff1aSopenharmony_cistatic void process_float(WavPackEncodeContext *s, int32_t *sample)
227cabdff1aSopenharmony_ci{
228cabdff1aSopenharmony_ci    int32_t shift_count, value, f = *sample;
229cabdff1aSopenharmony_ci
230cabdff1aSopenharmony_ci    if (get_exponent(f) == 255) {
231cabdff1aSopenharmony_ci        s->float_flags |= FLOAT_EXCEPTIONS;
232cabdff1aSopenharmony_ci        value = 0x1000000;
233cabdff1aSopenharmony_ci        shift_count = 0;
234cabdff1aSopenharmony_ci    } else if (get_exponent(f)) {
235cabdff1aSopenharmony_ci        shift_count = s->max_exp - get_exponent(f);
236cabdff1aSopenharmony_ci        value = 0x800000 + get_mantissa(f);
237cabdff1aSopenharmony_ci    } else {
238cabdff1aSopenharmony_ci        shift_count = s->max_exp ? s->max_exp - 1 : 0;
239cabdff1aSopenharmony_ci        value = get_mantissa(f);
240cabdff1aSopenharmony_ci    }
241cabdff1aSopenharmony_ci
242cabdff1aSopenharmony_ci    if (shift_count < 25)
243cabdff1aSopenharmony_ci        value >>= shift_count;
244cabdff1aSopenharmony_ci    else
245cabdff1aSopenharmony_ci        value = 0;
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci    if (!value) {
248cabdff1aSopenharmony_ci        if (get_exponent(f) || get_mantissa(f))
249cabdff1aSopenharmony_ci            s->false_zeros++;
250cabdff1aSopenharmony_ci        else if (get_sign(f))
251cabdff1aSopenharmony_ci            s->neg_zeros++;
252cabdff1aSopenharmony_ci    } else if (shift_count) {
253cabdff1aSopenharmony_ci        int32_t mask = (1 << shift_count) - 1;
254cabdff1aSopenharmony_ci
255cabdff1aSopenharmony_ci        if (!(get_mantissa(f) & mask))
256cabdff1aSopenharmony_ci            s->shifted_zeros++;
257cabdff1aSopenharmony_ci        else if ((get_mantissa(f) & mask) == mask)
258cabdff1aSopenharmony_ci            s->shifted_ones++;
259cabdff1aSopenharmony_ci        else
260cabdff1aSopenharmony_ci            s->shifted_both++;
261cabdff1aSopenharmony_ci    }
262cabdff1aSopenharmony_ci
263cabdff1aSopenharmony_ci    s->ordata |= value;
264cabdff1aSopenharmony_ci    *sample = get_sign(f) ? -value : value;
265cabdff1aSopenharmony_ci}
266cabdff1aSopenharmony_ci
267cabdff1aSopenharmony_cistatic int scan_float(WavPackEncodeContext *s,
268cabdff1aSopenharmony_ci                      int32_t *samples_l, int32_t *samples_r,
269cabdff1aSopenharmony_ci                      int nb_samples)
270cabdff1aSopenharmony_ci{
271cabdff1aSopenharmony_ci    uint32_t crc = 0xffffffffu;
272cabdff1aSopenharmony_ci    int i;
273cabdff1aSopenharmony_ci
274cabdff1aSopenharmony_ci    s->shifted_ones = s->shifted_zeros = s->shifted_both = s->ordata = 0;
275cabdff1aSopenharmony_ci    s->float_shift = s->float_flags = 0;
276cabdff1aSopenharmony_ci    s->false_zeros = s->neg_zeros = 0;
277cabdff1aSopenharmony_ci    s->max_exp = 0;
278cabdff1aSopenharmony_ci
279cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
280cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
281cabdff1aSopenharmony_ci            int32_t f = samples_l[i];
282cabdff1aSopenharmony_ci            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
283cabdff1aSopenharmony_ci
284cabdff1aSopenharmony_ci            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
285cabdff1aSopenharmony_ci                s->max_exp = get_exponent(f);
286cabdff1aSopenharmony_ci        }
287cabdff1aSopenharmony_ci    } else {
288cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
289cabdff1aSopenharmony_ci            int32_t f;
290cabdff1aSopenharmony_ci
291cabdff1aSopenharmony_ci            f = samples_l[i];
292cabdff1aSopenharmony_ci            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
293cabdff1aSopenharmony_ci            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
294cabdff1aSopenharmony_ci                s->max_exp = get_exponent(f);
295cabdff1aSopenharmony_ci
296cabdff1aSopenharmony_ci            f = samples_r[i];
297cabdff1aSopenharmony_ci            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
298cabdff1aSopenharmony_ci
299cabdff1aSopenharmony_ci            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
300cabdff1aSopenharmony_ci                s->max_exp = get_exponent(f);
301cabdff1aSopenharmony_ci        }
302cabdff1aSopenharmony_ci    }
303cabdff1aSopenharmony_ci
304cabdff1aSopenharmony_ci    s->crc_x = crc;
305cabdff1aSopenharmony_ci
306cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
307cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++)
308cabdff1aSopenharmony_ci            process_float(s, &samples_l[i]);
309cabdff1aSopenharmony_ci    } else {
310cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
311cabdff1aSopenharmony_ci            process_float(s, &samples_l[i]);
312cabdff1aSopenharmony_ci            process_float(s, &samples_r[i]);
313cabdff1aSopenharmony_ci        }
314cabdff1aSopenharmony_ci    }
315cabdff1aSopenharmony_ci
316cabdff1aSopenharmony_ci    s->float_max_exp = s->max_exp;
317cabdff1aSopenharmony_ci
318cabdff1aSopenharmony_ci    if (s->shifted_both)
319cabdff1aSopenharmony_ci        s->float_flags |= FLOAT_SHIFT_SENT;
320cabdff1aSopenharmony_ci    else if (s->shifted_ones && !s->shifted_zeros)
321cabdff1aSopenharmony_ci        s->float_flags |= FLOAT_SHIFT_ONES;
322cabdff1aSopenharmony_ci    else if (s->shifted_ones && s->shifted_zeros)
323cabdff1aSopenharmony_ci        s->float_flags |= FLOAT_SHIFT_SAME;
324cabdff1aSopenharmony_ci    else if (s->ordata && !(s->ordata & 1)) {
325cabdff1aSopenharmony_ci        do {
326cabdff1aSopenharmony_ci            s->float_shift++;
327cabdff1aSopenharmony_ci            s->ordata >>= 1;
328cabdff1aSopenharmony_ci        } while (!(s->ordata & 1));
329cabdff1aSopenharmony_ci
330cabdff1aSopenharmony_ci        if (s->flags & WV_MONO_DATA)
331cabdff1aSopenharmony_ci            shift_mono(samples_l, nb_samples, s->float_shift);
332cabdff1aSopenharmony_ci        else
333cabdff1aSopenharmony_ci            shift_stereo(samples_l, samples_r, nb_samples, s->float_shift);
334cabdff1aSopenharmony_ci    }
335cabdff1aSopenharmony_ci
336cabdff1aSopenharmony_ci    s->flags &= ~MAG_MASK;
337cabdff1aSopenharmony_ci
338cabdff1aSopenharmony_ci    while (s->ordata) {
339cabdff1aSopenharmony_ci        s->flags += 1 << MAG_LSB;
340cabdff1aSopenharmony_ci        s->ordata >>= 1;
341cabdff1aSopenharmony_ci    }
342cabdff1aSopenharmony_ci
343cabdff1aSopenharmony_ci    if (s->false_zeros || s->neg_zeros)
344cabdff1aSopenharmony_ci        s->float_flags |= FLOAT_ZEROS_SENT;
345cabdff1aSopenharmony_ci
346cabdff1aSopenharmony_ci    if (s->neg_zeros)
347cabdff1aSopenharmony_ci        s->float_flags |= FLOAT_NEG_ZEROS;
348cabdff1aSopenharmony_ci
349cabdff1aSopenharmony_ci    return s->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT |
350cabdff1aSopenharmony_ci                             FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME);
351cabdff1aSopenharmony_ci}
352cabdff1aSopenharmony_ci
353cabdff1aSopenharmony_cistatic void scan_int23(WavPackEncodeContext *s,
354cabdff1aSopenharmony_ci                       int32_t *samples_l, int32_t *samples_r,
355cabdff1aSopenharmony_ci                       int nb_samples)
356cabdff1aSopenharmony_ci{
357cabdff1aSopenharmony_ci    uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0;
358cabdff1aSopenharmony_ci    int i, total_shift = 0;
359cabdff1aSopenharmony_ci
360cabdff1aSopenharmony_ci    s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0;
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
363cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
364cabdff1aSopenharmony_ci            int32_t M = samples_l[i];
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_ci            magdata |= (M < 0) ? ~M : M;
367cabdff1aSopenharmony_ci            xordata |= M ^ -(M & 1);
368cabdff1aSopenharmony_ci            anddata &= M;
369cabdff1aSopenharmony_ci            ordata  |= M;
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_ci            if ((ordata & 1) && !(anddata & 1) && (xordata & 2))
372cabdff1aSopenharmony_ci                return;
373cabdff1aSopenharmony_ci        }
374cabdff1aSopenharmony_ci    } else {
375cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
376cabdff1aSopenharmony_ci            int32_t L = samples_l[i];
377cabdff1aSopenharmony_ci            int32_t R = samples_r[i];
378cabdff1aSopenharmony_ci
379cabdff1aSopenharmony_ci            magdata |= (L < 0) ? ~L : L;
380cabdff1aSopenharmony_ci            magdata |= (R < 0) ? ~R : R;
381cabdff1aSopenharmony_ci            xordata |= L ^ -(L & 1);
382cabdff1aSopenharmony_ci            xordata |= R ^ -(R & 1);
383cabdff1aSopenharmony_ci            anddata &= L & R;
384cabdff1aSopenharmony_ci            ordata  |= L | R;
385cabdff1aSopenharmony_ci
386cabdff1aSopenharmony_ci            if ((ordata & 1) && !(anddata & 1) && (xordata & 2))
387cabdff1aSopenharmony_ci                return;
388cabdff1aSopenharmony_ci        }
389cabdff1aSopenharmony_ci    }
390cabdff1aSopenharmony_ci
391cabdff1aSopenharmony_ci    s->flags &= ~MAG_MASK;
392cabdff1aSopenharmony_ci
393cabdff1aSopenharmony_ci    while (magdata) {
394cabdff1aSopenharmony_ci        s->flags += 1 << MAG_LSB;
395cabdff1aSopenharmony_ci        magdata >>= 1;
396cabdff1aSopenharmony_ci    }
397cabdff1aSopenharmony_ci
398cabdff1aSopenharmony_ci    if (!(s->flags & MAG_MASK))
399cabdff1aSopenharmony_ci        return;
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci    if (!(ordata & 1)) {
402cabdff1aSopenharmony_ci        do {
403cabdff1aSopenharmony_ci            s->flags -= 1 << MAG_LSB;
404cabdff1aSopenharmony_ci            s->int32_zeros++;
405cabdff1aSopenharmony_ci            total_shift++;
406cabdff1aSopenharmony_ci            ordata >>= 1;
407cabdff1aSopenharmony_ci        } while (!(ordata & 1));
408cabdff1aSopenharmony_ci    } else if (anddata & 1) {
409cabdff1aSopenharmony_ci        do {
410cabdff1aSopenharmony_ci            s->flags -= 1 << MAG_LSB;
411cabdff1aSopenharmony_ci            s->int32_ones++;
412cabdff1aSopenharmony_ci            total_shift++;
413cabdff1aSopenharmony_ci            anddata >>= 1;
414cabdff1aSopenharmony_ci        } while (anddata & 1);
415cabdff1aSopenharmony_ci    } else if (!(xordata & 2)) {
416cabdff1aSopenharmony_ci        do {
417cabdff1aSopenharmony_ci            s->flags -= 1 << MAG_LSB;
418cabdff1aSopenharmony_ci            s->int32_dups++;
419cabdff1aSopenharmony_ci            total_shift++;
420cabdff1aSopenharmony_ci            xordata >>= 1;
421cabdff1aSopenharmony_ci        } while (!(xordata & 2));
422cabdff1aSopenharmony_ci    }
423cabdff1aSopenharmony_ci
424cabdff1aSopenharmony_ci    if (total_shift) {
425cabdff1aSopenharmony_ci        s->flags |= WV_INT32_DATA;
426cabdff1aSopenharmony_ci
427cabdff1aSopenharmony_ci        if (s->flags & WV_MONO_DATA)
428cabdff1aSopenharmony_ci            shift_mono(samples_l, nb_samples, total_shift);
429cabdff1aSopenharmony_ci        else
430cabdff1aSopenharmony_ci            shift_stereo(samples_l, samples_r, nb_samples, total_shift);
431cabdff1aSopenharmony_ci    }
432cabdff1aSopenharmony_ci}
433cabdff1aSopenharmony_ci
434cabdff1aSopenharmony_cistatic int scan_int32(WavPackEncodeContext *s,
435cabdff1aSopenharmony_ci                      int32_t *samples_l, int32_t *samples_r,
436cabdff1aSopenharmony_ci                      int nb_samples)
437cabdff1aSopenharmony_ci{
438cabdff1aSopenharmony_ci    uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0;
439cabdff1aSopenharmony_ci    uint32_t crc = 0xffffffffu;
440cabdff1aSopenharmony_ci    int i, total_shift = 0;
441cabdff1aSopenharmony_ci
442cabdff1aSopenharmony_ci    s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0;
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
445cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
446cabdff1aSopenharmony_ci            int32_t M = samples_l[i];
447cabdff1aSopenharmony_ci
448cabdff1aSopenharmony_ci            crc = crc * 9 + (M & 0xffff) * 3 + ((M >> 16) & 0xffff);
449cabdff1aSopenharmony_ci            magdata |= (M < 0) ? ~M : M;
450cabdff1aSopenharmony_ci            xordata |= M ^ -(M & 1);
451cabdff1aSopenharmony_ci            anddata &= M;
452cabdff1aSopenharmony_ci            ordata  |= M;
453cabdff1aSopenharmony_ci        }
454cabdff1aSopenharmony_ci    } else {
455cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
456cabdff1aSopenharmony_ci            int32_t L = samples_l[i];
457cabdff1aSopenharmony_ci            int32_t R = samples_r[i];
458cabdff1aSopenharmony_ci
459cabdff1aSopenharmony_ci            crc = crc * 9 + (L & 0xffff) * 3 + ((L >> 16) & 0xffff);
460cabdff1aSopenharmony_ci            crc = crc * 9 + (R & 0xffff) * 3 + ((R >> 16) & 0xffff);
461cabdff1aSopenharmony_ci            magdata |= (L < 0) ? ~L : L;
462cabdff1aSopenharmony_ci            magdata |= (R < 0) ? ~R : R;
463cabdff1aSopenharmony_ci            xordata |= L ^ -(L & 1);
464cabdff1aSopenharmony_ci            xordata |= R ^ -(R & 1);
465cabdff1aSopenharmony_ci            anddata &= L & R;
466cabdff1aSopenharmony_ci            ordata  |= L | R;
467cabdff1aSopenharmony_ci        }
468cabdff1aSopenharmony_ci    }
469cabdff1aSopenharmony_ci
470cabdff1aSopenharmony_ci    s->crc_x = crc;
471cabdff1aSopenharmony_ci    s->flags &= ~MAG_MASK;
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_ci    while (magdata) {
474cabdff1aSopenharmony_ci        s->flags += 1 << MAG_LSB;
475cabdff1aSopenharmony_ci        magdata >>= 1;
476cabdff1aSopenharmony_ci    }
477cabdff1aSopenharmony_ci
478cabdff1aSopenharmony_ci    if (!((s->flags & MAG_MASK) >> MAG_LSB)) {
479cabdff1aSopenharmony_ci        s->flags &= ~WV_INT32_DATA;
480cabdff1aSopenharmony_ci        return 0;
481cabdff1aSopenharmony_ci    }
482cabdff1aSopenharmony_ci
483cabdff1aSopenharmony_ci    if (!(ordata & 1))
484cabdff1aSopenharmony_ci        do {
485cabdff1aSopenharmony_ci            s->flags -= 1 << MAG_LSB;
486cabdff1aSopenharmony_ci            s->int32_zeros++;
487cabdff1aSopenharmony_ci            total_shift++;
488cabdff1aSopenharmony_ci            ordata >>= 1;
489cabdff1aSopenharmony_ci        } while (!(ordata & 1));
490cabdff1aSopenharmony_ci    else if (anddata & 1)
491cabdff1aSopenharmony_ci        do {
492cabdff1aSopenharmony_ci            s->flags -= 1 << MAG_LSB;
493cabdff1aSopenharmony_ci            s->int32_ones++;
494cabdff1aSopenharmony_ci            total_shift++;
495cabdff1aSopenharmony_ci            anddata >>= 1;
496cabdff1aSopenharmony_ci        } while (anddata & 1);
497cabdff1aSopenharmony_ci    else if (!(xordata & 2))
498cabdff1aSopenharmony_ci        do {
499cabdff1aSopenharmony_ci            s->flags -= 1 << MAG_LSB;
500cabdff1aSopenharmony_ci            s->int32_dups++;
501cabdff1aSopenharmony_ci            total_shift++;
502cabdff1aSopenharmony_ci            xordata >>= 1;
503cabdff1aSopenharmony_ci        } while (!(xordata & 2));
504cabdff1aSopenharmony_ci
505cabdff1aSopenharmony_ci    if (((s->flags & MAG_MASK) >> MAG_LSB) > 23) {
506cabdff1aSopenharmony_ci        s->int32_sent_bits = (uint8_t)(((s->flags & MAG_MASK) >> MAG_LSB) - 23);
507cabdff1aSopenharmony_ci        total_shift += s->int32_sent_bits;
508cabdff1aSopenharmony_ci        s->flags &= ~MAG_MASK;
509cabdff1aSopenharmony_ci        s->flags += 23 << MAG_LSB;
510cabdff1aSopenharmony_ci    }
511cabdff1aSopenharmony_ci
512cabdff1aSopenharmony_ci    if (total_shift) {
513cabdff1aSopenharmony_ci        s->flags |= WV_INT32_DATA;
514cabdff1aSopenharmony_ci
515cabdff1aSopenharmony_ci        if (s->flags & WV_MONO_DATA)
516cabdff1aSopenharmony_ci            shift_mono(samples_l, nb_samples, total_shift);
517cabdff1aSopenharmony_ci        else
518cabdff1aSopenharmony_ci            shift_stereo(samples_l, samples_r, nb_samples, total_shift);
519cabdff1aSopenharmony_ci    }
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci    return s->int32_sent_bits;
522cabdff1aSopenharmony_ci}
523cabdff1aSopenharmony_ci
524cabdff1aSopenharmony_cistatic int8_t store_weight(int weight)
525cabdff1aSopenharmony_ci{
526cabdff1aSopenharmony_ci    weight = av_clip(weight, -1024, 1024);
527cabdff1aSopenharmony_ci    if (weight > 0)
528cabdff1aSopenharmony_ci        weight -= (weight + 64) >> 7;
529cabdff1aSopenharmony_ci
530cabdff1aSopenharmony_ci    return (weight + 4) >> 3;
531cabdff1aSopenharmony_ci}
532cabdff1aSopenharmony_ci
533cabdff1aSopenharmony_cistatic int restore_weight(int8_t weight)
534cabdff1aSopenharmony_ci{
535cabdff1aSopenharmony_ci    int result = 8 * weight;
536cabdff1aSopenharmony_ci
537cabdff1aSopenharmony_ci    if (result > 0)
538cabdff1aSopenharmony_ci        result += (result + 64) >> 7;
539cabdff1aSopenharmony_ci
540cabdff1aSopenharmony_ci    return result;
541cabdff1aSopenharmony_ci}
542cabdff1aSopenharmony_ci
543cabdff1aSopenharmony_cistatic int log2s(int32_t value)
544cabdff1aSopenharmony_ci{
545cabdff1aSopenharmony_ci    return (value < 0) ? -wp_log2(-value) : wp_log2(value);
546cabdff1aSopenharmony_ci}
547cabdff1aSopenharmony_ci
548cabdff1aSopenharmony_cistatic void decorr_mono(int32_t *in_samples, int32_t *out_samples,
549cabdff1aSopenharmony_ci                        int nb_samples, struct Decorr *dpp, int dir)
550cabdff1aSopenharmony_ci{
551cabdff1aSopenharmony_ci    int m = 0, i;
552cabdff1aSopenharmony_ci
553cabdff1aSopenharmony_ci    dpp->sumA = 0;
554cabdff1aSopenharmony_ci
555cabdff1aSopenharmony_ci    if (dir < 0) {
556cabdff1aSopenharmony_ci        out_samples += (nb_samples - 1);
557cabdff1aSopenharmony_ci        in_samples  += (nb_samples - 1);
558cabdff1aSopenharmony_ci    }
559cabdff1aSopenharmony_ci
560cabdff1aSopenharmony_ci    dpp->weightA = restore_weight(store_weight(dpp->weightA));
561cabdff1aSopenharmony_ci
562cabdff1aSopenharmony_ci    for (i = 0; i < MAX_TERM; i++)
563cabdff1aSopenharmony_ci        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
564cabdff1aSopenharmony_ci
565cabdff1aSopenharmony_ci    if (dpp->value > MAX_TERM) {
566cabdff1aSopenharmony_ci        while (nb_samples--) {
567cabdff1aSopenharmony_ci            int32_t left, sam_A;
568cabdff1aSopenharmony_ci
569cabdff1aSopenharmony_ci            sam_A = ((3 - (dpp->value & 1)) * dpp->samplesA[0] - dpp->samplesA[1]) >> !(dpp->value & 1);
570cabdff1aSopenharmony_ci
571cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
572cabdff1aSopenharmony_ci            dpp->samplesA[0] = left = in_samples[0];
573cabdff1aSopenharmony_ci
574cabdff1aSopenharmony_ci            left -= APPLY_WEIGHT(dpp->weightA, sam_A);
575cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left);
576cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
577cabdff1aSopenharmony_ci            out_samples[0] = left;
578cabdff1aSopenharmony_ci            in_samples += dir;
579cabdff1aSopenharmony_ci            out_samples += dir;
580cabdff1aSopenharmony_ci        }
581cabdff1aSopenharmony_ci    } else if (dpp->value > 0) {
582cabdff1aSopenharmony_ci        while (nb_samples--) {
583cabdff1aSopenharmony_ci            int k = (m + dpp->value) & (MAX_TERM - 1);
584cabdff1aSopenharmony_ci            int32_t left, sam_A;
585cabdff1aSopenharmony_ci
586cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[m];
587cabdff1aSopenharmony_ci            dpp->samplesA[k] = left = in_samples[0];
588cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
589cabdff1aSopenharmony_ci
590cabdff1aSopenharmony_ci            left -= APPLY_WEIGHT(dpp->weightA, sam_A);
591cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left);
592cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
593cabdff1aSopenharmony_ci            out_samples[0] = left;
594cabdff1aSopenharmony_ci            in_samples += dir;
595cabdff1aSopenharmony_ci            out_samples += dir;
596cabdff1aSopenharmony_ci        }
597cabdff1aSopenharmony_ci    }
598cabdff1aSopenharmony_ci
599cabdff1aSopenharmony_ci    if (m && dpp->value > 0 && dpp->value <= MAX_TERM) {
600cabdff1aSopenharmony_ci        int32_t temp_A[MAX_TERM];
601cabdff1aSopenharmony_ci
602cabdff1aSopenharmony_ci        memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
603cabdff1aSopenharmony_ci
604cabdff1aSopenharmony_ci        for (i = 0; i < MAX_TERM; i++) {
605cabdff1aSopenharmony_ci            dpp->samplesA[i] = temp_A[m];
606cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
607cabdff1aSopenharmony_ci        }
608cabdff1aSopenharmony_ci    }
609cabdff1aSopenharmony_ci}
610cabdff1aSopenharmony_ci
611cabdff1aSopenharmony_cistatic void reverse_mono_decorr(struct Decorr *dpp)
612cabdff1aSopenharmony_ci{
613cabdff1aSopenharmony_ci    if (dpp->value > MAX_TERM) {
614cabdff1aSopenharmony_ci        int32_t sam_A;
615cabdff1aSopenharmony_ci
616cabdff1aSopenharmony_ci        if (dpp->value & 1)
617cabdff1aSopenharmony_ci            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
618cabdff1aSopenharmony_ci        else
619cabdff1aSopenharmony_ci            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
620cabdff1aSopenharmony_ci
621cabdff1aSopenharmony_ci        dpp->samplesA[1] = dpp->samplesA[0];
622cabdff1aSopenharmony_ci        dpp->samplesA[0] = sam_A;
623cabdff1aSopenharmony_ci
624cabdff1aSopenharmony_ci        if (dpp->value & 1)
625cabdff1aSopenharmony_ci            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
626cabdff1aSopenharmony_ci        else
627cabdff1aSopenharmony_ci            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
628cabdff1aSopenharmony_ci
629cabdff1aSopenharmony_ci        dpp->samplesA[1] = sam_A;
630cabdff1aSopenharmony_ci    } else if (dpp->value > 1) {
631cabdff1aSopenharmony_ci        int i, j, k;
632cabdff1aSopenharmony_ci
633cabdff1aSopenharmony_ci        for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) {
634cabdff1aSopenharmony_ci            i &= (MAX_TERM - 1);
635cabdff1aSopenharmony_ci            j &= (MAX_TERM - 1);
636cabdff1aSopenharmony_ci            dpp->samplesA[i] ^= dpp->samplesA[j];
637cabdff1aSopenharmony_ci            dpp->samplesA[j] ^= dpp->samplesA[i];
638cabdff1aSopenharmony_ci            dpp->samplesA[i] ^= dpp->samplesA[j];
639cabdff1aSopenharmony_ci        }
640cabdff1aSopenharmony_ci    }
641cabdff1aSopenharmony_ci}
642cabdff1aSopenharmony_ci
643cabdff1aSopenharmony_ci#define count_bits(av) ((av) ? 32 - ff_clz(av) : 0)
644cabdff1aSopenharmony_ci
645cabdff1aSopenharmony_cistatic uint32_t log2sample(uint32_t v, int limit, uint32_t *result)
646cabdff1aSopenharmony_ci{
647cabdff1aSopenharmony_ci    uint32_t dbits = count_bits(v);
648cabdff1aSopenharmony_ci
649cabdff1aSopenharmony_ci    if ((v += v >> 9) < (1 << 8)) {
650cabdff1aSopenharmony_ci        *result += (dbits << 8) + ff_wp_log2_table[(v << (9 - dbits)) & 0xff];
651cabdff1aSopenharmony_ci    } else {
652cabdff1aSopenharmony_ci        *result += dbits = (dbits << 8) + ff_wp_log2_table[(v >> (dbits - 9)) & 0xff];
653cabdff1aSopenharmony_ci
654cabdff1aSopenharmony_ci        if (limit && dbits >= limit)
655cabdff1aSopenharmony_ci            return 1;
656cabdff1aSopenharmony_ci    }
657cabdff1aSopenharmony_ci
658cabdff1aSopenharmony_ci    return 0;
659cabdff1aSopenharmony_ci}
660cabdff1aSopenharmony_ci
661cabdff1aSopenharmony_cistatic uint32_t log2mono(int32_t *samples, int nb_samples, int limit)
662cabdff1aSopenharmony_ci{
663cabdff1aSopenharmony_ci    uint32_t result = 0;
664cabdff1aSopenharmony_ci    while (nb_samples--) {
665cabdff1aSopenharmony_ci        if (log2sample(abs(*samples++), limit, &result))
666cabdff1aSopenharmony_ci            return UINT32_MAX;
667cabdff1aSopenharmony_ci    }
668cabdff1aSopenharmony_ci    return result;
669cabdff1aSopenharmony_ci}
670cabdff1aSopenharmony_ci
671cabdff1aSopenharmony_cistatic uint32_t log2stereo(int32_t *samples_l, int32_t *samples_r,
672cabdff1aSopenharmony_ci                           int nb_samples, int limit)
673cabdff1aSopenharmony_ci{
674cabdff1aSopenharmony_ci    uint32_t result = 0;
675cabdff1aSopenharmony_ci    while (nb_samples--) {
676cabdff1aSopenharmony_ci        if (log2sample(abs(*samples_l++), limit, &result) ||
677cabdff1aSopenharmony_ci            log2sample(abs(*samples_r++), limit, &result))
678cabdff1aSopenharmony_ci            return UINT32_MAX;
679cabdff1aSopenharmony_ci    }
680cabdff1aSopenharmony_ci    return result;
681cabdff1aSopenharmony_ci}
682cabdff1aSopenharmony_ci
683cabdff1aSopenharmony_cistatic void decorr_mono_buffer(int32_t *samples, int32_t *outsamples,
684cabdff1aSopenharmony_ci                               int nb_samples, struct Decorr *dpp,
685cabdff1aSopenharmony_ci                               int tindex)
686cabdff1aSopenharmony_ci{
687cabdff1aSopenharmony_ci    struct Decorr dp, *dppi = dpp + tindex;
688cabdff1aSopenharmony_ci    int delta = dppi->delta, pre_delta, term = dppi->value;
689cabdff1aSopenharmony_ci
690cabdff1aSopenharmony_ci    if (delta == 7)
691cabdff1aSopenharmony_ci        pre_delta = 7;
692cabdff1aSopenharmony_ci    else if (delta < 2)
693cabdff1aSopenharmony_ci        pre_delta = 3;
694cabdff1aSopenharmony_ci    else
695cabdff1aSopenharmony_ci        pre_delta = delta + 1;
696cabdff1aSopenharmony_ci
697cabdff1aSopenharmony_ci    CLEAR(dp);
698cabdff1aSopenharmony_ci    dp.value = term;
699cabdff1aSopenharmony_ci    dp.delta = pre_delta;
700cabdff1aSopenharmony_ci    decorr_mono(samples, outsamples, FFMIN(2048, nb_samples), &dp, -1);
701cabdff1aSopenharmony_ci    dp.delta = delta;
702cabdff1aSopenharmony_ci
703cabdff1aSopenharmony_ci    if (tindex == 0)
704cabdff1aSopenharmony_ci        reverse_mono_decorr(&dp);
705cabdff1aSopenharmony_ci    else
706cabdff1aSopenharmony_ci        CLEAR(dp.samplesA);
707cabdff1aSopenharmony_ci
708cabdff1aSopenharmony_ci    memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA));
709cabdff1aSopenharmony_ci    dppi->weightA = dp.weightA;
710cabdff1aSopenharmony_ci
711cabdff1aSopenharmony_ci    if (delta == 0) {
712cabdff1aSopenharmony_ci        dp.delta = 1;
713cabdff1aSopenharmony_ci        decorr_mono(samples, outsamples, nb_samples, &dp, 1);
714cabdff1aSopenharmony_ci        dp.delta = 0;
715cabdff1aSopenharmony_ci        memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA));
716cabdff1aSopenharmony_ci        dppi->weightA = dp.weightA = dp.sumA / nb_samples;
717cabdff1aSopenharmony_ci    }
718cabdff1aSopenharmony_ci
719cabdff1aSopenharmony_ci    decorr_mono(samples, outsamples, nb_samples, &dp, 1);
720cabdff1aSopenharmony_ci}
721cabdff1aSopenharmony_ci
722cabdff1aSopenharmony_cistatic void recurse_mono(WavPackEncodeContext *s, WavPackExtraInfo *info,
723cabdff1aSopenharmony_ci                         int depth, int delta, uint32_t input_bits)
724cabdff1aSopenharmony_ci{
725cabdff1aSopenharmony_ci    int term, branches = s->num_branches - depth;
726cabdff1aSopenharmony_ci    int32_t *samples, *outsamples;
727cabdff1aSopenharmony_ci    uint32_t term_bits[22], bits;
728cabdff1aSopenharmony_ci
729cabdff1aSopenharmony_ci    if (branches < 1 || depth + 1 == info->nterms)
730cabdff1aSopenharmony_ci        branches = 1;
731cabdff1aSopenharmony_ci
732cabdff1aSopenharmony_ci    CLEAR(term_bits);
733cabdff1aSopenharmony_ci    samples = s->sampleptrs[depth][0];
734cabdff1aSopenharmony_ci    outsamples = s->sampleptrs[depth + 1][0];
735cabdff1aSopenharmony_ci
736cabdff1aSopenharmony_ci    for (term = 1; term <= 18; term++) {
737cabdff1aSopenharmony_ci        if (term == 17 && branches == 1 && depth + 1 < info->nterms)
738cabdff1aSopenharmony_ci            continue;
739cabdff1aSopenharmony_ci
740cabdff1aSopenharmony_ci        if (term > 8 && term < 17)
741cabdff1aSopenharmony_ci            continue;
742cabdff1aSopenharmony_ci
743cabdff1aSopenharmony_ci        if (!s->extra_flags && (term > 4 && term < 17))
744cabdff1aSopenharmony_ci            continue;
745cabdff1aSopenharmony_ci
746cabdff1aSopenharmony_ci        info->dps[depth].value = term;
747cabdff1aSopenharmony_ci        info->dps[depth].delta = delta;
748cabdff1aSopenharmony_ci        decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth);
749cabdff1aSopenharmony_ci        bits = log2mono(outsamples, s->block_samples, info->log_limit);
750cabdff1aSopenharmony_ci
751cabdff1aSopenharmony_ci        if (bits < info->best_bits) {
752cabdff1aSopenharmony_ci            info->best_bits = bits;
753cabdff1aSopenharmony_ci            CLEAR(s->decorr_passes);
754cabdff1aSopenharmony_ci            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1));
755cabdff1aSopenharmony_ci            memcpy(s->sampleptrs[info->nterms + 1][0],
756cabdff1aSopenharmony_ci                   s->sampleptrs[depth + 1][0], s->block_samples * 4);
757cabdff1aSopenharmony_ci        }
758cabdff1aSopenharmony_ci
759cabdff1aSopenharmony_ci        term_bits[term + 3] = bits;
760cabdff1aSopenharmony_ci    }
761cabdff1aSopenharmony_ci
762cabdff1aSopenharmony_ci    while (depth + 1 < info->nterms && branches--) {
763cabdff1aSopenharmony_ci        uint32_t local_best_bits = input_bits;
764cabdff1aSopenharmony_ci        int best_term = 0, i;
765cabdff1aSopenharmony_ci
766cabdff1aSopenharmony_ci        for (i = 0; i < 22; i++)
767cabdff1aSopenharmony_ci            if (term_bits[i] && term_bits[i] < local_best_bits) {
768cabdff1aSopenharmony_ci                local_best_bits = term_bits[i];
769cabdff1aSopenharmony_ci                best_term = i - 3;
770cabdff1aSopenharmony_ci            }
771cabdff1aSopenharmony_ci
772cabdff1aSopenharmony_ci        if (!best_term)
773cabdff1aSopenharmony_ci            break;
774cabdff1aSopenharmony_ci
775cabdff1aSopenharmony_ci        term_bits[best_term + 3] = 0;
776cabdff1aSopenharmony_ci
777cabdff1aSopenharmony_ci        info->dps[depth].value = best_term;
778cabdff1aSopenharmony_ci        info->dps[depth].delta = delta;
779cabdff1aSopenharmony_ci        decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth);
780cabdff1aSopenharmony_ci
781cabdff1aSopenharmony_ci        recurse_mono(s, info, depth + 1, delta, local_best_bits);
782cabdff1aSopenharmony_ci    }
783cabdff1aSopenharmony_ci}
784cabdff1aSopenharmony_ci
785cabdff1aSopenharmony_cistatic void sort_mono(WavPackEncodeContext *s, WavPackExtraInfo *info)
786cabdff1aSopenharmony_ci{
787cabdff1aSopenharmony_ci    int reversed = 1;
788cabdff1aSopenharmony_ci    uint32_t bits;
789cabdff1aSopenharmony_ci
790cabdff1aSopenharmony_ci    while (reversed) {
791cabdff1aSopenharmony_ci        int ri, i;
792cabdff1aSopenharmony_ci
793cabdff1aSopenharmony_ci        memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes));
794cabdff1aSopenharmony_ci        reversed = 0;
795cabdff1aSopenharmony_ci
796cabdff1aSopenharmony_ci        for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) {
797cabdff1aSopenharmony_ci
798cabdff1aSopenharmony_ci            if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value)
799cabdff1aSopenharmony_ci                break;
800cabdff1aSopenharmony_ci
801cabdff1aSopenharmony_ci            if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) {
802cabdff1aSopenharmony_ci                decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0],
803cabdff1aSopenharmony_ci                                   s->block_samples, info->dps, ri);
804cabdff1aSopenharmony_ci                continue;
805cabdff1aSopenharmony_ci            }
806cabdff1aSopenharmony_ci
807cabdff1aSopenharmony_ci            info->dps[ri  ] = s->decorr_passes[ri+1];
808cabdff1aSopenharmony_ci            info->dps[ri+1] = s->decorr_passes[ri  ];
809cabdff1aSopenharmony_ci
810cabdff1aSopenharmony_ci            for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++)
811cabdff1aSopenharmony_ci                decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
812cabdff1aSopenharmony_ci                                   s->block_samples, info->dps, i);
813cabdff1aSopenharmony_ci
814cabdff1aSopenharmony_ci            bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
815cabdff1aSopenharmony_ci            if (bits < info->best_bits) {
816cabdff1aSopenharmony_ci                reversed = 1;
817cabdff1aSopenharmony_ci                info->best_bits = bits;
818cabdff1aSopenharmony_ci                CLEAR(s->decorr_passes);
819cabdff1aSopenharmony_ci                memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
820cabdff1aSopenharmony_ci                memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
821cabdff1aSopenharmony_ci                       s->block_samples * 4);
822cabdff1aSopenharmony_ci            } else {
823cabdff1aSopenharmony_ci                info->dps[ri  ] = s->decorr_passes[ri];
824cabdff1aSopenharmony_ci                info->dps[ri+1] = s->decorr_passes[ri+1];
825cabdff1aSopenharmony_ci                decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0],
826cabdff1aSopenharmony_ci                                   s->block_samples, info->dps, ri);
827cabdff1aSopenharmony_ci            }
828cabdff1aSopenharmony_ci        }
829cabdff1aSopenharmony_ci    }
830cabdff1aSopenharmony_ci}
831cabdff1aSopenharmony_ci
832cabdff1aSopenharmony_cistatic void delta_mono(WavPackEncodeContext *s, WavPackExtraInfo *info)
833cabdff1aSopenharmony_ci{
834cabdff1aSopenharmony_ci    int lower = 0, delta, d;
835cabdff1aSopenharmony_ci    uint32_t bits;
836cabdff1aSopenharmony_ci
837cabdff1aSopenharmony_ci    if (!s->decorr_passes[0].value)
838cabdff1aSopenharmony_ci        return;
839cabdff1aSopenharmony_ci    delta = s->decorr_passes[0].delta;
840cabdff1aSopenharmony_ci
841cabdff1aSopenharmony_ci    for (d = delta - 1; d >= 0; d--) {
842cabdff1aSopenharmony_ci        int i;
843cabdff1aSopenharmony_ci
844cabdff1aSopenharmony_ci        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
845cabdff1aSopenharmony_ci            info->dps[i].value = s->decorr_passes[i].value;
846cabdff1aSopenharmony_ci            info->dps[i].delta = d;
847cabdff1aSopenharmony_ci            decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
848cabdff1aSopenharmony_ci                               s->block_samples, info->dps, i);
849cabdff1aSopenharmony_ci        }
850cabdff1aSopenharmony_ci
851cabdff1aSopenharmony_ci        bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
852cabdff1aSopenharmony_ci        if (bits >= info->best_bits)
853cabdff1aSopenharmony_ci            break;
854cabdff1aSopenharmony_ci
855cabdff1aSopenharmony_ci        lower = 1;
856cabdff1aSopenharmony_ci        info->best_bits = bits;
857cabdff1aSopenharmony_ci        CLEAR(s->decorr_passes);
858cabdff1aSopenharmony_ci        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
859cabdff1aSopenharmony_ci        memcpy(s->sampleptrs[info->nterms + 1][0],  s->sampleptrs[i][0],
860cabdff1aSopenharmony_ci               s->block_samples * 4);
861cabdff1aSopenharmony_ci    }
862cabdff1aSopenharmony_ci
863cabdff1aSopenharmony_ci    for (d = delta + 1; !lower && d <= 7; d++) {
864cabdff1aSopenharmony_ci        int i;
865cabdff1aSopenharmony_ci
866cabdff1aSopenharmony_ci        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
867cabdff1aSopenharmony_ci            info->dps[i].value = s->decorr_passes[i].value;
868cabdff1aSopenharmony_ci            info->dps[i].delta = d;
869cabdff1aSopenharmony_ci            decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
870cabdff1aSopenharmony_ci                               s->block_samples, info->dps, i);
871cabdff1aSopenharmony_ci        }
872cabdff1aSopenharmony_ci
873cabdff1aSopenharmony_ci        bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
874cabdff1aSopenharmony_ci        if (bits >= info->best_bits)
875cabdff1aSopenharmony_ci            break;
876cabdff1aSopenharmony_ci
877cabdff1aSopenharmony_ci        info->best_bits = bits;
878cabdff1aSopenharmony_ci        CLEAR(s->decorr_passes);
879cabdff1aSopenharmony_ci        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
880cabdff1aSopenharmony_ci        memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
881cabdff1aSopenharmony_ci               s->block_samples * 4);
882cabdff1aSopenharmony_ci    }
883cabdff1aSopenharmony_ci}
884cabdff1aSopenharmony_ci
885cabdff1aSopenharmony_cistatic int allocate_buffers2(WavPackEncodeContext *s, int nterms)
886cabdff1aSopenharmony_ci{
887cabdff1aSopenharmony_ci    int i;
888cabdff1aSopenharmony_ci
889cabdff1aSopenharmony_ci    for (i = 0; i < nterms + 2; i++) {
890cabdff1aSopenharmony_ci        av_fast_padded_malloc(&s->sampleptrs[i][0], &s->sampleptrs_size[i][0],
891cabdff1aSopenharmony_ci                              s->block_samples * 4);
892cabdff1aSopenharmony_ci        if (!s->sampleptrs[i][0])
893cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
894cabdff1aSopenharmony_ci        if (!(s->flags & WV_MONO_DATA)) {
895cabdff1aSopenharmony_ci            av_fast_padded_malloc(&s->sampleptrs[i][1], &s->sampleptrs_size[i][1],
896cabdff1aSopenharmony_ci                                  s->block_samples * 4);
897cabdff1aSopenharmony_ci            if (!s->sampleptrs[i][1])
898cabdff1aSopenharmony_ci                return AVERROR(ENOMEM);
899cabdff1aSopenharmony_ci        }
900cabdff1aSopenharmony_ci    }
901cabdff1aSopenharmony_ci
902cabdff1aSopenharmony_ci    return 0;
903cabdff1aSopenharmony_ci}
904cabdff1aSopenharmony_ci
905cabdff1aSopenharmony_cistatic int allocate_buffers(WavPackEncodeContext *s)
906cabdff1aSopenharmony_ci{
907cabdff1aSopenharmony_ci    int i;
908cabdff1aSopenharmony_ci
909cabdff1aSopenharmony_ci    for (i = 0; i < 2; i++) {
910cabdff1aSopenharmony_ci        av_fast_padded_malloc(&s->best_buffer[0], &s->best_buffer_size[0],
911cabdff1aSopenharmony_ci                              s->block_samples * 4);
912cabdff1aSopenharmony_ci        if (!s->best_buffer[0])
913cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
914cabdff1aSopenharmony_ci
915cabdff1aSopenharmony_ci        av_fast_padded_malloc(&s->temp_buffer[i][0], &s->temp_buffer_size[i][0],
916cabdff1aSopenharmony_ci                              s->block_samples * 4);
917cabdff1aSopenharmony_ci        if (!s->temp_buffer[i][0])
918cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
919cabdff1aSopenharmony_ci        if (!(s->flags & WV_MONO_DATA)) {
920cabdff1aSopenharmony_ci            av_fast_padded_malloc(&s->best_buffer[1], &s->best_buffer_size[1],
921cabdff1aSopenharmony_ci                                  s->block_samples * 4);
922cabdff1aSopenharmony_ci            if (!s->best_buffer[1])
923cabdff1aSopenharmony_ci                return AVERROR(ENOMEM);
924cabdff1aSopenharmony_ci
925cabdff1aSopenharmony_ci            av_fast_padded_malloc(&s->temp_buffer[i][1], &s->temp_buffer_size[i][1],
926cabdff1aSopenharmony_ci                                  s->block_samples * 4);
927cabdff1aSopenharmony_ci            if (!s->temp_buffer[i][1])
928cabdff1aSopenharmony_ci                return AVERROR(ENOMEM);
929cabdff1aSopenharmony_ci        }
930cabdff1aSopenharmony_ci    }
931cabdff1aSopenharmony_ci
932cabdff1aSopenharmony_ci    return 0;
933cabdff1aSopenharmony_ci}
934cabdff1aSopenharmony_ci
935cabdff1aSopenharmony_cistatic void analyze_mono(WavPackEncodeContext *s, int32_t *samples, int do_samples)
936cabdff1aSopenharmony_ci{
937cabdff1aSopenharmony_ci    WavPackExtraInfo info;
938cabdff1aSopenharmony_ci    int i;
939cabdff1aSopenharmony_ci
940cabdff1aSopenharmony_ci    info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
941cabdff1aSopenharmony_ci    info.log_limit = FFMIN(6912, info.log_limit);
942cabdff1aSopenharmony_ci
943cabdff1aSopenharmony_ci    info.nterms = s->num_terms;
944cabdff1aSopenharmony_ci
945cabdff1aSopenharmony_ci    if (allocate_buffers2(s, s->num_terms))
946cabdff1aSopenharmony_ci        return;
947cabdff1aSopenharmony_ci
948cabdff1aSopenharmony_ci    memcpy(info.dps, s->decorr_passes, sizeof(info.dps));
949cabdff1aSopenharmony_ci    memcpy(s->sampleptrs[0][0], samples, s->block_samples * 4);
950cabdff1aSopenharmony_ci
951cabdff1aSopenharmony_ci    for (i = 0; i < info.nterms && info.dps[i].value; i++)
952cabdff1aSopenharmony_ci        decorr_mono(s->sampleptrs[i][0], s->sampleptrs[i + 1][0],
953cabdff1aSopenharmony_ci                    s->block_samples, info.dps + i, 1);
954cabdff1aSopenharmony_ci
955cabdff1aSopenharmony_ci    info.best_bits = log2mono(s->sampleptrs[info.nterms][0], s->block_samples, 0) * 1;
956cabdff1aSopenharmony_ci    memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4);
957cabdff1aSopenharmony_ci
958cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_BRANCHES)
959cabdff1aSopenharmony_ci        recurse_mono(s, &info, 0, (int) floor(s->delta_decay + 0.5),
960cabdff1aSopenharmony_ci                     log2mono(s->sampleptrs[0][0], s->block_samples, 0));
961cabdff1aSopenharmony_ci
962cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_SORT_FIRST)
963cabdff1aSopenharmony_ci        sort_mono(s, &info);
964cabdff1aSopenharmony_ci
965cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_TRY_DELTAS) {
966cabdff1aSopenharmony_ci        delta_mono(s, &info);
967cabdff1aSopenharmony_ci
968cabdff1aSopenharmony_ci        if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value)
969cabdff1aSopenharmony_ci            s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0);
970cabdff1aSopenharmony_ci        else
971cabdff1aSopenharmony_ci            s->delta_decay = 2.0;
972cabdff1aSopenharmony_ci    }
973cabdff1aSopenharmony_ci
974cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_SORT_LAST)
975cabdff1aSopenharmony_ci        sort_mono(s, &info);
976cabdff1aSopenharmony_ci
977cabdff1aSopenharmony_ci    if (do_samples)
978cabdff1aSopenharmony_ci        memcpy(samples, s->sampleptrs[info.nterms + 1][0], s->block_samples * 4);
979cabdff1aSopenharmony_ci
980cabdff1aSopenharmony_ci    for (i = 0; i < info.nterms; i++)
981cabdff1aSopenharmony_ci        if (!s->decorr_passes[i].value)
982cabdff1aSopenharmony_ci            break;
983cabdff1aSopenharmony_ci
984cabdff1aSopenharmony_ci    s->num_terms = i;
985cabdff1aSopenharmony_ci}
986cabdff1aSopenharmony_ci
987cabdff1aSopenharmony_cistatic void scan_word(WavPackEncodeContext *s, WvChannel *c,
988cabdff1aSopenharmony_ci                      int32_t *samples, int nb_samples, int dir)
989cabdff1aSopenharmony_ci{
990cabdff1aSopenharmony_ci    if (dir < 0)
991cabdff1aSopenharmony_ci        samples += nb_samples - 1;
992cabdff1aSopenharmony_ci
993cabdff1aSopenharmony_ci    while (nb_samples--) {
994cabdff1aSopenharmony_ci        uint32_t low, value = labs(samples[0]);
995cabdff1aSopenharmony_ci
996cabdff1aSopenharmony_ci        if (value < GET_MED(0)) {
997cabdff1aSopenharmony_ci            DEC_MED(0);
998cabdff1aSopenharmony_ci        } else {
999cabdff1aSopenharmony_ci            low = GET_MED(0);
1000cabdff1aSopenharmony_ci            INC_MED(0);
1001cabdff1aSopenharmony_ci
1002cabdff1aSopenharmony_ci            if (value - low < GET_MED(1)) {
1003cabdff1aSopenharmony_ci                DEC_MED(1);
1004cabdff1aSopenharmony_ci            } else {
1005cabdff1aSopenharmony_ci                low += GET_MED(1);
1006cabdff1aSopenharmony_ci                INC_MED(1);
1007cabdff1aSopenharmony_ci
1008cabdff1aSopenharmony_ci                if (value - low < GET_MED(2)) {
1009cabdff1aSopenharmony_ci                    DEC_MED(2);
1010cabdff1aSopenharmony_ci                } else {
1011cabdff1aSopenharmony_ci                    INC_MED(2);
1012cabdff1aSopenharmony_ci                }
1013cabdff1aSopenharmony_ci            }
1014cabdff1aSopenharmony_ci        }
1015cabdff1aSopenharmony_ci        samples += dir;
1016cabdff1aSopenharmony_ci    }
1017cabdff1aSopenharmony_ci}
1018cabdff1aSopenharmony_ci
1019cabdff1aSopenharmony_cistatic int wv_mono(WavPackEncodeContext *s, int32_t *samples,
1020cabdff1aSopenharmony_ci                   int no_history, int do_samples)
1021cabdff1aSopenharmony_ci{
1022cabdff1aSopenharmony_ci    struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}};
1023cabdff1aSopenharmony_ci    int nb_samples = s->block_samples;
1024cabdff1aSopenharmony_ci    int buf_size = sizeof(int32_t) * nb_samples;
1025cabdff1aSopenharmony_ci    uint32_t best_size = UINT32_MAX, size;
1026cabdff1aSopenharmony_ci    int log_limit, pi, i, ret;
1027cabdff1aSopenharmony_ci
1028cabdff1aSopenharmony_ci    for (i = 0; i < nb_samples; i++)
1029cabdff1aSopenharmony_ci        if (samples[i])
1030cabdff1aSopenharmony_ci            break;
1031cabdff1aSopenharmony_ci
1032cabdff1aSopenharmony_ci    if (i == nb_samples) {
1033cabdff1aSopenharmony_ci        CLEAR(s->decorr_passes);
1034cabdff1aSopenharmony_ci        CLEAR(s->w);
1035cabdff1aSopenharmony_ci        s->num_terms = 0;
1036cabdff1aSopenharmony_ci        return 0;
1037cabdff1aSopenharmony_ci    }
1038cabdff1aSopenharmony_ci
1039cabdff1aSopenharmony_ci    log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
1040cabdff1aSopenharmony_ci    log_limit = FFMIN(6912, log_limit);
1041cabdff1aSopenharmony_ci
1042cabdff1aSopenharmony_ci    if ((ret = allocate_buffers(s)) < 0)
1043cabdff1aSopenharmony_ci        return ret;
1044cabdff1aSopenharmony_ci
1045cabdff1aSopenharmony_ci    if (no_history || s->num_passes >= 7)
1046cabdff1aSopenharmony_ci        s->best_decorr = s->mask_decorr = 0;
1047cabdff1aSopenharmony_ci
1048cabdff1aSopenharmony_ci    for (pi = 0; pi < s->num_passes;) {
1049cabdff1aSopenharmony_ci        const WavPackDecorrSpec *wpds;
1050cabdff1aSopenharmony_ci        int nterms, c, j;
1051cabdff1aSopenharmony_ci
1052cabdff1aSopenharmony_ci        if (!pi) {
1053cabdff1aSopenharmony_ci            c = s->best_decorr;
1054cabdff1aSopenharmony_ci        } else {
1055cabdff1aSopenharmony_ci            if (s->mask_decorr == 0)
1056cabdff1aSopenharmony_ci                c = 0;
1057cabdff1aSopenharmony_ci            else
1058cabdff1aSopenharmony_ci                c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr;
1059cabdff1aSopenharmony_ci
1060cabdff1aSopenharmony_ci            if (c == s->best_decorr) {
1061cabdff1aSopenharmony_ci                s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
1062cabdff1aSopenharmony_ci                continue;
1063cabdff1aSopenharmony_ci            }
1064cabdff1aSopenharmony_ci        }
1065cabdff1aSopenharmony_ci
1066cabdff1aSopenharmony_ci        wpds = &s->decorr_specs[c];
1067cabdff1aSopenharmony_ci        nterms = decorr_filter_nterms[s->decorr_filter];
1068cabdff1aSopenharmony_ci
1069cabdff1aSopenharmony_ci        while (1) {
1070cabdff1aSopenharmony_ci        memcpy(s->temp_buffer[0][0], samples, buf_size);
1071cabdff1aSopenharmony_ci        CLEAR(save_decorr_passes);
1072cabdff1aSopenharmony_ci
1073cabdff1aSopenharmony_ci        for (j = 0; j < nterms; j++) {
1074cabdff1aSopenharmony_ci            CLEAR(temp_decorr_pass);
1075cabdff1aSopenharmony_ci            temp_decorr_pass.delta = wpds->delta;
1076cabdff1aSopenharmony_ci            temp_decorr_pass.value = wpds->terms[j];
1077cabdff1aSopenharmony_ci
1078cabdff1aSopenharmony_ci            if (temp_decorr_pass.value < 0)
1079cabdff1aSopenharmony_ci                temp_decorr_pass.value = 1;
1080cabdff1aSopenharmony_ci
1081cabdff1aSopenharmony_ci            decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0],
1082cabdff1aSopenharmony_ci                        FFMIN(nb_samples, 2048), &temp_decorr_pass, -1);
1083cabdff1aSopenharmony_ci
1084cabdff1aSopenharmony_ci            if (j) {
1085cabdff1aSopenharmony_ci                CLEAR(temp_decorr_pass.samplesA);
1086cabdff1aSopenharmony_ci            } else {
1087cabdff1aSopenharmony_ci                reverse_mono_decorr(&temp_decorr_pass);
1088cabdff1aSopenharmony_ci            }
1089cabdff1aSopenharmony_ci
1090cabdff1aSopenharmony_ci            memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr));
1091cabdff1aSopenharmony_ci            decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0],
1092cabdff1aSopenharmony_ci                        nb_samples, &temp_decorr_pass, 1);
1093cabdff1aSopenharmony_ci        }
1094cabdff1aSopenharmony_ci
1095cabdff1aSopenharmony_ci        size = log2mono(s->temp_buffer[j&1][0], nb_samples, log_limit);
1096cabdff1aSopenharmony_ci        if (size != UINT32_MAX || !nterms)
1097cabdff1aSopenharmony_ci            break;
1098cabdff1aSopenharmony_ci        nterms >>= 1;
1099cabdff1aSopenharmony_ci        }
1100cabdff1aSopenharmony_ci
1101cabdff1aSopenharmony_ci        if (size < best_size) {
1102cabdff1aSopenharmony_ci            memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size);
1103cabdff1aSopenharmony_ci            memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS);
1104cabdff1aSopenharmony_ci            s->num_terms = nterms;
1105cabdff1aSopenharmony_ci            s->best_decorr = c;
1106cabdff1aSopenharmony_ci            best_size = size;
1107cabdff1aSopenharmony_ci        }
1108cabdff1aSopenharmony_ci
1109cabdff1aSopenharmony_ci        if (pi++)
1110cabdff1aSopenharmony_ci            s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
1111cabdff1aSopenharmony_ci    }
1112cabdff1aSopenharmony_ci
1113cabdff1aSopenharmony_ci    if (s->extra_flags)
1114cabdff1aSopenharmony_ci        analyze_mono(s, samples, do_samples);
1115cabdff1aSopenharmony_ci    else if (do_samples)
1116cabdff1aSopenharmony_ci        memcpy(samples, s->best_buffer[0], buf_size);
1117cabdff1aSopenharmony_ci
1118cabdff1aSopenharmony_ci    if (no_history || s->extra_flags) {
1119cabdff1aSopenharmony_ci        CLEAR(s->w);
1120cabdff1aSopenharmony_ci        scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1);
1121cabdff1aSopenharmony_ci    }
1122cabdff1aSopenharmony_ci    return 0;
1123cabdff1aSopenharmony_ci}
1124cabdff1aSopenharmony_ci
1125cabdff1aSopenharmony_cistatic void decorr_stereo(int32_t *in_left, int32_t *in_right,
1126cabdff1aSopenharmony_ci                          int32_t *out_left, int32_t *out_right,
1127cabdff1aSopenharmony_ci                          int nb_samples, struct Decorr *dpp, int dir)
1128cabdff1aSopenharmony_ci{
1129cabdff1aSopenharmony_ci    int m = 0, i;
1130cabdff1aSopenharmony_ci
1131cabdff1aSopenharmony_ci    dpp->sumA = dpp->sumB = 0;
1132cabdff1aSopenharmony_ci
1133cabdff1aSopenharmony_ci    if (dir < 0) {
1134cabdff1aSopenharmony_ci        out_left  += nb_samples - 1;
1135cabdff1aSopenharmony_ci        out_right += nb_samples - 1;
1136cabdff1aSopenharmony_ci        in_left   += nb_samples - 1;
1137cabdff1aSopenharmony_ci        in_right  += nb_samples - 1;
1138cabdff1aSopenharmony_ci    }
1139cabdff1aSopenharmony_ci
1140cabdff1aSopenharmony_ci    dpp->weightA = restore_weight(store_weight(dpp->weightA));
1141cabdff1aSopenharmony_ci    dpp->weightB = restore_weight(store_weight(dpp->weightB));
1142cabdff1aSopenharmony_ci
1143cabdff1aSopenharmony_ci    for (i = 0; i < MAX_TERM; i++) {
1144cabdff1aSopenharmony_ci        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
1145cabdff1aSopenharmony_ci        dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i]));
1146cabdff1aSopenharmony_ci    }
1147cabdff1aSopenharmony_ci
1148cabdff1aSopenharmony_ci    switch (dpp->value) {
1149cabdff1aSopenharmony_ci    case 2:
1150cabdff1aSopenharmony_ci        while (nb_samples--) {
1151cabdff1aSopenharmony_ci            int32_t sam, tmp;
1152cabdff1aSopenharmony_ci
1153cabdff1aSopenharmony_ci            sam = dpp->samplesA[0];
1154cabdff1aSopenharmony_ci            dpp->samplesA[0] = dpp->samplesA[1];
1155cabdff1aSopenharmony_ci            out_left[0] = tmp = (dpp->samplesA[1] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
1156cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1157cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1158cabdff1aSopenharmony_ci
1159cabdff1aSopenharmony_ci            sam = dpp->samplesB[0];
1160cabdff1aSopenharmony_ci            dpp->samplesB[0] = dpp->samplesB[1];
1161cabdff1aSopenharmony_ci            out_right[0] = tmp = (dpp->samplesB[1] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
1162cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1163cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1164cabdff1aSopenharmony_ci
1165cabdff1aSopenharmony_ci            in_left   += dir;
1166cabdff1aSopenharmony_ci            out_left  += dir;
1167cabdff1aSopenharmony_ci            in_right  += dir;
1168cabdff1aSopenharmony_ci            out_right += dir;
1169cabdff1aSopenharmony_ci        }
1170cabdff1aSopenharmony_ci        break;
1171cabdff1aSopenharmony_ci    case 17:
1172cabdff1aSopenharmony_ci        while (nb_samples--) {
1173cabdff1aSopenharmony_ci            int32_t sam, tmp;
1174cabdff1aSopenharmony_ci
1175cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
1176cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
1177cabdff1aSopenharmony_ci            out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
1178cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1179cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1180cabdff1aSopenharmony_ci
1181cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
1182cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
1183cabdff1aSopenharmony_ci            out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT (dpp->weightB, sam);
1184cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1185cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1186cabdff1aSopenharmony_ci
1187cabdff1aSopenharmony_ci            in_left   += dir;
1188cabdff1aSopenharmony_ci            out_left  += dir;
1189cabdff1aSopenharmony_ci            in_right  += dir;
1190cabdff1aSopenharmony_ci            out_right += dir;
1191cabdff1aSopenharmony_ci        }
1192cabdff1aSopenharmony_ci        break;
1193cabdff1aSopenharmony_ci    case 18:
1194cabdff1aSopenharmony_ci        while (nb_samples--) {
1195cabdff1aSopenharmony_ci            int32_t sam, tmp;
1196cabdff1aSopenharmony_ci
1197cabdff1aSopenharmony_ci            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
1198cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
1199cabdff1aSopenharmony_ci            out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
1200cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1201cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1202cabdff1aSopenharmony_ci
1203cabdff1aSopenharmony_ci            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
1204cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
1205cabdff1aSopenharmony_ci            out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
1206cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1207cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1208cabdff1aSopenharmony_ci
1209cabdff1aSopenharmony_ci            in_left   += dir;
1210cabdff1aSopenharmony_ci            out_left  += dir;
1211cabdff1aSopenharmony_ci            in_right  += dir;
1212cabdff1aSopenharmony_ci            out_right += dir;
1213cabdff1aSopenharmony_ci        }
1214cabdff1aSopenharmony_ci        break;
1215cabdff1aSopenharmony_ci    default: {
1216cabdff1aSopenharmony_ci        int k = dpp->value & (MAX_TERM - 1);
1217cabdff1aSopenharmony_ci
1218cabdff1aSopenharmony_ci        while (nb_samples--) {
1219cabdff1aSopenharmony_ci            int32_t sam, tmp;
1220cabdff1aSopenharmony_ci
1221cabdff1aSopenharmony_ci            sam = dpp->samplesA[m];
1222cabdff1aSopenharmony_ci            out_left[0] = tmp = (dpp->samplesA[k] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
1223cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1224cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1225cabdff1aSopenharmony_ci
1226cabdff1aSopenharmony_ci            sam = dpp->samplesB[m];
1227cabdff1aSopenharmony_ci            out_right[0] = tmp = (dpp->samplesB[k] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
1228cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1229cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1230cabdff1aSopenharmony_ci
1231cabdff1aSopenharmony_ci            in_left   += dir;
1232cabdff1aSopenharmony_ci            out_left  += dir;
1233cabdff1aSopenharmony_ci            in_right  += dir;
1234cabdff1aSopenharmony_ci            out_right += dir;
1235cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
1236cabdff1aSopenharmony_ci            k = (k + 1) & (MAX_TERM - 1);
1237cabdff1aSopenharmony_ci        }
1238cabdff1aSopenharmony_ci
1239cabdff1aSopenharmony_ci        if (m) {
1240cabdff1aSopenharmony_ci            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
1241cabdff1aSopenharmony_ci            int k;
1242cabdff1aSopenharmony_ci
1243cabdff1aSopenharmony_ci            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
1244cabdff1aSopenharmony_ci            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
1245cabdff1aSopenharmony_ci
1246cabdff1aSopenharmony_ci            for (k = 0; k < MAX_TERM; k++) {
1247cabdff1aSopenharmony_ci                dpp->samplesA[k] = temp_A[m];
1248cabdff1aSopenharmony_ci                dpp->samplesB[k] = temp_B[m];
1249cabdff1aSopenharmony_ci                m = (m + 1) & (MAX_TERM - 1);
1250cabdff1aSopenharmony_ci            }
1251cabdff1aSopenharmony_ci        }
1252cabdff1aSopenharmony_ci        break;
1253cabdff1aSopenharmony_ci        }
1254cabdff1aSopenharmony_ci    case -1:
1255cabdff1aSopenharmony_ci        while (nb_samples--) {
1256cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
1257cabdff1aSopenharmony_ci
1258cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
1259cabdff1aSopenharmony_ci            out_left[0] = tmp = (sam_B = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A);
1260cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
1261cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1262cabdff1aSopenharmony_ci
1263cabdff1aSopenharmony_ci            out_right[0] = tmp = (dpp->samplesA[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B);
1264cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
1265cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1266cabdff1aSopenharmony_ci
1267cabdff1aSopenharmony_ci            in_left   += dir;
1268cabdff1aSopenharmony_ci            out_left  += dir;
1269cabdff1aSopenharmony_ci            in_right  += dir;
1270cabdff1aSopenharmony_ci            out_right += dir;
1271cabdff1aSopenharmony_ci        }
1272cabdff1aSopenharmony_ci        break;
1273cabdff1aSopenharmony_ci    case -2:
1274cabdff1aSopenharmony_ci        while (nb_samples--) {
1275cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
1276cabdff1aSopenharmony_ci
1277cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
1278cabdff1aSopenharmony_ci            out_right[0] = tmp = (sam_A = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B);
1279cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
1280cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1281cabdff1aSopenharmony_ci
1282cabdff1aSopenharmony_ci            out_left[0] = tmp = (dpp->samplesB[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A);
1283cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
1284cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1285cabdff1aSopenharmony_ci
1286cabdff1aSopenharmony_ci            in_left   += dir;
1287cabdff1aSopenharmony_ci            out_left  += dir;
1288cabdff1aSopenharmony_ci            in_right  += dir;
1289cabdff1aSopenharmony_ci            out_right += dir;
1290cabdff1aSopenharmony_ci        }
1291cabdff1aSopenharmony_ci        break;
1292cabdff1aSopenharmony_ci    case -3:
1293cabdff1aSopenharmony_ci        while (nb_samples--) {
1294cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
1295cabdff1aSopenharmony_ci
1296cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
1297cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
1298cabdff1aSopenharmony_ci
1299cabdff1aSopenharmony_ci            dpp->samplesA[0] = tmp = in_right[0];
1300cabdff1aSopenharmony_ci            out_right[0] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B);
1301cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
1302cabdff1aSopenharmony_ci            dpp->sumB += dpp->weightB;
1303cabdff1aSopenharmony_ci
1304cabdff1aSopenharmony_ci            dpp->samplesB[0] = tmp = in_left[0];
1305cabdff1aSopenharmony_ci            out_left[0] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A);
1306cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
1307cabdff1aSopenharmony_ci            dpp->sumA += dpp->weightA;
1308cabdff1aSopenharmony_ci
1309cabdff1aSopenharmony_ci            in_left   += dir;
1310cabdff1aSopenharmony_ci            out_left  += dir;
1311cabdff1aSopenharmony_ci            in_right  += dir;
1312cabdff1aSopenharmony_ci            out_right += dir;
1313cabdff1aSopenharmony_ci        }
1314cabdff1aSopenharmony_ci        break;
1315cabdff1aSopenharmony_ci    }
1316cabdff1aSopenharmony_ci}
1317cabdff1aSopenharmony_ci
1318cabdff1aSopenharmony_cistatic void reverse_decorr(struct Decorr *dpp)
1319cabdff1aSopenharmony_ci{
1320cabdff1aSopenharmony_ci    if (dpp->value > MAX_TERM) {
1321cabdff1aSopenharmony_ci        int32_t sam_A, sam_B;
1322cabdff1aSopenharmony_ci
1323cabdff1aSopenharmony_ci        if (dpp->value & 1) {
1324cabdff1aSopenharmony_ci            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
1325cabdff1aSopenharmony_ci            sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1];
1326cabdff1aSopenharmony_ci        } else {
1327cabdff1aSopenharmony_ci            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
1328cabdff1aSopenharmony_ci            sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1;
1329cabdff1aSopenharmony_ci        }
1330cabdff1aSopenharmony_ci
1331cabdff1aSopenharmony_ci        dpp->samplesA[1] = dpp->samplesA[0];
1332cabdff1aSopenharmony_ci        dpp->samplesB[1] = dpp->samplesB[0];
1333cabdff1aSopenharmony_ci        dpp->samplesA[0] = sam_A;
1334cabdff1aSopenharmony_ci        dpp->samplesB[0] = sam_B;
1335cabdff1aSopenharmony_ci
1336cabdff1aSopenharmony_ci        if (dpp->value & 1) {
1337cabdff1aSopenharmony_ci            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
1338cabdff1aSopenharmony_ci            sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1];
1339cabdff1aSopenharmony_ci        } else {
1340cabdff1aSopenharmony_ci            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
1341cabdff1aSopenharmony_ci            sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1;
1342cabdff1aSopenharmony_ci        }
1343cabdff1aSopenharmony_ci
1344cabdff1aSopenharmony_ci        dpp->samplesA[1] = sam_A;
1345cabdff1aSopenharmony_ci        dpp->samplesB[1] = sam_B;
1346cabdff1aSopenharmony_ci    } else if (dpp->value > 1) {
1347cabdff1aSopenharmony_ci        int i, j, k;
1348cabdff1aSopenharmony_ci
1349cabdff1aSopenharmony_ci        for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) {
1350cabdff1aSopenharmony_ci            i &= (MAX_TERM - 1);
1351cabdff1aSopenharmony_ci            j &= (MAX_TERM - 1);
1352cabdff1aSopenharmony_ci            dpp->samplesA[i] ^= dpp->samplesA[j];
1353cabdff1aSopenharmony_ci            dpp->samplesA[j] ^= dpp->samplesA[i];
1354cabdff1aSopenharmony_ci            dpp->samplesA[i] ^= dpp->samplesA[j];
1355cabdff1aSopenharmony_ci            dpp->samplesB[i] ^= dpp->samplesB[j];
1356cabdff1aSopenharmony_ci            dpp->samplesB[j] ^= dpp->samplesB[i];
1357cabdff1aSopenharmony_ci            dpp->samplesB[i] ^= dpp->samplesB[j];
1358cabdff1aSopenharmony_ci        }
1359cabdff1aSopenharmony_ci    }
1360cabdff1aSopenharmony_ci}
1361cabdff1aSopenharmony_ci
1362cabdff1aSopenharmony_cistatic void decorr_stereo_quick(int32_t *in_left,  int32_t *in_right,
1363cabdff1aSopenharmony_ci                                int32_t *out_left, int32_t *out_right,
1364cabdff1aSopenharmony_ci                                int nb_samples, struct Decorr *dpp)
1365cabdff1aSopenharmony_ci{
1366cabdff1aSopenharmony_ci    int m = 0, i;
1367cabdff1aSopenharmony_ci
1368cabdff1aSopenharmony_ci    dpp->weightA = restore_weight(store_weight(dpp->weightA));
1369cabdff1aSopenharmony_ci    dpp->weightB = restore_weight(store_weight(dpp->weightB));
1370cabdff1aSopenharmony_ci
1371cabdff1aSopenharmony_ci    for (i = 0; i < MAX_TERM; i++) {
1372cabdff1aSopenharmony_ci        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
1373cabdff1aSopenharmony_ci        dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i]));
1374cabdff1aSopenharmony_ci    }
1375cabdff1aSopenharmony_ci
1376cabdff1aSopenharmony_ci    switch (dpp->value) {
1377cabdff1aSopenharmony_ci    case 2:
1378cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1379cabdff1aSopenharmony_ci            int32_t sam, tmp;
1380cabdff1aSopenharmony_ci
1381cabdff1aSopenharmony_ci            sam = dpp->samplesA[0];
1382cabdff1aSopenharmony_ci            dpp->samplesA[0] = dpp->samplesA[1];
1383cabdff1aSopenharmony_ci            out_left[i] = tmp = (dpp->samplesA[1] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
1384cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1385cabdff1aSopenharmony_ci
1386cabdff1aSopenharmony_ci            sam = dpp->samplesB[0];
1387cabdff1aSopenharmony_ci            dpp->samplesB[0] = dpp->samplesB[1];
1388cabdff1aSopenharmony_ci            out_right[i] = tmp = (dpp->samplesB[1] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
1389cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1390cabdff1aSopenharmony_ci        }
1391cabdff1aSopenharmony_ci        break;
1392cabdff1aSopenharmony_ci    case 17:
1393cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1394cabdff1aSopenharmony_ci            int32_t sam, tmp;
1395cabdff1aSopenharmony_ci
1396cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
1397cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
1398cabdff1aSopenharmony_ci            out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
1399cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1400cabdff1aSopenharmony_ci
1401cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
1402cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
1403cabdff1aSopenharmony_ci            out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
1404cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1405cabdff1aSopenharmony_ci        }
1406cabdff1aSopenharmony_ci        break;
1407cabdff1aSopenharmony_ci    case 18:
1408cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1409cabdff1aSopenharmony_ci            int32_t sam, tmp;
1410cabdff1aSopenharmony_ci
1411cabdff1aSopenharmony_ci            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
1412cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
1413cabdff1aSopenharmony_ci            out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
1414cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1415cabdff1aSopenharmony_ci
1416cabdff1aSopenharmony_ci            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
1417cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
1418cabdff1aSopenharmony_ci            out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
1419cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1420cabdff1aSopenharmony_ci        }
1421cabdff1aSopenharmony_ci        break;
1422cabdff1aSopenharmony_ci    default: {
1423cabdff1aSopenharmony_ci        int k = dpp->value & (MAX_TERM - 1);
1424cabdff1aSopenharmony_ci
1425cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1426cabdff1aSopenharmony_ci            int32_t sam, tmp;
1427cabdff1aSopenharmony_ci
1428cabdff1aSopenharmony_ci            sam = dpp->samplesA[m];
1429cabdff1aSopenharmony_ci            out_left[i] = tmp = (dpp->samplesA[k] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
1430cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
1431cabdff1aSopenharmony_ci
1432cabdff1aSopenharmony_ci            sam = dpp->samplesB[m];
1433cabdff1aSopenharmony_ci            out_right[i] = tmp = (dpp->samplesB[k] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
1434cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
1435cabdff1aSopenharmony_ci
1436cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
1437cabdff1aSopenharmony_ci            k = (k + 1) & (MAX_TERM - 1);
1438cabdff1aSopenharmony_ci        }
1439cabdff1aSopenharmony_ci
1440cabdff1aSopenharmony_ci        if (m) {
1441cabdff1aSopenharmony_ci            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
1442cabdff1aSopenharmony_ci            int k;
1443cabdff1aSopenharmony_ci
1444cabdff1aSopenharmony_ci            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
1445cabdff1aSopenharmony_ci            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
1446cabdff1aSopenharmony_ci
1447cabdff1aSopenharmony_ci            for (k = 0; k < MAX_TERM; k++) {
1448cabdff1aSopenharmony_ci                dpp->samplesA[k] = temp_A[m];
1449cabdff1aSopenharmony_ci                dpp->samplesB[k] = temp_B[m];
1450cabdff1aSopenharmony_ci                m = (m + 1) & (MAX_TERM - 1);
1451cabdff1aSopenharmony_ci            }
1452cabdff1aSopenharmony_ci        }
1453cabdff1aSopenharmony_ci        break;
1454cabdff1aSopenharmony_ci    }
1455cabdff1aSopenharmony_ci    case -1:
1456cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1457cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
1458cabdff1aSopenharmony_ci
1459cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
1460cabdff1aSopenharmony_ci            out_left[i] = tmp = (sam_B = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
1461cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
1462cabdff1aSopenharmony_ci
1463cabdff1aSopenharmony_ci            out_right[i] = tmp = (dpp->samplesA[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
1464cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
1465cabdff1aSopenharmony_ci        }
1466cabdff1aSopenharmony_ci        break;
1467cabdff1aSopenharmony_ci    case -2:
1468cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1469cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
1470cabdff1aSopenharmony_ci
1471cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
1472cabdff1aSopenharmony_ci            out_right[i] = tmp = (sam_A = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
1473cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
1474cabdff1aSopenharmony_ci
1475cabdff1aSopenharmony_ci            out_left[i] = tmp = (dpp->samplesB[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
1476cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
1477cabdff1aSopenharmony_ci        }
1478cabdff1aSopenharmony_ci        break;
1479cabdff1aSopenharmony_ci    case -3:
1480cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
1481cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
1482cabdff1aSopenharmony_ci
1483cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
1484cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
1485cabdff1aSopenharmony_ci
1486cabdff1aSopenharmony_ci            dpp->samplesA[0] = tmp = in_right[i];
1487cabdff1aSopenharmony_ci            out_right[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B);
1488cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
1489cabdff1aSopenharmony_ci
1490cabdff1aSopenharmony_ci            dpp->samplesB[0] = tmp = in_left[i];
1491cabdff1aSopenharmony_ci            out_left[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A);
1492cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
1493cabdff1aSopenharmony_ci        }
1494cabdff1aSopenharmony_ci        break;
1495cabdff1aSopenharmony_ci    }
1496cabdff1aSopenharmony_ci}
1497cabdff1aSopenharmony_ci
1498cabdff1aSopenharmony_cistatic void decorr_stereo_buffer(WavPackExtraInfo *info,
1499cabdff1aSopenharmony_ci                                 int32_t *in_left,  int32_t *in_right,
1500cabdff1aSopenharmony_ci                                 int32_t *out_left, int32_t *out_right,
1501cabdff1aSopenharmony_ci                                 int nb_samples, int tindex)
1502cabdff1aSopenharmony_ci{
1503cabdff1aSopenharmony_ci    struct Decorr dp = {0}, *dppi = info->dps + tindex;
1504cabdff1aSopenharmony_ci    int delta = dppi->delta, pre_delta;
1505cabdff1aSopenharmony_ci    int term = dppi->value;
1506cabdff1aSopenharmony_ci
1507cabdff1aSopenharmony_ci    if (delta == 7)
1508cabdff1aSopenharmony_ci        pre_delta = 7;
1509cabdff1aSopenharmony_ci    else if (delta < 2)
1510cabdff1aSopenharmony_ci        pre_delta = 3;
1511cabdff1aSopenharmony_ci    else
1512cabdff1aSopenharmony_ci        pre_delta = delta + 1;
1513cabdff1aSopenharmony_ci
1514cabdff1aSopenharmony_ci    dp.value = term;
1515cabdff1aSopenharmony_ci    dp.delta = pre_delta;
1516cabdff1aSopenharmony_ci    decorr_stereo(in_left, in_right, out_left, out_right,
1517cabdff1aSopenharmony_ci                  FFMIN(2048, nb_samples), &dp, -1);
1518cabdff1aSopenharmony_ci    dp.delta = delta;
1519cabdff1aSopenharmony_ci
1520cabdff1aSopenharmony_ci    if (tindex == 0) {
1521cabdff1aSopenharmony_ci        reverse_decorr(&dp);
1522cabdff1aSopenharmony_ci    } else {
1523cabdff1aSopenharmony_ci        CLEAR(dp.samplesA);
1524cabdff1aSopenharmony_ci        CLEAR(dp.samplesB);
1525cabdff1aSopenharmony_ci    }
1526cabdff1aSopenharmony_ci
1527cabdff1aSopenharmony_ci    memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA));
1528cabdff1aSopenharmony_ci    memcpy(dppi->samplesB, dp.samplesB, sizeof(dp.samplesB));
1529cabdff1aSopenharmony_ci    dppi->weightA = dp.weightA;
1530cabdff1aSopenharmony_ci    dppi->weightB = dp.weightB;
1531cabdff1aSopenharmony_ci
1532cabdff1aSopenharmony_ci    if (delta == 0) {
1533cabdff1aSopenharmony_ci        dp.delta = 1;
1534cabdff1aSopenharmony_ci        decorr_stereo(in_left, in_right, out_left, out_right, nb_samples, &dp, 1);
1535cabdff1aSopenharmony_ci        dp.delta = 0;
1536cabdff1aSopenharmony_ci        memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA));
1537cabdff1aSopenharmony_ci        memcpy(dp.samplesB, dppi->samplesB, sizeof(dp.samplesB));
1538cabdff1aSopenharmony_ci        dppi->weightA = dp.weightA = dp.sumA / nb_samples;
1539cabdff1aSopenharmony_ci        dppi->weightB = dp.weightB = dp.sumB / nb_samples;
1540cabdff1aSopenharmony_ci    }
1541cabdff1aSopenharmony_ci
1542cabdff1aSopenharmony_ci    if (info->gt16bit)
1543cabdff1aSopenharmony_ci        decorr_stereo(in_left, in_right, out_left, out_right,
1544cabdff1aSopenharmony_ci                           nb_samples, &dp, 1);
1545cabdff1aSopenharmony_ci    else
1546cabdff1aSopenharmony_ci        decorr_stereo_quick(in_left, in_right, out_left, out_right,
1547cabdff1aSopenharmony_ci                            nb_samples, &dp);
1548cabdff1aSopenharmony_ci}
1549cabdff1aSopenharmony_ci
1550cabdff1aSopenharmony_cistatic void sort_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info)
1551cabdff1aSopenharmony_ci{
1552cabdff1aSopenharmony_ci    int reversed = 1;
1553cabdff1aSopenharmony_ci    uint32_t bits;
1554cabdff1aSopenharmony_ci
1555cabdff1aSopenharmony_ci    while (reversed) {
1556cabdff1aSopenharmony_ci        int ri, i;
1557cabdff1aSopenharmony_ci
1558cabdff1aSopenharmony_ci        memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes));
1559cabdff1aSopenharmony_ci        reversed = 0;
1560cabdff1aSopenharmony_ci
1561cabdff1aSopenharmony_ci        for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) {
1562cabdff1aSopenharmony_ci
1563cabdff1aSopenharmony_ci            if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value)
1564cabdff1aSopenharmony_ci                break;
1565cabdff1aSopenharmony_ci
1566cabdff1aSopenharmony_ci            if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) {
1567cabdff1aSopenharmony_ci                decorr_stereo_buffer(info,
1568cabdff1aSopenharmony_ci                                     s->sampleptrs[ri  ][0], s->sampleptrs[ri  ][1],
1569cabdff1aSopenharmony_ci                                     s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1],
1570cabdff1aSopenharmony_ci                                     s->block_samples, ri);
1571cabdff1aSopenharmony_ci                continue;
1572cabdff1aSopenharmony_ci            }
1573cabdff1aSopenharmony_ci
1574cabdff1aSopenharmony_ci            info->dps[ri  ] = s->decorr_passes[ri+1];
1575cabdff1aSopenharmony_ci            info->dps[ri+1] = s->decorr_passes[ri  ];
1576cabdff1aSopenharmony_ci
1577cabdff1aSopenharmony_ci            for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++)
1578cabdff1aSopenharmony_ci                decorr_stereo_buffer(info,
1579cabdff1aSopenharmony_ci                                     s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
1580cabdff1aSopenharmony_ci                                     s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
1581cabdff1aSopenharmony_ci                                     s->block_samples, i);
1582cabdff1aSopenharmony_ci
1583cabdff1aSopenharmony_ci            bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
1584cabdff1aSopenharmony_ci                              s->block_samples, info->log_limit);
1585cabdff1aSopenharmony_ci
1586cabdff1aSopenharmony_ci            if (bits < info->best_bits) {
1587cabdff1aSopenharmony_ci                reversed = 1;
1588cabdff1aSopenharmony_ci                info->best_bits = bits;
1589cabdff1aSopenharmony_ci                CLEAR(s->decorr_passes);
1590cabdff1aSopenharmony_ci                memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
1591cabdff1aSopenharmony_ci                memcpy(s->sampleptrs[info->nterms + 1][0],
1592cabdff1aSopenharmony_ci                       s->sampleptrs[i][0], s->block_samples * 4);
1593cabdff1aSopenharmony_ci                memcpy(s->sampleptrs[info->nterms + 1][1],
1594cabdff1aSopenharmony_ci                       s->sampleptrs[i][1], s->block_samples * 4);
1595cabdff1aSopenharmony_ci            } else {
1596cabdff1aSopenharmony_ci                info->dps[ri  ] = s->decorr_passes[ri  ];
1597cabdff1aSopenharmony_ci                info->dps[ri+1] = s->decorr_passes[ri+1];
1598cabdff1aSopenharmony_ci                decorr_stereo_buffer(info,
1599cabdff1aSopenharmony_ci                                     s->sampleptrs[ri  ][0], s->sampleptrs[ri  ][1],
1600cabdff1aSopenharmony_ci                                     s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1],
1601cabdff1aSopenharmony_ci                                     s->block_samples, ri);
1602cabdff1aSopenharmony_ci            }
1603cabdff1aSopenharmony_ci        }
1604cabdff1aSopenharmony_ci    }
1605cabdff1aSopenharmony_ci}
1606cabdff1aSopenharmony_ci
1607cabdff1aSopenharmony_cistatic void delta_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info)
1608cabdff1aSopenharmony_ci{
1609cabdff1aSopenharmony_ci    int lower = 0, delta, d, i;
1610cabdff1aSopenharmony_ci    uint32_t bits;
1611cabdff1aSopenharmony_ci
1612cabdff1aSopenharmony_ci    if (!s->decorr_passes[0].value)
1613cabdff1aSopenharmony_ci        return;
1614cabdff1aSopenharmony_ci    delta = s->decorr_passes[0].delta;
1615cabdff1aSopenharmony_ci
1616cabdff1aSopenharmony_ci    for (d = delta - 1; d >= 0; d--) {
1617cabdff1aSopenharmony_ci        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
1618cabdff1aSopenharmony_ci            info->dps[i].value = s->decorr_passes[i].value;
1619cabdff1aSopenharmony_ci            info->dps[i].delta = d;
1620cabdff1aSopenharmony_ci            decorr_stereo_buffer(info,
1621cabdff1aSopenharmony_ci                                 s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
1622cabdff1aSopenharmony_ci                                 s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
1623cabdff1aSopenharmony_ci                                 s->block_samples, i);
1624cabdff1aSopenharmony_ci        }
1625cabdff1aSopenharmony_ci
1626cabdff1aSopenharmony_ci        bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
1627cabdff1aSopenharmony_ci                          s->block_samples, info->log_limit);
1628cabdff1aSopenharmony_ci        if (bits >= info->best_bits)
1629cabdff1aSopenharmony_ci            break;
1630cabdff1aSopenharmony_ci        lower = 1;
1631cabdff1aSopenharmony_ci        info->best_bits = bits;
1632cabdff1aSopenharmony_ci        CLEAR(s->decorr_passes);
1633cabdff1aSopenharmony_ci        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
1634cabdff1aSopenharmony_ci        memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
1635cabdff1aSopenharmony_ci               s->block_samples * 4);
1636cabdff1aSopenharmony_ci        memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[i][1],
1637cabdff1aSopenharmony_ci               s->block_samples * 4);
1638cabdff1aSopenharmony_ci    }
1639cabdff1aSopenharmony_ci
1640cabdff1aSopenharmony_ci    for (d = delta + 1; !lower && d <= 7; d++) {
1641cabdff1aSopenharmony_ci        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
1642cabdff1aSopenharmony_ci            info->dps[i].value = s->decorr_passes[i].value;
1643cabdff1aSopenharmony_ci            info->dps[i].delta = d;
1644cabdff1aSopenharmony_ci            decorr_stereo_buffer(info,
1645cabdff1aSopenharmony_ci                                 s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
1646cabdff1aSopenharmony_ci                                 s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
1647cabdff1aSopenharmony_ci                                 s->block_samples, i);
1648cabdff1aSopenharmony_ci        }
1649cabdff1aSopenharmony_ci
1650cabdff1aSopenharmony_ci        bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
1651cabdff1aSopenharmony_ci                          s->block_samples, info->log_limit);
1652cabdff1aSopenharmony_ci
1653cabdff1aSopenharmony_ci        if (bits < info->best_bits) {
1654cabdff1aSopenharmony_ci            info->best_bits = bits;
1655cabdff1aSopenharmony_ci            CLEAR(s->decorr_passes);
1656cabdff1aSopenharmony_ci            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
1657cabdff1aSopenharmony_ci            memcpy(s->sampleptrs[info->nterms + 1][0],
1658cabdff1aSopenharmony_ci                   s->sampleptrs[i][0], s->block_samples * 4);
1659cabdff1aSopenharmony_ci            memcpy(s->sampleptrs[info->nterms + 1][1],
1660cabdff1aSopenharmony_ci                   s->sampleptrs[i][1], s->block_samples * 4);
1661cabdff1aSopenharmony_ci        }
1662cabdff1aSopenharmony_ci        else
1663cabdff1aSopenharmony_ci            break;
1664cabdff1aSopenharmony_ci    }
1665cabdff1aSopenharmony_ci}
1666cabdff1aSopenharmony_ci
1667cabdff1aSopenharmony_cistatic void recurse_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info,
1668cabdff1aSopenharmony_ci                           int depth, int delta, uint32_t input_bits)
1669cabdff1aSopenharmony_ci{
1670cabdff1aSopenharmony_ci    int term, branches = s->num_branches - depth;
1671cabdff1aSopenharmony_ci    int32_t *in_left, *in_right, *out_left, *out_right;
1672cabdff1aSopenharmony_ci    uint32_t term_bits[22], bits;
1673cabdff1aSopenharmony_ci
1674cabdff1aSopenharmony_ci    if (branches < 1 || depth + 1 == info->nterms)
1675cabdff1aSopenharmony_ci        branches = 1;
1676cabdff1aSopenharmony_ci
1677cabdff1aSopenharmony_ci    CLEAR(term_bits);
1678cabdff1aSopenharmony_ci    in_left   = s->sampleptrs[depth    ][0];
1679cabdff1aSopenharmony_ci    in_right  = s->sampleptrs[depth    ][1];
1680cabdff1aSopenharmony_ci    out_left  = s->sampleptrs[depth + 1][0];
1681cabdff1aSopenharmony_ci    out_right = s->sampleptrs[depth + 1][1];
1682cabdff1aSopenharmony_ci
1683cabdff1aSopenharmony_ci    for (term = -3; term <= 18; term++) {
1684cabdff1aSopenharmony_ci        if (!term || (term > 8 && term < 17))
1685cabdff1aSopenharmony_ci            continue;
1686cabdff1aSopenharmony_ci
1687cabdff1aSopenharmony_ci        if (term == 17 && branches == 1 && depth + 1 < info->nterms)
1688cabdff1aSopenharmony_ci            continue;
1689cabdff1aSopenharmony_ci
1690cabdff1aSopenharmony_ci        if (term == -1 || term == -2)
1691cabdff1aSopenharmony_ci            if (!(s->flags & WV_CROSS_DECORR))
1692cabdff1aSopenharmony_ci                continue;
1693cabdff1aSopenharmony_ci
1694cabdff1aSopenharmony_ci        if (!s->extra_flags && (term > 4 && term < 17))
1695cabdff1aSopenharmony_ci            continue;
1696cabdff1aSopenharmony_ci
1697cabdff1aSopenharmony_ci        info->dps[depth].value = term;
1698cabdff1aSopenharmony_ci        info->dps[depth].delta = delta;
1699cabdff1aSopenharmony_ci        decorr_stereo_buffer(info, in_left, in_right, out_left, out_right,
1700cabdff1aSopenharmony_ci                             s->block_samples, depth);
1701cabdff1aSopenharmony_ci        bits = log2stereo(out_left, out_right, s->block_samples, info->log_limit);
1702cabdff1aSopenharmony_ci
1703cabdff1aSopenharmony_ci        if (bits < info->best_bits) {
1704cabdff1aSopenharmony_ci            info->best_bits = bits;
1705cabdff1aSopenharmony_ci            CLEAR(s->decorr_passes);
1706cabdff1aSopenharmony_ci            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1));
1707cabdff1aSopenharmony_ci            memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[depth + 1][0],
1708cabdff1aSopenharmony_ci                   s->block_samples * 4);
1709cabdff1aSopenharmony_ci            memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[depth + 1][1],
1710cabdff1aSopenharmony_ci                   s->block_samples * 4);
1711cabdff1aSopenharmony_ci        }
1712cabdff1aSopenharmony_ci
1713cabdff1aSopenharmony_ci        term_bits[term + 3] = bits;
1714cabdff1aSopenharmony_ci    }
1715cabdff1aSopenharmony_ci
1716cabdff1aSopenharmony_ci    while (depth + 1 < info->nterms && branches--) {
1717cabdff1aSopenharmony_ci        uint32_t local_best_bits = input_bits;
1718cabdff1aSopenharmony_ci        int best_term = 0, i;
1719cabdff1aSopenharmony_ci
1720cabdff1aSopenharmony_ci        for (i = 0; i < 22; i++)
1721cabdff1aSopenharmony_ci            if (term_bits[i] && term_bits[i] < local_best_bits) {
1722cabdff1aSopenharmony_ci                local_best_bits = term_bits[i];
1723cabdff1aSopenharmony_ci                best_term = i - 3;
1724cabdff1aSopenharmony_ci            }
1725cabdff1aSopenharmony_ci
1726cabdff1aSopenharmony_ci        if (!best_term)
1727cabdff1aSopenharmony_ci            break;
1728cabdff1aSopenharmony_ci
1729cabdff1aSopenharmony_ci        term_bits[best_term + 3] = 0;
1730cabdff1aSopenharmony_ci
1731cabdff1aSopenharmony_ci        info->dps[depth].value = best_term;
1732cabdff1aSopenharmony_ci        info->dps[depth].delta = delta;
1733cabdff1aSopenharmony_ci        decorr_stereo_buffer(info, in_left, in_right, out_left, out_right,
1734cabdff1aSopenharmony_ci                             s->block_samples, depth);
1735cabdff1aSopenharmony_ci
1736cabdff1aSopenharmony_ci        recurse_stereo(s, info, depth + 1, delta, local_best_bits);
1737cabdff1aSopenharmony_ci    }
1738cabdff1aSopenharmony_ci}
1739cabdff1aSopenharmony_ci
1740cabdff1aSopenharmony_cistatic void analyze_stereo(WavPackEncodeContext *s,
1741cabdff1aSopenharmony_ci                           int32_t *in_left, int32_t *in_right,
1742cabdff1aSopenharmony_ci                           int do_samples)
1743cabdff1aSopenharmony_ci{
1744cabdff1aSopenharmony_ci    WavPackExtraInfo info;
1745cabdff1aSopenharmony_ci    int i;
1746cabdff1aSopenharmony_ci
1747cabdff1aSopenharmony_ci    info.gt16bit = ((s->flags & MAG_MASK) >> MAG_LSB) >= 16;
1748cabdff1aSopenharmony_ci
1749cabdff1aSopenharmony_ci    info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
1750cabdff1aSopenharmony_ci    info.log_limit = FFMIN(6912, info.log_limit);
1751cabdff1aSopenharmony_ci
1752cabdff1aSopenharmony_ci    info.nterms = s->num_terms;
1753cabdff1aSopenharmony_ci
1754cabdff1aSopenharmony_ci    if (allocate_buffers2(s, s->num_terms))
1755cabdff1aSopenharmony_ci        return;
1756cabdff1aSopenharmony_ci
1757cabdff1aSopenharmony_ci    memcpy(info.dps, s->decorr_passes, sizeof(info.dps));
1758cabdff1aSopenharmony_ci    memcpy(s->sampleptrs[0][0], in_left,  s->block_samples * 4);
1759cabdff1aSopenharmony_ci    memcpy(s->sampleptrs[0][1], in_right, s->block_samples * 4);
1760cabdff1aSopenharmony_ci
1761cabdff1aSopenharmony_ci    for (i = 0; i < info.nterms && info.dps[i].value; i++)
1762cabdff1aSopenharmony_ci        if (info.gt16bit)
1763cabdff1aSopenharmony_ci            decorr_stereo(s->sampleptrs[i    ][0], s->sampleptrs[i    ][1],
1764cabdff1aSopenharmony_ci                          s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1],
1765cabdff1aSopenharmony_ci                          s->block_samples, info.dps + i, 1);
1766cabdff1aSopenharmony_ci        else
1767cabdff1aSopenharmony_ci            decorr_stereo_quick(s->sampleptrs[i    ][0], s->sampleptrs[i    ][1],
1768cabdff1aSopenharmony_ci                                s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1],
1769cabdff1aSopenharmony_ci                                s->block_samples, info.dps + i);
1770cabdff1aSopenharmony_ci
1771cabdff1aSopenharmony_ci    info.best_bits = log2stereo(s->sampleptrs[info.nterms][0], s->sampleptrs[info.nterms][1],
1772cabdff1aSopenharmony_ci                                s->block_samples, 0);
1773cabdff1aSopenharmony_ci
1774cabdff1aSopenharmony_ci    memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4);
1775cabdff1aSopenharmony_ci    memcpy(s->sampleptrs[info.nterms + 1][1], s->sampleptrs[i][1], s->block_samples * 4);
1776cabdff1aSopenharmony_ci
1777cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_BRANCHES)
1778cabdff1aSopenharmony_ci        recurse_stereo(s, &info, 0, (int) floor(s->delta_decay + 0.5),
1779cabdff1aSopenharmony_ci                       log2stereo(s->sampleptrs[0][0], s->sampleptrs[0][1],
1780cabdff1aSopenharmony_ci                                  s->block_samples, 0));
1781cabdff1aSopenharmony_ci
1782cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_SORT_FIRST)
1783cabdff1aSopenharmony_ci        sort_stereo(s, &info);
1784cabdff1aSopenharmony_ci
1785cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_TRY_DELTAS) {
1786cabdff1aSopenharmony_ci        delta_stereo(s, &info);
1787cabdff1aSopenharmony_ci
1788cabdff1aSopenharmony_ci        if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value)
1789cabdff1aSopenharmony_ci            s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0);
1790cabdff1aSopenharmony_ci        else
1791cabdff1aSopenharmony_ci            s->delta_decay = 2.0;
1792cabdff1aSopenharmony_ci    }
1793cabdff1aSopenharmony_ci
1794cabdff1aSopenharmony_ci    if (s->extra_flags & EXTRA_SORT_LAST)
1795cabdff1aSopenharmony_ci        sort_stereo(s, &info);
1796cabdff1aSopenharmony_ci
1797cabdff1aSopenharmony_ci    if (do_samples) {
1798cabdff1aSopenharmony_ci        memcpy(in_left,  s->sampleptrs[info.nterms + 1][0], s->block_samples * 4);
1799cabdff1aSopenharmony_ci        memcpy(in_right, s->sampleptrs[info.nterms + 1][1], s->block_samples * 4);
1800cabdff1aSopenharmony_ci    }
1801cabdff1aSopenharmony_ci
1802cabdff1aSopenharmony_ci    for (i = 0; i < info.nterms; i++)
1803cabdff1aSopenharmony_ci        if (!s->decorr_passes[i].value)
1804cabdff1aSopenharmony_ci            break;
1805cabdff1aSopenharmony_ci
1806cabdff1aSopenharmony_ci    s->num_terms = i;
1807cabdff1aSopenharmony_ci}
1808cabdff1aSopenharmony_ci
1809cabdff1aSopenharmony_cistatic int wv_stereo(WavPackEncodeContext *s,
1810cabdff1aSopenharmony_ci                     int32_t *samples_l, int32_t *samples_r,
1811cabdff1aSopenharmony_ci                     int no_history, int do_samples)
1812cabdff1aSopenharmony_ci{
1813cabdff1aSopenharmony_ci    struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}};
1814cabdff1aSopenharmony_ci    int nb_samples = s->block_samples, ret;
1815cabdff1aSopenharmony_ci    int buf_size = sizeof(int32_t) * nb_samples;
1816cabdff1aSopenharmony_ci    int log_limit, force_js = 0, force_ts = 0, got_js = 0, pi, i;
1817cabdff1aSopenharmony_ci    uint32_t best_size = UINT32_MAX, size;
1818cabdff1aSopenharmony_ci
1819cabdff1aSopenharmony_ci    for (i = 0; i < nb_samples; i++)
1820cabdff1aSopenharmony_ci        if (samples_l[i] || samples_r[i])
1821cabdff1aSopenharmony_ci            break;
1822cabdff1aSopenharmony_ci
1823cabdff1aSopenharmony_ci    if (i == nb_samples) {
1824cabdff1aSopenharmony_ci        s->flags &= ~((uint32_t) WV_JOINT_STEREO);
1825cabdff1aSopenharmony_ci        CLEAR(s->decorr_passes);
1826cabdff1aSopenharmony_ci        CLEAR(s->w);
1827cabdff1aSopenharmony_ci        s->num_terms = 0;
1828cabdff1aSopenharmony_ci        return 0;
1829cabdff1aSopenharmony_ci    }
1830cabdff1aSopenharmony_ci
1831cabdff1aSopenharmony_ci    log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
1832cabdff1aSopenharmony_ci    log_limit = FFMIN(6912, log_limit);
1833cabdff1aSopenharmony_ci
1834cabdff1aSopenharmony_ci    if (s->joint != -1) {
1835cabdff1aSopenharmony_ci        force_js =  s->joint;
1836cabdff1aSopenharmony_ci        force_ts = !s->joint;
1837cabdff1aSopenharmony_ci    }
1838cabdff1aSopenharmony_ci
1839cabdff1aSopenharmony_ci    if ((ret = allocate_buffers(s)) < 0)
1840cabdff1aSopenharmony_ci        return ret;
1841cabdff1aSopenharmony_ci
1842cabdff1aSopenharmony_ci    if (no_history || s->num_passes >= 7)
1843cabdff1aSopenharmony_ci        s->best_decorr = s->mask_decorr = 0;
1844cabdff1aSopenharmony_ci
1845cabdff1aSopenharmony_ci    for (pi = 0; pi < s->num_passes;) {
1846cabdff1aSopenharmony_ci        const WavPackDecorrSpec *wpds;
1847cabdff1aSopenharmony_ci        int nterms, c, j;
1848cabdff1aSopenharmony_ci
1849cabdff1aSopenharmony_ci        if (!pi)
1850cabdff1aSopenharmony_ci            c = s->best_decorr;
1851cabdff1aSopenharmony_ci        else {
1852cabdff1aSopenharmony_ci            if (s->mask_decorr == 0)
1853cabdff1aSopenharmony_ci                c = 0;
1854cabdff1aSopenharmony_ci            else
1855cabdff1aSopenharmony_ci                c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr;
1856cabdff1aSopenharmony_ci
1857cabdff1aSopenharmony_ci            if (c == s->best_decorr) {
1858cabdff1aSopenharmony_ci                s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
1859cabdff1aSopenharmony_ci                continue;
1860cabdff1aSopenharmony_ci            }
1861cabdff1aSopenharmony_ci        }
1862cabdff1aSopenharmony_ci
1863cabdff1aSopenharmony_ci        wpds = &s->decorr_specs[c];
1864cabdff1aSopenharmony_ci        nterms = decorr_filter_nterms[s->decorr_filter];
1865cabdff1aSopenharmony_ci
1866cabdff1aSopenharmony_ci        while (1) {
1867cabdff1aSopenharmony_ci            if (force_js || (wpds->joint_stereo && !force_ts)) {
1868cabdff1aSopenharmony_ci                if (!got_js) {
1869cabdff1aSopenharmony_ci                    av_fast_padded_malloc(&s->js_left,  &s->js_left_size,  buf_size);
1870cabdff1aSopenharmony_ci                    av_fast_padded_malloc(&s->js_right, &s->js_right_size, buf_size);
1871cabdff1aSopenharmony_ci                    memcpy(s->js_left,  samples_l, buf_size);
1872cabdff1aSopenharmony_ci                    memcpy(s->js_right, samples_r, buf_size);
1873cabdff1aSopenharmony_ci
1874cabdff1aSopenharmony_ci                    for (i = 0; i < nb_samples; i++)
1875cabdff1aSopenharmony_ci                        s->js_right[i] += ((s->js_left[i] -= s->js_right[i]) >> 1);
1876cabdff1aSopenharmony_ci                    got_js = 1;
1877cabdff1aSopenharmony_ci                }
1878cabdff1aSopenharmony_ci
1879cabdff1aSopenharmony_ci                memcpy(s->temp_buffer[0][0], s->js_left,  buf_size);
1880cabdff1aSopenharmony_ci                memcpy(s->temp_buffer[0][1], s->js_right, buf_size);
1881cabdff1aSopenharmony_ci            } else {
1882cabdff1aSopenharmony_ci                memcpy(s->temp_buffer[0][0], samples_l, buf_size);
1883cabdff1aSopenharmony_ci                memcpy(s->temp_buffer[0][1], samples_r, buf_size);
1884cabdff1aSopenharmony_ci            }
1885cabdff1aSopenharmony_ci
1886cabdff1aSopenharmony_ci            CLEAR(save_decorr_passes);
1887cabdff1aSopenharmony_ci
1888cabdff1aSopenharmony_ci            for (j = 0; j < nterms; j++) {
1889cabdff1aSopenharmony_ci                CLEAR(temp_decorr_pass);
1890cabdff1aSopenharmony_ci                temp_decorr_pass.delta = wpds->delta;
1891cabdff1aSopenharmony_ci                temp_decorr_pass.value = wpds->terms[j];
1892cabdff1aSopenharmony_ci
1893cabdff1aSopenharmony_ci                if (temp_decorr_pass.value < 0 && !(s->flags & WV_CROSS_DECORR))
1894cabdff1aSopenharmony_ci                    temp_decorr_pass.value = -3;
1895cabdff1aSopenharmony_ci
1896cabdff1aSopenharmony_ci                decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
1897cabdff1aSopenharmony_ci                              s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
1898cabdff1aSopenharmony_ci                              FFMIN(2048, nb_samples), &temp_decorr_pass, -1);
1899cabdff1aSopenharmony_ci
1900cabdff1aSopenharmony_ci                if (j) {
1901cabdff1aSopenharmony_ci                    CLEAR(temp_decorr_pass.samplesA);
1902cabdff1aSopenharmony_ci                    CLEAR(temp_decorr_pass.samplesB);
1903cabdff1aSopenharmony_ci                } else {
1904cabdff1aSopenharmony_ci                    reverse_decorr(&temp_decorr_pass);
1905cabdff1aSopenharmony_ci                }
1906cabdff1aSopenharmony_ci
1907cabdff1aSopenharmony_ci                memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr));
1908cabdff1aSopenharmony_ci
1909cabdff1aSopenharmony_ci                if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16)
1910cabdff1aSopenharmony_ci                    decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
1911cabdff1aSopenharmony_ci                                  s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
1912cabdff1aSopenharmony_ci                                  nb_samples, &temp_decorr_pass, 1);
1913cabdff1aSopenharmony_ci                else
1914cabdff1aSopenharmony_ci                    decorr_stereo_quick(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
1915cabdff1aSopenharmony_ci                                        s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
1916cabdff1aSopenharmony_ci                                        nb_samples, &temp_decorr_pass);
1917cabdff1aSopenharmony_ci            }
1918cabdff1aSopenharmony_ci
1919cabdff1aSopenharmony_ci            size = log2stereo(s->temp_buffer[j&1][0], s->temp_buffer[j&1][1],
1920cabdff1aSopenharmony_ci                              nb_samples, log_limit);
1921cabdff1aSopenharmony_ci            if (size != UINT32_MAX || !nterms)
1922cabdff1aSopenharmony_ci                break;
1923cabdff1aSopenharmony_ci            nterms >>= 1;
1924cabdff1aSopenharmony_ci        }
1925cabdff1aSopenharmony_ci
1926cabdff1aSopenharmony_ci        if (size < best_size) {
1927cabdff1aSopenharmony_ci            memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size);
1928cabdff1aSopenharmony_ci            memcpy(s->best_buffer[1], s->temp_buffer[j&1][1], buf_size);
1929cabdff1aSopenharmony_ci            memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS);
1930cabdff1aSopenharmony_ci            s->num_terms = nterms;
1931cabdff1aSopenharmony_ci            s->best_decorr = c;
1932cabdff1aSopenharmony_ci            best_size = size;
1933cabdff1aSopenharmony_ci        }
1934cabdff1aSopenharmony_ci
1935cabdff1aSopenharmony_ci        if (pi++)
1936cabdff1aSopenharmony_ci            s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
1937cabdff1aSopenharmony_ci    }
1938cabdff1aSopenharmony_ci
1939cabdff1aSopenharmony_ci    if (force_js || (s->decorr_specs[s->best_decorr].joint_stereo && !force_ts))
1940cabdff1aSopenharmony_ci        s->flags |= WV_JOINT_STEREO;
1941cabdff1aSopenharmony_ci    else
1942cabdff1aSopenharmony_ci        s->flags &= ~((uint32_t) WV_JOINT_STEREO);
1943cabdff1aSopenharmony_ci
1944cabdff1aSopenharmony_ci    if (s->extra_flags) {
1945cabdff1aSopenharmony_ci        if (s->flags & WV_JOINT_STEREO) {
1946cabdff1aSopenharmony_ci            analyze_stereo(s, s->js_left, s->js_right, do_samples);
1947cabdff1aSopenharmony_ci
1948cabdff1aSopenharmony_ci            if (do_samples) {
1949cabdff1aSopenharmony_ci                memcpy(samples_l, s->js_left,  buf_size);
1950cabdff1aSopenharmony_ci                memcpy(samples_r, s->js_right, buf_size);
1951cabdff1aSopenharmony_ci            }
1952cabdff1aSopenharmony_ci        } else
1953cabdff1aSopenharmony_ci            analyze_stereo(s, samples_l, samples_r, do_samples);
1954cabdff1aSopenharmony_ci    } else if (do_samples) {
1955cabdff1aSopenharmony_ci        memcpy(samples_l, s->best_buffer[0], buf_size);
1956cabdff1aSopenharmony_ci        memcpy(samples_r, s->best_buffer[1], buf_size);
1957cabdff1aSopenharmony_ci    }
1958cabdff1aSopenharmony_ci
1959cabdff1aSopenharmony_ci    if (s->extra_flags || no_history ||
1960cabdff1aSopenharmony_ci        s->joint_stereo != s->decorr_specs[s->best_decorr].joint_stereo) {
1961cabdff1aSopenharmony_ci        s->joint_stereo = s->decorr_specs[s->best_decorr].joint_stereo;
1962cabdff1aSopenharmony_ci        CLEAR(s->w);
1963cabdff1aSopenharmony_ci        scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1);
1964cabdff1aSopenharmony_ci        scan_word(s, &s->w.c[1], s->best_buffer[1], nb_samples, -1);
1965cabdff1aSopenharmony_ci    }
1966cabdff1aSopenharmony_ci    return 0;
1967cabdff1aSopenharmony_ci}
1968cabdff1aSopenharmony_ci
1969cabdff1aSopenharmony_cistatic void encode_flush(WavPackEncodeContext *s)
1970cabdff1aSopenharmony_ci{
1971cabdff1aSopenharmony_ci    WavPackWords *w = &s->w;
1972cabdff1aSopenharmony_ci    PutBitContext *pb = &s->pb;
1973cabdff1aSopenharmony_ci
1974cabdff1aSopenharmony_ci    if (w->zeros_acc) {
1975cabdff1aSopenharmony_ci        int cbits = count_bits(w->zeros_acc);
1976cabdff1aSopenharmony_ci
1977cabdff1aSopenharmony_ci        do {
1978cabdff1aSopenharmony_ci            if (cbits > 31) {
1979cabdff1aSopenharmony_ci                put_bits(pb, 31, 0x7FFFFFFF);
1980cabdff1aSopenharmony_ci                cbits -= 31;
1981cabdff1aSopenharmony_ci            } else {
1982cabdff1aSopenharmony_ci                put_bits(pb, cbits, (1U << cbits) - 1);
1983cabdff1aSopenharmony_ci                cbits = 0;
1984cabdff1aSopenharmony_ci            }
1985cabdff1aSopenharmony_ci        } while (cbits);
1986cabdff1aSopenharmony_ci
1987cabdff1aSopenharmony_ci        put_bits(pb, 1, 0);
1988cabdff1aSopenharmony_ci
1989cabdff1aSopenharmony_ci        while (w->zeros_acc > 1) {
1990cabdff1aSopenharmony_ci            put_bits(pb, 1, w->zeros_acc & 1);
1991cabdff1aSopenharmony_ci            w->zeros_acc >>= 1;
1992cabdff1aSopenharmony_ci        }
1993cabdff1aSopenharmony_ci
1994cabdff1aSopenharmony_ci        w->zeros_acc = 0;
1995cabdff1aSopenharmony_ci    }
1996cabdff1aSopenharmony_ci
1997cabdff1aSopenharmony_ci    if (w->holding_one) {
1998cabdff1aSopenharmony_ci        if (w->holding_one >= 16) {
1999cabdff1aSopenharmony_ci            int cbits;
2000cabdff1aSopenharmony_ci
2001cabdff1aSopenharmony_ci            put_bits(pb, 16, (1 << 16) - 1);
2002cabdff1aSopenharmony_ci            put_bits(pb, 1, 0);
2003cabdff1aSopenharmony_ci            w->holding_one -= 16;
2004cabdff1aSopenharmony_ci            cbits = count_bits(w->holding_one);
2005cabdff1aSopenharmony_ci
2006cabdff1aSopenharmony_ci            do {
2007cabdff1aSopenharmony_ci                if (cbits > 31) {
2008cabdff1aSopenharmony_ci                    put_bits(pb, 31, 0x7FFFFFFF);
2009cabdff1aSopenharmony_ci                    cbits -= 31;
2010cabdff1aSopenharmony_ci                } else {
2011cabdff1aSopenharmony_ci                    put_bits(pb, cbits, (1U << cbits) - 1);
2012cabdff1aSopenharmony_ci                    cbits = 0;
2013cabdff1aSopenharmony_ci                }
2014cabdff1aSopenharmony_ci            } while (cbits);
2015cabdff1aSopenharmony_ci
2016cabdff1aSopenharmony_ci            put_bits(pb, 1, 0);
2017cabdff1aSopenharmony_ci
2018cabdff1aSopenharmony_ci            while (w->holding_one > 1) {
2019cabdff1aSopenharmony_ci                put_bits(pb, 1, w->holding_one & 1);
2020cabdff1aSopenharmony_ci                w->holding_one >>= 1;
2021cabdff1aSopenharmony_ci            }
2022cabdff1aSopenharmony_ci
2023cabdff1aSopenharmony_ci            w->holding_zero = 0;
2024cabdff1aSopenharmony_ci        } else {
2025cabdff1aSopenharmony_ci            put_bits(pb, w->holding_one, (1 << w->holding_one) - 1);
2026cabdff1aSopenharmony_ci        }
2027cabdff1aSopenharmony_ci
2028cabdff1aSopenharmony_ci        w->holding_one = 0;
2029cabdff1aSopenharmony_ci    }
2030cabdff1aSopenharmony_ci
2031cabdff1aSopenharmony_ci    if (w->holding_zero) {
2032cabdff1aSopenharmony_ci        put_bits(pb, 1, 0);
2033cabdff1aSopenharmony_ci        w->holding_zero = 0;
2034cabdff1aSopenharmony_ci    }
2035cabdff1aSopenharmony_ci
2036cabdff1aSopenharmony_ci    if (w->pend_count) {
2037cabdff1aSopenharmony_ci        put_bits(pb, w->pend_count, w->pend_data);
2038cabdff1aSopenharmony_ci        w->pend_data = w->pend_count = 0;
2039cabdff1aSopenharmony_ci    }
2040cabdff1aSopenharmony_ci}
2041cabdff1aSopenharmony_ci
2042cabdff1aSopenharmony_cistatic void wavpack_encode_sample(WavPackEncodeContext *s, WvChannel *c, int32_t sample)
2043cabdff1aSopenharmony_ci{
2044cabdff1aSopenharmony_ci    WavPackWords *w = &s->w;
2045cabdff1aSopenharmony_ci    uint32_t ones_count, low, high;
2046cabdff1aSopenharmony_ci    int sign = sample < 0;
2047cabdff1aSopenharmony_ci
2048cabdff1aSopenharmony_ci    if (s->w.c[0].median[0] < 2 && !s->w.holding_zero && s->w.c[1].median[0] < 2) {
2049cabdff1aSopenharmony_ci        if (w->zeros_acc) {
2050cabdff1aSopenharmony_ci            if (sample)
2051cabdff1aSopenharmony_ci                encode_flush(s);
2052cabdff1aSopenharmony_ci            else {
2053cabdff1aSopenharmony_ci                w->zeros_acc++;
2054cabdff1aSopenharmony_ci                return;
2055cabdff1aSopenharmony_ci            }
2056cabdff1aSopenharmony_ci        } else if (sample) {
2057cabdff1aSopenharmony_ci            put_bits(&s->pb, 1, 0);
2058cabdff1aSopenharmony_ci        } else {
2059cabdff1aSopenharmony_ci            CLEAR(s->w.c[0].median);
2060cabdff1aSopenharmony_ci            CLEAR(s->w.c[1].median);
2061cabdff1aSopenharmony_ci            w->zeros_acc = 1;
2062cabdff1aSopenharmony_ci            return;
2063cabdff1aSopenharmony_ci        }
2064cabdff1aSopenharmony_ci    }
2065cabdff1aSopenharmony_ci
2066cabdff1aSopenharmony_ci    if (sign)
2067cabdff1aSopenharmony_ci        sample = ~sample;
2068cabdff1aSopenharmony_ci
2069cabdff1aSopenharmony_ci    if (sample < (int32_t) GET_MED(0)) {
2070cabdff1aSopenharmony_ci        ones_count = low = 0;
2071cabdff1aSopenharmony_ci        high = GET_MED(0) - 1;
2072cabdff1aSopenharmony_ci        DEC_MED(0);
2073cabdff1aSopenharmony_ci    } else {
2074cabdff1aSopenharmony_ci        low = GET_MED(0);
2075cabdff1aSopenharmony_ci        INC_MED(0);
2076cabdff1aSopenharmony_ci
2077cabdff1aSopenharmony_ci        if (sample - low < GET_MED(1)) {
2078cabdff1aSopenharmony_ci            ones_count = 1;
2079cabdff1aSopenharmony_ci            high = low + GET_MED(1) - 1;
2080cabdff1aSopenharmony_ci            DEC_MED(1);
2081cabdff1aSopenharmony_ci        } else {
2082cabdff1aSopenharmony_ci            low += GET_MED(1);
2083cabdff1aSopenharmony_ci            INC_MED(1);
2084cabdff1aSopenharmony_ci
2085cabdff1aSopenharmony_ci            if (sample - low < GET_MED(2)) {
2086cabdff1aSopenharmony_ci                ones_count = 2;
2087cabdff1aSopenharmony_ci                high = low + GET_MED(2) - 1;
2088cabdff1aSopenharmony_ci                DEC_MED(2);
2089cabdff1aSopenharmony_ci            } else {
2090cabdff1aSopenharmony_ci                ones_count = 2 + (sample - low) / GET_MED(2);
2091cabdff1aSopenharmony_ci                low += (ones_count - 2) * GET_MED(2);
2092cabdff1aSopenharmony_ci                high = low + GET_MED(2) - 1;
2093cabdff1aSopenharmony_ci                INC_MED(2);
2094cabdff1aSopenharmony_ci            }
2095cabdff1aSopenharmony_ci        }
2096cabdff1aSopenharmony_ci    }
2097cabdff1aSopenharmony_ci
2098cabdff1aSopenharmony_ci    if (w->holding_zero) {
2099cabdff1aSopenharmony_ci        if (ones_count)
2100cabdff1aSopenharmony_ci            w->holding_one++;
2101cabdff1aSopenharmony_ci
2102cabdff1aSopenharmony_ci        encode_flush(s);
2103cabdff1aSopenharmony_ci
2104cabdff1aSopenharmony_ci        if (ones_count) {
2105cabdff1aSopenharmony_ci            w->holding_zero = 1;
2106cabdff1aSopenharmony_ci            ones_count--;
2107cabdff1aSopenharmony_ci        } else
2108cabdff1aSopenharmony_ci            w->holding_zero = 0;
2109cabdff1aSopenharmony_ci    } else
2110cabdff1aSopenharmony_ci        w->holding_zero = 1;
2111cabdff1aSopenharmony_ci
2112cabdff1aSopenharmony_ci    w->holding_one = ones_count * 2;
2113cabdff1aSopenharmony_ci
2114cabdff1aSopenharmony_ci    if (high != low) {
2115cabdff1aSopenharmony_ci        uint32_t maxcode = high - low, code = sample - low;
2116cabdff1aSopenharmony_ci        int bitcount = count_bits(maxcode);
2117cabdff1aSopenharmony_ci        uint32_t extras = (1 << bitcount) - maxcode - 1;
2118cabdff1aSopenharmony_ci
2119cabdff1aSopenharmony_ci        if (code < extras) {
2120cabdff1aSopenharmony_ci            w->pend_data |= code << w->pend_count;
2121cabdff1aSopenharmony_ci            w->pend_count += bitcount - 1;
2122cabdff1aSopenharmony_ci        } else {
2123cabdff1aSopenharmony_ci            w->pend_data |= ((code + extras) >> 1) << w->pend_count;
2124cabdff1aSopenharmony_ci            w->pend_count += bitcount - 1;
2125cabdff1aSopenharmony_ci            w->pend_data |= ((code + extras) & 1) << w->pend_count++;
2126cabdff1aSopenharmony_ci        }
2127cabdff1aSopenharmony_ci    }
2128cabdff1aSopenharmony_ci
2129cabdff1aSopenharmony_ci    w->pend_data |= ((int32_t) sign << w->pend_count++);
2130cabdff1aSopenharmony_ci
2131cabdff1aSopenharmony_ci    if (!w->holding_zero)
2132cabdff1aSopenharmony_ci        encode_flush(s);
2133cabdff1aSopenharmony_ci}
2134cabdff1aSopenharmony_ci
2135cabdff1aSopenharmony_cistatic void pack_int32(WavPackEncodeContext *s,
2136cabdff1aSopenharmony_ci                       int32_t *samples_l, int32_t *samples_r,
2137cabdff1aSopenharmony_ci                       int nb_samples)
2138cabdff1aSopenharmony_ci{
2139cabdff1aSopenharmony_ci    const int sent_bits = s->int32_sent_bits;
2140cabdff1aSopenharmony_ci    PutBitContext *pb = &s->pb;
2141cabdff1aSopenharmony_ci    int i, pre_shift;
2142cabdff1aSopenharmony_ci
2143cabdff1aSopenharmony_ci    pre_shift = s->int32_zeros + s->int32_ones + s->int32_dups;
2144cabdff1aSopenharmony_ci
2145cabdff1aSopenharmony_ci    if (!sent_bits)
2146cabdff1aSopenharmony_ci        return;
2147cabdff1aSopenharmony_ci
2148cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
2149cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2150cabdff1aSopenharmony_ci            put_sbits(pb, sent_bits, samples_l[i] >> pre_shift);
2151cabdff1aSopenharmony_ci        }
2152cabdff1aSopenharmony_ci    } else {
2153cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2154cabdff1aSopenharmony_ci            put_sbits(pb, sent_bits, samples_l[i] >> pre_shift);
2155cabdff1aSopenharmony_ci            put_sbits(pb, sent_bits, samples_r[i] >> pre_shift);
2156cabdff1aSopenharmony_ci        }
2157cabdff1aSopenharmony_ci    }
2158cabdff1aSopenharmony_ci}
2159cabdff1aSopenharmony_ci
2160cabdff1aSopenharmony_cistatic void pack_float_sample(WavPackEncodeContext *s, int32_t *sample)
2161cabdff1aSopenharmony_ci{
2162cabdff1aSopenharmony_ci    const int max_exp = s->float_max_exp;
2163cabdff1aSopenharmony_ci    PutBitContext *pb = &s->pb;
2164cabdff1aSopenharmony_ci    int32_t value, shift_count;
2165cabdff1aSopenharmony_ci
2166cabdff1aSopenharmony_ci    if (get_exponent(*sample) == 255) {
2167cabdff1aSopenharmony_ci        if (get_mantissa(*sample)) {
2168cabdff1aSopenharmony_ci            put_bits(pb, 1, 1);
2169cabdff1aSopenharmony_ci            put_bits(pb, 23, get_mantissa(*sample));
2170cabdff1aSopenharmony_ci        } else {
2171cabdff1aSopenharmony_ci            put_bits(pb, 1, 0);
2172cabdff1aSopenharmony_ci        }
2173cabdff1aSopenharmony_ci
2174cabdff1aSopenharmony_ci        value = 0x1000000;
2175cabdff1aSopenharmony_ci        shift_count = 0;
2176cabdff1aSopenharmony_ci    } else if (get_exponent(*sample)) {
2177cabdff1aSopenharmony_ci        shift_count = max_exp - get_exponent(*sample);
2178cabdff1aSopenharmony_ci        value = 0x800000 + get_mantissa(*sample);
2179cabdff1aSopenharmony_ci    } else {
2180cabdff1aSopenharmony_ci        shift_count = max_exp ? max_exp - 1 : 0;
2181cabdff1aSopenharmony_ci        value = get_mantissa(*sample);
2182cabdff1aSopenharmony_ci    }
2183cabdff1aSopenharmony_ci
2184cabdff1aSopenharmony_ci    if (shift_count < 25)
2185cabdff1aSopenharmony_ci        value >>= shift_count;
2186cabdff1aSopenharmony_ci    else
2187cabdff1aSopenharmony_ci        value = 0;
2188cabdff1aSopenharmony_ci
2189cabdff1aSopenharmony_ci    if (!value) {
2190cabdff1aSopenharmony_ci        if (s->float_flags & FLOAT_ZEROS_SENT) {
2191cabdff1aSopenharmony_ci            if (get_exponent(*sample) || get_mantissa(*sample)) {
2192cabdff1aSopenharmony_ci                put_bits(pb, 1, 1);
2193cabdff1aSopenharmony_ci                put_bits(pb, 23, get_mantissa(*sample));
2194cabdff1aSopenharmony_ci
2195cabdff1aSopenharmony_ci                if (max_exp >= 25)
2196cabdff1aSopenharmony_ci                    put_bits(pb, 8, get_exponent(*sample));
2197cabdff1aSopenharmony_ci
2198cabdff1aSopenharmony_ci                put_bits(pb, 1, get_sign(*sample));
2199cabdff1aSopenharmony_ci            } else {
2200cabdff1aSopenharmony_ci                put_bits(pb, 1, 0);
2201cabdff1aSopenharmony_ci
2202cabdff1aSopenharmony_ci                if (s->float_flags & FLOAT_NEG_ZEROS)
2203cabdff1aSopenharmony_ci                    put_bits(pb, 1, get_sign(*sample));
2204cabdff1aSopenharmony_ci            }
2205cabdff1aSopenharmony_ci        }
2206cabdff1aSopenharmony_ci    } else if (shift_count) {
2207cabdff1aSopenharmony_ci        if (s->float_flags & FLOAT_SHIFT_SENT) {
2208cabdff1aSopenharmony_ci            put_sbits(pb, shift_count, get_mantissa(*sample));
2209cabdff1aSopenharmony_ci        } else if (s->float_flags & FLOAT_SHIFT_SAME) {
2210cabdff1aSopenharmony_ci            put_bits(pb, 1, get_mantissa(*sample) & 1);
2211cabdff1aSopenharmony_ci        }
2212cabdff1aSopenharmony_ci    }
2213cabdff1aSopenharmony_ci}
2214cabdff1aSopenharmony_ci
2215cabdff1aSopenharmony_cistatic void pack_float(WavPackEncodeContext *s,
2216cabdff1aSopenharmony_ci                       int32_t *samples_l, int32_t *samples_r,
2217cabdff1aSopenharmony_ci                       int nb_samples)
2218cabdff1aSopenharmony_ci{
2219cabdff1aSopenharmony_ci    int i;
2220cabdff1aSopenharmony_ci
2221cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
2222cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++)
2223cabdff1aSopenharmony_ci            pack_float_sample(s, &samples_l[i]);
2224cabdff1aSopenharmony_ci    } else {
2225cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2226cabdff1aSopenharmony_ci            pack_float_sample(s, &samples_l[i]);
2227cabdff1aSopenharmony_ci            pack_float_sample(s, &samples_r[i]);
2228cabdff1aSopenharmony_ci        }
2229cabdff1aSopenharmony_ci    }
2230cabdff1aSopenharmony_ci}
2231cabdff1aSopenharmony_ci
2232cabdff1aSopenharmony_cistatic void decorr_stereo_pass2(struct Decorr *dpp,
2233cabdff1aSopenharmony_ci                                int32_t *samples_l, int32_t *samples_r,
2234cabdff1aSopenharmony_ci                                int nb_samples)
2235cabdff1aSopenharmony_ci{
2236cabdff1aSopenharmony_ci    int i, m, k;
2237cabdff1aSopenharmony_ci
2238cabdff1aSopenharmony_ci    switch (dpp->value) {
2239cabdff1aSopenharmony_ci    case 17:
2240cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2241cabdff1aSopenharmony_ci            int32_t sam, tmp;
2242cabdff1aSopenharmony_ci
2243cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
2244cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
2245cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
2246cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
2247cabdff1aSopenharmony_ci
2248cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
2249cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
2250cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
2251cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
2252cabdff1aSopenharmony_ci        }
2253cabdff1aSopenharmony_ci        break;
2254cabdff1aSopenharmony_ci    case 18:
2255cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2256cabdff1aSopenharmony_ci            int32_t sam, tmp;
2257cabdff1aSopenharmony_ci
2258cabdff1aSopenharmony_ci            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
2259cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
2260cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
2261cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
2262cabdff1aSopenharmony_ci
2263cabdff1aSopenharmony_ci            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
2264cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
2265cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
2266cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
2267cabdff1aSopenharmony_ci        }
2268cabdff1aSopenharmony_ci        break;
2269cabdff1aSopenharmony_ci    default:
2270cabdff1aSopenharmony_ci        for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) {
2271cabdff1aSopenharmony_ci            int32_t sam, tmp;
2272cabdff1aSopenharmony_ci
2273cabdff1aSopenharmony_ci            sam = dpp->samplesA[m];
2274cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
2275cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
2276cabdff1aSopenharmony_ci
2277cabdff1aSopenharmony_ci            sam = dpp->samplesB[m];
2278cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
2279cabdff1aSopenharmony_ci            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
2280cabdff1aSopenharmony_ci
2281cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
2282cabdff1aSopenharmony_ci            k = (k + 1) & (MAX_TERM - 1);
2283cabdff1aSopenharmony_ci        }
2284cabdff1aSopenharmony_ci        if (m) {
2285cabdff1aSopenharmony_ci            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
2286cabdff1aSopenharmony_ci
2287cabdff1aSopenharmony_ci            memcpy(temp_A, dpp->samplesA, sizeof (dpp->samplesA));
2288cabdff1aSopenharmony_ci            memcpy(temp_B, dpp->samplesB, sizeof (dpp->samplesB));
2289cabdff1aSopenharmony_ci
2290cabdff1aSopenharmony_ci            for (k = 0; k < MAX_TERM; k++) {
2291cabdff1aSopenharmony_ci                dpp->samplesA[k] = temp_A[m];
2292cabdff1aSopenharmony_ci                dpp->samplesB[k] = temp_B[m];
2293cabdff1aSopenharmony_ci                m = (m + 1) & (MAX_TERM - 1);
2294cabdff1aSopenharmony_ci            }
2295cabdff1aSopenharmony_ci        }
2296cabdff1aSopenharmony_ci        break;
2297cabdff1aSopenharmony_ci    case -1:
2298cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2299cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
2300cabdff1aSopenharmony_ci
2301cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
2302cabdff1aSopenharmony_ci            samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A);
2303cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
2304cabdff1aSopenharmony_ci
2305cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B);
2306cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
2307cabdff1aSopenharmony_ci        }
2308cabdff1aSopenharmony_ci        break;
2309cabdff1aSopenharmony_ci    case -2:
2310cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2311cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
2312cabdff1aSopenharmony_ci
2313cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
2314cabdff1aSopenharmony_ci            samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B);
2315cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
2316cabdff1aSopenharmony_ci
2317cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A);
2318cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
2319cabdff1aSopenharmony_ci        }
2320cabdff1aSopenharmony_ci        break;
2321cabdff1aSopenharmony_ci    case -3:
2322cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2323cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
2324cabdff1aSopenharmony_ci
2325cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
2326cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
2327cabdff1aSopenharmony_ci
2328cabdff1aSopenharmony_ci            dpp->samplesA[0] = tmp = samples_r[i];
2329cabdff1aSopenharmony_ci            samples_r[i] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B);
2330cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
2331cabdff1aSopenharmony_ci
2332cabdff1aSopenharmony_ci            dpp->samplesB[0] = tmp = samples_l[i];
2333cabdff1aSopenharmony_ci            samples_l[i] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A);
2334cabdff1aSopenharmony_ci            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
2335cabdff1aSopenharmony_ci        }
2336cabdff1aSopenharmony_ci        break;
2337cabdff1aSopenharmony_ci    }
2338cabdff1aSopenharmony_ci}
2339cabdff1aSopenharmony_ci
2340cabdff1aSopenharmony_ci#define update_weight_d2(weight, delta, source, result) \
2341cabdff1aSopenharmony_ci    if (source && result) \
2342cabdff1aSopenharmony_ci        weight -= (((source ^ result) >> 29) & 4) - 2;
2343cabdff1aSopenharmony_ci
2344cabdff1aSopenharmony_ci#define update_weight_clip_d2(weight, delta, source, result) \
2345cabdff1aSopenharmony_ci    if (source && result) { \
2346cabdff1aSopenharmony_ci        const int32_t s = (source ^ result) >> 31; \
2347cabdff1aSopenharmony_ci        if ((weight = (weight ^ s) + (2 - s)) > 1024) weight = 1024; \
2348cabdff1aSopenharmony_ci        weight = (weight ^ s) - s; \
2349cabdff1aSopenharmony_ci    }
2350cabdff1aSopenharmony_ci
2351cabdff1aSopenharmony_cistatic void decorr_stereo_pass_id2(struct Decorr *dpp,
2352cabdff1aSopenharmony_ci                                   int32_t *samples_l, int32_t *samples_r,
2353cabdff1aSopenharmony_ci                                   int nb_samples)
2354cabdff1aSopenharmony_ci{
2355cabdff1aSopenharmony_ci    int i, m, k;
2356cabdff1aSopenharmony_ci
2357cabdff1aSopenharmony_ci    switch (dpp->value) {
2358cabdff1aSopenharmony_ci    case 17:
2359cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2360cabdff1aSopenharmony_ci            int32_t sam, tmp;
2361cabdff1aSopenharmony_ci
2362cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
2363cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
2364cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
2365cabdff1aSopenharmony_ci            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);
2366cabdff1aSopenharmony_ci
2367cabdff1aSopenharmony_ci            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
2368cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
2369cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
2370cabdff1aSopenharmony_ci            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
2371cabdff1aSopenharmony_ci        }
2372cabdff1aSopenharmony_ci        break;
2373cabdff1aSopenharmony_ci    case 18:
2374cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2375cabdff1aSopenharmony_ci            int32_t sam, tmp;
2376cabdff1aSopenharmony_ci
2377cabdff1aSopenharmony_ci            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
2378cabdff1aSopenharmony_ci            dpp->samplesA[1] = dpp->samplesA[0];
2379cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
2380cabdff1aSopenharmony_ci            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);
2381cabdff1aSopenharmony_ci
2382cabdff1aSopenharmony_ci            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
2383cabdff1aSopenharmony_ci            dpp->samplesB[1] = dpp->samplesB[0];
2384cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
2385cabdff1aSopenharmony_ci            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
2386cabdff1aSopenharmony_ci        }
2387cabdff1aSopenharmony_ci        break;
2388cabdff1aSopenharmony_ci    default:
2389cabdff1aSopenharmony_ci        for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) {
2390cabdff1aSopenharmony_ci            int32_t sam, tmp;
2391cabdff1aSopenharmony_ci
2392cabdff1aSopenharmony_ci            sam = dpp->samplesA[m];
2393cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
2394cabdff1aSopenharmony_ci            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);
2395cabdff1aSopenharmony_ci
2396cabdff1aSopenharmony_ci            sam = dpp->samplesB[m];
2397cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
2398cabdff1aSopenharmony_ci            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
2399cabdff1aSopenharmony_ci
2400cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
2401cabdff1aSopenharmony_ci            k = (k + 1) & (MAX_TERM - 1);
2402cabdff1aSopenharmony_ci        }
2403cabdff1aSopenharmony_ci
2404cabdff1aSopenharmony_ci        if (m) {
2405cabdff1aSopenharmony_ci            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
2406cabdff1aSopenharmony_ci
2407cabdff1aSopenharmony_ci            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
2408cabdff1aSopenharmony_ci            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
2409cabdff1aSopenharmony_ci
2410cabdff1aSopenharmony_ci            for (k = 0; k < MAX_TERM; k++) {
2411cabdff1aSopenharmony_ci                dpp->samplesA[k] = temp_A[m];
2412cabdff1aSopenharmony_ci                dpp->samplesB[k] = temp_B[m];
2413cabdff1aSopenharmony_ci                m = (m + 1) & (MAX_TERM - 1);
2414cabdff1aSopenharmony_ci            }
2415cabdff1aSopenharmony_ci        }
2416cabdff1aSopenharmony_ci        break;
2417cabdff1aSopenharmony_ci    case -1:
2418cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2419cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
2420cabdff1aSopenharmony_ci
2421cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
2422cabdff1aSopenharmony_ci            samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
2423cabdff1aSopenharmony_ci            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
2424cabdff1aSopenharmony_ci
2425cabdff1aSopenharmony_ci            samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
2426cabdff1aSopenharmony_ci            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
2427cabdff1aSopenharmony_ci        }
2428cabdff1aSopenharmony_ci        break;
2429cabdff1aSopenharmony_ci    case -2:
2430cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2431cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
2432cabdff1aSopenharmony_ci
2433cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
2434cabdff1aSopenharmony_ci            samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
2435cabdff1aSopenharmony_ci            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
2436cabdff1aSopenharmony_ci
2437cabdff1aSopenharmony_ci            samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
2438cabdff1aSopenharmony_ci            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
2439cabdff1aSopenharmony_ci        }
2440cabdff1aSopenharmony_ci        break;
2441cabdff1aSopenharmony_ci    case -3:
2442cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2443cabdff1aSopenharmony_ci            int32_t sam_A, sam_B, tmp;
2444cabdff1aSopenharmony_ci
2445cabdff1aSopenharmony_ci            sam_A = dpp->samplesA[0];
2446cabdff1aSopenharmony_ci            sam_B = dpp->samplesB[0];
2447cabdff1aSopenharmony_ci
2448cabdff1aSopenharmony_ci            dpp->samplesA[0] = tmp = samples_r[i];
2449cabdff1aSopenharmony_ci            samples_r[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B);
2450cabdff1aSopenharmony_ci            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
2451cabdff1aSopenharmony_ci
2452cabdff1aSopenharmony_ci            dpp->samplesB[0] = tmp = samples_l[i];
2453cabdff1aSopenharmony_ci            samples_l[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A);
2454cabdff1aSopenharmony_ci            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
2455cabdff1aSopenharmony_ci        }
2456cabdff1aSopenharmony_ci        break;
2457cabdff1aSopenharmony_ci    }
2458cabdff1aSopenharmony_ci}
2459cabdff1aSopenharmony_ci
2460cabdff1aSopenharmony_cistatic void put_metadata_block(PutByteContext *pb, int flags, int size)
2461cabdff1aSopenharmony_ci{
2462cabdff1aSopenharmony_ci    if (size & 1)
2463cabdff1aSopenharmony_ci        flags |= WP_IDF_ODD;
2464cabdff1aSopenharmony_ci
2465cabdff1aSopenharmony_ci    bytestream2_put_byte(pb, flags);
2466cabdff1aSopenharmony_ci    bytestream2_put_byte(pb, (size + 1) >> 1);
2467cabdff1aSopenharmony_ci}
2468cabdff1aSopenharmony_ci
2469cabdff1aSopenharmony_cistatic int wavpack_encode_block(WavPackEncodeContext *s,
2470cabdff1aSopenharmony_ci                                int32_t *samples_l, int32_t *samples_r,
2471cabdff1aSopenharmony_ci                                uint8_t *out, int out_size)
2472cabdff1aSopenharmony_ci{
2473cabdff1aSopenharmony_ci    int block_size, start, end, data_size, tcount, temp, m = 0;
2474cabdff1aSopenharmony_ci    int i, j, ret = 0, got_extra = 0, nb_samples = s->block_samples;
2475cabdff1aSopenharmony_ci    uint32_t crc = 0xffffffffu;
2476cabdff1aSopenharmony_ci    struct Decorr *dpp;
2477cabdff1aSopenharmony_ci    PutByteContext pb;
2478cabdff1aSopenharmony_ci
2479cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
2480cabdff1aSopenharmony_ci        CLEAR(s->w);
2481cabdff1aSopenharmony_ci    }
2482cabdff1aSopenharmony_ci    if (!(s->flags & WV_MONO) && s->optimize_mono) {
2483cabdff1aSopenharmony_ci        int32_t lor = 0, diff = 0;
2484cabdff1aSopenharmony_ci
2485cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2486cabdff1aSopenharmony_ci            lor  |= samples_l[i] | samples_r[i];
2487cabdff1aSopenharmony_ci            diff |= samples_l[i] - samples_r[i];
2488cabdff1aSopenharmony_ci
2489cabdff1aSopenharmony_ci            if (lor && diff)
2490cabdff1aSopenharmony_ci                break;
2491cabdff1aSopenharmony_ci        }
2492cabdff1aSopenharmony_ci
2493cabdff1aSopenharmony_ci        if (i == nb_samples && lor && !diff) {
2494cabdff1aSopenharmony_ci            s->flags &= ~(WV_JOINT_STEREO | WV_CROSS_DECORR);
2495cabdff1aSopenharmony_ci            s->flags |= WV_FALSE_STEREO;
2496cabdff1aSopenharmony_ci
2497cabdff1aSopenharmony_ci            if (!s->false_stereo) {
2498cabdff1aSopenharmony_ci                s->false_stereo = 1;
2499cabdff1aSopenharmony_ci                s->num_terms = 0;
2500cabdff1aSopenharmony_ci                CLEAR(s->w);
2501cabdff1aSopenharmony_ci            }
2502cabdff1aSopenharmony_ci        } else if (s->false_stereo) {
2503cabdff1aSopenharmony_ci            s->false_stereo = 0;
2504cabdff1aSopenharmony_ci            s->num_terms = 0;
2505cabdff1aSopenharmony_ci            CLEAR(s->w);
2506cabdff1aSopenharmony_ci        }
2507cabdff1aSopenharmony_ci    }
2508cabdff1aSopenharmony_ci
2509cabdff1aSopenharmony_ci    if (s->flags & SHIFT_MASK) {
2510cabdff1aSopenharmony_ci        int shift = (s->flags & SHIFT_MASK) >> SHIFT_LSB;
2511cabdff1aSopenharmony_ci        int mag = (s->flags & MAG_MASK) >> MAG_LSB;
2512cabdff1aSopenharmony_ci
2513cabdff1aSopenharmony_ci        if (s->flags & WV_MONO_DATA)
2514cabdff1aSopenharmony_ci            shift_mono(samples_l, nb_samples, shift);
2515cabdff1aSopenharmony_ci        else
2516cabdff1aSopenharmony_ci            shift_stereo(samples_l, samples_r, nb_samples, shift);
2517cabdff1aSopenharmony_ci
2518cabdff1aSopenharmony_ci        if ((mag -= shift) < 0)
2519cabdff1aSopenharmony_ci            s->flags &= ~MAG_MASK;
2520cabdff1aSopenharmony_ci        else
2521cabdff1aSopenharmony_ci            s->flags -= (1 << MAG_LSB) * shift;
2522cabdff1aSopenharmony_ci    }
2523cabdff1aSopenharmony_ci
2524cabdff1aSopenharmony_ci    if ((s->flags & WV_FLOAT_DATA) || (s->flags & MAG_MASK) >> MAG_LSB >= 24) {
2525cabdff1aSopenharmony_ci        av_fast_padded_malloc(&s->orig_l, &s->orig_l_size, sizeof(int32_t) * nb_samples);
2526cabdff1aSopenharmony_ci        memcpy(s->orig_l, samples_l, sizeof(int32_t) * nb_samples);
2527cabdff1aSopenharmony_ci        if (!(s->flags & WV_MONO_DATA)) {
2528cabdff1aSopenharmony_ci            av_fast_padded_malloc(&s->orig_r, &s->orig_r_size, sizeof(int32_t) * nb_samples);
2529cabdff1aSopenharmony_ci            memcpy(s->orig_r, samples_r, sizeof(int32_t) * nb_samples);
2530cabdff1aSopenharmony_ci        }
2531cabdff1aSopenharmony_ci
2532cabdff1aSopenharmony_ci        if (s->flags & WV_FLOAT_DATA)
2533cabdff1aSopenharmony_ci            got_extra = scan_float(s, samples_l, samples_r, nb_samples);
2534cabdff1aSopenharmony_ci        else
2535cabdff1aSopenharmony_ci            got_extra = scan_int32(s, samples_l, samples_r, nb_samples);
2536cabdff1aSopenharmony_ci        s->num_terms = 0;
2537cabdff1aSopenharmony_ci    } else {
2538cabdff1aSopenharmony_ci        scan_int23(s, samples_l, samples_r, nb_samples);
2539cabdff1aSopenharmony_ci        if (s->shift != s->int32_zeros + s->int32_ones + s->int32_dups) {
2540cabdff1aSopenharmony_ci            s->shift = s->int32_zeros + s->int32_ones + s->int32_dups;
2541cabdff1aSopenharmony_ci            s->num_terms = 0;
2542cabdff1aSopenharmony_ci        }
2543cabdff1aSopenharmony_ci    }
2544cabdff1aSopenharmony_ci
2545cabdff1aSopenharmony_ci    if (!s->num_passes && !s->num_terms) {
2546cabdff1aSopenharmony_ci        s->num_passes = 1;
2547cabdff1aSopenharmony_ci
2548cabdff1aSopenharmony_ci        if (s->flags & WV_MONO_DATA)
2549cabdff1aSopenharmony_ci            ret = wv_mono(s, samples_l, 1, 0);
2550cabdff1aSopenharmony_ci        else
2551cabdff1aSopenharmony_ci            ret = wv_stereo(s, samples_l, samples_r, 1, 0);
2552cabdff1aSopenharmony_ci
2553cabdff1aSopenharmony_ci        s->num_passes = 0;
2554cabdff1aSopenharmony_ci    }
2555cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
2556cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++)
2557cabdff1aSopenharmony_ci            crc += (crc << 1) + samples_l[i];
2558cabdff1aSopenharmony_ci
2559cabdff1aSopenharmony_ci        if (s->num_passes)
2560cabdff1aSopenharmony_ci            ret = wv_mono(s, samples_l, !s->num_terms, 1);
2561cabdff1aSopenharmony_ci    } else {
2562cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++)
2563cabdff1aSopenharmony_ci            crc += (crc << 3) + ((uint32_t)samples_l[i] << 1) + samples_l[i] + samples_r[i];
2564cabdff1aSopenharmony_ci
2565cabdff1aSopenharmony_ci        if (s->num_passes)
2566cabdff1aSopenharmony_ci            ret = wv_stereo(s, samples_l, samples_r, !s->num_terms, 1);
2567cabdff1aSopenharmony_ci    }
2568cabdff1aSopenharmony_ci    if (ret < 0)
2569cabdff1aSopenharmony_ci        return ret;
2570cabdff1aSopenharmony_ci
2571cabdff1aSopenharmony_ci    if (!s->ch_offset)
2572cabdff1aSopenharmony_ci        s->flags |= WV_INITIAL_BLOCK;
2573cabdff1aSopenharmony_ci
2574cabdff1aSopenharmony_ci    s->ch_offset += 1 + !(s->flags & WV_MONO);
2575cabdff1aSopenharmony_ci
2576cabdff1aSopenharmony_ci    if (s->ch_offset == s->avctx->ch_layout.nb_channels)
2577cabdff1aSopenharmony_ci        s->flags |= WV_FINAL_BLOCK;
2578cabdff1aSopenharmony_ci
2579cabdff1aSopenharmony_ci    bytestream2_init_writer(&pb, out, out_size);
2580cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, MKTAG('w', 'v', 'p', 'k'));
2581cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, 0);
2582cabdff1aSopenharmony_ci    bytestream2_put_le16(&pb, 0x410);
2583cabdff1aSopenharmony_ci    bytestream2_put_le16(&pb, 0);
2584cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, 0);
2585cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, s->sample_index);
2586cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, nb_samples);
2587cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, s->flags);
2588cabdff1aSopenharmony_ci    bytestream2_put_le32(&pb, crc);
2589cabdff1aSopenharmony_ci
2590cabdff1aSopenharmony_ci    if (s->flags & WV_INITIAL_BLOCK &&
2591cabdff1aSopenharmony_ci        s->avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
2592cabdff1aSopenharmony_ci        s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_MONO &&
2593cabdff1aSopenharmony_ci        s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_STEREO) {
2594cabdff1aSopenharmony_ci        put_metadata_block(&pb, WP_ID_CHANINFO, 5);
2595cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->avctx->ch_layout.nb_channels);
2596cabdff1aSopenharmony_ci        bytestream2_put_le32(&pb, s->avctx->ch_layout.u.mask);
2597cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, 0);
2598cabdff1aSopenharmony_ci    }
2599cabdff1aSopenharmony_ci
2600cabdff1aSopenharmony_ci    if ((s->flags & SRATE_MASK) == SRATE_MASK) {
2601cabdff1aSopenharmony_ci        put_metadata_block(&pb, WP_ID_SAMPLE_RATE, 3);
2602cabdff1aSopenharmony_ci        bytestream2_put_le24(&pb, s->avctx->sample_rate);
2603cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, 0);
2604cabdff1aSopenharmony_ci    }
2605cabdff1aSopenharmony_ci
2606cabdff1aSopenharmony_ci    put_metadata_block(&pb, WP_ID_DECTERMS, s->num_terms);
2607cabdff1aSopenharmony_ci    for (i = 0; i < s->num_terms; i++) {
2608cabdff1aSopenharmony_ci        struct Decorr *dpp = &s->decorr_passes[i];
2609cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, ((dpp->value + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0));
2610cabdff1aSopenharmony_ci    }
2611cabdff1aSopenharmony_ci    if (s->num_terms & 1)
2612cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, 0);
2613cabdff1aSopenharmony_ci
2614cabdff1aSopenharmony_ci#define WRITE_DECWEIGHT(type) do {            \
2615cabdff1aSopenharmony_ci        temp = store_weight(type);    \
2616cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, temp);      \
2617cabdff1aSopenharmony_ci        type = restore_weight(temp);  \
2618cabdff1aSopenharmony_ci    } while (0)
2619cabdff1aSopenharmony_ci
2620cabdff1aSopenharmony_ci    bytestream2_put_byte(&pb, WP_ID_DECWEIGHTS);
2621cabdff1aSopenharmony_ci    bytestream2_put_byte(&pb, 0);
2622cabdff1aSopenharmony_ci    start = bytestream2_tell_p(&pb);
2623cabdff1aSopenharmony_ci    for (i = s->num_terms - 1; i >= 0; --i) {
2624cabdff1aSopenharmony_ci        struct Decorr *dpp = &s->decorr_passes[i];
2625cabdff1aSopenharmony_ci
2626cabdff1aSopenharmony_ci        if (store_weight(dpp->weightA) ||
2627cabdff1aSopenharmony_ci            (!(s->flags & WV_MONO_DATA) && store_weight(dpp->weightB)))
2628cabdff1aSopenharmony_ci                break;
2629cabdff1aSopenharmony_ci    }
2630cabdff1aSopenharmony_ci    tcount = i + 1;
2631cabdff1aSopenharmony_ci    for (i = 0; i < s->num_terms; i++) {
2632cabdff1aSopenharmony_ci        struct Decorr *dpp = &s->decorr_passes[i];
2633cabdff1aSopenharmony_ci        if (i < tcount) {
2634cabdff1aSopenharmony_ci            WRITE_DECWEIGHT(dpp->weightA);
2635cabdff1aSopenharmony_ci            if (!(s->flags & WV_MONO_DATA))
2636cabdff1aSopenharmony_ci                WRITE_DECWEIGHT(dpp->weightB);
2637cabdff1aSopenharmony_ci        } else {
2638cabdff1aSopenharmony_ci            dpp->weightA = dpp->weightB = 0;
2639cabdff1aSopenharmony_ci        }
2640cabdff1aSopenharmony_ci    }
2641cabdff1aSopenharmony_ci    end = bytestream2_tell_p(&pb);
2642cabdff1aSopenharmony_ci    out[start - 2] = WP_ID_DECWEIGHTS | (((end - start) & 1) ? WP_IDF_ODD: 0);
2643cabdff1aSopenharmony_ci    out[start - 1] = (end - start + 1) >> 1;
2644cabdff1aSopenharmony_ci    if ((end - start) & 1)
2645cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, 0);
2646cabdff1aSopenharmony_ci
2647cabdff1aSopenharmony_ci#define WRITE_DECSAMPLE(type) do {        \
2648cabdff1aSopenharmony_ci        temp = log2s(type);               \
2649cabdff1aSopenharmony_ci        type = wp_exp2(temp);             \
2650cabdff1aSopenharmony_ci        bytestream2_put_le16(&pb, temp);  \
2651cabdff1aSopenharmony_ci    } while (0)
2652cabdff1aSopenharmony_ci
2653cabdff1aSopenharmony_ci    bytestream2_put_byte(&pb, WP_ID_DECSAMPLES);
2654cabdff1aSopenharmony_ci    bytestream2_put_byte(&pb, 0);
2655cabdff1aSopenharmony_ci    start = bytestream2_tell_p(&pb);
2656cabdff1aSopenharmony_ci    for (i = 0; i < s->num_terms; i++) {
2657cabdff1aSopenharmony_ci        struct Decorr *dpp = &s->decorr_passes[i];
2658cabdff1aSopenharmony_ci        if (i == 0) {
2659cabdff1aSopenharmony_ci            if (dpp->value > MAX_TERM) {
2660cabdff1aSopenharmony_ci                WRITE_DECSAMPLE(dpp->samplesA[0]);
2661cabdff1aSopenharmony_ci                WRITE_DECSAMPLE(dpp->samplesA[1]);
2662cabdff1aSopenharmony_ci                if (!(s->flags & WV_MONO_DATA)) {
2663cabdff1aSopenharmony_ci                    WRITE_DECSAMPLE(dpp->samplesB[0]);
2664cabdff1aSopenharmony_ci                    WRITE_DECSAMPLE(dpp->samplesB[1]);
2665cabdff1aSopenharmony_ci                }
2666cabdff1aSopenharmony_ci            } else if (dpp->value < 0) {
2667cabdff1aSopenharmony_ci                WRITE_DECSAMPLE(dpp->samplesA[0]);
2668cabdff1aSopenharmony_ci                WRITE_DECSAMPLE(dpp->samplesB[0]);
2669cabdff1aSopenharmony_ci            } else {
2670cabdff1aSopenharmony_ci                for (j = 0; j < dpp->value; j++) {
2671cabdff1aSopenharmony_ci                    WRITE_DECSAMPLE(dpp->samplesA[j]);
2672cabdff1aSopenharmony_ci                    if (!(s->flags & WV_MONO_DATA))
2673cabdff1aSopenharmony_ci                        WRITE_DECSAMPLE(dpp->samplesB[j]);
2674cabdff1aSopenharmony_ci                }
2675cabdff1aSopenharmony_ci            }
2676cabdff1aSopenharmony_ci        } else {
2677cabdff1aSopenharmony_ci            CLEAR(dpp->samplesA);
2678cabdff1aSopenharmony_ci            CLEAR(dpp->samplesB);
2679cabdff1aSopenharmony_ci        }
2680cabdff1aSopenharmony_ci    }
2681cabdff1aSopenharmony_ci    end = bytestream2_tell_p(&pb);
2682cabdff1aSopenharmony_ci    out[start - 1] = (end - start) >> 1;
2683cabdff1aSopenharmony_ci
2684cabdff1aSopenharmony_ci#define WRITE_CHAN_ENTROPY(chan) do {               \
2685cabdff1aSopenharmony_ci        for (i = 0; i < 3; i++) {                   \
2686cabdff1aSopenharmony_ci            temp = wp_log2(s->w.c[chan].median[i]); \
2687cabdff1aSopenharmony_ci            bytestream2_put_le16(&pb, temp);        \
2688cabdff1aSopenharmony_ci            s->w.c[chan].median[i] = wp_exp2(temp); \
2689cabdff1aSopenharmony_ci        }                                           \
2690cabdff1aSopenharmony_ci    } while (0)
2691cabdff1aSopenharmony_ci
2692cabdff1aSopenharmony_ci    put_metadata_block(&pb, WP_ID_ENTROPY, 6 * (1 + (!(s->flags & WV_MONO_DATA))));
2693cabdff1aSopenharmony_ci    WRITE_CHAN_ENTROPY(0);
2694cabdff1aSopenharmony_ci    if (!(s->flags & WV_MONO_DATA))
2695cabdff1aSopenharmony_ci        WRITE_CHAN_ENTROPY(1);
2696cabdff1aSopenharmony_ci
2697cabdff1aSopenharmony_ci    if (s->flags & WV_FLOAT_DATA) {
2698cabdff1aSopenharmony_ci        put_metadata_block(&pb, WP_ID_FLOATINFO, 4);
2699cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->float_flags);
2700cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->float_shift);
2701cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->float_max_exp);
2702cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, 127);
2703cabdff1aSopenharmony_ci    }
2704cabdff1aSopenharmony_ci
2705cabdff1aSopenharmony_ci    if (s->flags & WV_INT32_DATA) {
2706cabdff1aSopenharmony_ci        put_metadata_block(&pb, WP_ID_INT32INFO, 4);
2707cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->int32_sent_bits);
2708cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->int32_zeros);
2709cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->int32_ones);
2710cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, s->int32_dups);
2711cabdff1aSopenharmony_ci    }
2712cabdff1aSopenharmony_ci
2713cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA && !s->num_passes) {
2714cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2715cabdff1aSopenharmony_ci            int32_t code = samples_l[i];
2716cabdff1aSopenharmony_ci
2717cabdff1aSopenharmony_ci            for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++) {
2718cabdff1aSopenharmony_ci                int32_t sam;
2719cabdff1aSopenharmony_ci
2720cabdff1aSopenharmony_ci                if (dpp->value > MAX_TERM) {
2721cabdff1aSopenharmony_ci                    if (dpp->value & 1)
2722cabdff1aSopenharmony_ci                        sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
2723cabdff1aSopenharmony_ci                    else
2724cabdff1aSopenharmony_ci                        sam = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
2725cabdff1aSopenharmony_ci
2726cabdff1aSopenharmony_ci                    dpp->samplesA[1] = dpp->samplesA[0];
2727cabdff1aSopenharmony_ci                    dpp->samplesA[0] = code;
2728cabdff1aSopenharmony_ci                } else {
2729cabdff1aSopenharmony_ci                    sam = dpp->samplesA[m];
2730cabdff1aSopenharmony_ci                    dpp->samplesA[(m + dpp->value) & (MAX_TERM - 1)] = code;
2731cabdff1aSopenharmony_ci                }
2732cabdff1aSopenharmony_ci
2733cabdff1aSopenharmony_ci                code -= APPLY_WEIGHT(dpp->weightA, sam);
2734cabdff1aSopenharmony_ci                UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, code);
2735cabdff1aSopenharmony_ci            }
2736cabdff1aSopenharmony_ci
2737cabdff1aSopenharmony_ci            m = (m + 1) & (MAX_TERM - 1);
2738cabdff1aSopenharmony_ci            samples_l[i] = code;
2739cabdff1aSopenharmony_ci        }
2740cabdff1aSopenharmony_ci        if (m) {
2741cabdff1aSopenharmony_ci            for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++)
2742cabdff1aSopenharmony_ci                if (dpp->value > 0 && dpp->value <= MAX_TERM) {
2743cabdff1aSopenharmony_ci                int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
2744cabdff1aSopenharmony_ci                int k;
2745cabdff1aSopenharmony_ci
2746cabdff1aSopenharmony_ci                memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
2747cabdff1aSopenharmony_ci                memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));
2748cabdff1aSopenharmony_ci
2749cabdff1aSopenharmony_ci                for (k = 0; k < MAX_TERM; k++) {
2750cabdff1aSopenharmony_ci                    dpp->samplesA[k] = temp_A[m];
2751cabdff1aSopenharmony_ci                    dpp->samplesB[k] = temp_B[m];
2752cabdff1aSopenharmony_ci                    m = (m + 1) & (MAX_TERM - 1);
2753cabdff1aSopenharmony_ci                }
2754cabdff1aSopenharmony_ci            }
2755cabdff1aSopenharmony_ci        }
2756cabdff1aSopenharmony_ci    } else if (!s->num_passes) {
2757cabdff1aSopenharmony_ci        if (s->flags & WV_JOINT_STEREO) {
2758cabdff1aSopenharmony_ci            for (i = 0; i < nb_samples; i++)
2759cabdff1aSopenharmony_ci                samples_r[i] += ((samples_l[i] -= samples_r[i]) >> 1);
2760cabdff1aSopenharmony_ci        }
2761cabdff1aSopenharmony_ci
2762cabdff1aSopenharmony_ci        for (i = 0; i < s->num_terms; i++) {
2763cabdff1aSopenharmony_ci            struct Decorr *dpp = &s->decorr_passes[i];
2764cabdff1aSopenharmony_ci            if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16 || dpp->delta != 2)
2765cabdff1aSopenharmony_ci                decorr_stereo_pass2(dpp, samples_l, samples_r, nb_samples);
2766cabdff1aSopenharmony_ci            else
2767cabdff1aSopenharmony_ci                decorr_stereo_pass_id2(dpp, samples_l, samples_r, nb_samples);
2768cabdff1aSopenharmony_ci        }
2769cabdff1aSopenharmony_ci    }
2770cabdff1aSopenharmony_ci
2771cabdff1aSopenharmony_ci    bytestream2_put_byte(&pb, WP_ID_DATA | WP_IDF_LONG);
2772cabdff1aSopenharmony_ci    init_put_bits(&s->pb, pb.buffer + 3, bytestream2_get_bytes_left_p(&pb));
2773cabdff1aSopenharmony_ci    if (s->flags & WV_MONO_DATA) {
2774cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++)
2775cabdff1aSopenharmony_ci            wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]);
2776cabdff1aSopenharmony_ci    } else {
2777cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++) {
2778cabdff1aSopenharmony_ci            wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]);
2779cabdff1aSopenharmony_ci            wavpack_encode_sample(s, &s->w.c[1], s->samples[1][i]);
2780cabdff1aSopenharmony_ci        }
2781cabdff1aSopenharmony_ci    }
2782cabdff1aSopenharmony_ci    encode_flush(s);
2783cabdff1aSopenharmony_ci    flush_put_bits(&s->pb);
2784cabdff1aSopenharmony_ci    data_size = put_bytes_output(&s->pb);
2785cabdff1aSopenharmony_ci    bytestream2_put_le24(&pb, (data_size + 1) >> 1);
2786cabdff1aSopenharmony_ci    bytestream2_skip_p(&pb, data_size);
2787cabdff1aSopenharmony_ci    if (data_size & 1)
2788cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, 0);
2789cabdff1aSopenharmony_ci
2790cabdff1aSopenharmony_ci    if (got_extra) {
2791cabdff1aSopenharmony_ci        bytestream2_put_byte(&pb, WP_ID_EXTRABITS | WP_IDF_LONG);
2792cabdff1aSopenharmony_ci        init_put_bits(&s->pb, pb.buffer + 7, bytestream2_get_bytes_left_p(&pb));
2793cabdff1aSopenharmony_ci        if (s->flags & WV_FLOAT_DATA)
2794cabdff1aSopenharmony_ci            pack_float(s, s->orig_l, s->orig_r, nb_samples);
2795cabdff1aSopenharmony_ci        else
2796cabdff1aSopenharmony_ci            pack_int32(s, s->orig_l, s->orig_r, nb_samples);
2797cabdff1aSopenharmony_ci        flush_put_bits(&s->pb);
2798cabdff1aSopenharmony_ci        data_size = put_bytes_output(&s->pb);
2799cabdff1aSopenharmony_ci        bytestream2_put_le24(&pb, (data_size + 5) >> 1);
2800cabdff1aSopenharmony_ci        bytestream2_put_le32(&pb, s->crc_x);
2801cabdff1aSopenharmony_ci        bytestream2_skip_p(&pb, data_size);
2802cabdff1aSopenharmony_ci        if (data_size & 1)
2803cabdff1aSopenharmony_ci            bytestream2_put_byte(&pb, 0);
2804cabdff1aSopenharmony_ci    }
2805cabdff1aSopenharmony_ci
2806cabdff1aSopenharmony_ci    block_size = bytestream2_tell_p(&pb);
2807cabdff1aSopenharmony_ci    AV_WL32(out + 4, block_size - 8);
2808cabdff1aSopenharmony_ci
2809cabdff1aSopenharmony_ci    av_assert0(!bytestream2_get_eof(&pb));
2810cabdff1aSopenharmony_ci
2811cabdff1aSopenharmony_ci    return block_size;
2812cabdff1aSopenharmony_ci}
2813cabdff1aSopenharmony_ci
2814cabdff1aSopenharmony_cistatic void fill_buffer(WavPackEncodeContext *s,
2815cabdff1aSopenharmony_ci                        const int8_t *src, int32_t *dst,
2816cabdff1aSopenharmony_ci                        int nb_samples)
2817cabdff1aSopenharmony_ci{
2818cabdff1aSopenharmony_ci    int i;
2819cabdff1aSopenharmony_ci
2820cabdff1aSopenharmony_ci#define COPY_SAMPLES(type, offset, shift) do {            \
2821cabdff1aSopenharmony_ci        const type *sptr = (const type *)src;             \
2822cabdff1aSopenharmony_ci        for (i = 0; i < nb_samples; i++)                  \
2823cabdff1aSopenharmony_ci            dst[i] = (sptr[i] - offset) >> shift;         \
2824cabdff1aSopenharmony_ci    } while (0)
2825cabdff1aSopenharmony_ci
2826cabdff1aSopenharmony_ci    switch (s->avctx->sample_fmt) {
2827cabdff1aSopenharmony_ci    case AV_SAMPLE_FMT_U8P:
2828cabdff1aSopenharmony_ci        COPY_SAMPLES(int8_t, 0x80, 0);
2829cabdff1aSopenharmony_ci        break;
2830cabdff1aSopenharmony_ci    case AV_SAMPLE_FMT_S16P:
2831cabdff1aSopenharmony_ci        COPY_SAMPLES(int16_t, 0, 0);
2832cabdff1aSopenharmony_ci        break;
2833cabdff1aSopenharmony_ci    case AV_SAMPLE_FMT_S32P:
2834cabdff1aSopenharmony_ci        if (s->avctx->bits_per_raw_sample <= 24) {
2835cabdff1aSopenharmony_ci            COPY_SAMPLES(int32_t, 0, 8);
2836cabdff1aSopenharmony_ci            break;
2837cabdff1aSopenharmony_ci        }
2838cabdff1aSopenharmony_ci    case AV_SAMPLE_FMT_FLTP:
2839cabdff1aSopenharmony_ci        memcpy(dst, src, nb_samples * 4);
2840cabdff1aSopenharmony_ci    }
2841cabdff1aSopenharmony_ci}
2842cabdff1aSopenharmony_ci
2843cabdff1aSopenharmony_cistatic void set_samplerate(WavPackEncodeContext *s)
2844cabdff1aSopenharmony_ci{
2845cabdff1aSopenharmony_ci    int i;
2846cabdff1aSopenharmony_ci
2847cabdff1aSopenharmony_ci    for (i = 0; i < 15; i++) {
2848cabdff1aSopenharmony_ci        if (wv_rates[i] == s->avctx->sample_rate)
2849cabdff1aSopenharmony_ci            break;
2850cabdff1aSopenharmony_ci    }
2851cabdff1aSopenharmony_ci
2852cabdff1aSopenharmony_ci    s->flags = i << SRATE_LSB;
2853cabdff1aSopenharmony_ci}
2854cabdff1aSopenharmony_ci
2855cabdff1aSopenharmony_cistatic int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
2856cabdff1aSopenharmony_ci                                const AVFrame *frame, int *got_packet_ptr)
2857cabdff1aSopenharmony_ci{
2858cabdff1aSopenharmony_ci    WavPackEncodeContext *s = avctx->priv_data;
2859cabdff1aSopenharmony_ci    int buf_size, ret;
2860cabdff1aSopenharmony_ci    uint8_t *buf;
2861cabdff1aSopenharmony_ci
2862cabdff1aSopenharmony_ci    s->block_samples = frame->nb_samples;
2863cabdff1aSopenharmony_ci    av_fast_padded_malloc(&s->samples[0], &s->samples_size[0],
2864cabdff1aSopenharmony_ci                          sizeof(int32_t) * s->block_samples);
2865cabdff1aSopenharmony_ci    if (!s->samples[0])
2866cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
2867cabdff1aSopenharmony_ci    if (avctx->ch_layout.nb_channels > 1) {
2868cabdff1aSopenharmony_ci        av_fast_padded_malloc(&s->samples[1], &s->samples_size[1],
2869cabdff1aSopenharmony_ci                              sizeof(int32_t) * s->block_samples);
2870cabdff1aSopenharmony_ci        if (!s->samples[1])
2871cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
2872cabdff1aSopenharmony_ci    }
2873cabdff1aSopenharmony_ci
2874cabdff1aSopenharmony_ci    buf_size = s->block_samples * avctx->ch_layout.nb_channels * 8
2875cabdff1aSopenharmony_ci             + 200 * avctx->ch_layout.nb_channels /* for headers */;
2876cabdff1aSopenharmony_ci    if ((ret = ff_alloc_packet(avctx, avpkt, buf_size)) < 0)
2877cabdff1aSopenharmony_ci        return ret;
2878cabdff1aSopenharmony_ci    buf = avpkt->data;
2879cabdff1aSopenharmony_ci
2880cabdff1aSopenharmony_ci    for (s->ch_offset = 0; s->ch_offset < avctx->ch_layout.nb_channels;) {
2881cabdff1aSopenharmony_ci        set_samplerate(s);
2882cabdff1aSopenharmony_ci
2883cabdff1aSopenharmony_ci        switch (s->avctx->sample_fmt) {
2884cabdff1aSopenharmony_ci        case AV_SAMPLE_FMT_S16P: s->flags |= 1; break;
2885cabdff1aSopenharmony_ci        case AV_SAMPLE_FMT_S32P: s->flags |= 3 - (s->avctx->bits_per_raw_sample <= 24); break;
2886cabdff1aSopenharmony_ci        case AV_SAMPLE_FMT_FLTP: s->flags |= 3 | WV_FLOAT_DATA;
2887cabdff1aSopenharmony_ci        }
2888cabdff1aSopenharmony_ci
2889cabdff1aSopenharmony_ci        fill_buffer(s, frame->extended_data[s->ch_offset], s->samples[0], s->block_samples);
2890cabdff1aSopenharmony_ci        if (avctx->ch_layout.nb_channels - s->ch_offset == 1) {
2891cabdff1aSopenharmony_ci            s->flags |= WV_MONO;
2892cabdff1aSopenharmony_ci        } else {
2893cabdff1aSopenharmony_ci            s->flags |= WV_CROSS_DECORR;
2894cabdff1aSopenharmony_ci            fill_buffer(s, frame->extended_data[s->ch_offset + 1], s->samples[1], s->block_samples);
2895cabdff1aSopenharmony_ci        }
2896cabdff1aSopenharmony_ci
2897cabdff1aSopenharmony_ci        s->flags += (1 << MAG_LSB) * ((s->flags & 3) * 8 + 7);
2898cabdff1aSopenharmony_ci
2899cabdff1aSopenharmony_ci        if ((ret = wavpack_encode_block(s, s->samples[0], s->samples[1],
2900cabdff1aSopenharmony_ci                                        buf, buf_size)) < 0)
2901cabdff1aSopenharmony_ci            return ret;
2902cabdff1aSopenharmony_ci
2903cabdff1aSopenharmony_ci        buf      += ret;
2904cabdff1aSopenharmony_ci        buf_size -= ret;
2905cabdff1aSopenharmony_ci    }
2906cabdff1aSopenharmony_ci    s->sample_index += frame->nb_samples;
2907cabdff1aSopenharmony_ci
2908cabdff1aSopenharmony_ci    avpkt->pts      = frame->pts;
2909cabdff1aSopenharmony_ci    avpkt->size     = buf - avpkt->data;
2910cabdff1aSopenharmony_ci    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
2911cabdff1aSopenharmony_ci    *got_packet_ptr = 1;
2912cabdff1aSopenharmony_ci    return 0;
2913cabdff1aSopenharmony_ci}
2914cabdff1aSopenharmony_ci
2915cabdff1aSopenharmony_cistatic av_cold int wavpack_encode_close(AVCodecContext *avctx)
2916cabdff1aSopenharmony_ci{
2917cabdff1aSopenharmony_ci    WavPackEncodeContext *s = avctx->priv_data;
2918cabdff1aSopenharmony_ci    int i;
2919cabdff1aSopenharmony_ci
2920cabdff1aSopenharmony_ci    for (i = 0; i < MAX_TERMS + 2; i++) {
2921cabdff1aSopenharmony_ci        av_freep(&s->sampleptrs[i][0]);
2922cabdff1aSopenharmony_ci        av_freep(&s->sampleptrs[i][1]);
2923cabdff1aSopenharmony_ci        s->sampleptrs_size[i][0] = s->sampleptrs_size[i][1] = 0;
2924cabdff1aSopenharmony_ci    }
2925cabdff1aSopenharmony_ci
2926cabdff1aSopenharmony_ci    for (i = 0; i < 2; i++) {
2927cabdff1aSopenharmony_ci        av_freep(&s->samples[i]);
2928cabdff1aSopenharmony_ci        s->samples_size[i] = 0;
2929cabdff1aSopenharmony_ci
2930cabdff1aSopenharmony_ci        av_freep(&s->best_buffer[i]);
2931cabdff1aSopenharmony_ci        s->best_buffer_size[i] = 0;
2932cabdff1aSopenharmony_ci
2933cabdff1aSopenharmony_ci        av_freep(&s->temp_buffer[i][0]);
2934cabdff1aSopenharmony_ci        av_freep(&s->temp_buffer[i][1]);
2935cabdff1aSopenharmony_ci        s->temp_buffer_size[i][0] = s->temp_buffer_size[i][1] = 0;
2936cabdff1aSopenharmony_ci    }
2937cabdff1aSopenharmony_ci
2938cabdff1aSopenharmony_ci    av_freep(&s->js_left);
2939cabdff1aSopenharmony_ci    av_freep(&s->js_right);
2940cabdff1aSopenharmony_ci    s->js_left_size = s->js_right_size = 0;
2941cabdff1aSopenharmony_ci
2942cabdff1aSopenharmony_ci    av_freep(&s->orig_l);
2943cabdff1aSopenharmony_ci    av_freep(&s->orig_r);
2944cabdff1aSopenharmony_ci    s->orig_l_size = s->orig_r_size = 0;
2945cabdff1aSopenharmony_ci
2946cabdff1aSopenharmony_ci    return 0;
2947cabdff1aSopenharmony_ci}
2948cabdff1aSopenharmony_ci
2949cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(WavPackEncodeContext, x)
2950cabdff1aSopenharmony_ci#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
2951cabdff1aSopenharmony_cistatic const AVOption options[] = {
2952cabdff1aSopenharmony_ci    { "joint_stereo",  "", OFFSET(joint), AV_OPT_TYPE_BOOL, {.i64=-1}, -1, 1, FLAGS },
2953cabdff1aSopenharmony_ci    { "optimize_mono", "", OFFSET(optimize_mono), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
2954cabdff1aSopenharmony_ci    { NULL },
2955cabdff1aSopenharmony_ci};
2956cabdff1aSopenharmony_ci
2957cabdff1aSopenharmony_cistatic const AVClass wavpack_encoder_class = {
2958cabdff1aSopenharmony_ci    .class_name = "WavPack encoder",
2959cabdff1aSopenharmony_ci    .item_name  = av_default_item_name,
2960cabdff1aSopenharmony_ci    .option     = options,
2961cabdff1aSopenharmony_ci    .version    = LIBAVUTIL_VERSION_INT,
2962cabdff1aSopenharmony_ci};
2963cabdff1aSopenharmony_ci
2964cabdff1aSopenharmony_ciconst FFCodec ff_wavpack_encoder = {
2965cabdff1aSopenharmony_ci    .p.name         = "wavpack",
2966cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("WavPack"),
2967cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
2968cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_WAVPACK,
2969cabdff1aSopenharmony_ci    .priv_data_size = sizeof(WavPackEncodeContext),
2970cabdff1aSopenharmony_ci    .p.priv_class   = &wavpack_encoder_class,
2971cabdff1aSopenharmony_ci    .init           = wavpack_encode_init,
2972cabdff1aSopenharmony_ci    FF_CODEC_ENCODE_CB(wavpack_encode_frame),
2973cabdff1aSopenharmony_ci    .close          = wavpack_encode_close,
2974cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
2975cabdff1aSopenharmony_ci    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8P,
2976cabdff1aSopenharmony_ci                                                     AV_SAMPLE_FMT_S16P,
2977cabdff1aSopenharmony_ci                                                     AV_SAMPLE_FMT_S32P,
2978cabdff1aSopenharmony_ci                                                     AV_SAMPLE_FMT_FLTP,
2979cabdff1aSopenharmony_ci                                                     AV_SAMPLE_FMT_NONE },
2980cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
2981cabdff1aSopenharmony_ci};
2982