annotate flac.c @ 2296:789802d99629

Add basic FLAC decoder and add FLAC playback support to the media player
author Michael Pavone <pavone@retrodev.com>
date Sun, 19 Feb 2023 21:12:46 -0800
parents
children 9d68799f945b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 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
21 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 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
23 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
24 return 0;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 return result;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 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
30 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 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
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 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
35 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 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
37 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 *(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
39 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 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
43 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 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
45 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
46 return ret;
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
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 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
50 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 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
52 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
53 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 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
55 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
56 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
57 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 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
59 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
60 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
61 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 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
63 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
64 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
65 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
66 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
67 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 return ret;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 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
72 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 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
74 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
75 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 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
77 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
78 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
79 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 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
81 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
82 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 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 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
85 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
86 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
87 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
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 typedef struct {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 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
96 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
97 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
98 } 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
99
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100 enum {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 STREAMINFO,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 PADDING,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 APPLICATION,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 SEEKTABLE,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 VORBIS_COMMENT,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 CUESHEET,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 PICTURE
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 };
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 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
111 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 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
113 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
114 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
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 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
118 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119 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
120 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
121 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
122 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
123 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
124 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
125 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
126 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
127 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
128 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 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
131 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 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
133 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
134 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
135 return 0;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137 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
138 do {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139 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
140 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
141 parse_streaminfo(f);
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 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
144 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
145 } while (!header.is_last);
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
146 return 1;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 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
150 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 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
152 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
153 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
154 f->seek = seek_buffer;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 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
156 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
157 return f;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 free(f);
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 return NULL;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
163 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
164 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 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
166 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
167 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
168 f->seek = seek_file;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
169 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
170 return f;
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 free(f);
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173 return NULL;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 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
177 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 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
179 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
180 return byte;
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 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
183 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
184 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
185 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186 mask >>= 1;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 length++;
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 uint64_t value = byte + (mask - 1);
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190 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
191 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
192 value <<= 6;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
193 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
194 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
195 return value;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
196 }
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 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
199 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
200 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
201 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
202 return byte;
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 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
205 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
206 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
207 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
208 mask >>= 1;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
209 length++;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
210 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
211 uint32_t value = byte + (mask - 1);
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
212 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
213 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
214 value <<= 6;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
215 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
216 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
217 return value;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
218 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
219
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
220 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
221 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
222 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
223 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
224 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
225 return 0;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
226 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
227 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
228 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
229 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
230 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
231 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
232 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
233 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
234 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
235 channels = 2;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
236 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
237 ++channels;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
238 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
239 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
240 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
241 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
242 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
243 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
244 } 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
245 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
246 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
247 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
248 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
249 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
250 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
251 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
252 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
253 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
254 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
255 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
256 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
257 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
258 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
259 case 0:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
260 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
261 return 0;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
262 case 1:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
263 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
264 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
265 case 6:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
266 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
267 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
268 case 7:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
269 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
270 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
271 default:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
272 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
273 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
274 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
275 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
276 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
277 break;
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_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
280 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
281 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
282 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
283 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
284 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
285 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
286 case 15:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
287 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
288 case 0:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
289 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
290 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
291 case 1:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
292 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
293 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
294 case 2:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
295 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
296 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
297 case 3:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
298 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
299 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
300 case 4:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
301 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
302 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
303 case 5:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
304 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
305 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
306 case 6:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
307 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
308 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
309 case 7:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
310 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
311 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
312 case 8:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
313 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
314 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
315 case 9:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
316 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
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 case 10:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
319 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
320 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
321 case 11:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
322 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
323 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
324 case 12:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
325 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
326 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
327 case 13:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
328 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
329 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
330 case 14:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
331 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
332 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
333 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
334 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
335 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
336 return 1;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
337 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
338
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
339 enum {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
340 SUBFRAME_CONSTANT,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
341 SUBFRAME_VERBATIM,
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
342 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
343 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
344 };
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
345
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
346 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
347 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
348 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
349 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
350 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
351 return value;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
352 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
353
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
354 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
355 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
356 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
357 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
358 return sample;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
359 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
360
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
361 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
362 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
363 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
364 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
365 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
366 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
367 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
368 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
369 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
370 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
371 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
372 //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
373 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
374 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
375 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
376 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
377 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
378 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
379 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
380 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
381 if (shift) {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
382 prediction >>= shift;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
383 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
384 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
385 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
386 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
387 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
388 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
389 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
390 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
391 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
392 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
393 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
394 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
395 if (shift) {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
396 prediction >>= shift;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
397 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
398 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
399 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
400 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
401 ++residual;
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 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
404 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
405 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
406 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
407 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
408 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
409 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
410 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
411 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
412 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
413 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
414
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
415 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
416 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
417 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
418 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
419 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
420 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
421 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
422 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
423 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
424 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
425 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
426 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
427 ++wasted_bits;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
428 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
429 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
430 ++wasted_bits;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
431 }
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 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
434 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
435 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
436 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
437 sample_bits++;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
438 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
439 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
440 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
441 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
442 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
443 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
444 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
445 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
446 } 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
447 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
448 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
449 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
450 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
451 } 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
452 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
453 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
454 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
455 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
456 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
457 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
458 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
459 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
460 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
461 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
462 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
463 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
464 } 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
465 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
466 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
467 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
468 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
469 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
470 switch (order)
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 case 1:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
473 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
474 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
475 case 2:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
476 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
477 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
478 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
479 case 3:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
480 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
481 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
482 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
483 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
484 case 4:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
485 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
486 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
487 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
488 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
489 break;
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 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
492 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
493 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
494 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
495 }
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 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
498 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
499 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
500 return 0;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
501 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
502 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
503 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
504 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
505 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
506 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
507 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
508 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
509 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
510 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
511 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
512 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
513 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
514 return 1;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
515 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
516
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
517 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
518 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
519 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
520 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
521 return 0;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
522 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
523 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
524 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
525 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
526 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
527 *(out++) = sample;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
528 *(out++) = sample;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
529 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
530 } else {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
531 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
532 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
533 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
534 case 0:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
535 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
536 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
537 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
538 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
539 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
540 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
541 *(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
542 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
543 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
544 case 1:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
545 //left-side
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
546 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
547 *(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
548 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
549 *(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
550 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
551 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
552 case 2:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
553 //side-right
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
554 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
555 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
556 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
557 *(out++) = left;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
558 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
559 *(out++) = right;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
560 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
561 break;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
562 case 3:
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
563 //mid-side
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
564 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
565 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
566 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
567 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
568 *(out++) = left;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
569 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
570 *(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
571 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
572 break;
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 }
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
575 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
576 {
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
577 *(out++) = 0;
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 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
580
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
581 return 1;
789802d99629 Add basic FLAC decoder and add FLAC playback support to the media player
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
582 }