Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdint.h>
34 : #include "options.h"
35 : #include "cnst.h"
36 : #include "prot.h"
37 : #include "ivas_prot.h"
38 : #include <assert.h>
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include "wmc_auto.h"
43 :
44 : #ifdef FIX_1119_SPLIT_RENDERING_VOIP
45 : /*---------------------------------------------------------------------*
46 : * CLDFB ring-buffer functions needed in split-rendering outputs
47 : *---------------------------------------------------------------------*/
48 :
49 : /*---------------------------------------------------------------------*
50 : * ivas_cldfb_ringbuf_IsEmpty()
51 : *
52 : * Returns 1 if the ring buffer is empty, or 0 otherwise.
53 : *---------------------------------------------------------------------*/
54 :
55 19104816 : static int16_t ivas_cldfb_ringbuf_IsEmpty(
56 : ISAR_CLDFB_RINGBUF_HANDLE h )
57 : {
58 19104816 : return (int16_t) ( h->read_pos == h->write_pos && !h->is_full );
59 : }
60 :
61 :
62 : /*---------------------------------------------------------------------*
63 : * ivas_cldfb_ringbuf_IsFull()
64 : *
65 : * Returns 1 if the ring buffer is full, or 0 otherwise.
66 : *---------------------------------------------------------------------*/
67 :
68 45387756 : static int16_t ivas_cldfb_ringbuf_IsFull(
69 : ISAR_CLDFB_RINGBUF_HANDLE h )
70 : {
71 45387756 : return h->is_full;
72 : }
73 :
74 :
75 : /*---------------------------------------------------------------------*
76 : * ivas_CLDFB_RINGBUF_Open()
77 : *
78 : * Allocate a ring buffer for CLDFB data with the given capacity of CLDFB columns.
79 : * Each column is expected to contain at most CLDFB_NO_CHANNELS_MAX frequency bands.
80 : *
81 : * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise.
82 : *---------------------------------------------------------------------*/
83 :
84 6300 : ivas_error ivas_CLDFB_RINGBUF_Open(
85 : ISAR_CLDFB_RINGBUF_HANDLE *ph,
86 : const int16_t capacity_columns )
87 : {
88 : ISAR_CLDFB_RINGBUF_HANDLE h;
89 : int32_t capacity;
90 :
91 6300 : capacity = capacity_columns * CLDFB_NO_CHANNELS_MAX;
92 :
93 6300 : if ( ( h = malloc( sizeof( ISAR_CLDFB_RINGBUF ) ) ) == NULL )
94 : {
95 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for CLDFB ring buffer\n" );
96 : }
97 6300 : h->real = NULL;
98 6300 : h->imag = NULL;
99 6300 : h->capacity = 0;
100 6300 : h->write_pos = 0;
101 6300 : h->read_pos = 0;
102 6300 : h->is_full = 0;
103 6300 : *ph = h;
104 :
105 6300 : if ( ( h->real = malloc( capacity * sizeof( float ) ) ) == NULL )
106 : {
107 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for CLDFB ring buffer\n" );
108 : }
109 6300 : if ( ( h->imag = malloc( capacity * sizeof( float ) ) ) == NULL )
110 : {
111 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for CLDFB ring buffer\n" );
112 : }
113 6300 : h->capacity = capacity;
114 :
115 6300 : return IVAS_ERR_OK;
116 : }
117 :
118 :
119 : /*---------------------------------------------------------------------*
120 : * ivas_CLDFB_RINGBUF_Close()
121 : *
122 : * Dellocate CLDFB ring buffer. The given handle will be set to NULL.
123 : *---------------------------------------------------------------------*/
124 :
125 6300 : void ivas_CLDFB_RINGBUF_Close(
126 : ISAR_CLDFB_RINGBUF_HANDLE *ph )
127 : {
128 : ISAR_CLDFB_RINGBUF_HANDLE h;
129 :
130 6300 : if ( ph == NULL )
131 : {
132 0 : return;
133 : }
134 6300 : h = *ph;
135 :
136 6300 : if ( h == NULL )
137 : {
138 0 : return;
139 : }
140 :
141 6300 : if ( h->real != NULL )
142 : {
143 6300 : free( h->real );
144 : }
145 6300 : if ( h->imag != NULL )
146 : {
147 6300 : free( h->imag );
148 : }
149 :
150 6300 : free( h );
151 6300 : *ph = NULL;
152 :
153 6300 : return;
154 : }
155 :
156 :
157 : /*---------------------------------------------------------------------*
158 : * ivas_CLDFB_RINGBUF_Push()
159 : *
160 : * Push a single column onto the back of the CLDFB ring buffer from real and imag arrays.
161 : *---------------------------------------------------------------------*/
162 :
163 19113108 : void ivas_CLDFB_RINGBUF_Push(
164 : ISAR_CLDFB_RINGBUF_HANDLE h,
165 : const float *real,
166 : const float *imag,
167 : const int16_t num_bands )
168 : {
169 19113108 : assert( num_bands <= CLDFB_NO_CHANNELS_MAX );
170 19113108 : assert( !ivas_cldfb_ringbuf_IsFull( h ) );
171 :
172 19113108 : mvr2r( real, &h->real[h->write_pos], num_bands );
173 19113108 : mvr2r( imag, &h->imag[h->write_pos], num_bands );
174 :
175 19113108 : h->write_pos += CLDFB_NO_CHANNELS_MAX;
176 19113108 : if ( h->write_pos == h->capacity )
177 : {
178 1194050 : h->write_pos = 0;
179 : }
180 :
181 19113108 : if ( h->read_pos == h->write_pos )
182 : {
183 1186002 : h->is_full = 1;
184 : }
185 :
186 19113108 : return;
187 : }
188 :
189 :
190 : /*---------------------------------------------------------------------*
191 : * ivas_CLDFB_RINGBUF_Pop()
192 : *
193 : * Pop a single column from the front of the CLDFB ring buffer into real and imag arrays.
194 : *---------------------------------------------------------------------*/
195 :
196 19104816 : void ivas_CLDFB_RINGBUF_Pop(
197 : ISAR_CLDFB_RINGBUF_HANDLE h,
198 : float *real,
199 : float *imag,
200 : const int16_t num_bands )
201 : {
202 19104816 : assert( num_bands <= CLDFB_NO_CHANNELS_MAX );
203 19104816 : assert( !ivas_cldfb_ringbuf_IsEmpty( h ) );
204 :
205 19104816 : if ( real != NULL )
206 : {
207 0 : mvr2r( &h->real[h->read_pos], real, num_bands );
208 : }
209 19104816 : if ( imag != NULL )
210 : {
211 0 : mvr2r( &h->imag[h->read_pos], imag, num_bands );
212 : }
213 :
214 19104816 : h->read_pos += CLDFB_NO_CHANNELS_MAX;
215 19104816 : if ( h->read_pos == h->capacity )
216 : {
217 1194050 : h->read_pos = 0;
218 : }
219 :
220 19104816 : h->is_full = 0;
221 :
222 19104816 : return;
223 : }
224 :
225 :
226 : /*---------------------------------------------------------------------*
227 : * ivas_cldfb_ringbuf_total_size()
228 : *
229 : * Returns total number of buffered samples (including number of channels)
230 : *---------------------------------------------------------------------*/
231 :
232 26274648 : static uint32_t ivas_cldfb_ringbuf_total_size(
233 : ISAR_CLDFB_RINGBUF_HANDLE h )
234 : {
235 26274648 : if ( ivas_cldfb_ringbuf_IsFull( h ) )
236 : {
237 7941626 : return h->capacity;
238 : }
239 :
240 18333022 : if ( h->read_pos <= h->write_pos )
241 : {
242 486656 : return h->write_pos - h->read_pos;
243 : }
244 :
245 : /* else wrap around */
246 17846366 : return h->write_pos + h->capacity - h->read_pos;
247 : }
248 :
249 :
250 : /*---------------------------------------------------------------------*
251 : * ivas_CLDFB_RINGBUF_GetByIdx()
252 : *
253 : * Get pointers into a specific column in the CLDFB ring buffer based on given index.
254 : * Non-negative indices access from the front of the ring buffer, negative indexes access
255 : * from the back, similar to Python arrays. For example:
256 : *
257 : * - index 0 accesses the front of the buffer, i.e. the oldest CLDFB column in the queue.
258 : * - index -1 accesses the back of the buffer, i.e. the newest (last pushed) CLDFB column in the queue.
259 : *---------------------------------------------------------------------*/
260 :
261 26274648 : void ivas_CLDFB_RINGBUF_GetByIdx(
262 : ISAR_CLDFB_RINGBUF_HANDLE h,
263 : float **p_real,
264 : float **p_imag,
265 : const int16_t col_idx )
266 : {
267 26274648 : int32_t idx = col_idx * CLDFB_NO_CHANNELS_MAX;
268 26274648 : int32_t num_floats = (int32_t) ivas_cldfb_ringbuf_total_size( h );
269 : uint32_t offset, uidx;
270 :
271 26274648 : assert( -num_floats <= idx && idx <= num_floats );
272 :
273 26274648 : if ( idx >= 0 )
274 : {
275 19104816 : offset = h->read_pos + idx;
276 19104816 : if ( h->capacity <= offset )
277 : {
278 0 : offset -= h->capacity;
279 : }
280 : }
281 : else
282 : {
283 7169832 : uidx = (uint32_t) -idx;
284 7169832 : if ( uidx <= h->write_pos )
285 : {
286 414208 : offset = h->write_pos - uidx;
287 : }
288 : else
289 : {
290 6755624 : offset = h->write_pos + h->capacity - uidx;
291 : }
292 : }
293 :
294 26274648 : *p_real = &h->real[offset];
295 26274648 : *p_imag = &h->imag[offset];
296 :
297 26274648 : return;
298 : }
299 : #endif
|