/src/flac/include/FLAC++/encoder.h
Line | Count | Source (jump to first uncovered line) |
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__ENCODER_H |
34 | | #define FLACPP__ENCODER_H |
35 | | |
36 | | #include "export.h" |
37 | | |
38 | | #include "FLAC/stream_encoder.h" |
39 | | #include "decoder.h" |
40 | | #include "metadata.h" |
41 | | |
42 | | |
43 | | /** \file include/FLAC++/encoder.h |
44 | | * |
45 | | * \brief |
46 | | * This module contains the classes which implement the various |
47 | | * encoders. |
48 | | * |
49 | | * See the detailed documentation in the |
50 | | * \link flacpp_encoder encoder \endlink module. |
51 | | */ |
52 | | |
53 | | /** \defgroup flacpp_encoder FLAC++/encoder.h: encoder classes |
54 | | * \ingroup flacpp |
55 | | * |
56 | | * \brief |
57 | | * This module describes the encoder layers provided by libFLAC++. |
58 | | * |
59 | | * The libFLAC++ encoder classes are object wrappers around their |
60 | | * counterparts in libFLAC. All encoding layers available in |
61 | | * libFLAC are also provided here. The interface is very similar; |
62 | | * make sure to read the \link flac_encoder libFLAC encoder module \endlink. |
63 | | * |
64 | | * There are only two significant differences here. First, instead of |
65 | | * passing in C function pointers for callbacks, you inherit from the |
66 | | * encoder class and provide implementations for the callbacks in your |
67 | | * derived class; because of this there is no need for a 'client_data' |
68 | | * property. |
69 | | * |
70 | | * Second, there are two stream encoder classes. FLAC::Encoder::Stream |
71 | | * is used for the same cases that FLAC__stream_encoder_init_stream() / |
72 | | * FLAC__stream_encoder_init_ogg_stream() are used, and FLAC::Encoder::File |
73 | | * is used for the same cases that |
74 | | * FLAC__stream_encoder_init_FILE() and FLAC__stream_encoder_init_file() / |
75 | | * FLAC__stream_encoder_init_ogg_FILE() and FLAC__stream_encoder_init_ogg_file() |
76 | | * are used. |
77 | | */ |
78 | | |
79 | | namespace FLAC { |
80 | | namespace Encoder { |
81 | | |
82 | | /** \ingroup flacpp_encoder |
83 | | * \brief |
84 | | * This class wraps the ::FLAC__StreamEncoder. If you are |
85 | | * encoding to a file, FLAC::Encoder::File may be more |
86 | | * convenient. |
87 | | * |
88 | | * The usage of this class is similar to FLAC__StreamEncoder, |
89 | | * except instead of providing callbacks to |
90 | | * FLAC__stream_encoder_init*_stream(), you will inherit from this |
91 | | * class and override the virtual callback functions with your |
92 | | * own implementations, then call init() or init_ogg(). The rest of |
93 | | * the calls work the same as in the C layer. |
94 | | * |
95 | | * Only the write callback is mandatory. The others are |
96 | | * optional; this class provides default implementations that do |
97 | | * nothing. In order for some STREAMINFO and SEEKTABLE data to |
98 | | * be written properly, you must override seek_callback() and |
99 | | * tell_callback(); see FLAC__stream_encoder_init_stream() as to |
100 | | * why. |
101 | | */ |
102 | | class FLACPP_API Stream { |
103 | | public: |
104 | | /** This class is a wrapper around FLAC__StreamEncoderState. |
105 | | */ |
106 | | class FLACPP_API State { |
107 | | public: |
108 | 37.5k | inline State(::FLAC__StreamEncoderState state): state_(state) { } |
109 | 37.5k | inline operator ::FLAC__StreamEncoderState() const { return state_; } |
110 | 0 | inline const char *as_cstring() const { return ::FLAC__StreamEncoderStateString[state_]; } |
111 | 0 | inline const char *resolved_as_cstring(const Stream &encoder) const { return ::FLAC__stream_encoder_get_resolved_state_string(encoder.encoder_); } |
112 | | protected: |
113 | | ::FLAC__StreamEncoderState state_; |
114 | | }; |
115 | | |
116 | | Stream(); |
117 | | virtual ~Stream(); |
118 | | |
119 | | //@{ |
120 | | /** Call after construction to check that the object was created |
121 | | * successfully. If not, use get_state() to find out why not. |
122 | | * |
123 | | */ |
124 | | virtual bool is_valid() const; |
125 | 0 | inline operator bool() const { return is_valid(); } ///< See is_valid() |
126 | | //@} |
127 | | |
128 | | virtual bool set_ogg_serial_number(long value); ///< See FLAC__stream_encoder_set_ogg_serial_number() |
129 | | virtual bool set_verify(bool value); ///< See FLAC__stream_encoder_set_verify() |
130 | | virtual bool set_streamable_subset(bool value); ///< See FLAC__stream_encoder_set_streamable_subset() |
131 | | virtual bool set_channels(uint32_t value); ///< See FLAC__stream_encoder_set_channels() |
132 | | virtual bool set_bits_per_sample(uint32_t value); ///< See FLAC__stream_encoder_set_bits_per_sample() |
133 | | virtual bool set_sample_rate(uint32_t value); ///< See FLAC__stream_encoder_set_sample_rate() |
134 | | virtual bool set_compression_level(uint32_t value); ///< See FLAC__stream_encoder_set_compression_level() |
135 | | virtual bool set_blocksize(uint32_t value); ///< See FLAC__stream_encoder_set_blocksize() |
136 | | virtual bool set_do_mid_side_stereo(bool value); ///< See FLAC__stream_encoder_set_do_mid_side_stereo() |
137 | | virtual bool set_loose_mid_side_stereo(bool value); ///< See FLAC__stream_encoder_set_loose_mid_side_stereo() |
138 | | virtual bool set_apodization(const char *specification); ///< See FLAC__stream_encoder_set_apodization() |
139 | | virtual bool set_max_lpc_order(uint32_t value); ///< See FLAC__stream_encoder_set_max_lpc_order() |
140 | | virtual bool set_qlp_coeff_precision(uint32_t value); ///< See FLAC__stream_encoder_set_qlp_coeff_precision() |
141 | | virtual bool set_do_qlp_coeff_prec_search(bool value); ///< See FLAC__stream_encoder_set_do_qlp_coeff_prec_search() |
142 | | virtual bool set_do_escape_coding(bool value); ///< See FLAC__stream_encoder_set_do_escape_coding() |
143 | | virtual bool set_do_exhaustive_model_search(bool value); ///< See FLAC__stream_encoder_set_do_exhaustive_model_search() |
144 | | virtual bool set_min_residual_partition_order(uint32_t value); ///< See FLAC__stream_encoder_set_min_residual_partition_order() |
145 | | virtual bool set_max_residual_partition_order(uint32_t value); ///< See FLAC__stream_encoder_set_max_residual_partition_order() |
146 | | virtual bool set_rice_parameter_search_dist(uint32_t value); ///< See FLAC__stream_encoder_set_rice_parameter_search_dist() |
147 | | virtual bool set_total_samples_estimate(FLAC__uint64 value); ///< See FLAC__stream_encoder_set_total_samples_estimate() |
148 | | virtual bool set_metadata(::FLAC__StreamMetadata **metadata, uint32_t num_blocks); ///< See FLAC__stream_encoder_set_metadata() |
149 | | virtual bool set_metadata(FLAC::Metadata::Prototype **metadata, uint32_t num_blocks); ///< See FLAC__stream_encoder_set_metadata() |
150 | | virtual bool set_limit_min_bitrate(bool value); ///< See FLAC__stream_encoder_set_limit_min_bitrate() |
151 | | virtual uint32_t set_num_threads(uint32_t value); ///< See FLAC__stream_encoder_set_num_threads() |
152 | | |
153 | | /* get_state() is not virtual since we want subclasses to be able to return their own state */ |
154 | | State get_state() const; ///< See FLAC__stream_encoder_get_state() |
155 | | virtual Decoder::Stream::State get_verify_decoder_state() const; ///< See FLAC__stream_encoder_get_verify_decoder_state() |
156 | | virtual void get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, uint32_t *frame_number, uint32_t *channel, uint32_t *sample, FLAC__int32 *expected, FLAC__int32 *got); ///< See FLAC__stream_encoder_get_verify_decoder_error_stats() |
157 | | virtual bool get_verify() const; ///< See FLAC__stream_encoder_get_verify() |
158 | | virtual bool get_streamable_subset() const; ///< See FLAC__stream_encoder_get_streamable_subset() |
159 | | virtual bool get_do_mid_side_stereo() const; ///< See FLAC__stream_encoder_get_do_mid_side_stereo() |
160 | | virtual bool get_loose_mid_side_stereo() const; ///< See FLAC__stream_encoder_get_loose_mid_side_stereo() |
161 | | virtual uint32_t get_channels() const; ///< See FLAC__stream_encoder_get_channels() |
162 | | virtual uint32_t get_bits_per_sample() const; ///< See FLAC__stream_encoder_get_bits_per_sample() |
163 | | virtual uint32_t get_sample_rate() const; ///< See FLAC__stream_encoder_get_sample_rate() |
164 | | virtual uint32_t get_blocksize() const; ///< See FLAC__stream_encoder_get_blocksize() |
165 | | virtual uint32_t get_max_lpc_order() const; ///< See FLAC__stream_encoder_get_max_lpc_order() |
166 | | virtual uint32_t get_qlp_coeff_precision() const; ///< See FLAC__stream_encoder_get_qlp_coeff_precision() |
167 | | virtual bool get_do_qlp_coeff_prec_search() const; ///< See FLAC__stream_encoder_get_do_qlp_coeff_prec_search() |
168 | | virtual bool get_do_escape_coding() const; ///< See FLAC__stream_encoder_get_do_escape_coding() |
169 | | virtual bool get_do_exhaustive_model_search() const; ///< See FLAC__stream_encoder_get_do_exhaustive_model_search() |
170 | | virtual uint32_t get_min_residual_partition_order() const; ///< See FLAC__stream_encoder_get_min_residual_partition_order() |
171 | | virtual uint32_t get_max_residual_partition_order() const; ///< See FLAC__stream_encoder_get_max_residual_partition_order() |
172 | | virtual uint32_t get_rice_parameter_search_dist() const; ///< See FLAC__stream_encoder_get_rice_parameter_search_dist() |
173 | | virtual FLAC__uint64 get_total_samples_estimate() const; ///< See FLAC__stream_encoder_get_total_samples_estimate() |
174 | | virtual bool get_limit_min_bitrate() const; ///< See FLAC__stream_encoder_get_limit_min_bitrate() |
175 | | virtual uint32_t get_num_threads() const; ///< See FLAC__stream_encoder_get_num_threads() |
176 | | |
177 | | virtual ::FLAC__StreamEncoderInitStatus init(); ///< See FLAC__stream_encoder_init_stream() |
178 | | virtual ::FLAC__StreamEncoderInitStatus init_ogg(); ///< See FLAC__stream_encoder_init_ogg_stream() |
179 | | |
180 | | virtual bool finish(); ///< See FLAC__stream_encoder_finish() |
181 | | |
182 | | virtual bool process(const FLAC__int32 * const buffer[], uint32_t samples); ///< See FLAC__stream_encoder_process() |
183 | | virtual bool process_interleaved(const FLAC__int32 buffer[], uint32_t samples); ///< See FLAC__stream_encoder_process_interleaved() |
184 | | protected: |
185 | | /// See FLAC__StreamEncoderReadCallback |
186 | | virtual ::FLAC__StreamEncoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); |
187 | | |
188 | | /// See FLAC__StreamEncoderWriteCallback |
189 | | virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame) = 0; |
190 | | |
191 | | /// See FLAC__StreamEncoderSeekCallback |
192 | | virtual ::FLAC__StreamEncoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); |
193 | | |
194 | | /// See FLAC__StreamEncoderTellCallback |
195 | | virtual ::FLAC__StreamEncoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); |
196 | | |
197 | | /// See FLAC__StreamEncoderMetadataCallback |
198 | | virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata); |
199 | | |
200 | | #if (defined __BORLANDC__) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96))) || (defined __SUNPRO_CC) |
201 | | // lame hack: some compilers can't see a protected encoder_ from nested State::resolved_as_cstring() |
202 | | friend State; |
203 | | #endif |
204 | | ::FLAC__StreamEncoder *encoder_; |
205 | | |
206 | | static ::FLAC__StreamEncoderReadStatus read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); |
207 | | static ::FLAC__StreamEncoderWriteStatus write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data); |
208 | | static ::FLAC__StreamEncoderSeekStatus seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); |
209 | | static ::FLAC__StreamEncoderTellStatus tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); |
210 | | static void metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data); |
211 | | private: |
212 | | // Private and undefined so you can't use them: |
213 | | Stream(const Stream &); |
214 | | void operator=(const Stream &); |
215 | | }; |
216 | | |
217 | | /** \ingroup flacpp_encoder |
218 | | * \brief |
219 | | * This class wraps the ::FLAC__StreamEncoder. If you are |
220 | | * not encoding to a file, you may need to use |
221 | | * FLAC::Encoder::Stream. |
222 | | * |
223 | | * The usage of this class is similar to FLAC__StreamEncoder, |
224 | | * except instead of providing callbacks to |
225 | | * FLAC__stream_encoder_init*_FILE() or |
226 | | * FLAC__stream_encoder_init*_file(), you will inherit from this |
227 | | * class and override the virtual callback functions with your |
228 | | * own implementations, then call init() or init_ogg(). The rest |
229 | | * of the calls work the same as in the C layer. |
230 | | * |
231 | | * There are no mandatory callbacks; all the callbacks from |
232 | | * FLAC::Encoder::Stream are implemented here fully and support |
233 | | * full post-encode STREAMINFO and SEEKTABLE updating. There is |
234 | | * only an optional progress callback which you may override to |
235 | | * get periodic reports on the progress of the encode. |
236 | | */ |
237 | | class FLACPP_API File: public Stream { |
238 | | public: |
239 | | File(); |
240 | | virtual ~File(); |
241 | | |
242 | | using Stream::init; |
243 | | virtual ::FLAC__StreamEncoderInitStatus init(FILE *file); ///< See FLAC__stream_encoder_init_FILE() |
244 | | virtual ::FLAC__StreamEncoderInitStatus init(const char *filename); ///< See FLAC__stream_encoder_init_file() |
245 | | virtual ::FLAC__StreamEncoderInitStatus init(const std::string &filename); ///< See FLAC__stream_encoder_init_file() |
246 | | using Stream::init_ogg; |
247 | | virtual ::FLAC__StreamEncoderInitStatus init_ogg(FILE *file); ///< See FLAC__stream_encoder_init_ogg_FILE() |
248 | | virtual ::FLAC__StreamEncoderInitStatus init_ogg(const char *filename); ///< See FLAC__stream_encoder_init_ogg_file() |
249 | | virtual ::FLAC__StreamEncoderInitStatus init_ogg(const std::string &filename); ///< See FLAC__stream_encoder_init_ogg_file() |
250 | | protected: |
251 | | /// See FLAC__StreamEncoderProgressCallback |
252 | | virtual void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, uint32_t frames_written, uint32_t total_frames_estimate); |
253 | | |
254 | | /// This is a dummy implementation to satisfy the pure virtual in Stream that is actually supplied internally by the C layer |
255 | | virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame); |
256 | | private: |
257 | | static void progress_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, uint32_t frames_written, uint32_t total_frames_estimate, void *client_data); |
258 | | |
259 | | // Private and undefined so you can't use them: |
260 | | File(const Stream &); |
261 | | void operator=(const Stream &); |
262 | | }; |
263 | | |
264 | | } |
265 | | } |
266 | | |
267 | | #endif |