GCC Code Coverage Report


Directory: ./
File: submodules/raylib/src/external/qoa.h
Date: 2023-09-29 04:53:15
Exec Total Coverage
Lines: 0 193 0.0%
Branches: 0 88 0.0%

Line Branch Exec Source
1 /*
2
3 Copyright (c) 2023, Dominic Szablewski - https://phoboslab.org
4 SPDX-License-Identifier: MIT
5
6 QOA - The "Quite OK Audio" format for fast, lossy audio compression
7
8
9 -- Data Format
10
11 A QOA file has an 8 byte file header, followed by a number of frames. Each frame
12 consists of an 8 byte frame header, the current 8 byte en-/decoder state per
13 channel and 256 slices per channel. Each slice is 8 bytes wide and encodes 20
14 samples of audio data.
15
16 Note that the last frame of a file may contain less than 256 slices per channel.
17 The last slice (per channel) in the last frame may contain less 20 samples, but
18 the slice will still be 8 bytes wide, with the unused samples zeroed out.
19
20 The samplerate and number of channels is only stated in the frame headers, but
21 not in the file header. A decoder may peek into the first frame of the file to
22 find these values.
23
24 In a valid QOA file all frames have the same number of channels and the same
25 samplerate. These restrictions may be relaxed for streaming. This remains to
26 be decided.
27
28 All values in a QOA file are BIG ENDIAN. Luckily, EVERYTHING in a QOA file,
29 including the headers, is 64 bit aligned, so it's possible to read files with
30 just a read_u64() that does the byte swapping if necessary.
31
32 In pseudocode, the file layout is as follows:
33
34 struct {
35 struct {
36 char magic[4]; // magic bytes 'qoaf'
37 uint32_t samples; // number of samples per channel in this file
38 } file_header; // = 64 bits
39
40 struct {
41 struct {
42 uint8_t num_channels; // number of channels
43 uint24_t samplerate; // samplerate in hz
44 uint16_t fsamples; // sample count per channel in this frame
45 uint16_t fsize; // frame size (including the frame header)
46 } frame_header; // = 64 bits
47
48 struct {
49 int16_t history[4]; // = 64 bits
50 int16_t weights[4]; // = 64 bits
51 } lms_state[num_channels];
52
53 qoa_slice_t slices[256][num_channels]; // = 64 bits each
54 } frames[samples * channels / qoa_max_framesize()];
55 } qoa_file;
56
57 Wheras the 64bit qoa_slice_t is defined as follows:
58
59 .- QOA_SLICE -- 64 bits, 20 samples --------------------------/ /------------.
60 | Byte[0] | Byte[1] | Byte[2] \ \ Byte[7] |
61 | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | 7 6 5 / / 2 1 0 |
62 |------------+--------+--------+--------+---------+---------+-\ \--+---------|
63 | sf_index | r00 | r01 | r02 | r03 | r04 | / / | r19 |
64 `-------------------------------------------------------------\ \------------`
65
66 `sf_index` defines the scalefactor to use for this slice as an index into the
67 qoa_scalefactor_tab[16]
68
69 `r00`--`r19` are the residuals for the individual samples, divided by the
70 scalefactor and quantized by the qoa_quant_tab[].
71
72 In the decoder, a prediction of the next sample is computed by multiplying the
73 state (the last four output samples) with the predictor. The residual from the
74 slice is then dequantized using the qoa_dequant_tab[] and added to the
75 prediction. The result is clamped to int16 to form the final output sample.
76
77 */
78
79
80
81 /* -----------------------------------------------------------------------------
82 Header - Public functions */
83
84 #ifndef QOA_H
85 #define QOA_H
86
87 #ifdef __cplusplus
88 extern "C" {
89 #endif
90
91 #define QOA_MIN_FILESIZE 16
92 #define QOA_MAX_CHANNELS 8
93
94 #define QOA_SLICE_LEN 20
95 #define QOA_SLICES_PER_FRAME 256
96 #define QOA_FRAME_LEN (QOA_SLICES_PER_FRAME * QOA_SLICE_LEN)
97 #define QOA_LMS_LEN 4
98 #define QOA_MAGIC 0x716f6166 /* 'qoaf' */
99
100 #define QOA_FRAME_SIZE(channels, slices) \
101 (8 + QOA_LMS_LEN * 4 * channels + 8 * slices * channels)
102
103 typedef struct {
104 int history[QOA_LMS_LEN];
105 int weights[QOA_LMS_LEN];
106 } qoa_lms_t;
107
108 typedef struct {
109 unsigned int channels;
110 unsigned int samplerate;
111 unsigned int samples;
112 qoa_lms_t lms[QOA_MAX_CHANNELS];
113 #ifdef QOA_RECORD_TOTAL_ERROR
114 double error;
115 #endif
116 } qoa_desc;
117
118 unsigned int qoa_encode_header(qoa_desc *qoa, unsigned char *bytes);
119 unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned int frame_len, unsigned char *bytes);
120 void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len);
121
122 unsigned int qoa_max_frame_size(qoa_desc *qoa);
123 unsigned int qoa_decode_header(const unsigned char *bytes, int size, qoa_desc *qoa);
124 unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa_desc *qoa, short *sample_data, unsigned int *frame_len);
125 short *qoa_decode(const unsigned char *bytes, int size, qoa_desc *file);
126
127 #ifndef QOA_NO_STDIO
128
129 int qoa_write(const char *filename, const short *sample_data, qoa_desc *qoa);
130 void *qoa_read(const char *filename, qoa_desc *qoa);
131
132 #endif /* QOA_NO_STDIO */
133
134
135 #ifdef __cplusplus
136 }
137 #endif
138 #endif /* QOA_H */
139
140
141 /* -----------------------------------------------------------------------------
142 Implementation */
143
144 #ifdef QOA_IMPLEMENTATION
145 #include <stdlib.h>
146
147 #ifndef QOA_MALLOC
148 #define QOA_MALLOC(sz) malloc(sz)
149 #define QOA_FREE(p) free(p)
150 #endif
151
152 typedef unsigned long long qoa_uint64_t;
153
154
155 /* The quant_tab provides an index into the dequant_tab for residuals in the
156 range of -8 .. 8. It maps this range to just 3bits and becomes less accurate at
157 the higher end. Note that the residual zero is identical to the lowest positive
158 value. This is mostly fine, since the qoa_div() function always rounds away
159 from zero. */
160
161 static int qoa_quant_tab[17] = {
162 7, 7, 7, 5, 5, 3, 3, 1, /* -8..-1 */
163 0, /* 0 */
164 0, 2, 2, 4, 4, 6, 6, 6 /* 1.. 8 */
165 };
166
167
168 /* We have 16 different scalefactors. Like the quantized residuals these become
169 less accurate at the higher end. In theory, the highest scalefactor that we
170 would need to encode the highest 16bit residual is (2**16)/8 = 8192. However we
171 rely on the LMS filter to predict samples accurately enough that a maximum
172 residual of one quarter of the 16 bit range is high sufficient. I.e. with the
173 scalefactor 2048 times the quant range of 8 we can encode residuals up to 2**14.
174
175 The scalefactor values are computed as:
176 scalefactor_tab[s] <- round(pow(s + 1, 2.75)) */
177
178 static int qoa_scalefactor_tab[16] = {
179 1, 7, 21, 45, 84, 138, 211, 304, 421, 562, 731, 928, 1157, 1419, 1715, 2048
180 };
181
182
183 /* The reciprocal_tab maps each of the 16 scalefactors to their rounded
184 reciprocals 1/scalefactor. This allows us to calculate the scaled residuals in
185 the encoder with just one multiplication instead of an expensive division. We
186 do this in .16 fixed point with integers, instead of floats.
187
188 The reciprocal_tab is computed as:
189 reciprocal_tab[s] <- ((1<<16) + scalefactor_tab[s] - 1) / scalefactor_tab[s] */
190
191 static int qoa_reciprocal_tab[16] = {
192 65536, 9363, 3121, 1457, 781, 475, 311, 216, 156, 117, 90, 71, 57, 47, 39, 32
193 };
194
195
196 /* The dequant_tab maps each of the scalefactors and quantized residuals to
197 their unscaled & dequantized version.
198
199 Since qoa_div rounds away from the zero, the smallest entries are mapped to 3/4
200 instead of 1. The dequant_tab assumes the following dequantized values for each
201 of the quant_tab indices and is computed as:
202 float dqt[8] = {0.75, -0.75, 2.5, -2.5, 4.5, -4.5, 7, -7};
203 dequant_tab[s][q] <- round(scalefactor_tab[s] * dqt[q]) */
204
205 static int qoa_dequant_tab[16][8] = {
206 { 1, -1, 3, -3, 5, -5, 7, -7},
207 { 5, -5, 18, -18, 32, -32, 49, -49},
208 { 16, -16, 53, -53, 95, -95, 147, -147},
209 { 34, -34, 113, -113, 203, -203, 315, -315},
210 { 63, -63, 210, -210, 378, -378, 588, -588},
211 { 104, -104, 345, -345, 621, -621, 966, -966},
212 { 158, -158, 528, -528, 950, -950, 1477, -1477},
213 { 228, -228, 760, -760, 1368, -1368, 2128, -2128},
214 { 316, -316, 1053, -1053, 1895, -1895, 2947, -2947},
215 { 422, -422, 1405, -1405, 2529, -2529, 3934, -3934},
216 { 548, -548, 1828, -1828, 3290, -3290, 5117, -5117},
217 { 696, -696, 2320, -2320, 4176, -4176, 6496, -6496},
218 { 868, -868, 2893, -2893, 5207, -5207, 8099, -8099},
219 {1064, -1064, 3548, -3548, 6386, -6386, 9933, -9933},
220 {1286, -1286, 4288, -4288, 7718, -7718, 12005, -12005},
221 {1536, -1536, 5120, -5120, 9216, -9216, 14336, -14336},
222 };
223
224
225 /* The Least Mean Squares Filter is the heart of QOA. It predicts the next
226 sample based on the previous 4 reconstructed samples. It does so by continuously
227 adjusting 4 weights based on the residual of the previous prediction.
228
229 The next sample is predicted as the sum of (weight[i] * history[i]).
230
231 The adjustment of the weights is done with a "Sign-Sign-LMS" that adds or
232 subtracts the residual to each weight, based on the corresponding sample from
233 the history. This, surprisingly, is sufficient to get worthwhile predictions.
234
235 This is all done with fixed point integers. Hence the right-shifts when updating
236 the weights and calculating the prediction. */
237
238 static int qoa_lms_predict(qoa_lms_t *lms) {
239 int prediction = 0;
240 for (int i = 0; i < QOA_LMS_LEN; i++) {
241 prediction += lms->weights[i] * lms->history[i];
242 }
243 return prediction >> 13;
244 }
245
246 static void qoa_lms_update(qoa_lms_t *lms, int sample, int residual) {
247 int delta = residual >> 4;
248 for (int i = 0; i < QOA_LMS_LEN; i++) {
249 lms->weights[i] += lms->history[i] < 0 ? -delta : delta;
250 }
251
252 for (int i = 0; i < QOA_LMS_LEN-1; i++) {
253 lms->history[i] = lms->history[i+1];
254 }
255 lms->history[QOA_LMS_LEN-1] = sample;
256 }
257
258
259 /* qoa_div() implements a rounding division, but avoids rounding to zero for
260 small numbers. E.g. 0.1 will be rounded to 1. Note that 0 itself still
261 returns as 0, which is handled in the qoa_quant_tab[].
262 qoa_div() takes an index into the .16 fixed point qoa_reciprocal_tab as an
263 argument, so it can do the division with a cheaper integer multiplication. */
264
265 static inline int qoa_div(int v, int scalefactor) {
266 int reciprocal = qoa_reciprocal_tab[scalefactor];
267 int n = (v * reciprocal + (1 << 15)) >> 16;
268 n = n + ((v > 0) - (v < 0)) - ((n > 0) - (n < 0)); /* round away from 0 */
269 return n;
270 }
271
272 static inline int qoa_clamp(int v, int min, int max) {
273 return (v < min) ? min : (v > max) ? max : v;
274 }
275
276 static inline qoa_uint64_t qoa_read_u64(const unsigned char *bytes, unsigned int *p) {
277 bytes += *p;
278 *p += 8;
279 return
280 ((qoa_uint64_t)(bytes[0]) << 56) | ((qoa_uint64_t)(bytes[1]) << 48) |
281 ((qoa_uint64_t)(bytes[2]) << 40) | ((qoa_uint64_t)(bytes[3]) << 32) |
282 ((qoa_uint64_t)(bytes[4]) << 24) | ((qoa_uint64_t)(bytes[5]) << 16) |
283 ((qoa_uint64_t)(bytes[6]) << 8) | ((qoa_uint64_t)(bytes[7]) << 0);
284 }
285
286 static inline void qoa_write_u64(qoa_uint64_t v, unsigned char *bytes, unsigned int *p) {
287 bytes += *p;
288 *p += 8;
289 bytes[0] = (v >> 56) & 0xff;
290 bytes[1] = (v >> 48) & 0xff;
291 bytes[2] = (v >> 40) & 0xff;
292 bytes[3] = (v >> 32) & 0xff;
293 bytes[4] = (v >> 24) & 0xff;
294 bytes[5] = (v >> 16) & 0xff;
295 bytes[6] = (v >> 8) & 0xff;
296 bytes[7] = (v >> 0) & 0xff;
297 }
298
299
300 /* -----------------------------------------------------------------------------
301 Encoder */
302
303 unsigned int qoa_encode_header(qoa_desc *qoa, unsigned char *bytes) {
304 unsigned int p = 0;
305 qoa_write_u64(((qoa_uint64_t)QOA_MAGIC << 32) | qoa->samples, bytes, &p);
306 return p;
307 }
308
309 unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned int frame_len, unsigned char *bytes) {
310 unsigned int channels = qoa->channels;
311
312 unsigned int p = 0;
313 unsigned int slices = (frame_len + QOA_SLICE_LEN - 1) / QOA_SLICE_LEN;
314 unsigned int frame_size = QOA_FRAME_SIZE(channels, slices);
315
316 /* Write the frame header */
317 qoa_write_u64((
318 (qoa_uint64_t)qoa->channels << 56 |
319 (qoa_uint64_t)qoa->samplerate << 32 |
320 (qoa_uint64_t)frame_len << 16 |
321 (qoa_uint64_t)frame_size
322 ), bytes, &p);
323
324 /* Write the current LMS state */
325 for (int c = 0; c < channels; c++) {
326 qoa_uint64_t weights = 0;
327 qoa_uint64_t history = 0;
328 for (int i = 0; i < QOA_LMS_LEN; i++) {
329 history = (history << 16) | (qoa->lms[c].history[i] & 0xffff);
330 weights = (weights << 16) | (qoa->lms[c].weights[i] & 0xffff);
331 }
332 qoa_write_u64(history, bytes, &p);
333 qoa_write_u64(weights, bytes, &p);
334 }
335
336 /* We encode all samples with the channels interleaved on a slice level.
337 E.g. for stereo: (ch-0, slice 0), (ch 1, slice 0), (ch 0, slice 1), ...*/
338 for (int sample_index = 0; sample_index < frame_len; sample_index += QOA_SLICE_LEN) {
339
340 for (int c = 0; c < channels; c++) {
341 int slice_len = qoa_clamp(QOA_SLICE_LEN, 0, frame_len - sample_index);
342 int slice_start = sample_index * channels + c;
343 int slice_end = (sample_index + slice_len) * channels + c;
344
345 /* Brute for search for the best scalefactor. Just go through all
346 16 scalefactors, encode all samples for the current slice and
347 meassure the total squared error. */
348 qoa_uint64_t best_error = -1;
349 qoa_uint64_t best_slice;
350 qoa_lms_t best_lms;
351
352 for (int scalefactor = 0; scalefactor < 16; scalefactor++) {
353
354 /* We have to reset the LMS state to the last known good one
355 before trying each scalefactor, as each pass updates the LMS
356 state when encoding. */
357 qoa_lms_t lms = qoa->lms[c];
358 qoa_uint64_t slice = scalefactor;
359 qoa_uint64_t current_error = 0;
360
361 for (int si = slice_start; si < slice_end; si += channels) {
362 int sample = sample_data[si];
363 int predicted = qoa_lms_predict(&lms);
364
365 int residual = sample - predicted;
366 int scaled = qoa_div(residual, scalefactor);
367 int clamped = qoa_clamp(scaled, -8, 8);
368 int quantized = qoa_quant_tab[clamped + 8];
369 int dequantized = qoa_dequant_tab[scalefactor][quantized];
370 int reconstructed = qoa_clamp(predicted + dequantized, -32768, 32767);
371
372 long long error = (sample - reconstructed);
373 current_error += error * error;
374 if (current_error > best_error) {
375 break;
376 }
377
378 qoa_lms_update(&lms, reconstructed, dequantized);
379 slice = (slice << 3) | quantized;
380 }
381
382 if (current_error < best_error) {
383 best_error = current_error;
384 best_slice = slice;
385 best_lms = lms;
386 }
387 }
388
389 qoa->lms[c] = best_lms;
390 #ifdef QOA_RECORD_TOTAL_ERROR
391 qoa->error += best_error;
392 #endif
393
394 /* If this slice was shorter than QOA_SLICE_LEN, we have to left-
395 shift all encoded data, to ensure the rightmost bits are the empty
396 ones. This should only happen in the last frame of a file as all
397 slices are completely filled otherwise. */
398 best_slice <<= (QOA_SLICE_LEN - slice_len) * 3;
399 qoa_write_u64(best_slice, bytes, &p);
400 }
401 }
402
403 return p;
404 }
405
406 void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len) {
407 if (
408 qoa->samples == 0 ||
409 qoa->samplerate == 0 || qoa->samplerate > 0xffffff ||
410 qoa->channels == 0 || qoa->channels > QOA_MAX_CHANNELS
411 ) {
412 return NULL;
413 }
414
415 /* Calculate the encoded size and allocate */
416 unsigned int num_frames = (qoa->samples + QOA_FRAME_LEN-1) / QOA_FRAME_LEN;
417 unsigned int num_slices = (qoa->samples + QOA_SLICE_LEN-1) / QOA_SLICE_LEN;
418 unsigned int encoded_size = 8 + /* 8 byte file header */
419 num_frames * 8 + /* 8 byte frame headers */
420 num_frames * QOA_LMS_LEN * 4 * qoa->channels + /* 4 * 4 bytes lms state per channel */
421 num_slices * 8 * qoa->channels; /* 8 byte slices */
422
423 unsigned char *bytes = QOA_MALLOC(encoded_size);
424
425 for (int c = 0; c < qoa->channels; c++) {
426 /* Set the initial LMS weights to {0, 0, -1, 2}. This helps with the
427 prediction of the first few ms of a file. */
428 qoa->lms[c].weights[0] = 0;
429 qoa->lms[c].weights[1] = 0;
430 qoa->lms[c].weights[2] = -(1<<13);
431 qoa->lms[c].weights[3] = (1<<14);
432
433 /* Explicitly set the history samples to 0, as we might have some
434 garbage in there. */
435 for (int i = 0; i < QOA_LMS_LEN; i++) {
436 qoa->lms[c].history[i] = 0;
437 }
438 }
439
440
441 /* Encode the header and go through all frames */
442 unsigned int p = qoa_encode_header(qoa, bytes);
443 #ifdef QOA_RECORD_TOTAL_ERROR
444 qoa->error = 0;
445 #endif
446
447 int frame_len = QOA_FRAME_LEN;
448 for (int sample_index = 0; sample_index < qoa->samples; sample_index += frame_len) {
449 frame_len = qoa_clamp(QOA_FRAME_LEN, 0, qoa->samples - sample_index);
450 const short *frame_samples = sample_data + sample_index * qoa->channels;
451 unsigned int frame_size = qoa_encode_frame(frame_samples, qoa, frame_len, bytes + p);
452 p += frame_size;
453 }
454
455 *out_len = p;
456 return bytes;
457 }
458
459
460
461 /* -----------------------------------------------------------------------------
462 Decoder */
463
464 unsigned int qoa_max_frame_size(qoa_desc *qoa) {
465 return QOA_FRAME_SIZE(qoa->channels, QOA_SLICES_PER_FRAME);
466 }
467
468 unsigned int qoa_decode_header(const unsigned char *bytes, int size, qoa_desc *qoa) {
469 unsigned int p = 0;
470 if (size < QOA_MIN_FILESIZE) {
471 return 0;
472 }
473
474
475 /* Read the file header, verify the magic number ('qoaf') and read the
476 total number of samples. */
477 qoa_uint64_t file_header = qoa_read_u64(bytes, &p);
478
479 if ((file_header >> 32) != QOA_MAGIC) {
480 return 0;
481 }
482
483 qoa->samples = file_header & 0xffffffff;
484 if (!qoa->samples) {
485 return 0;
486 }
487
488 /* Peek into the first frame header to get the number of channels and
489 the samplerate. */
490 qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
491 qoa->channels = (frame_header >> 56) & 0x0000ff;
492 qoa->samplerate = (frame_header >> 32) & 0xffffff;
493
494 if (qoa->channels == 0 || qoa->samples == 0 || qoa->samplerate == 0) {
495 return 0;
496 }
497
498 return 8;
499 }
500
501 unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa_desc *qoa, short *sample_data, unsigned int *frame_len) {
502 unsigned int p = 0;
503 *frame_len = 0;
504
505 if (size < 8 + QOA_LMS_LEN * 4 * qoa->channels) {
506 return 0;
507 }
508
509 /* Read and verify the frame header */
510 qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
511 int channels = (frame_header >> 56) & 0x0000ff;
512 int samplerate = (frame_header >> 32) & 0xffffff;
513 int samples = (frame_header >> 16) & 0x00ffff;
514 int frame_size = (frame_header ) & 0x00ffff;
515
516 int data_size = frame_size - 8 - QOA_LMS_LEN * 4 * channels;
517 int num_slices = data_size / 8;
518 int max_total_samples = num_slices * QOA_SLICE_LEN;
519
520 if (
521 channels != qoa->channels ||
522 samplerate != qoa->samplerate ||
523 frame_size > size ||
524 samples * channels > max_total_samples
525 ) {
526 return 0;
527 }
528
529
530 /* Read the LMS state: 4 x 2 bytes history, 4 x 2 bytes weights per channel */
531 for (int c = 0; c < channels; c++) {
532 qoa_uint64_t history = qoa_read_u64(bytes, &p);
533 qoa_uint64_t weights = qoa_read_u64(bytes, &p);
534 for (int i = 0; i < QOA_LMS_LEN; i++) {
535 qoa->lms[c].history[i] = ((signed short)(history >> 48));
536 history <<= 16;
537 qoa->lms[c].weights[i] = ((signed short)(weights >> 48));
538 weights <<= 16;
539 }
540 }
541
542
543 /* Decode all slices for all channels in this frame */
544 for (int sample_index = 0; sample_index < samples; sample_index += QOA_SLICE_LEN) {
545 for (int c = 0; c < channels; c++) {
546 qoa_uint64_t slice = qoa_read_u64(bytes, &p);
547
548 int scalefactor = (slice >> 60) & 0xf;
549 int slice_start = sample_index * channels + c;
550 int slice_end = qoa_clamp(sample_index + QOA_SLICE_LEN, 0, samples) * channels + c;
551
552 for (int si = slice_start; si < slice_end; si += channels) {
553 int predicted = qoa_lms_predict(&qoa->lms[c]);
554 int quantized = (slice >> 57) & 0x7;
555 int dequantized = qoa_dequant_tab[scalefactor][quantized];
556 int reconstructed = qoa_clamp(predicted + dequantized, -32768, 32767);
557
558 sample_data[si] = reconstructed;
559 slice <<= 3;
560
561 qoa_lms_update(&qoa->lms[c], reconstructed, dequantized);
562 }
563 }
564 }
565
566 *frame_len = samples;
567 return p;
568 }
569
570 short *qoa_decode(const unsigned char *bytes, int size, qoa_desc *qoa) {
571 unsigned int p = qoa_decode_header(bytes, size, qoa);
572 if (!p) {
573 return NULL;
574 }
575
576 /* Calculate the required size of the sample buffer and allocate */
577 int total_samples = qoa->samples * qoa->channels;
578 short *sample_data = QOA_MALLOC(total_samples * sizeof(short));
579
580 unsigned int sample_index = 0;
581 unsigned int frame_len;
582 unsigned int frame_size;
583
584 /* Decode all frames */
585 do {
586 short *sample_ptr = sample_data + sample_index * qoa->channels;
587 frame_size = qoa_decode_frame(bytes + p, size - p, qoa, sample_ptr, &frame_len);
588
589 p += frame_size;
590 sample_index += frame_len;
591 } while (frame_size && sample_index < qoa->samples);
592
593 qoa->samples = sample_index;
594 return sample_data;
595 }
596
597
598
599 /* -----------------------------------------------------------------------------
600 File read/write convenience functions */
601
602 #ifndef QOA_NO_STDIO
603 #include <stdio.h>
604
605 int qoa_write(const char *filename, const short *sample_data, qoa_desc *qoa) {
606 FILE *f = fopen(filename, "wb");
607 unsigned int size;
608 void *encoded;
609
610 if (!f) {
611 return 0;
612 }
613
614 encoded = qoa_encode(sample_data, qoa, &size);
615 if (!encoded) {
616 fclose(f);
617 return 0;
618 }
619
620 fwrite(encoded, 1, size, f);
621 fclose(f);
622
623 QOA_FREE(encoded);
624 return size;
625 }
626
627 void *qoa_read(const char *filename, qoa_desc *qoa) {
628 FILE *f = fopen(filename, "rb");
629 int size, bytes_read;
630 void *data;
631 short *sample_data;
632
633 if (!f) {
634 return NULL;
635 }
636
637 fseek(f, 0, SEEK_END);
638 size = ftell(f);
639 if (size <= 0) {
640 fclose(f);
641 return NULL;
642 }
643 fseek(f, 0, SEEK_SET);
644
645 data = QOA_MALLOC(size);
646 if (!data) {
647 fclose(f);
648 return NULL;
649 }
650
651 bytes_read = fread(data, 1, size, f);
652 fclose(f);
653
654 sample_data = qoa_decode(data, bytes_read, qoa);
655 QOA_FREE(data);
656 return sample_data;
657 }
658
659 #endif /* QOA_NO_STDIO */
660 #endif /* QOA_IMPLEMENTATION */
661