/src/libxaac/encoder/iusace_ms.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2023 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | |
21 | | #include "ixheaac_type_def.h" |
22 | | #include "ixheaac_constants.h" |
23 | | #include "iusace_cnst.h" |
24 | | #include "iusace_bitbuffer.h" |
25 | | #include "iusace_tns_usac.h" |
26 | | #include "iusace_psy_mod.h" |
27 | | #include "ixheaac_basic_ops32.h" |
28 | | #include "ixheaac_basic_ops40.h" |
29 | | #include "ixheaac_basic_ops.h" |
30 | | |
31 | | VOID iusace_ms_apply(ia_psy_mod_data_struct *pstr_psy_data, FLOAT64 *ptr_spec_left, |
32 | | FLOAT64 *ptr_spec_right, WORD32 *ms_select, |
33 | | WORD32 ms_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], const WORD32 sfb_count, |
34 | | const WORD32 sfb_per_group, const WORD32 max_sfb_per_grp, |
35 | 124k | const WORD32 *ptr_sfb_offsets, WORD32 chn, FLOAT64 *ptr_ms_spec) { |
36 | 124k | FLOAT32 *ptr_sfb_enegry_left = pstr_psy_data[chn].ptr_sfb_energy_long; |
37 | 124k | FLOAT32 *ptr_sfb_energy_right = pstr_psy_data[chn + 1].ptr_sfb_energy_long; |
38 | 124k | const FLOAT32 *ptr_sfb_energy_mid = pstr_psy_data[chn].ptr_sfb_energy_long_ms; |
39 | 124k | const FLOAT32 *ptr_sfb_energy_side = pstr_psy_data[chn + 1].ptr_sfb_energy_long_ms; |
40 | 124k | FLOAT32 *ptr_sfb_thr_left = pstr_psy_data[chn].ptr_sfb_thr_long; |
41 | 124k | FLOAT32 *ptr_sfb_thr_right = pstr_psy_data[chn + 1].ptr_sfb_thr_long; |
42 | 124k | FLOAT32 *ptr_sfb_spread_energy_left = pstr_psy_data[chn].ptr_sfb_spreaded_energy_long; |
43 | 124k | FLOAT32 *ptr_sfb_spread_energy_right = pstr_psy_data[chn + 1].ptr_sfb_spreaded_energy_long; |
44 | 124k | WORD32 sfb, sfb_offsets, j; |
45 | 124k | WORD32 grp = 0; |
46 | 124k | WORD32 ms_counter = 0; |
47 | 124k | WORD32 lr_counter = 0; |
48 | | |
49 | 124k | *ms_select = 0; |
50 | | |
51 | 473k | for (sfb = 0; sfb < sfb_count; sfb += sfb_per_group, grp++) { |
52 | 6.05M | for (sfb_offsets = 0; sfb_offsets < max_sfb_per_grp; sfb_offsets++) { |
53 | 5.70M | FLOAT32 left_right, mid_side, min_thr; |
54 | 5.70M | WORD32 use_ms; |
55 | 5.70M | ms_used[grp][sfb_offsets] = 0; |
56 | | |
57 | 5.70M | min_thr = MIN(ptr_sfb_thr_left[sfb + sfb_offsets], ptr_sfb_thr_right[sfb + sfb_offsets]); |
58 | | |
59 | 5.70M | left_right = |
60 | 5.70M | (ptr_sfb_thr_left[sfb + sfb_offsets] / |
61 | 5.70M | MAX(ptr_sfb_enegry_left[sfb + sfb_offsets], ptr_sfb_thr_left[sfb + sfb_offsets])) * |
62 | 5.70M | (ptr_sfb_thr_right[sfb + sfb_offsets] / |
63 | 5.70M | max(ptr_sfb_energy_right[sfb + sfb_offsets], ptr_sfb_thr_right[sfb + sfb_offsets])); |
64 | | |
65 | 5.70M | mid_side = (min_thr / max(ptr_sfb_energy_mid[sfb + sfb_offsets], min_thr)) * |
66 | 5.70M | (min_thr / max(ptr_sfb_energy_side[sfb + sfb_offsets], min_thr)); |
67 | | |
68 | 5.70M | use_ms = (mid_side >= left_right); |
69 | | |
70 | 5.70M | if (use_ms) { |
71 | 5.60M | ms_used[grp][sfb_offsets] = 1; |
72 | | |
73 | 104M | for (j = ptr_sfb_offsets[sfb + sfb_offsets]; j < ptr_sfb_offsets[sfb + sfb_offsets + 1]; |
74 | 99.3M | j++) { |
75 | 99.3M | if (ptr_ms_spec != NULL) { |
76 | 73.6M | ptr_spec_left[j] = ptr_ms_spec[j]; |
77 | 73.6M | ptr_spec_right[j] = ptr_ms_spec[1024 + j]; |
78 | 73.6M | } else { |
79 | 25.7M | FLOAT64 tmp = ptr_spec_left[j]; |
80 | | |
81 | 25.7M | ptr_spec_left[j] = 0.5f * (ptr_spec_left[j] + ptr_spec_right[j]); |
82 | | |
83 | 25.7M | ptr_spec_right[j] = 0.5f * (tmp - ptr_spec_right[j]); |
84 | 25.7M | } |
85 | 99.3M | } |
86 | | |
87 | 5.60M | ptr_sfb_thr_left[sfb + sfb_offsets] = ptr_sfb_thr_right[sfb + sfb_offsets] = min_thr; |
88 | | |
89 | 5.60M | ptr_sfb_enegry_left[sfb + sfb_offsets] = ptr_sfb_energy_mid[sfb + sfb_offsets]; |
90 | 5.60M | ptr_sfb_energy_right[sfb + sfb_offsets] = ptr_sfb_energy_side[sfb + sfb_offsets]; |
91 | | |
92 | 5.60M | ptr_sfb_spread_energy_left[sfb + sfb_offsets] = |
93 | 5.60M | ptr_sfb_spread_energy_right[sfb + sfb_offsets] = |
94 | 5.60M | min(ptr_sfb_spread_energy_left[sfb + sfb_offsets], |
95 | 5.60M | ptr_sfb_spread_energy_right[sfb + sfb_offsets]) * |
96 | 5.60M | 0.5f; |
97 | | |
98 | 5.60M | ms_counter++; |
99 | 5.60M | } else { |
100 | 98.5k | ms_used[grp][sfb_offsets] = 0; |
101 | 98.5k | lr_counter++; |
102 | 98.5k | } |
103 | 5.70M | } |
104 | 349k | } |
105 | | |
106 | 124k | if (ms_counter == 0) { |
107 | 6.01k | *ms_select = 0; |
108 | 117k | } else { |
109 | 117k | if (lr_counter != 0) { |
110 | 17.1k | *ms_select = 1; |
111 | 100k | } else { |
112 | 100k | *ms_select = 2; |
113 | 100k | } |
114 | 117k | } |
115 | 124k | return; |
116 | 124k | } |
117 | | |
118 | | VOID iusace_calc_ms_band_energy(const FLOAT64 *ptr_spec_left, const FLOAT64 *ptr_spec_right, |
119 | | const WORD32 *ptr_band_offset, const WORD32 num_bands, |
120 | 841k | FLOAT32 *ptr_band_energy_mid, FLOAT32 *ptr_band_energy_side) { |
121 | 841k | WORD32 i, j; |
122 | | |
123 | 841k | j = 0; |
124 | 14.7M | for (i = 0; i < num_bands; i++) { |
125 | 13.8M | ptr_band_energy_mid[i] = 0.0f; |
126 | 13.8M | ptr_band_energy_side[i] = 0.0f; |
127 | | |
128 | 181M | while (j < ptr_band_offset[i + 1]) { |
129 | 167M | FLOAT32 specm, specs; |
130 | | |
131 | 167M | specm = (FLOAT32)(0.5f * (ptr_spec_left[j] + ptr_spec_right[j])); |
132 | 167M | specs = (FLOAT32)(0.5f * (ptr_spec_left[j] - ptr_spec_right[j])); |
133 | | |
134 | 167M | ptr_band_energy_mid[i] += specm * specm; |
135 | 167M | ptr_band_energy_side[i] += specs * specs; |
136 | | |
137 | 167M | j++; |
138 | 167M | } |
139 | 13.8M | } |
140 | | |
141 | 841k | return; |
142 | 841k | } |