2222580a357fcb102249373b1ec67c31b1939f51
[flac.git] / src / libFLAC++ / stream_decoder.cpp
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002-2009  Josh Coalson
3  * Copyright (C) 2011-2014  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                 decoder_(::FLAC__stream_decoder_new())
56                 { }
57
58                 Stream::~Stream()
59                 {
60                         if(0 != decoder_) {
61                                 (void)::FLAC__stream_decoder_finish(decoder_);
62                                 ::FLAC__stream_decoder_delete(decoder_);
63                         }
64                 }
65
66                 bool Stream::is_valid() const
67                 {
68                         return 0 != decoder_;
69                 }
70
71                 bool Stream::set_ogg_serial_number(long value)
72                 {
73                         FLAC__ASSERT(is_valid());
74                         return (bool)::FLAC__stream_decoder_set_ogg_serial_number(decoder_, value);
75                 }
76
77                 bool Stream::set_md5_checking(bool value)
78                 {
79                         FLAC__ASSERT(is_valid());
80                         return (bool)::FLAC__stream_decoder_set_md5_checking(decoder_, value);
81                 }
82
83                 bool Stream::set_metadata_respond(::FLAC__MetadataType type)
84                 {
85                         FLAC__ASSERT(is_valid());
86                         return (bool)::FLAC__stream_decoder_set_metadata_respond(decoder_, type);
87                 }
88
89                 bool Stream::set_metadata_respond_application(const FLAC__byte id[4])
90                 {
91                         FLAC__ASSERT(is_valid());
92                         return (bool)::FLAC__stream_decoder_set_metadata_respond_application(decoder_, id);
93                 }
94
95                 bool Stream::set_metadata_respond_all()
96                 {
97                         FLAC__ASSERT(is_valid());
98                         return (bool)::FLAC__stream_decoder_set_metadata_respond_all(decoder_);
99                 }
100
101                 bool Stream::set_metadata_ignore(::FLAC__MetadataType type)
102                 {
103                         FLAC__ASSERT(is_valid());
104                         return (bool)::FLAC__stream_decoder_set_metadata_ignore(decoder_, type);
105                 }
106
107                 bool Stream::set_metadata_ignore_application(const FLAC__byte id[4])
108                 {
109                         FLAC__ASSERT(is_valid());
110                         return (bool)::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id);
111                 }
112
113                 bool Stream::set_metadata_ignore_all()
114                 {
115                         FLAC__ASSERT(is_valid());
116                         return (bool)::FLAC__stream_decoder_set_metadata_ignore_all(decoder_);
117                 }
118
119                 Stream::State Stream::get_state() const
120                 {
121                         FLAC__ASSERT(is_valid());
122                         return State(::FLAC__stream_decoder_get_state(decoder_));
123                 }
124
125                 bool Stream::get_md5_checking() const
126                 {
127                         FLAC__ASSERT(is_valid());
128                         return (bool)::FLAC__stream_decoder_get_md5_checking(decoder_);
129                 }
130
131                 FLAC__uint64 Stream::get_total_samples() const
132                 {
133                         FLAC__ASSERT(is_valid());
134                         return ::FLAC__stream_decoder_get_total_samples(decoder_);
135                 }
136
137                 unsigned Stream::get_channels() const
138                 {
139                         FLAC__ASSERT(is_valid());
140                         return ::FLAC__stream_decoder_get_channels(decoder_);
141                 }
142
143                 ::FLAC__ChannelAssignment Stream::get_channel_assignment() const
144                 {
145                         FLAC__ASSERT(is_valid());
146                         return ::FLAC__stream_decoder_get_channel_assignment(decoder_);
147                 }
148
149                 unsigned Stream::get_bits_per_sample() const
150                 {
151                         FLAC__ASSERT(is_valid());
152                         return ::FLAC__stream_decoder_get_bits_per_sample(decoder_);
153                 }
154
155                 unsigned Stream::get_sample_rate() const
156                 {
157                         FLAC__ASSERT(is_valid());
158                         return ::FLAC__stream_decoder_get_sample_rate(decoder_);
159                 }
160
161                 unsigned Stream::get_blocksize() const
162                 {
163                         FLAC__ASSERT(is_valid());
164                         return ::FLAC__stream_decoder_get_blocksize(decoder_);
165                 }
166
167                 bool Stream::get_decode_position(FLAC__uint64 *position) const
168                 {
169                         FLAC__ASSERT(is_valid());
170                         return ::FLAC__stream_decoder_get_decode_position(decoder_, position);
171                 }
172
173                 ::FLAC__StreamDecoderInitStatus Stream::init()
174                 {
175                         FLAC__ASSERT(is_valid());
176                         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);
177                 }
178
179                 ::FLAC__StreamDecoderInitStatus Stream::init_ogg()
180                 {
181                         FLAC__ASSERT(is_valid());
182                         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);
183                 }
184
185                 bool Stream::finish()
186                 {
187                         FLAC__ASSERT(is_valid());
188                         return (bool)::FLAC__stream_decoder_finish(decoder_);
189                 }
190
191                 bool Stream::flush()
192                 {
193                         FLAC__ASSERT(is_valid());
194                         return (bool)::FLAC__stream_decoder_flush(decoder_);
195                 }
196
197                 bool Stream::reset()
198                 {
199                         FLAC__ASSERT(is_valid());
200                         return (bool)::FLAC__stream_decoder_reset(decoder_);
201                 }
202
203                 bool Stream::process_single()
204                 {
205                         FLAC__ASSERT(is_valid());
206                         return (bool)::FLAC__stream_decoder_process_single(decoder_);
207                 }
208
209                 bool Stream::process_until_end_of_metadata()
210                 {
211                         FLAC__ASSERT(is_valid());
212                         return (bool)::FLAC__stream_decoder_process_until_end_of_metadata(decoder_);
213                 }
214
215                 bool Stream::process_until_end_of_stream()
216                 {
217                         FLAC__ASSERT(is_valid());
218                         return (bool)::FLAC__stream_decoder_process_until_end_of_stream(decoder_);
219                 }
220
221                 bool Stream::skip_single_frame()
222                 {
223                         FLAC__ASSERT(is_valid());
224                         return (bool)::FLAC__stream_decoder_skip_single_frame(decoder_);
225                 }
226
227                 bool Stream::seek_absolute(FLAC__uint64 sample)
228                 {
229                         FLAC__ASSERT(is_valid());
230                         return (bool)::FLAC__stream_decoder_seek_absolute(decoder_, sample);
231                 }
232
233                 ::FLAC__StreamDecoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
234                 {
235                         (void)absolute_byte_offset;
236                         return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
237                 }
238
239                 ::FLAC__StreamDecoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
240                 {
241                         (void)absolute_byte_offset;
242                         return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
243                 }
244
245                 ::FLAC__StreamDecoderLengthStatus Stream::length_callback(FLAC__uint64 *stream_length)
246                 {
247                         (void)stream_length;
248                         return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
249                 }
250
251                 bool Stream::eof_callback()
252                 {
253                         return false;
254                 }
255
256                 void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
257                 {
258                         (void)metadata;
259                 }
260
261                 ::FLAC__StreamDecoderReadStatus Stream::read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
262                 {
263                         (void)decoder;
264                         FLAC__ASSERT(0 != client_data);
265                         Stream *instance = reinterpret_cast<Stream *>(client_data);
266                         FLAC__ASSERT(0 != instance);
267                         return instance->read_callback(buffer, bytes);
268                 }
269
270                 ::FLAC__StreamDecoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
271                 {
272                         (void) decoder;
273                         FLAC__ASSERT(0 != client_data);
274                         Stream *instance = reinterpret_cast<Stream *>(client_data);
275                         FLAC__ASSERT(0 != instance);
276                         return instance->seek_callback(absolute_byte_offset);
277                 }
278
279                 ::FLAC__StreamDecoderTellStatus Stream::tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
280                 {
281                         (void) decoder;
282                         FLAC__ASSERT(0 != client_data);
283                         Stream *instance = reinterpret_cast<Stream *>(client_data);
284                         FLAC__ASSERT(0 != instance);
285                         return instance->tell_callback(absolute_byte_offset);
286                 }
287
288                 ::FLAC__StreamDecoderLengthStatus Stream::length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
289                 {
290                         (void) decoder;
291                         FLAC__ASSERT(0 != client_data);
292                         Stream *instance = reinterpret_cast<Stream *>(client_data);
293                         FLAC__ASSERT(0 != instance);
294                         return instance->length_callback(stream_length);
295                 }
296
297                 FLAC__bool Stream::eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data)
298                 {
299                         (void) decoder;
300                         FLAC__ASSERT(0 != client_data);
301                         Stream *instance = reinterpret_cast<Stream *>(client_data);
302                         FLAC__ASSERT(0 != instance);
303                         return instance->eof_callback();
304                 }
305
306                 ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
307                 {
308                         (void)decoder;
309                         FLAC__ASSERT(0 != client_data);
310                         Stream *instance = reinterpret_cast<Stream *>(client_data);
311                         FLAC__ASSERT(0 != instance);
312                         return instance->write_callback(frame, buffer);
313                 }
314
315                 void Stream::metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
316                 {
317                         (void)decoder;
318                         FLAC__ASSERT(0 != client_data);
319                         Stream *instance = reinterpret_cast<Stream *>(client_data);
320                         FLAC__ASSERT(0 != instance);
321                         instance->metadata_callback(metadata);
322                 }
323
324                 void Stream::error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data)
325                 {
326                         (void)decoder;
327                         FLAC__ASSERT(0 != client_data);
328                         Stream *instance = reinterpret_cast<Stream *>(client_data);
329                         FLAC__ASSERT(0 != instance);
330                         instance->error_callback(status);
331                 }
332
333                 // ------------------------------------------------------------
334                 //
335                 // File
336                 //
337                 // ------------------------------------------------------------
338
339                 File::File():
340                         Stream()
341                 { }
342
343                 File::~File()
344                 {
345                 }
346
347                 ::FLAC__StreamDecoderInitStatus File::init(FILE *file)
348                 {
349                         FLAC__ASSERT(0 != decoder_);
350                         return ::FLAC__stream_decoder_init_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
351                 }
352
353                 ::FLAC__StreamDecoderInitStatus File::init(const char *filename)
354                 {
355                         FLAC__ASSERT(0 != decoder_);
356                         return ::FLAC__stream_decoder_init_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
357                 }
358
359                 ::FLAC__StreamDecoderInitStatus File::init(const std::string &filename)
360                 {
361                         return init(filename.c_str());
362                 }
363
364                 ::FLAC__StreamDecoderInitStatus File::init_ogg(FILE *file)
365                 {
366                         FLAC__ASSERT(0 != decoder_);
367                         return ::FLAC__stream_decoder_init_ogg_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
368                 }
369
370                 ::FLAC__StreamDecoderInitStatus File::init_ogg(const char *filename)
371                 {
372                         FLAC__ASSERT(0 != decoder_);
373                         return ::FLAC__stream_decoder_init_ogg_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
374                 }
375
376                 ::FLAC__StreamDecoderInitStatus File::init_ogg(const std::string &filename)
377                 {
378                         return init_ogg(filename.c_str());
379                 }
380
381                 // This is a dummy to satisfy the pure virtual from Stream; the
382                 // read callback will never be called since we are initializing
383                 // with FLAC__stream_decoder_init_FILE() or
384                 // FLAC__stream_decoder_init_file() and those supply the read
385                 // callback internally.
386                 ::FLAC__StreamDecoderReadStatus File::read_callback(FLAC__byte buffer[], size_t *bytes)
387                 {
388                         (void)buffer, (void)bytes;
389                         FLAC__ASSERT(false);
390                         return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; // double protection
391                 }
392
393         }
394 }