Mercurial > repos > blastem
comparison flac.c @ 2296:789802d99629
Add basic FLAC decoder and add FLAC playback support to the media player
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 19 Feb 2023 21:12:46 -0800 |
parents | |
children | 9d68799f945b |
comparison
equal
deleted
inserted
replaced
2295:eb45ad9d8a3f | 2296:789802d99629 |
---|---|
1 #include <stdlib.h> | |
2 #include <string.h> | |
3 #include <inttypes.h> | |
4 #include "flac.h" | |
5 | |
6 static uint8_t read_byte_buffer(flac_file *f) | |
7 { | |
8 if (f->offset >= f->buffer_size) { | |
9 return 0; | |
10 } | |
11 uint8_t *buf = f->read_data; | |
12 return buf[f->offset++]; | |
13 } | |
14 | |
15 static void seek_buffer(flac_file *f, uint32_t offset, uint8_t relative) | |
16 { | |
17 f->offset = relative ? f->offset + offset : offset; | |
18 } | |
19 | |
20 static uint8_t read_byte_file(flac_file *f) | |
21 { | |
22 int result = fgetc(f->read_data); | |
23 if (result == EOF) { | |
24 return 0; | |
25 } | |
26 return result; | |
27 } | |
28 | |
29 static void seek_file(flac_file *f, uint32_t offset, uint8_t relative) | |
30 { | |
31 fseek(f->read_data, offset, relative ? SEEK_CUR : SEEK_SET); | |
32 } | |
33 | |
34 static void read_chars(flac_file *f, char *dest, uint32_t count) | |
35 { | |
36 for (; count > 0; --count) | |
37 { | |
38 *(dest++) = f->read_byte(f); | |
39 } | |
40 } | |
41 | |
42 static uint16_t read16(flac_file *f) | |
43 { | |
44 uint16_t ret = f->read_byte(f) << 8; | |
45 ret |= f->read_byte(f); | |
46 return ret; | |
47 } | |
48 | |
49 static uint32_t read_bits(flac_file *f, uint32_t num_bits) | |
50 { | |
51 uint32_t ret = 0; | |
52 while (num_bits) | |
53 { | |
54 if (!f->bits) { | |
55 f->cur_byte = f->read_byte(f); | |
56 f->bits = 8; | |
57 } | |
58 uint32_t new_bits = f->bits; | |
59 if (new_bits > num_bits) { | |
60 new_bits = num_bits; | |
61 } | |
62 ret <<= new_bits; | |
63 uint32_t mask = (1 << new_bits) - 1; | |
64 ret |= (f->cur_byte >> (f->bits - new_bits)) & mask; | |
65 f->bits -= new_bits; | |
66 num_bits -= new_bits; | |
67 } | |
68 return ret; | |
69 } | |
70 | |
71 static uint64_t read_bits64(flac_file *f, uint64_t num_bits) | |
72 { | |
73 uint64_t ret = 0; | |
74 while (num_bits) | |
75 { | |
76 if (!f->bits) { | |
77 f->cur_byte = f->read_byte(f); | |
78 f->bits = 8; | |
79 } | |
80 uint64_t new_bits = f->bits; | |
81 if (new_bits > num_bits) { | |
82 new_bits = num_bits; | |
83 } | |
84 ret <<= new_bits; | |
85 uint64_t mask = (1 << new_bits) - 1; | |
86 ret |= f->cur_byte & mask; | |
87 f->cur_byte >>= new_bits; | |
88 f->bits -= new_bits; | |
89 num_bits -= new_bits; | |
90 } | |
91 return ret; | |
92 } | |
93 | |
94 typedef struct { | |
95 uint32_t size; | |
96 uint8_t type; | |
97 uint8_t is_last; | |
98 } meta_block_header; | |
99 | |
100 enum { | |
101 STREAMINFO, | |
102 PADDING, | |
103 APPLICATION, | |
104 SEEKTABLE, | |
105 VORBIS_COMMENT, | |
106 CUESHEET, | |
107 PICTURE | |
108 }; | |
109 | |
110 static void read_meta_block_header(flac_file *f, meta_block_header *dest) | |
111 { | |
112 dest->is_last = read_bits(f, 1); | |
113 dest->type = read_bits(f, 7); | |
114 dest->size = read_bits(f, 24); | |
115 } | |
116 | |
117 static void parse_streaminfo(flac_file *f) | |
118 { | |
119 read16(f);//min block size | |
120 read16(f);//max block size | |
121 read_bits(f, 24);//min frame size | |
122 read_bits(f, 24);//max frame size | |
123 f->sample_rate = read_bits(f, 20); | |
124 f->channels = read_bits(f, 3) + 1; | |
125 f->bits_per_sample = read_bits(f, 5) + 1; | |
126 f->total_samples = read_bits64(f, 36); | |
127 f->seek(f, 16, 1);//MD5 | |
128 } | |
129 | |
130 static uint8_t parse_header(flac_file *f) | |
131 { | |
132 char id[4]; | |
133 read_chars(f, id, sizeof(id)); | |
134 if (memcmp("fLaC", id, sizeof(id))) { | |
135 return 0; | |
136 } | |
137 meta_block_header header; | |
138 do { | |
139 read_meta_block_header(f, &header); | |
140 if (header.type == STREAMINFO) { | |
141 parse_streaminfo(f); | |
142 } else { | |
143 f->seek(f, header.size, 1); | |
144 } | |
145 } while (!header.is_last); | |
146 return 1; | |
147 } | |
148 | |
149 flac_file *flac_file_from_buffer(void *buffer, uint32_t size) | |
150 { | |
151 flac_file *f = calloc(1, sizeof(flac_file)); | |
152 f->read_data = buffer; | |
153 f->read_byte = read_byte_buffer; | |
154 f->seek = seek_buffer; | |
155 f->buffer_size = size; | |
156 if (parse_header(f)) { | |
157 return f; | |
158 } | |
159 free(f); | |
160 return NULL; | |
161 } | |
162 | |
163 flac_file *flac_file_from_file(FILE *file) | |
164 { | |
165 flac_file *f = calloc(1, sizeof(flac_file)); | |
166 f->read_data = file; | |
167 f->read_byte = read_byte_file; | |
168 f->seek = seek_file; | |
169 if (parse_header(f)) { | |
170 return f; | |
171 } | |
172 free(f); | |
173 return NULL; | |
174 } | |
175 | |
176 static uint64_t read_utf64(flac_file *f) | |
177 { | |
178 uint8_t byte = f->read_byte(f); | |
179 if (!(byte & 0x80)) { | |
180 return byte; | |
181 } | |
182 uint8_t mask = 0x40; | |
183 uint8_t length = 0; | |
184 while (byte & mask) | |
185 { | |
186 mask >>= 1; | |
187 length++; | |
188 } | |
189 uint64_t value = byte + (mask - 1); | |
190 for (uint8_t i = 0; i < length; i++) | |
191 { | |
192 value <<= 6; | |
193 value |= f->read_byte(f) & 0x3F; | |
194 } | |
195 return value; | |
196 } | |
197 | |
198 static uint32_t read_utf32(flac_file *f) | |
199 { | |
200 uint8_t byte = f->read_byte(f); | |
201 if (!(byte & 0x80)) { | |
202 return byte; | |
203 } | |
204 uint8_t mask = 0x40; | |
205 uint8_t length = 0; | |
206 while (byte & mask) | |
207 { | |
208 mask >>= 1; | |
209 length++; | |
210 } | |
211 uint32_t value = byte + (mask - 1); | |
212 for (uint8_t i = 0; i < length; i++) | |
213 { | |
214 value <<= 6; | |
215 value |= f->read_byte(f) & 0x3F; | |
216 } | |
217 return value; | |
218 } | |
219 | |
220 static uint8_t parse_frame_header(flac_file *f) | |
221 { | |
222 uint16_t sync = read_bits(f, 14); | |
223 if (sync != 0x3FFE) { | |
224 fprintf(stderr, "Invalid sync FLAC sync pattern: %X\n", sync); | |
225 return 0; | |
226 } | |
227 read_bits(f, 1);//reserved | |
228 uint8_t block_size_strategy = read_bits(f, 1); | |
229 uint8_t block_size_code = read_bits(f, 4); | |
230 uint8_t sample_rate_code = read_bits(f, 4); | |
231 uint8_t channels = read_bits(f, 4); | |
232 uint8_t joint_stereo = 0; | |
233 if (channels > 7) { | |
234 joint_stereo = (channels & 7) + 1; | |
235 channels = 2; | |
236 } else { | |
237 ++channels; | |
238 } | |
239 f->frame_channels = channels; | |
240 f->frame_joint_stereo = joint_stereo; | |
241 uint8_t bits_per_sample_code = read_bits(f, 3); | |
242 if (!bits_per_sample_code) { | |
243 f->frame_bits_per_sample = f->bits_per_sample; | |
244 } else if (bits_per_sample_code < 3) { | |
245 f->frame_bits_per_sample = 4 + 4 * bits_per_sample_code; | |
246 } else { | |
247 f->frame_bits_per_sample = 4 * bits_per_sample_code; | |
248 } | |
249 read_bits(f, 1);//reserved | |
250 uint32_t block_num; | |
251 if (block_size_strategy) { | |
252 f->frame_start_sample = read_utf64(f); | |
253 } else { | |
254 block_num = read_utf32(f); | |
255 } | |
256 uint32_t block_size = 0; | |
257 switch (block_size_code) | |
258 { | |
259 case 0: | |
260 fputs("Detected reserved block size 0", stderr); | |
261 return 0; | |
262 case 1: | |
263 block_size = 192; | |
264 break; | |
265 case 6: | |
266 block_size = f->read_byte(f) + 1; | |
267 break; | |
268 case 7: | |
269 block_size = read16(f) + 1; | |
270 break; | |
271 default: | |
272 if (block_size_code < 8) { | |
273 block_size = 576 * (1 << (block_size_code - 2)); | |
274 } else { | |
275 block_size = 256 * (1 << (block_size_code - 8)); | |
276 } | |
277 break; | |
278 } | |
279 f->frame_block_size = block_size; | |
280 if (!block_size_strategy) { | |
281 f->frame_start_sample = ((uint64_t)block_num) * ((uint64_t)block_size); | |
282 } | |
283 uint32_t sample_rate; | |
284 switch (sample_rate_code) | |
285 { | |
286 case 15: | |
287 fputs("Invalid frame header sample rate", stderr); | |
288 case 0: | |
289 sample_rate = f->sample_rate; | |
290 break; | |
291 case 1: | |
292 sample_rate = 88200; | |
293 break; | |
294 case 2: | |
295 sample_rate = 176400; | |
296 break; | |
297 case 3: | |
298 sample_rate = 192000; | |
299 break; | |
300 case 4: | |
301 sample_rate = 8000; | |
302 break; | |
303 case 5: | |
304 sample_rate = 16000; | |
305 break; | |
306 case 6: | |
307 sample_rate = 22050; | |
308 break; | |
309 case 7: | |
310 sample_rate = 44100; | |
311 break; | |
312 case 8: | |
313 sample_rate = 32000; | |
314 break; | |
315 case 9: | |
316 sample_rate = 44100; | |
317 break; | |
318 case 10: | |
319 sample_rate = 48000; | |
320 break; | |
321 case 11: | |
322 sample_rate = 96000; | |
323 break; | |
324 case 12: | |
325 sample_rate = f->read_byte(f) * 1000; | |
326 break; | |
327 case 13: | |
328 sample_rate = read16(f); | |
329 break; | |
330 case 14: | |
331 sample_rate = read16(f) * 10; | |
332 break; | |
333 } | |
334 f->frame_sample_rate = sample_rate; | |
335 f->read_byte(f);//CRC-8 | |
336 return 1; | |
337 } | |
338 | |
339 enum { | |
340 SUBFRAME_CONSTANT, | |
341 SUBFRAME_VERBATIM, | |
342 SUBFRAME_FIXED = 8, | |
343 SUBFRAME_LPC = 0x20, | |
344 }; | |
345 | |
346 static int32_t sign_extend(uint32_t value, uint32_t bits) | |
347 { | |
348 if (value & (1 << (bits - 1))) { | |
349 value |= ~((1 << bits) - 1); | |
350 } | |
351 return value; | |
352 } | |
353 | |
354 static int32_t signed_sample(uint32_t sample_bits, uint32_t sample, uint8_t wasted_bits) | |
355 { | |
356 sample <<= wasted_bits; | |
357 sample = sign_extend(sample, sample_bits); | |
358 return sample; | |
359 } | |
360 | |
361 static void decode_residuals(flac_file *f, flac_subframe *sub, int64_t *coefficients, uint32_t order, int64_t shift) | |
362 { | |
363 uint8_t residual_method = read_bits(f, 2); | |
364 uint8_t rice_param_bits = residual_method ? 5 : 4; | |
365 uint32_t partition_count = 1 << read_bits(f, 4); | |
366 uint32_t cur = order; | |
367 uint32_t partition_size = f->frame_block_size / partition_count; | |
368 for (uint32_t partition = 0; partition < partition_count; partition++) | |
369 { | |
370 uint32_t rice_param = read_bits(f, rice_param_bits); | |
371 if (rice_param == (1 << rice_param_bits) - 1) { | |
372 //escape code, residuals are unencoded | |
373 rice_param = read_bits(f, rice_param_bits); | |
374 for (uint32_t end = partition ? cur + partition_size : partition_size; cur < end; cur++) | |
375 { | |
376 int64_t prediction = 0; | |
377 for (uint32_t i = 0; i < order; i++) | |
378 { | |
379 prediction += ((int64_t)sub->decoded[cur - 1 - i]) * coefficients[i]; | |
380 } | |
381 if (shift) { | |
382 prediction >>= shift; | |
383 } | |
384 prediction += sign_extend(read_bits(f, rice_param), rice_param); | |
385 sub->decoded[cur] = prediction; | |
386 } | |
387 } else { | |
388 for (uint32_t end = partition ? cur + partition_size : partition_size; cur < end; cur++) | |
389 { | |
390 int64_t prediction = 0; | |
391 for (uint32_t i = 0; i < order; i++) | |
392 { | |
393 prediction += ((int64_t)sub->decoded[cur - 1 - i]) * coefficients[i]; | |
394 } | |
395 if (shift) { | |
396 prediction >>= shift; | |
397 } | |
398 uint32_t residual = 0; | |
399 while (!read_bits(f, 1)) | |
400 { | |
401 ++residual; | |
402 } | |
403 residual <<= rice_param; | |
404 residual |= read_bits(f, rice_param); | |
405 if (residual & 1) { | |
406 sub->decoded[cur] = prediction - (residual >> 1) - 1; | |
407 } else { | |
408 sub->decoded[cur] = prediction + (residual >> 1); | |
409 } | |
410 } | |
411 } | |
412 } | |
413 } | |
414 | |
415 static void decode_subframe(flac_file *f, flac_subframe *sub) | |
416 { | |
417 if (f->frame_block_size > sub->allocated_samples) { | |
418 sub->decoded = realloc(sub->decoded, sizeof(int32_t) * f->frame_block_size); | |
419 sub->allocated_samples = f->frame_block_size ; | |
420 } | |
421 int64_t prediction_coefficients[32]; | |
422 read_bits(f, 1);//reserved | |
423 uint8_t type = read_bits(f, 6); | |
424 uint8_t has_wasted_bits = read_bits(f, 1); | |
425 uint8_t wasted_bits = 0; | |
426 if (has_wasted_bits) { | |
427 ++wasted_bits; | |
428 while (!read_bits(f, 1)) | |
429 { | |
430 ++wasted_bits; | |
431 } | |
432 } | |
433 uint32_t sample_bits = f->frame_bits_per_sample - wasted_bits; | |
434 if (f->frame_joint_stereo) { | |
435 int channel = sub - f->subframes; | |
436 if (f->frame_joint_stereo == 2 && !channel || (channel && f->frame_joint_stereo != 2)) { | |
437 sample_bits++; | |
438 } | |
439 } | |
440 if (type == SUBFRAME_CONSTANT) { | |
441 int32_t sample = signed_sample(sample_bits, read_bits(f, sample_bits), wasted_bits); | |
442 for (uint32_t i = 0; i < f->frame_block_size; i++) | |
443 { | |
444 sub->decoded[i] = sample; | |
445 } | |
446 } else if (type == SUBFRAME_VERBATIM) { | |
447 for (uint32_t i = 0; i < f->frame_block_size; i++) | |
448 { | |
449 sub->decoded[i] = signed_sample(sample_bits, read_bits(f, sample_bits), wasted_bits); | |
450 } | |
451 } else if (type & SUBFRAME_LPC) { | |
452 uint32_t order = (type & 0x1F) + 1; | |
453 for (uint32_t i = 0; i < order; i++) | |
454 { | |
455 sub->decoded[i] = signed_sample(sample_bits, read_bits(f, sample_bits), wasted_bits); | |
456 } | |
457 uint32_t coefficient_bits = read_bits(f, 4) + 1; | |
458 int64_t shift_bits = read_bits(f, 5); | |
459 for (uint32_t i = 0; i < order; i++) | |
460 { | |
461 prediction_coefficients[i] = sign_extend(read_bits(f, coefficient_bits), coefficient_bits); | |
462 } | |
463 decode_residuals(f, sub, prediction_coefficients, order, shift_bits); | |
464 } else if (type & SUBFRAME_FIXED) { | |
465 uint32_t order = type & 7; | |
466 for (uint32_t i = 0; i < order; i++) | |
467 { | |
468 sub->decoded[i] = signed_sample(sample_bits, read_bits(f, sample_bits), wasted_bits); | |
469 } | |
470 switch (order) | |
471 { | |
472 case 1: | |
473 prediction_coefficients[0] = 1; | |
474 break; | |
475 case 2: | |
476 prediction_coefficients[0] = 2; | |
477 prediction_coefficients[1] = -1; | |
478 break; | |
479 case 3: | |
480 prediction_coefficients[0] = 3; | |
481 prediction_coefficients[1] = -3; | |
482 prediction_coefficients[2] = 1; | |
483 break; | |
484 case 4: | |
485 prediction_coefficients[0] = 4; | |
486 prediction_coefficients[1] = -6; | |
487 prediction_coefficients[2] = 4; | |
488 prediction_coefficients[3] = -1; | |
489 break; | |
490 } | |
491 decode_residuals(f, sub, prediction_coefficients, order, 0); | |
492 } else { | |
493 fprintf(stderr, "Invalid subframe type %X\n", type); | |
494 } | |
495 } | |
496 | |
497 static uint8_t decode_frame(flac_file *f) | |
498 { | |
499 if (!parse_frame_header(f)) { | |
500 return 0; | |
501 } | |
502 if (f->frame_channels > f->subframe_alloc) { | |
503 f->subframes = realloc(f->subframes, sizeof(flac_subframe) * f->frame_channels); | |
504 memset(f->subframes + f->subframe_alloc, 0, sizeof(flac_subframe) * (f->frame_channels - f->subframe_alloc)); | |
505 f->subframe_alloc = f->frame_channels; | |
506 } | |
507 for (uint8_t channel = 0; channel < f->frame_channels; channel++) | |
508 { | |
509 decode_subframe(f, f->subframes + channel); | |
510 } | |
511 f->bits = 0; | |
512 read16(f);//Frame footer CRC-16 | |
513 f->frame_sample_pos = 0; | |
514 return 1; | |
515 } | |
516 | |
517 uint8_t flac_get_sample(flac_file *f, int16_t *out, uint8_t desired_channels) | |
518 { | |
519 if (f->frame_sample_pos == f->frame_block_size) { | |
520 if (!decode_frame(f)) { | |
521 return 0; | |
522 } | |
523 } | |
524 uint8_t copy_channels; | |
525 if (f->frame_channels == 1 && desired_channels > 1) { | |
526 int16_t sample = f->subframes->decoded[f->frame_sample_pos]; | |
527 *(out++) = sample; | |
528 *(out++) = sample; | |
529 copy_channels = 2; | |
530 } else { | |
531 int32_t left, right, mid, diff; | |
532 switch (f->frame_joint_stereo) | |
533 { | |
534 case 0: | |
535 copy_channels = desired_channels; | |
536 if (copy_channels > f->frame_channels) { | |
537 copy_channels = f->frame_channels; | |
538 } | |
539 for (uint8_t i = 0; i < copy_channels; i++) | |
540 { | |
541 *(out++) = f->subframes[i].decoded[f->frame_sample_pos]; | |
542 } | |
543 break; | |
544 case 1: | |
545 //left-side | |
546 copy_channels = 2; | |
547 *(out++) = left = f->subframes[0].decoded[f->frame_sample_pos]; | |
548 if (desired_channels > 1) { | |
549 *(out++) = left + f->subframes[1].decoded[f->frame_sample_pos]; | |
550 } | |
551 break; | |
552 case 2: | |
553 //side-right | |
554 copy_channels = 2; | |
555 right = f->subframes[1].decoded[f->frame_sample_pos]; | |
556 left = right + f->subframes[0].decoded[f->frame_sample_pos]; | |
557 *(out++) = left; | |
558 if (desired_channels > 1) { | |
559 *(out++) = right; | |
560 } | |
561 break; | |
562 case 3: | |
563 //mid-side | |
564 copy_channels = 2; | |
565 mid = f->subframes[0].decoded[f->frame_sample_pos]; | |
566 diff = f->subframes[1].decoded[f->frame_sample_pos]; | |
567 left = (diff + 2 * mid) >> 1; | |
568 *(out++) = left; | |
569 if (desired_channels > 1) { | |
570 *(out++) = left - diff; | |
571 } | |
572 break; | |
573 } | |
574 } | |
575 for (uint8_t i = copy_channels; i < desired_channels; i++) | |
576 { | |
577 *(out++) = 0; | |
578 } | |
579 f->frame_sample_pos++; | |
580 | |
581 return 1; | |
582 } |