/src/flac/include/FLAC++/decoder.h
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 | | #ifndef FLACPP__DECODER_H |
34 | | #define FLACPP__DECODER_H |
35 | | |
36 | | #include "export.h" |
37 | | |
38 | | #include <string> |
39 | | #include "FLAC/stream_decoder.h" |
40 | | |
41 | | |
42 | | /** \file include/FLAC++/decoder.h |
43 | | * |
44 | | * \brief |
45 | | * This module contains the classes which implement the various |
46 | | * decoders. |
47 | | * |
48 | | * See the detailed documentation in the |
49 | | * \link flacpp_decoder decoder \endlink module. |
50 | | */ |
51 | | |
52 | | /** \defgroup flacpp_decoder FLAC++/decoder.h: decoder classes |
53 | | * \ingroup flacpp |
54 | | * |
55 | | * \brief |
56 | | * This module describes the decoder layers provided by libFLAC++. |
57 | | * |
58 | | * The libFLAC++ decoder classes are object wrappers around their |
59 | | * counterparts in libFLAC. All decoding layers available in |
60 | | * libFLAC are also provided here. The interface is very similar; |
61 | | * make sure to read the \link flac_decoder libFLAC decoder module \endlink. |
62 | | * |
63 | | * There are only two significant differences here. First, instead of |
64 | | * passing in C function pointers for callbacks, you inherit from the |
65 | | * decoder class and provide implementations for the callbacks in your |
66 | | * derived class; because of this there is no need for a 'client_data' |
67 | | * property. |
68 | | * |
69 | | * Second, there are two stream decoder classes. FLAC::Decoder::Stream |
70 | | * is used for the same cases that FLAC__stream_decoder_init_stream() / |
71 | | * FLAC__stream_decoder_init_ogg_stream() are used, and FLAC::Decoder::File |
72 | | * is used for the same cases that |
73 | | * FLAC__stream_decoder_init_FILE() and FLAC__stream_decoder_init_file() / |
74 | | * FLAC__stream_decoder_init_ogg_FILE() and FLAC__stream_decoder_init_ogg_file() |
75 | | * are used. |
76 | | */ |
77 | | |
78 | | namespace FLAC { |
79 | | namespace Decoder { |
80 | | |
81 | | /** \ingroup flacpp_decoder |
82 | | * \brief |
83 | | * This class wraps the ::FLAC__StreamDecoder. If you are |
84 | | * decoding from a file, FLAC::Decoder::File may be more |
85 | | * convenient. |
86 | | * |
87 | | * The usage of this class is similar to FLAC__StreamDecoder, |
88 | | * except instead of providing callbacks to |
89 | | * FLAC__stream_decoder_init*_stream(), you will inherit from this |
90 | | * class and override the virtual callback functions with your |
91 | | * own implementations, then call init() or init_ogg(). The rest |
92 | | * of the calls work the same as in the C layer. |
93 | | * |
94 | | * Only the read, write, and error callbacks are mandatory. The |
95 | | * others are optional; this class provides default |
96 | | * implementations that do nothing. In order for seeking to work |
97 | | * you must override seek_callback(), tell_callback(), |
98 | | * length_callback(), and eof_callback(). |
99 | | */ |
100 | | class FLACPP_API Stream { |
101 | | public: |
102 | | /** This class is a wrapper around FLAC__StreamDecoderState. |
103 | | */ |
104 | | class FLACPP_API State { |
105 | | public: |
106 | 0 | inline State(::FLAC__StreamDecoderState state): state_(state) { } |
107 | 0 | inline operator ::FLAC__StreamDecoderState() const { return state_; } |
108 | 0 | inline const char *as_cstring() const { return ::FLAC__StreamDecoderStateString[state_]; } |
109 | 0 | inline const char *resolved_as_cstring(const Stream &decoder) const { return ::FLAC__stream_decoder_get_resolved_state_string(decoder.decoder_); } |
110 | | protected: |
111 | | ::FLAC__StreamDecoderState state_; |
112 | | }; |
113 | | |
114 | | Stream(); |
115 | | virtual ~Stream(); |
116 | | |
117 | | //@{ |
118 | | /** Call after construction to check that the object was created |
119 | | * successfully. If not, use get_state() to find out why not. |
120 | | */ |
121 | | virtual bool is_valid() const; |
122 | 0 | inline operator bool() const { return is_valid(); } ///< See is_valid() |
123 | | //@} |
124 | | |
125 | | virtual bool set_ogg_serial_number(long value); ///< See FLAC__stream_decoder_set_ogg_serial_number() |
126 | | virtual bool set_decode_chained_stream(bool value); ///< See FLAC__stream_decoder_set_decode_chained_stream() |
127 | | virtual bool set_md5_checking(bool value); ///< See FLAC__stream_decoder_set_md5_checking() |
128 | | virtual bool set_metadata_respond(::FLAC__MetadataType type); ///< See FLAC__stream_decoder_set_metadata_respond() |
129 | | virtual bool set_metadata_respond_application(const FLAC__byte id[4]); ///< See FLAC__stream_decoder_set_metadata_respond_application() |
130 | | virtual bool set_metadata_respond_all(); ///< See FLAC__stream_decoder_set_metadata_respond_all() |
131 | | virtual bool set_metadata_ignore(::FLAC__MetadataType type); ///< See FLAC__stream_decoder_set_metadata_ignore() |
132 | | virtual bool set_metadata_ignore_application(const FLAC__byte id[4]); ///< See FLAC__stream_decoder_set_metadata_ignore_application() |
133 | | virtual bool set_metadata_ignore_all(); ///< See FLAC__stream_decoder_set_metadata_ignore_all() |
134 | | |
135 | | /* get_state() is not virtual since we want subclasses to be able to return their own state */ |
136 | | State get_state() const; ///< See FLAC__stream_decoder_get_state() |
137 | | virtual bool get_decode_chained_stream() const; ///< See FLAC__stream_decoder_get_decode_chained_stream() |
138 | | virtual bool get_md5_checking() const; ///< See FLAC__stream_decoder_get_md5_checking() |
139 | | virtual FLAC__uint64 get_total_samples() const; ///< See FLAC__stream_decoder_get_total_samples() |
140 | | virtual FLAC__uint64 find_total_samples(); ///< See FLAC__stream_decoder_find_total_samples() |
141 | | virtual uint32_t get_channels() const; ///< See FLAC__stream_decoder_get_channels() |
142 | | virtual ::FLAC__ChannelAssignment get_channel_assignment() const; ///< See FLAC__stream_decoder_get_channel_assignment() |
143 | | virtual uint32_t get_bits_per_sample() const; ///< See FLAC__stream_decoder_get_bits_per_sample() |
144 | | virtual uint32_t get_sample_rate() const; ///< See FLAC__stream_decoder_get_sample_rate() |
145 | | virtual uint32_t get_blocksize() const; ///< See FLAC__stream_decoder_get_blocksize() |
146 | | virtual bool get_decode_position(FLAC__uint64 *position) const; ///< See FLAC__stream_decoder_get_decode_position() |
147 | | virtual int32_t get_link_lengths(FLAC__uint64 **link_lengths); ///< See FLAC__stream_decoder_get_link_lengths() |
148 | | |
149 | | virtual ::FLAC__StreamDecoderInitStatus init(); ///< Seek FLAC__stream_decoder_init_stream() |
150 | | virtual ::FLAC__StreamDecoderInitStatus init_ogg(); ///< Seek FLAC__stream_decoder_init_ogg_stream() |
151 | | |
152 | | virtual bool finish(); ///< See FLAC__stream_decoder_finish() |
153 | | virtual bool finish_link(); ///< See FLAC__stream_decoder_finish_link() |
154 | | |
155 | | virtual bool flush(); ///< See FLAC__stream_decoder_flush() |
156 | | virtual bool reset(); ///< See FLAC__stream_decoder_reset() |
157 | | |
158 | | virtual bool process_single(); ///< See FLAC__stream_decoder_process_single() |
159 | | virtual bool process_until_end_of_metadata(); ///< See FLAC__stream_decoder_process_until_end_of_metadata() |
160 | | virtual bool process_until_end_of_link(); ///< See FLAC__stream_decoder_process_until_end_of_link() |
161 | | virtual bool process_until_end_of_stream(); ///< See FLAC__stream_decoder_process_until_end_of_stream() |
162 | | virtual bool skip_single_frame(); ///< See FLAC__stream_decoder_skip_single_frame() |
163 | | virtual bool skip_single_link(); ///< See FLAC__stream_decoder_skip_single_link() |
164 | | |
165 | | virtual bool seek_absolute(FLAC__uint64 sample); ///< See FLAC__stream_decoder_seek_absolute() |
166 | | protected: |
167 | | /// see FLAC__StreamDecoderReadCallback |
168 | | virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes) = 0; |
169 | | |
170 | | /// see FLAC__StreamDecoderSeekCallback |
171 | | virtual ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); |
172 | | |
173 | | /// see FLAC__StreamDecoderTellCallback |
174 | | virtual ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); |
175 | | |
176 | | /// see FLAC__StreamDecoderLengthCallback |
177 | | virtual ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length); |
178 | | |
179 | | /// see FLAC__StreamDecoderEofCallback |
180 | | virtual bool eof_callback(); |
181 | | |
182 | | /// see FLAC__StreamDecoderWriteCallback |
183 | | virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0; |
184 | | |
185 | | /// see FLAC__StreamDecoderMetadataCallback |
186 | | virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata); |
187 | | |
188 | | /// see FLAC__StreamDecoderErrorCallback |
189 | | virtual void error_callback(::FLAC__StreamDecoderErrorStatus status) = 0; |
190 | | |
191 | | #if (defined __BORLANDC__) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96))) || (defined __SUNPRO_CC) |
192 | | // lame hack: some compilers can't see a protected decoder_ from nested State::resolved_as_cstring() |
193 | | friend State; |
194 | | #endif |
195 | | ::FLAC__StreamDecoder *decoder_; |
196 | | |
197 | | static ::FLAC__StreamDecoderReadStatus read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); |
198 | | static ::FLAC__StreamDecoderSeekStatus seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); |
199 | | static ::FLAC__StreamDecoderTellStatus tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); |
200 | | static ::FLAC__StreamDecoderLengthStatus length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); |
201 | | static FLAC__bool eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data); |
202 | | static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); |
203 | | static void metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data); |
204 | | static void error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data); |
205 | | private: |
206 | | // Private and undefined so you can't use them: |
207 | | Stream(const Stream &); |
208 | | void operator=(const Stream &); |
209 | | }; |
210 | | |
211 | | /** \ingroup flacpp_decoder |
212 | | * \brief |
213 | | * This class wraps the ::FLAC__StreamDecoder. If you are |
214 | | * not decoding from a file, you may need to use |
215 | | * FLAC::Decoder::Stream. |
216 | | * |
217 | | * The usage of this class is similar to FLAC__StreamDecoder, |
218 | | * except instead of providing callbacks to |
219 | | * FLAC__stream_decoder_init*_FILE() or |
220 | | * FLAC__stream_decoder_init*_file(), you will inherit from this |
221 | | * class and override the virtual callback functions with your |
222 | | * own implementations, then call init() or init_off(). The rest |
223 | | * of the calls work the same as in the C layer. |
224 | | * |
225 | | * Only the write, and error callbacks from FLAC::Decoder::Stream |
226 | | * are mandatory. The others are optional; this class provides |
227 | | * full working implementations for all other callbacks and |
228 | | * supports seeking. |
229 | | */ |
230 | | class FLACPP_API File: public Stream { |
231 | | public: |
232 | | File(); |
233 | | virtual ~File(); |
234 | | |
235 | | using Stream::init; |
236 | | virtual ::FLAC__StreamDecoderInitStatus init(FILE *file); ///< See FLAC__stream_decoder_init_FILE() |
237 | | virtual ::FLAC__StreamDecoderInitStatus init(const char *filename); ///< See FLAC__stream_decoder_init_file() |
238 | | virtual ::FLAC__StreamDecoderInitStatus init(const std::string &filename); ///< See FLAC__stream_decoder_init_file() |
239 | | using Stream::init_ogg; |
240 | | virtual ::FLAC__StreamDecoderInitStatus init_ogg(FILE *file); ///< See FLAC__stream_decoder_init_ogg_FILE() |
241 | | virtual ::FLAC__StreamDecoderInitStatus init_ogg(const char *filename); ///< See FLAC__stream_decoder_init_ogg_file() |
242 | | virtual ::FLAC__StreamDecoderInitStatus init_ogg(const std::string &filename); ///< See FLAC__stream_decoder_init_ogg_file() |
243 | | protected: |
244 | | // this is a dummy implementation to satisfy the pure virtual in Stream that is actually supplied internally by the C layer |
245 | | virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); |
246 | | private: |
247 | | // Private and undefined so you can't use them: |
248 | | File(const File &); |
249 | | void operator=(const File &); |
250 | | }; |
251 | | |
252 | | } |
253 | | } |
254 | | |
255 | | #endif |