/src/flac/src/libFLAC++/stream_decoder.cpp
Line | Count | Source |
1 | | /* libFLAC++ - Free Lossless Audio Codec library |
2 | | * Copyright (C) 2002-2009 Josh Coalson |
3 | | * Copyright (C) 2011-2025 Xiph.Org Foundation |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * |
9 | | * - Redistributions of source code must retain the above copyright |
10 | | * notice, this list of conditions and the following disclaimer. |
11 | | * |
12 | | * - Redistributions in binary form must reproduce the above copyright |
13 | | * notice, this list of conditions and the following disclaimer in the |
14 | | * documentation and/or other materials provided with the distribution. |
15 | | * |
16 | | * - Neither the name of the Xiph.org Foundation nor the names of its |
17 | | * contributors may be used to endorse or promote products derived from |
18 | | * this software without specific prior written permission. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
24 | | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | | */ |
32 | | |
33 | | #ifdef HAVE_CONFIG_H |
34 | | #include "config.h" |
35 | | #endif |
36 | | |
37 | | #include "FLAC++/decoder.h" |
38 | | #include "FLAC/assert.h" |
39 | | |
40 | | #ifdef _MSC_VER |
41 | | // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning) |
42 | | #pragma warning ( disable : 4800 ) |
43 | | #endif |
44 | | |
45 | | namespace FLAC { |
46 | | namespace Decoder { |
47 | | |
48 | | // ------------------------------------------------------------ |
49 | | // |
50 | | // Stream |
51 | | // |
52 | | // ------------------------------------------------------------ |
53 | | |
54 | | Stream::Stream(): |
55 | 16.5k | decoder_(::FLAC__stream_decoder_new()) |
56 | 16.5k | { } |
57 | | |
58 | | Stream::~Stream() |
59 | 16.5k | { |
60 | 16.5k | if(0 != decoder_) { |
61 | 16.5k | (void)::FLAC__stream_decoder_finish(decoder_); |
62 | 16.5k | ::FLAC__stream_decoder_delete(decoder_); |
63 | 16.5k | } |
64 | 16.5k | } |
65 | | |
66 | | bool Stream::is_valid() const |
67 | 478k | { |
68 | 478k | return 0 != decoder_; |
69 | 478k | } |
70 | | |
71 | | bool Stream::set_ogg_serial_number(long value) |
72 | 23 | { |
73 | 23 | FLAC__ASSERT(is_valid()); |
74 | 23 | return static_cast<bool>(::FLAC__stream_decoder_set_ogg_serial_number(decoder_, value)); |
75 | 23 | } |
76 | | |
77 | | bool Stream::set_decode_chained_stream(bool value) |
78 | 8.84k | { |
79 | 8.84k | FLAC__ASSERT(is_valid()); |
80 | 8.84k | return static_cast<bool>(::FLAC__stream_decoder_set_decode_chained_stream(decoder_, value)); |
81 | 8.84k | } |
82 | | |
83 | | bool Stream::set_md5_checking(bool value) |
84 | 1.31k | { |
85 | 1.31k | FLAC__ASSERT(is_valid()); |
86 | 1.31k | return static_cast<bool>(::FLAC__stream_decoder_set_md5_checking(decoder_, value)); |
87 | 1.31k | } |
88 | | |
89 | | bool Stream::set_metadata_respond(::FLAC__MetadataType type) |
90 | 66 | { |
91 | 66 | FLAC__ASSERT(is_valid()); |
92 | 66 | return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond(decoder_, type)); |
93 | 66 | } |
94 | | |
95 | | bool Stream::set_metadata_respond_application(const FLAC__byte id[4]) |
96 | 19 | { |
97 | 19 | FLAC__ASSERT(is_valid()); |
98 | 19 | return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond_application(decoder_, id)); |
99 | 19 | } |
100 | | |
101 | | bool Stream::set_metadata_respond_all() |
102 | 12.2k | { |
103 | 12.2k | FLAC__ASSERT(is_valid()); |
104 | 12.2k | return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond_all(decoder_)); |
105 | 12.2k | } |
106 | | |
107 | | bool Stream::set_metadata_ignore(::FLAC__MetadataType type) |
108 | 86 | { |
109 | 86 | FLAC__ASSERT(is_valid()); |
110 | 86 | return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore(decoder_, type)); |
111 | 86 | } |
112 | | |
113 | | bool Stream::set_metadata_ignore_application(const FLAC__byte id[4]) |
114 | 66 | { |
115 | 66 | FLAC__ASSERT(is_valid()); |
116 | 66 | return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id)); |
117 | 66 | } |
118 | | |
119 | | bool Stream::set_metadata_ignore_all() |
120 | 3.01k | { |
121 | 3.01k | FLAC__ASSERT(is_valid()); |
122 | 3.01k | return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore_all(decoder_)); |
123 | 3.01k | } |
124 | | |
125 | | Stream::State Stream::get_state() const |
126 | 0 | { |
127 | 0 | FLAC__ASSERT(is_valid()); |
128 | 0 | return State(::FLAC__stream_decoder_get_state(decoder_)); |
129 | 0 | } |
130 | | |
131 | | bool Stream::get_decode_chained_stream() const |
132 | 0 | { |
133 | 0 | FLAC__ASSERT(is_valid()); |
134 | 0 | return static_cast<bool>(::FLAC__stream_decoder_get_decode_chained_stream(decoder_)); |
135 | 0 | } |
136 | | |
137 | | bool Stream::get_md5_checking() const |
138 | 229 | { |
139 | 229 | FLAC__ASSERT(is_valid()); |
140 | 229 | return static_cast<bool>(::FLAC__stream_decoder_get_md5_checking(decoder_)); |
141 | 229 | } |
142 | | |
143 | | FLAC__uint64 Stream::get_total_samples() const |
144 | 539 | { |
145 | 539 | FLAC__ASSERT(is_valid()); |
146 | 539 | return ::FLAC__stream_decoder_get_total_samples(decoder_); |
147 | 539 | } |
148 | | |
149 | | FLAC__uint64 Stream::find_total_samples() |
150 | 0 | { |
151 | 0 | FLAC__ASSERT(is_valid()); |
152 | 0 | return ::FLAC__stream_decoder_find_total_samples(decoder_); |
153 | 0 | } |
154 | | |
155 | | uint32_t Stream::get_channels() const |
156 | 161k | { |
157 | 161k | FLAC__ASSERT(is_valid()); |
158 | 161k | return ::FLAC__stream_decoder_get_channels(decoder_); |
159 | 161k | } |
160 | | |
161 | | ::FLAC__ChannelAssignment Stream::get_channel_assignment() const |
162 | 0 | { |
163 | 0 | FLAC__ASSERT(is_valid()); |
164 | 0 | return ::FLAC__stream_decoder_get_channel_assignment(decoder_); |
165 | 0 | } |
166 | | |
167 | | uint32_t Stream::get_bits_per_sample() const |
168 | 42.7k | { |
169 | 42.7k | FLAC__ASSERT(is_valid()); |
170 | 42.7k | return ::FLAC__stream_decoder_get_bits_per_sample(decoder_); |
171 | 42.7k | } |
172 | | |
173 | | uint32_t Stream::get_sample_rate() const |
174 | 703 | { |
175 | 703 | FLAC__ASSERT(is_valid()); |
176 | 703 | return ::FLAC__stream_decoder_get_sample_rate(decoder_); |
177 | 703 | } |
178 | | |
179 | | uint32_t Stream::get_blocksize() const |
180 | 332 | { |
181 | 332 | FLAC__ASSERT(is_valid()); |
182 | 332 | return ::FLAC__stream_decoder_get_blocksize(decoder_); |
183 | 332 | } |
184 | | |
185 | | bool Stream::get_decode_position(FLAC__uint64 *position) const |
186 | 0 | { |
187 | 0 | FLAC__ASSERT(is_valid()); |
188 | 0 | return ::FLAC__stream_decoder_get_decode_position(decoder_, position); |
189 | 0 | } |
190 | | |
191 | | int32_t Stream::get_link_lengths(FLAC__uint64 **link_lengths) |
192 | 0 | { |
193 | 0 | FLAC__ASSERT(is_valid()); |
194 | 0 | return ::FLAC__stream_decoder_get_link_lengths(decoder_, link_lengths); |
195 | 0 | } |
196 | | |
197 | | ::FLAC__StreamDecoderInitStatus Stream::init() |
198 | 14.2k | { |
199 | 14.2k | FLAC__ASSERT(is_valid()); |
200 | 14.2k | return ::FLAC__stream_decoder_init_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); |
201 | 14.2k | } |
202 | | |
203 | | ::FLAC__StreamDecoderInitStatus Stream::init_ogg() |
204 | 1.91k | { |
205 | 1.91k | FLAC__ASSERT(is_valid()); |
206 | 1.91k | return ::FLAC__stream_decoder_init_ogg_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); |
207 | 1.91k | } |
208 | | |
209 | | bool Stream::finish() |
210 | 16.5k | { |
211 | 16.5k | FLAC__ASSERT(is_valid()); |
212 | 16.5k | return static_cast<bool>(::FLAC__stream_decoder_finish(decoder_)); |
213 | 16.5k | } |
214 | | |
215 | | bool Stream::finish_link() |
216 | 0 | { |
217 | 0 | FLAC__ASSERT(is_valid()); |
218 | 0 | return static_cast<bool>(::FLAC__stream_decoder_finish_link(decoder_)); |
219 | 0 | } |
220 | | |
221 | | bool Stream::flush() |
222 | 11.2k | { |
223 | 11.2k | FLAC__ASSERT(is_valid()); |
224 | 11.2k | return static_cast<bool>(::FLAC__stream_decoder_flush(decoder_)); |
225 | 11.2k | } |
226 | | |
227 | | bool Stream::reset() |
228 | 76.7k | { |
229 | 76.7k | FLAC__ASSERT(is_valid()); |
230 | 76.7k | return static_cast<bool>(::FLAC__stream_decoder_reset(decoder_)); |
231 | 76.7k | } |
232 | | |
233 | | bool Stream::process_single() |
234 | 15.6k | { |
235 | 15.6k | FLAC__ASSERT(is_valid()); |
236 | 15.6k | return static_cast<bool>(::FLAC__stream_decoder_process_single(decoder_)); |
237 | 15.6k | } |
238 | | |
239 | | bool Stream::process_until_end_of_metadata() |
240 | 76.0k | { |
241 | 76.0k | FLAC__ASSERT(is_valid()); |
242 | 76.0k | return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_metadata(decoder_)); |
243 | 76.0k | } |
244 | | |
245 | | bool Stream::process_until_end_of_link() |
246 | 0 | { |
247 | 0 | FLAC__ASSERT(is_valid()); |
248 | 0 | return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_link(decoder_)); |
249 | 0 | } |
250 | | |
251 | | bool Stream::process_until_end_of_stream() |
252 | 31.2k | { |
253 | 31.2k | FLAC__ASSERT(is_valid()); |
254 | 31.2k | return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_stream(decoder_)); |
255 | 31.2k | } |
256 | | |
257 | | bool Stream::skip_single_frame() |
258 | 1.67k | { |
259 | 1.67k | FLAC__ASSERT(is_valid()); |
260 | 1.67k | return static_cast<bool>(::FLAC__stream_decoder_skip_single_frame(decoder_)); |
261 | 1.67k | } |
262 | | |
263 | | bool Stream::skip_single_link() |
264 | 0 | { |
265 | 0 | FLAC__ASSERT(is_valid()); |
266 | 0 | return static_cast<bool>(::FLAC__stream_decoder_skip_single_link(decoder_)); |
267 | 0 | } |
268 | | |
269 | | bool Stream::seek_absolute(FLAC__uint64 sample) |
270 | 723 | { |
271 | 723 | FLAC__ASSERT(is_valid()); |
272 | 723 | return static_cast<bool>(::FLAC__stream_decoder_seek_absolute(decoder_, sample)); |
273 | 723 | } |
274 | | |
275 | | ::FLAC__StreamDecoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset) |
276 | 0 | { |
277 | 0 | (void)absolute_byte_offset; |
278 | 0 | return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; |
279 | 0 | } |
280 | | |
281 | | ::FLAC__StreamDecoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset) |
282 | 141k | { |
283 | 141k | (void)absolute_byte_offset; |
284 | 141k | return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; |
285 | 141k | } |
286 | | |
287 | | ::FLAC__StreamDecoderLengthStatus Stream::length_callback(FLAC__uint64 *stream_length) |
288 | 524 | { |
289 | 524 | (void)stream_length; |
290 | 524 | return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; |
291 | 524 | } |
292 | | |
293 | | bool Stream::eof_callback() |
294 | 240k | { |
295 | 240k | return false; |
296 | 240k | } |
297 | | |
298 | | void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata) |
299 | 0 | { |
300 | 0 | (void)metadata; |
301 | 0 | } |
302 | | |
303 | | ::FLAC__StreamDecoderReadStatus Stream::read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) |
304 | 262k | { |
305 | 262k | (void)decoder; |
306 | 262k | FLAC__ASSERT(0 != client_data); |
307 | 262k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
308 | 262k | FLAC__ASSERT(0 != instance); |
309 | 262k | return instance->read_callback(buffer, bytes); |
310 | 262k | } |
311 | | |
312 | | ::FLAC__StreamDecoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) |
313 | 76.4k | { |
314 | 76.4k | (void) decoder; |
315 | 76.4k | FLAC__ASSERT(0 != client_data); |
316 | 76.4k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
317 | 76.4k | FLAC__ASSERT(0 != instance); |
318 | 76.4k | return instance->seek_callback(absolute_byte_offset); |
319 | 76.4k | } |
320 | | |
321 | | ::FLAC__StreamDecoderTellStatus Stream::tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) |
322 | 141k | { |
323 | 141k | (void) decoder; |
324 | 141k | FLAC__ASSERT(0 != client_data); |
325 | 141k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
326 | 141k | FLAC__ASSERT(0 != instance); |
327 | 141k | return instance->tell_callback(absolute_byte_offset); |
328 | 141k | } |
329 | | |
330 | | ::FLAC__StreamDecoderLengthStatus Stream::length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) |
331 | 524 | { |
332 | 524 | (void) decoder; |
333 | 524 | FLAC__ASSERT(0 != client_data); |
334 | 524 | Stream *instance = reinterpret_cast<Stream *>(client_data); |
335 | 524 | FLAC__ASSERT(0 != instance); |
336 | 524 | return instance->length_callback(stream_length); |
337 | 524 | } |
338 | | |
339 | | FLAC__bool Stream::eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data) |
340 | 240k | { |
341 | 240k | (void) decoder; |
342 | 240k | FLAC__ASSERT(0 != client_data); |
343 | 240k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
344 | 240k | FLAC__ASSERT(0 != instance); |
345 | 240k | return instance->eof_callback(); |
346 | 240k | } |
347 | | |
348 | | ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) |
349 | 120k | { |
350 | 120k | (void)decoder; |
351 | 120k | FLAC__ASSERT(0 != client_data); |
352 | 120k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
353 | 120k | FLAC__ASSERT(0 != instance); |
354 | 120k | return instance->write_callback(frame, buffer); |
355 | 120k | } |
356 | | |
357 | | void Stream::metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data) |
358 | 68.7k | { |
359 | 68.7k | (void)decoder; |
360 | 68.7k | FLAC__ASSERT(0 != client_data); |
361 | 68.7k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
362 | 68.7k | FLAC__ASSERT(0 != instance); |
363 | 68.7k | instance->metadata_callback(metadata); |
364 | 68.7k | } |
365 | | |
366 | | void Stream::error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data) |
367 | 315k | { |
368 | 315k | (void)decoder; |
369 | 315k | FLAC__ASSERT(0 != client_data); |
370 | 315k | Stream *instance = reinterpret_cast<Stream *>(client_data); |
371 | 315k | FLAC__ASSERT(0 != instance); |
372 | 315k | instance->error_callback(status); |
373 | 315k | } |
374 | | |
375 | | // ------------------------------------------------------------ |
376 | | // |
377 | | // File |
378 | | // |
379 | | // ------------------------------------------------------------ |
380 | | |
381 | | File::File(): |
382 | 0 | Stream() |
383 | 0 | { } |
384 | | |
385 | | File::~File() |
386 | | { |
387 | | } |
388 | | |
389 | | ::FLAC__StreamDecoderInitStatus File::init(FILE *file) |
390 | 0 | { |
391 | 0 | FLAC__ASSERT(0 != decoder_); |
392 | 0 | return ::FLAC__stream_decoder_init_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); |
393 | 0 | } |
394 | | |
395 | | ::FLAC__StreamDecoderInitStatus File::init(const char *filename) |
396 | 0 | { |
397 | 0 | FLAC__ASSERT(0 != decoder_); |
398 | 0 | return ::FLAC__stream_decoder_init_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); |
399 | 0 | } |
400 | | |
401 | | ::FLAC__StreamDecoderInitStatus File::init(const std::string &filename) |
402 | 0 | { |
403 | 0 | return init(filename.c_str()); |
404 | 0 | } |
405 | | |
406 | | ::FLAC__StreamDecoderInitStatus File::init_ogg(FILE *file) |
407 | 0 | { |
408 | 0 | FLAC__ASSERT(0 != decoder_); |
409 | 0 | return ::FLAC__stream_decoder_init_ogg_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); |
410 | 0 | } |
411 | | |
412 | | ::FLAC__StreamDecoderInitStatus File::init_ogg(const char *filename) |
413 | 0 | { |
414 | 0 | FLAC__ASSERT(0 != decoder_); |
415 | 0 | return ::FLAC__stream_decoder_init_ogg_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); |
416 | 0 | } |
417 | | |
418 | | ::FLAC__StreamDecoderInitStatus File::init_ogg(const std::string &filename) |
419 | 0 | { |
420 | 0 | return init_ogg(filename.c_str()); |
421 | 0 | } |
422 | | |
423 | | // This is a dummy to satisfy the pure virtual from Stream; the |
424 | | // read callback will never be called since we are initializing |
425 | | // with FLAC__stream_decoder_init_FILE() or |
426 | | // FLAC__stream_decoder_init_file() and those supply the read |
427 | | // callback internally. |
428 | | ::FLAC__StreamDecoderReadStatus File::read_callback(FLAC__byte buffer[], size_t *bytes) |
429 | 0 | { |
430 | 0 | (void)buffer, (void)bytes; |
431 | 0 | FLAC__ASSERT(false); |
432 | 0 | return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; // double protection |
433 | 0 | } |
434 | | |
435 | | } // namespace Decoder |
436 | | } // namespace FLAC |