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