1 /*
2 * Squeezelite - lightweight headless squeezeplay emulator for linux
3 *
4 * (c) Adrian Smith 2012, triode1@btinternet.com
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include "squeezelite.h"
22
23 #include <FLAC/stream_decoder.h>
24
25 #if BYTES_PER_FRAME == 4
26 #define ALIGN8(n) (n << 8)
27 #define ALIGN16(n) (n)
28 #define ALIGN24(n) (n >> 8)
29 #define ALIGN32(n) (n >> 16)
30 #else
31 #define ALIGN8(n) (n << 24)
32 #define ALIGN16(n) (n << 16)
33 #define ALIGN24(n) (n << 8)
34 #define ALIGN32(n) (n)
35 #endif
36
37 struct flac {
38 FLAC__StreamDecoder *decoder;
39 u8_t container;
40 #if !LINKALL
41 // FLAC symbols to be dynamically loaded
42 const char **FLAC__StreamDecoderErrorStatusString;
43 const char **FLAC__StreamDecoderStateString;
44 FLAC__StreamDecoder * (* FLAC__stream_decoder_new)(void);
45 FLAC__bool (* FLAC__stream_decoder_reset)(FLAC__StreamDecoder *decoder);
46 void (* FLAC__stream_decoder_delete)(FLAC__StreamDecoder *decoder);
47 FLAC__StreamDecoderInitStatus (* FLAC__stream_decoder_init_stream)(
48 FLAC__StreamDecoder *decoder,
49 FLAC__StreamDecoderReadCallback read_callback,
50 FLAC__StreamDecoderSeekCallback seek_callback,
51 FLAC__StreamDecoderTellCallback tell_callback,
52 FLAC__StreamDecoderLengthCallback length_callback,
53 FLAC__StreamDecoderEofCallback eof_callback,
54 FLAC__StreamDecoderWriteCallback write_callback,
55 FLAC__StreamDecoderMetadataCallback metadata_callback,
56 FLAC__StreamDecoderErrorCallback error_callback,
57 void *client_data
58 );
59 FLAC__StreamDecoderInitStatus (* FLAC__stream_decoder_init_ogg_stream)(
60 FLAC__StreamDecoder *decoder,
61 FLAC__StreamDecoderReadCallback read_callback,
62 FLAC__StreamDecoderSeekCallback seek_callback,
63 FLAC__StreamDecoderTellCallback tell_callback,
64 FLAC__StreamDecoderLengthCallback length_callback,
65 FLAC__StreamDecoderEofCallback eof_callback,
66 FLAC__StreamDecoderWriteCallback write_callback,
67 FLAC__StreamDecoderMetadataCallback metadata_callback,
68 FLAC__StreamDecoderErrorCallback error_callback,
69 void *client_data
70 );
71 FLAC__bool (* FLAC__stream_decoder_process_single)(FLAC__StreamDecoder *decoder);
72 FLAC__StreamDecoderState (* FLAC__stream_decoder_get_state)(const FLAC__StreamDecoder *decoder);
73 #endif
74 };
75
76 static struct flac *f;
77
78 extern log_level loglevel;
79
80 extern struct buffer *streambuf;
81 extern struct buffer *outputbuf;
82 extern struct streamstate stream;
83 extern struct outputstate output;
84 extern struct decodestate decode;
85 extern struct processstate process;
86
87 #define LOCK_S mutex_lock(streambuf->mutex)
88 #define UNLOCK_S mutex_unlock(streambuf->mutex)
89 #define LOCK_O mutex_lock(outputbuf->mutex)
90 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
91 #if PROCESS
92 #define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
93 #define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
94 #define IF_DIRECT(x) if (decode.direct) { x }
95 #define IF_PROCESS(x) if (!decode.direct) { x }
96 #else
97 #define LOCK_O_direct mutex_lock(outputbuf->mutex)
98 #define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
99 #define IF_DIRECT(x) { x }
100 #define IF_PROCESS(x)
101 #endif
102
103 #if LINKALL
104 #define FLAC(h, fn, ...) (FLAC__ ## fn)(__VA_ARGS__)
105 #define FLAC_A(h, a) (FLAC__ ## a)
106 #else
107 #define FLAC(h, fn, ...) (h)->FLAC__##fn(__VA_ARGS__)
108 #define FLAC_A(h, a) (h)->FLAC__ ## a
109 #endif
110
read_cb(const FLAC__StreamDecoder * decoder,FLAC__byte buffer[],size_t * want,void * client_data)111 static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *want, void *client_data) {
112 size_t bytes;
113 bool end;
114
115 LOCK_S;
116 bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
117 bytes = min(bytes, *want);
118 end = (stream.state <= DISCONNECT && bytes == 0);
119
120 memcpy(buffer, streambuf->readp, bytes);
121 _buf_inc_readp(streambuf, bytes);
122 UNLOCK_S;
123
124 *want = bytes;
125
126 return end ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
127 }
128
write_cb(const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)129 static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
130 const FLAC__int32 *const buffer[], void *client_data) {
131
132 size_t frames = frame->header.blocksize;
133 unsigned bits_per_sample = frame->header.bits_per_sample;
134 unsigned channels = frame->header.channels;
135
136 FLAC__int32 *lptr = (FLAC__int32 *)buffer[0];
137 FLAC__int32 *rptr = (FLAC__int32 *)buffer[channels > 1 ? 1 : 0];
138
139 if (decode.new_stream) {
140 LOCK_O;
141 LOG_INFO("setting track_start");
142 output.track_start = outputbuf->writep;
143 decode.new_stream = false;
144
145 #if DSD
146 #if SL_LITTLE_ENDIAN
147 #define MARKER_OFFSET 2
148 #else
149 #define MARKER_OFFSET 1
150 #endif
151 if (bits_per_sample == 24 && is_stream_dop(((u8_t *)lptr) + MARKER_OFFSET, ((u8_t *)rptr) + MARKER_OFFSET, 4, frames)) {
152 LOG_INFO("file contains DOP");
153 if (output.dsdfmt == DOP_S24_LE || output.dsdfmt == DOP_S24_3LE)
154 output.next_fmt = output.dsdfmt;
155 else
156 output.next_fmt = DOP;
157 output.next_sample_rate = frame->header.sample_rate;
158 output.fade = FADE_INACTIVE;
159 } else {
160 output.next_sample_rate = decode_newstream(frame->header.sample_rate, output.supported_rates);
161 output.next_fmt = PCM;
162 if (output.fade_mode) _checkfade(true);
163 }
164 #else
165 output.next_sample_rate = decode_newstream(frame->header.sample_rate, output.supported_rates);
166 if (output.fade_mode) _checkfade(true);
167 #endif
168
169 UNLOCK_O;
170 }
171
172 LOCK_O_direct;
173
174 while (frames > 0) {
175 frames_t f;
176 frames_t count;
177 ISAMPLE_T *optr;
178
179 IF_DIRECT(
180 optr = (ISAMPLE_T *)outputbuf->writep;
181 f = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
182 );
183 IF_PROCESS(
184 optr = (ISAMPLE_T *)process.inbuf;
185 f = process.max_in_frames;
186 );
187
188 f = min(f, frames);
189
190 count = f;
191
192 if (bits_per_sample == 8) {
193 while (count--) {
194 *optr++ = ALIGN8(*lptr++);
195 *optr++ = ALIGN8(*rptr++);
196 }
197 } else if (bits_per_sample == 16) {
198 while (count--) {
199 *optr++ = ALIGN16(*lptr++);
200 *optr++ = ALIGN16(*rptr++);
201 }
202 } else if (bits_per_sample == 24) {
203 while (count--) {
204 *optr++ = ALIGN24(*lptr++);
205 *optr++ = ALIGN24(*rptr++);
206 }
207 } else if (bits_per_sample == 32) {
208 while (count--) {
209 *optr++ = ALIGN32(*lptr++);
210 *optr++ = ALIGN32(*rptr++);
211 }
212 } else {
213 LOG_ERROR("unsupported bits per sample: %u", bits_per_sample);
214 }
215
216 frames -= f;
217
218 IF_DIRECT(
219 _buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
220 );
221 IF_PROCESS(
222 process.in_frames = f;
223 if (frames) LOG_ERROR("unhandled case");
224 );
225 }
226
227 UNLOCK_O_direct;
228
229 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
230 }
231
error_cb(const FLAC__StreamDecoder * decoder,FLAC__StreamDecoderErrorStatus status,void * client_data)232 static void error_cb(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) {
233 LOG_INFO("flac error: %s", FLAC_A(f, StreamDecoderErrorStatusString)[status]);
234 }
235
flac_close(void)236 static void flac_close(void) {
237 FLAC(f, stream_decoder_delete, f->decoder);
238 f->decoder = NULL;
239 }
240
flac_open(u8_t sample_size,u8_t sample_rate,u8_t channels,u8_t endianness)241 static void flac_open(u8_t sample_size, u8_t sample_rate, u8_t channels, u8_t endianness) {
242 if ( f->decoder && f->container != sample_size ) {
243 flac_close();
244 }
245
246 f->container = sample_size;
247
248 if (f->decoder) {
249 FLAC(f, stream_decoder_reset, f->decoder);
250 } else {
251 f->decoder = FLAC(f, stream_decoder_new);
252 }
253
254 if ( f->container == 'o' ) {
255 LOG_DEBUG("ogg/flac container - using init_ogg_stream");
256 FLAC(f, stream_decoder_init_ogg_stream, f->decoder, &read_cb, NULL, NULL, NULL, NULL, &write_cb, NULL, &error_cb, NULL);
257 } else {
258 FLAC(f, stream_decoder_init_stream, f->decoder, &read_cb, NULL, NULL, NULL, NULL, &write_cb, NULL, &error_cb, NULL);
259 }
260 }
261
flac_decode(void)262 static decode_state flac_decode(void) {
263 bool ok = FLAC(f, stream_decoder_process_single, f->decoder);
264 FLAC__StreamDecoderState state = FLAC(f, stream_decoder_get_state, f->decoder);
265
266 if (!ok && state != FLAC__STREAM_DECODER_END_OF_STREAM) {
267 LOG_INFO("flac error: %s", FLAC_A(f, StreamDecoderStateString)[state]);
268 };
269
270 if (state == FLAC__STREAM_DECODER_END_OF_STREAM) {
271 return DECODE_COMPLETE;
272 } else if (state > FLAC__STREAM_DECODER_END_OF_STREAM) {
273 return DECODE_ERROR;
274 } else {
275 return DECODE_RUNNING;
276 }
277 }
278
load_flac()279 static bool load_flac() {
280 #if !LINKALL
281 void *handle = dlopen(LIBFLAC, RTLD_NOW);
282 char *err;
283
284 if (!handle) {
285 LOG_INFO("dlerror: %s", dlerror());
286 return false;
287 }
288
289 f->FLAC__StreamDecoderErrorStatusString = dlsym(handle, "FLAC__StreamDecoderErrorStatusString");
290 f->FLAC__StreamDecoderStateString = dlsym(handle, "FLAC__StreamDecoderStateString");
291 f->FLAC__stream_decoder_new = dlsym(handle, "FLAC__stream_decoder_new");
292 f->FLAC__stream_decoder_reset = dlsym(handle, "FLAC__stream_decoder_reset");
293 f->FLAC__stream_decoder_delete = dlsym(handle, "FLAC__stream_decoder_delete");
294 f->FLAC__stream_decoder_init_stream = dlsym(handle, "FLAC__stream_decoder_init_stream");
295 f->FLAC__stream_decoder_init_ogg_stream = dlsym(handle, "FLAC__stream_decoder_init_ogg_stream");
296 f->FLAC__stream_decoder_process_single = dlsym(handle, "FLAC__stream_decoder_process_single");
297 f->FLAC__stream_decoder_get_state = dlsym(handle, "FLAC__stream_decoder_get_state");
298
299 if ((err = dlerror()) != NULL) {
300 LOG_INFO("dlerror: %s", err);
301 return false;
302 }
303
304 LOG_INFO("loaded "LIBFLAC);
305 #endif
306
307 return true;
308 }
309
register_flac(void)310 struct codec *register_flac(void) {
311 static struct codec ret = {
312 'f', // id
313 "ogf,flc", // types
314 16384, // min read
315 204800, // min space
316 flac_open, // open
317 flac_close, // close
318 flac_decode, // decode
319 };
320
321 f = malloc(sizeof(struct flac));
322 if (!f) {
323 return NULL;
324 }
325
326 f->decoder = NULL;
327
328 if (!load_flac()) {
329 return NULL;
330 }
331
332 LOG_INFO("using flac to decode ogf,flc");
333 return &ret;
334 }
335