xref: /aosp_15_r20/external/flac/src/libFLAC++/stream_encoder.cpp (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002-2009  Josh Coalson
3  * Copyright (C) 2011-2023  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++/encoder.h"
38 #include "FLAC++/metadata.h"
39 #include "FLAC/assert.h"
40 
41 #ifdef _MSC_VER
42 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
43 #pragma warning ( disable : 4800 )
44 #endif
45 
46 namespace FLAC {
47 	namespace Encoder {
48 
49 		// ------------------------------------------------------------
50 		//
51 		// Stream
52 		//
53 		// ------------------------------------------------------------
54 
Stream()55 		Stream::Stream():
56 		encoder_(::FLAC__stream_encoder_new())
57 		{ }
58 
~Stream()59 		Stream::~Stream()
60 		{
61 			if(0 != encoder_) {
62 				(void)::FLAC__stream_encoder_finish(encoder_);
63 				::FLAC__stream_encoder_delete(encoder_);
64 			}
65 		}
66 
is_valid() const67 		bool Stream::is_valid() const
68 		{
69 			return 0 != encoder_;
70 		}
71 
set_ogg_serial_number(long value)72 		bool Stream::set_ogg_serial_number(long value)
73 		{
74 			FLAC__ASSERT(is_valid());
75 			return static_cast<bool>(::FLAC__stream_encoder_set_ogg_serial_number(encoder_, value));
76 		}
77 
set_verify(bool value)78 		bool Stream::set_verify(bool value)
79 		{
80 			FLAC__ASSERT(is_valid());
81 			return static_cast<bool>(::FLAC__stream_encoder_set_verify(encoder_, value));
82 		}
83 
set_streamable_subset(bool value)84 		bool Stream::set_streamable_subset(bool value)
85 		{
86 			FLAC__ASSERT(is_valid());
87 			return static_cast<bool>(::FLAC__stream_encoder_set_streamable_subset(encoder_, value));
88 		}
89 
set_channels(uint32_t value)90 		bool Stream::set_channels(uint32_t value)
91 		{
92 			FLAC__ASSERT(is_valid());
93 			return static_cast<bool>(::FLAC__stream_encoder_set_channels(encoder_, value));
94 		}
95 
set_bits_per_sample(uint32_t value)96 		bool Stream::set_bits_per_sample(uint32_t value)
97 		{
98 			FLAC__ASSERT(is_valid());
99 			return static_cast<bool>(::FLAC__stream_encoder_set_bits_per_sample(encoder_, value));
100 		}
101 
set_sample_rate(uint32_t value)102 		bool Stream::set_sample_rate(uint32_t value)
103 		{
104 			FLAC__ASSERT(is_valid());
105 			return static_cast<bool>(::FLAC__stream_encoder_set_sample_rate(encoder_, value));
106 		}
107 
set_compression_level(uint32_t value)108 		bool Stream::set_compression_level(uint32_t value)
109 		{
110 			FLAC__ASSERT(is_valid());
111 			return static_cast<bool>(::FLAC__stream_encoder_set_compression_level(encoder_, value));
112 		}
113 
set_blocksize(uint32_t value)114 		bool Stream::set_blocksize(uint32_t value)
115 		{
116 			FLAC__ASSERT(is_valid());
117 			return static_cast<bool>(::FLAC__stream_encoder_set_blocksize(encoder_, value));
118 		}
119 
set_do_mid_side_stereo(bool value)120 		bool Stream::set_do_mid_side_stereo(bool value)
121 		{
122 			FLAC__ASSERT(is_valid());
123 			return static_cast<bool>(::FLAC__stream_encoder_set_do_mid_side_stereo(encoder_, value));
124 		}
125 
set_loose_mid_side_stereo(bool value)126 		bool Stream::set_loose_mid_side_stereo(bool value)
127 		{
128 			FLAC__ASSERT(is_valid());
129 			return static_cast<bool>(::FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_, value));
130 		}
131 
set_apodization(const char * specification)132 		bool Stream::set_apodization(const char *specification)
133 		{
134 			FLAC__ASSERT(is_valid());
135 			return static_cast<bool>(::FLAC__stream_encoder_set_apodization(encoder_, specification));
136 		}
137 
set_max_lpc_order(uint32_t value)138 		bool Stream::set_max_lpc_order(uint32_t value)
139 		{
140 			FLAC__ASSERT(is_valid());
141 			return static_cast<bool>(::FLAC__stream_encoder_set_max_lpc_order(encoder_, value));
142 		}
143 
set_qlp_coeff_precision(uint32_t value)144 		bool Stream::set_qlp_coeff_precision(uint32_t value)
145 		{
146 			FLAC__ASSERT(is_valid());
147 			return static_cast<bool>(::FLAC__stream_encoder_set_qlp_coeff_precision(encoder_, value));
148 		}
149 
set_do_qlp_coeff_prec_search(bool value)150 		bool Stream::set_do_qlp_coeff_prec_search(bool value)
151 		{
152 			FLAC__ASSERT(is_valid());
153 			return static_cast<bool>(::FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_, value));
154 		}
155 
set_do_escape_coding(bool value)156 		bool Stream::set_do_escape_coding(bool value)
157 		{
158 			FLAC__ASSERT(is_valid());
159 			return static_cast<bool>(::FLAC__stream_encoder_set_do_escape_coding(encoder_, value));
160 		}
161 
set_do_exhaustive_model_search(bool value)162 		bool Stream::set_do_exhaustive_model_search(bool value)
163 		{
164 			FLAC__ASSERT(is_valid());
165 			return static_cast<bool>(::FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_, value));
166 		}
167 
set_min_residual_partition_order(uint32_t value)168 		bool Stream::set_min_residual_partition_order(uint32_t value)
169 		{
170 			FLAC__ASSERT(is_valid());
171 			return static_cast<bool>(::FLAC__stream_encoder_set_min_residual_partition_order(encoder_, value));
172 		}
173 
set_max_residual_partition_order(uint32_t value)174 		bool Stream::set_max_residual_partition_order(uint32_t value)
175 		{
176 			FLAC__ASSERT(is_valid());
177 			return static_cast<bool>(::FLAC__stream_encoder_set_max_residual_partition_order(encoder_, value));
178 		}
179 
set_rice_parameter_search_dist(uint32_t value)180 		bool Stream::set_rice_parameter_search_dist(uint32_t value)
181 		{
182 			FLAC__ASSERT(is_valid());
183 			return static_cast<bool>(::FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_, value));
184 		}
185 
set_total_samples_estimate(FLAC__uint64 value)186 		bool Stream::set_total_samples_estimate(FLAC__uint64 value)
187 		{
188 			FLAC__ASSERT(is_valid());
189 			return static_cast<bool>(::FLAC__stream_encoder_set_total_samples_estimate(encoder_, value));
190 		}
191 
set_metadata(::FLAC__StreamMetadata ** metadata,uint32_t num_blocks)192 		bool Stream::set_metadata(::FLAC__StreamMetadata **metadata, uint32_t num_blocks)
193 		{
194 			FLAC__ASSERT(is_valid());
195 			return static_cast<bool>(::FLAC__stream_encoder_set_metadata(encoder_, metadata, num_blocks));
196 		}
197 
set_metadata(FLAC::Metadata::Prototype ** metadata,uint32_t num_blocks)198 		bool Stream::set_metadata(FLAC::Metadata::Prototype **metadata, uint32_t num_blocks)
199 		{
200 			FLAC__ASSERT(is_valid());
201 			// because C++ doesn't have VLA's (variable length arrays)
202 			// this ugly workaround is needed
203 			::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
204 			for(uint32_t i = 0; i < num_blocks; i++) {
205 				// we can get away with the const_cast since we know the encoder will only correct the is_last flags
206 				m[i] = const_cast< ::FLAC__StreamMetadata*>(static_cast<const ::FLAC__StreamMetadata*>(*metadata[i]));
207 			}
208 			// complete the hack
209 			const bool ok = static_cast<bool>(::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks));
210 			delete [] m;
211 			return ok;
212 		}
213 
set_limit_min_bitrate(bool value)214 		bool Stream::set_limit_min_bitrate(bool value)
215 		{
216 			FLAC__ASSERT(is_valid());
217 			return static_cast<bool>(::FLAC__stream_encoder_set_limit_min_bitrate(encoder_, value));
218 		}
219 
get_state() const220 		Stream::State Stream::get_state() const
221 		{
222 			FLAC__ASSERT(is_valid());
223 			return State(::FLAC__stream_encoder_get_state(encoder_));
224 		}
225 
get_verify_decoder_state() const226 		Decoder::Stream::State Stream::get_verify_decoder_state() const
227 		{
228 			FLAC__ASSERT(is_valid());
229 			return Decoder::Stream::State(::FLAC__stream_encoder_get_verify_decoder_state(encoder_));
230 		}
231 
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)232 		void Stream::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)
233 		{
234 			FLAC__ASSERT(is_valid());
235 			::FLAC__stream_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
236 		}
237 
get_verify() const238 		bool Stream::get_verify() const
239 		{
240 			FLAC__ASSERT(is_valid());
241 			return static_cast<bool>(::FLAC__stream_encoder_get_verify(encoder_));
242 		}
243 
get_streamable_subset() const244 		bool Stream::get_streamable_subset() const
245 		{
246 			FLAC__ASSERT(is_valid());
247 			return static_cast<bool>(::FLAC__stream_encoder_get_streamable_subset(encoder_));
248 		}
249 
get_do_mid_side_stereo() const250 		bool Stream::get_do_mid_side_stereo() const
251 		{
252 			FLAC__ASSERT(is_valid());
253 			return static_cast<bool>(::FLAC__stream_encoder_get_do_mid_side_stereo(encoder_));
254 		}
255 
get_loose_mid_side_stereo() const256 		bool Stream::get_loose_mid_side_stereo() const
257 		{
258 			FLAC__ASSERT(is_valid());
259 			return static_cast<bool>(::FLAC__stream_encoder_get_loose_mid_side_stereo(encoder_));
260 		}
261 
get_channels() const262 		uint32_t Stream::get_channels() const
263 		{
264 			FLAC__ASSERT(is_valid());
265 			return ::FLAC__stream_encoder_get_channels(encoder_);
266 		}
267 
get_bits_per_sample() const268 		uint32_t Stream::get_bits_per_sample() const
269 		{
270 			FLAC__ASSERT(is_valid());
271 			return ::FLAC__stream_encoder_get_bits_per_sample(encoder_);
272 		}
273 
get_sample_rate() const274 		uint32_t Stream::get_sample_rate() const
275 		{
276 			FLAC__ASSERT(is_valid());
277 			return ::FLAC__stream_encoder_get_sample_rate(encoder_);
278 		}
279 
get_blocksize() const280 		uint32_t Stream::get_blocksize() const
281 		{
282 			FLAC__ASSERT(is_valid());
283 			return ::FLAC__stream_encoder_get_blocksize(encoder_);
284 		}
285 
get_max_lpc_order() const286 		uint32_t Stream::get_max_lpc_order() const
287 		{
288 			FLAC__ASSERT(is_valid());
289 			return ::FLAC__stream_encoder_get_max_lpc_order(encoder_);
290 		}
291 
get_qlp_coeff_precision() const292 		uint32_t Stream::get_qlp_coeff_precision() const
293 		{
294 			FLAC__ASSERT(is_valid());
295 			return ::FLAC__stream_encoder_get_qlp_coeff_precision(encoder_);
296 		}
297 
get_do_qlp_coeff_prec_search() const298 		bool Stream::get_do_qlp_coeff_prec_search() const
299 		{
300 			FLAC__ASSERT(is_valid());
301 			return static_cast<bool>(::FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder_));
302 		}
303 
get_do_escape_coding() const304 		bool Stream::get_do_escape_coding() const
305 		{
306 			FLAC__ASSERT(is_valid());
307 			return static_cast<bool>(::FLAC__stream_encoder_get_do_escape_coding(encoder_));
308 		}
309 
get_do_exhaustive_model_search() const310 		bool Stream::get_do_exhaustive_model_search() const
311 		{
312 			FLAC__ASSERT(is_valid());
313 			return static_cast<bool>(::FLAC__stream_encoder_get_do_exhaustive_model_search(encoder_));
314 		}
315 
get_min_residual_partition_order() const316 		uint32_t Stream::get_min_residual_partition_order() const
317 		{
318 			FLAC__ASSERT(is_valid());
319 			return ::FLAC__stream_encoder_get_min_residual_partition_order(encoder_);
320 		}
321 
get_max_residual_partition_order() const322 		uint32_t Stream::get_max_residual_partition_order() const
323 		{
324 			FLAC__ASSERT(is_valid());
325 			return ::FLAC__stream_encoder_get_max_residual_partition_order(encoder_);
326 		}
327 
get_rice_parameter_search_dist() const328 		uint32_t Stream::get_rice_parameter_search_dist() const
329 		{
330 			FLAC__ASSERT(is_valid());
331 			return ::FLAC__stream_encoder_get_rice_parameter_search_dist(encoder_);
332 		}
333 
get_total_samples_estimate() const334 		FLAC__uint64 Stream::get_total_samples_estimate() const
335 		{
336 			FLAC__ASSERT(is_valid());
337 			return ::FLAC__stream_encoder_get_total_samples_estimate(encoder_);
338 		}
339 
get_limit_min_bitrate() const340 		bool Stream::get_limit_min_bitrate() const
341 		{
342 			FLAC__ASSERT(is_valid());
343 			return static_cast<bool>(::FLAC__stream_encoder_get_limit_min_bitrate(encoder_));
344 		}
345 
init()346 		::FLAC__StreamEncoderInitStatus Stream::init()
347 		{
348 			FLAC__ASSERT(is_valid());
349 			return ::FLAC__stream_encoder_init_stream(encoder_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
350 		}
351 
init_ogg()352 		::FLAC__StreamEncoderInitStatus Stream::init_ogg()
353 		{
354 			FLAC__ASSERT(is_valid());
355 			return ::FLAC__stream_encoder_init_ogg_stream(encoder_, read_callback_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
356 		}
357 
finish()358 		bool Stream::finish()
359 		{
360 			FLAC__ASSERT(is_valid());
361 			return static_cast<bool>(::FLAC__stream_encoder_finish(encoder_));
362 		}
363 
process(const FLAC__int32 * const buffer[],uint32_t samples)364 		bool Stream::process(const FLAC__int32 * const buffer[], uint32_t samples)
365 		{
366 			FLAC__ASSERT(is_valid());
367 			return static_cast<bool>(::FLAC__stream_encoder_process(encoder_, buffer, samples));
368 		}
369 
process_interleaved(const FLAC__int32 buffer[],uint32_t samples)370 		bool Stream::process_interleaved(const FLAC__int32 buffer[], uint32_t samples)
371 		{
372 			FLAC__ASSERT(is_valid());
373 			return static_cast<bool>(::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples));
374 		}
375 
read_callback(FLAC__byte buffer[],size_t * bytes)376 		::FLAC__StreamEncoderReadStatus Stream::read_callback(FLAC__byte buffer[], size_t *bytes)
377 		{
378 			(void)buffer, (void)bytes;
379 			return ::FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED;
380 		}
381 
seek_callback(FLAC__uint64 absolute_byte_offset)382 		::FLAC__StreamEncoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
383 		{
384 			(void)absolute_byte_offset;
385 			return ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
386 		}
387 
tell_callback(FLAC__uint64 * absolute_byte_offset)388 		::FLAC__StreamEncoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
389 		{
390 			(void)absolute_byte_offset;
391 			return ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
392 		}
393 
metadata_callback(const::FLAC__StreamMetadata * metadata)394 		void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
395 		{
396 			(void)metadata;
397 		}
398 
read_callback_(const::FLAC__StreamEncoder * encoder,FLAC__byte buffer[],size_t * bytes,void * client_data)399 		::FLAC__StreamEncoderReadStatus Stream::read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
400 		{
401 			(void)encoder;
402 			FLAC__ASSERT(0 != client_data);
403 			Stream *instance = reinterpret_cast<Stream *>(client_data);
404 			FLAC__ASSERT(0 != instance);
405 			return instance->read_callback(buffer, bytes);
406 		}
407 
write_callback_(const::FLAC__StreamEncoder * encoder,const FLAC__byte buffer[],size_t bytes,uint32_t samples,uint32_t current_frame,void * client_data)408 		::FLAC__StreamEncoderWriteStatus Stream::write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data)
409 		{
410 			(void)encoder;
411 			FLAC__ASSERT(0 != client_data);
412 			Stream *instance = reinterpret_cast<Stream *>(client_data);
413 			FLAC__ASSERT(0 != instance);
414 			return instance->write_callback(buffer, bytes, samples, current_frame);
415 		}
416 
seek_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 absolute_byte_offset,void * client_data)417 		::FLAC__StreamEncoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
418 		{
419 			(void)encoder;
420 			FLAC__ASSERT(0 != client_data);
421 			Stream *instance = reinterpret_cast<Stream *>(client_data);
422 			FLAC__ASSERT(0 != instance);
423 			return instance->seek_callback(absolute_byte_offset);
424 		}
425 
tell_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 * absolute_byte_offset,void * client_data)426 		::FLAC__StreamEncoderTellStatus Stream::tell_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
427 		{
428 			(void)encoder;
429 			FLAC__ASSERT(0 != client_data);
430 			Stream *instance = reinterpret_cast<Stream *>(client_data);
431 			FLAC__ASSERT(0 != instance);
432 			return instance->tell_callback(absolute_byte_offset);
433 		}
434 
metadata_callback_(const::FLAC__StreamEncoder * encoder,const::FLAC__StreamMetadata * metadata,void * client_data)435 		void Stream::metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
436 		{
437 			(void)encoder;
438 			FLAC__ASSERT(0 != client_data);
439 			Stream *instance = reinterpret_cast<Stream *>(client_data);
440 			FLAC__ASSERT(0 != instance);
441 			instance->metadata_callback(metadata);
442 		}
443 
444 		// ------------------------------------------------------------
445 		//
446 		// File
447 		//
448 		// ------------------------------------------------------------
449 
File()450 		File::File():
451 			Stream()
452 		{ }
453 
~File()454 		File::~File()
455 		{
456 		}
457 
init(FILE * file)458 		::FLAC__StreamEncoderInitStatus File::init(FILE *file)
459 		{
460 			FLAC__ASSERT(is_valid());
461 			return ::FLAC__stream_encoder_init_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
462 		}
463 
init(const char * filename)464 		::FLAC__StreamEncoderInitStatus File::init(const char *filename)
465 		{
466 			FLAC__ASSERT(is_valid());
467 			return ::FLAC__stream_encoder_init_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
468 		}
469 
init(const std::string & filename)470 		::FLAC__StreamEncoderInitStatus File::init(const std::string &filename)
471 		{
472 			return init(filename.c_str());
473 		}
474 
init_ogg(FILE * file)475 		::FLAC__StreamEncoderInitStatus File::init_ogg(FILE *file)
476 		{
477 			FLAC__ASSERT(is_valid());
478 			return ::FLAC__stream_encoder_init_ogg_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
479 		}
480 
init_ogg(const char * filename)481 		::FLAC__StreamEncoderInitStatus File::init_ogg(const char *filename)
482 		{
483 			FLAC__ASSERT(is_valid());
484 			return ::FLAC__stream_encoder_init_ogg_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
485 		}
486 
init_ogg(const std::string & filename)487 		::FLAC__StreamEncoderInitStatus File::init_ogg(const std::string &filename)
488 		{
489 			return init_ogg(filename.c_str());
490 		}
491 
492 		// This is a dummy to satisfy the pure virtual from Stream; the
493 		// read callback will never be called since we are initializing
494 		// with FLAC__stream_decoder_init_FILE() or
495 		// FLAC__stream_decoder_init_file() and those supply the read
496 		// callback internally.
write_callback(const FLAC__byte buffer[],size_t bytes,uint32_t samples,uint32_t current_frame)497 		::FLAC__StreamEncoderWriteStatus File::write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame)
498 		{
499 			(void)buffer, (void)bytes, (void)samples, (void)current_frame;
500 			FLAC__ASSERT(false);
501 			return ::FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; // double protection
502 		}
503 
progress_callback(FLAC__uint64 bytes_written,FLAC__uint64 samples_written,uint32_t frames_written,uint32_t total_frames_estimate)504 		void File::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, uint32_t frames_written, uint32_t total_frames_estimate)
505 		{
506 			(void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
507 		}
508 
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)509 		void File::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)
510 		{
511 			(void)encoder;
512 			FLAC__ASSERT(0 != client_data);
513 			File *instance = reinterpret_cast<File *>(client_data);
514 			FLAC__ASSERT(0 != instance);
515 			instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate);
516 		}
517 
518 	} // namespace Encoder
519 } // namespace FLAC
520