1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002-2009  Josh Coalson
3  * Copyright (C) 2011-2016  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 #ifndef HAVE_CXX_VARARRAYS
202 			// some compilers (MSVC++, Borland C, SunPro, some GCCs w/ -pedantic) can't handle:
203 			// ::FLAC__StreamMetadata *m[num_blocks];
204 			// so we do this ugly workaround
205 			::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
206 #else
207 			::FLAC__StreamMetadata *m[num_blocks];
208 #endif
209 			for(uint32_t i = 0; i < num_blocks; i++) {
210 				// we can get away with the const_cast since we know the encoder will only correct the is_last flags
211 				m[i] = const_cast< ::FLAC__StreamMetadata*>(static_cast<const ::FLAC__StreamMetadata*>(*metadata[i]));
212 			}
213 #ifndef HAVE_CXX_VARARRAYS
214 			// complete the hack
215 			const bool ok = static_cast<bool>(::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks));
216 			delete [] m;
217 			return ok;
218 #else
219 			return static_cast<bool>(::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks));
220 #endif
221 		}
222 
get_state() const223 		Stream::State Stream::get_state() const
224 		{
225 			FLAC__ASSERT(is_valid());
226 			return State(::FLAC__stream_encoder_get_state(encoder_));
227 		}
228 
get_verify_decoder_state() const229 		Decoder::Stream::State Stream::get_verify_decoder_state() const
230 		{
231 			FLAC__ASSERT(is_valid());
232 			return Decoder::Stream::State(::FLAC__stream_encoder_get_verify_decoder_state(encoder_));
233 		}
234 
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)235 		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)
236 		{
237 			FLAC__ASSERT(is_valid());
238 			::FLAC__stream_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
239 		}
240 
get_verify() const241 		bool Stream::get_verify() const
242 		{
243 			FLAC__ASSERT(is_valid());
244 			return static_cast<bool>(::FLAC__stream_encoder_get_verify(encoder_));
245 		}
246 
get_streamable_subset() const247 		bool Stream::get_streamable_subset() const
248 		{
249 			FLAC__ASSERT(is_valid());
250 			return static_cast<bool>(::FLAC__stream_encoder_get_streamable_subset(encoder_));
251 		}
252 
get_do_mid_side_stereo() const253 		bool Stream::get_do_mid_side_stereo() const
254 		{
255 			FLAC__ASSERT(is_valid());
256 			return static_cast<bool>(::FLAC__stream_encoder_get_do_mid_side_stereo(encoder_));
257 		}
258 
get_loose_mid_side_stereo() const259 		bool Stream::get_loose_mid_side_stereo() const
260 		{
261 			FLAC__ASSERT(is_valid());
262 			return static_cast<bool>(::FLAC__stream_encoder_get_loose_mid_side_stereo(encoder_));
263 		}
264 
get_channels() const265 		uint32_t Stream::get_channels() const
266 		{
267 			FLAC__ASSERT(is_valid());
268 			return ::FLAC__stream_encoder_get_channels(encoder_);
269 		}
270 
get_bits_per_sample() const271 		uint32_t Stream::get_bits_per_sample() const
272 		{
273 			FLAC__ASSERT(is_valid());
274 			return ::FLAC__stream_encoder_get_bits_per_sample(encoder_);
275 		}
276 
get_sample_rate() const277 		uint32_t Stream::get_sample_rate() const
278 		{
279 			FLAC__ASSERT(is_valid());
280 			return ::FLAC__stream_encoder_get_sample_rate(encoder_);
281 		}
282 
get_blocksize() const283 		uint32_t Stream::get_blocksize() const
284 		{
285 			FLAC__ASSERT(is_valid());
286 			return ::FLAC__stream_encoder_get_blocksize(encoder_);
287 		}
288 
get_max_lpc_order() const289 		uint32_t Stream::get_max_lpc_order() const
290 		{
291 			FLAC__ASSERT(is_valid());
292 			return ::FLAC__stream_encoder_get_max_lpc_order(encoder_);
293 		}
294 
get_qlp_coeff_precision() const295 		uint32_t Stream::get_qlp_coeff_precision() const
296 		{
297 			FLAC__ASSERT(is_valid());
298 			return ::FLAC__stream_encoder_get_qlp_coeff_precision(encoder_);
299 		}
300 
get_do_qlp_coeff_prec_search() const301 		bool Stream::get_do_qlp_coeff_prec_search() const
302 		{
303 			FLAC__ASSERT(is_valid());
304 			return static_cast<bool>(::FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder_));
305 		}
306 
get_do_escape_coding() const307 		bool Stream::get_do_escape_coding() const
308 		{
309 			FLAC__ASSERT(is_valid());
310 			return static_cast<bool>(::FLAC__stream_encoder_get_do_escape_coding(encoder_));
311 		}
312 
get_do_exhaustive_model_search() const313 		bool Stream::get_do_exhaustive_model_search() const
314 		{
315 			FLAC__ASSERT(is_valid());
316 			return static_cast<bool>(::FLAC__stream_encoder_get_do_exhaustive_model_search(encoder_));
317 		}
318 
get_min_residual_partition_order() const319 		uint32_t Stream::get_min_residual_partition_order() const
320 		{
321 			FLAC__ASSERT(is_valid());
322 			return ::FLAC__stream_encoder_get_min_residual_partition_order(encoder_);
323 		}
324 
get_max_residual_partition_order() const325 		uint32_t Stream::get_max_residual_partition_order() const
326 		{
327 			FLAC__ASSERT(is_valid());
328 			return ::FLAC__stream_encoder_get_max_residual_partition_order(encoder_);
329 		}
330 
get_rice_parameter_search_dist() const331 		uint32_t Stream::get_rice_parameter_search_dist() const
332 		{
333 			FLAC__ASSERT(is_valid());
334 			return ::FLAC__stream_encoder_get_rice_parameter_search_dist(encoder_);
335 		}
336 
get_total_samples_estimate() const337 		FLAC__uint64 Stream::get_total_samples_estimate() const
338 		{
339 			FLAC__ASSERT(is_valid());
340 			return ::FLAC__stream_encoder_get_total_samples_estimate(encoder_);
341 		}
342 
init()343 		::FLAC__StreamEncoderInitStatus Stream::init()
344 		{
345 			FLAC__ASSERT(is_valid());
346 			return ::FLAC__stream_encoder_init_stream(encoder_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
347 		}
348 
init_ogg()349 		::FLAC__StreamEncoderInitStatus Stream::init_ogg()
350 		{
351 			FLAC__ASSERT(is_valid());
352 			return ::FLAC__stream_encoder_init_ogg_stream(encoder_, read_callback_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
353 		}
354 
finish()355 		bool Stream::finish()
356 		{
357 			FLAC__ASSERT(is_valid());
358 			return static_cast<bool>(::FLAC__stream_encoder_finish(encoder_));
359 		}
360 
process(const FLAC__int32 * const buffer[],uint32_t samples)361 		bool Stream::process(const FLAC__int32 * const buffer[], uint32_t samples)
362 		{
363 			FLAC__ASSERT(is_valid());
364 			return static_cast<bool>(::FLAC__stream_encoder_process(encoder_, buffer, samples));
365 		}
366 
process_interleaved(const FLAC__int32 buffer[],uint32_t samples)367 		bool Stream::process_interleaved(const FLAC__int32 buffer[], uint32_t samples)
368 		{
369 			FLAC__ASSERT(is_valid());
370 			return static_cast<bool>(::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples));
371 		}
372 
read_callback(FLAC__byte buffer[],size_t * bytes)373 		::FLAC__StreamEncoderReadStatus Stream::read_callback(FLAC__byte buffer[], size_t *bytes)
374 		{
375 			(void)buffer, (void)bytes;
376 			return ::FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED;
377 		}
378 
seek_callback(FLAC__uint64 absolute_byte_offset)379 		::FLAC__StreamEncoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
380 		{
381 			(void)absolute_byte_offset;
382 			return ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
383 		}
384 
tell_callback(FLAC__uint64 * absolute_byte_offset)385 		::FLAC__StreamEncoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
386 		{
387 			(void)absolute_byte_offset;
388 			return ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
389 		}
390 
metadata_callback(const::FLAC__StreamMetadata * metadata)391 		void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
392 		{
393 			(void)metadata;
394 		}
395 
read_callback_(const::FLAC__StreamEncoder * encoder,FLAC__byte buffer[],size_t * bytes,void * client_data)396 		::FLAC__StreamEncoderReadStatus Stream::read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
397 		{
398 			(void)encoder;
399 			FLAC__ASSERT(0 != client_data);
400 			Stream *instance = reinterpret_cast<Stream *>(client_data);
401 			FLAC__ASSERT(0 != instance);
402 			return instance->read_callback(buffer, bytes);
403 		}
404 
write_callback_(const::FLAC__StreamEncoder * encoder,const FLAC__byte buffer[],size_t bytes,uint32_t samples,uint32_t current_frame,void * client_data)405 		::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)
406 		{
407 			(void)encoder;
408 			FLAC__ASSERT(0 != client_data);
409 			Stream *instance = reinterpret_cast<Stream *>(client_data);
410 			FLAC__ASSERT(0 != instance);
411 			return instance->write_callback(buffer, bytes, samples, current_frame);
412 		}
413 
seek_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 absolute_byte_offset,void * client_data)414 		::FLAC__StreamEncoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
415 		{
416 			(void)encoder;
417 			FLAC__ASSERT(0 != client_data);
418 			Stream *instance = reinterpret_cast<Stream *>(client_data);
419 			FLAC__ASSERT(0 != instance);
420 			return instance->seek_callback(absolute_byte_offset);
421 		}
422 
tell_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 * absolute_byte_offset,void * client_data)423 		::FLAC__StreamEncoderTellStatus Stream::tell_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
424 		{
425 			(void)encoder;
426 			FLAC__ASSERT(0 != client_data);
427 			Stream *instance = reinterpret_cast<Stream *>(client_data);
428 			FLAC__ASSERT(0 != instance);
429 			return instance->tell_callback(absolute_byte_offset);
430 		}
431 
metadata_callback_(const::FLAC__StreamEncoder * encoder,const::FLAC__StreamMetadata * metadata,void * client_data)432 		void Stream::metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
433 		{
434 			(void)encoder;
435 			FLAC__ASSERT(0 != client_data);
436 			Stream *instance = reinterpret_cast<Stream *>(client_data);
437 			FLAC__ASSERT(0 != instance);
438 			instance->metadata_callback(metadata);
439 		}
440 
441 		// ------------------------------------------------------------
442 		//
443 		// File
444 		//
445 		// ------------------------------------------------------------
446 
File()447 		File::File():
448 			Stream()
449 		{ }
450 
~File()451 		File::~File()
452 		{
453 		}
454 
init(FILE * file)455 		::FLAC__StreamEncoderInitStatus File::init(FILE *file)
456 		{
457 			FLAC__ASSERT(is_valid());
458 			return ::FLAC__stream_encoder_init_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
459 		}
460 
init(const char * filename)461 		::FLAC__StreamEncoderInitStatus File::init(const char *filename)
462 		{
463 			FLAC__ASSERT(is_valid());
464 			return ::FLAC__stream_encoder_init_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
465 		}
466 
init(const std::string & filename)467 		::FLAC__StreamEncoderInitStatus File::init(const std::string &filename)
468 		{
469 			return init(filename.c_str());
470 		}
471 
init_ogg(FILE * file)472 		::FLAC__StreamEncoderInitStatus File::init_ogg(FILE *file)
473 		{
474 			FLAC__ASSERT(is_valid());
475 			return ::FLAC__stream_encoder_init_ogg_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
476 		}
477 
init_ogg(const char * filename)478 		::FLAC__StreamEncoderInitStatus File::init_ogg(const char *filename)
479 		{
480 			FLAC__ASSERT(is_valid());
481 			return ::FLAC__stream_encoder_init_ogg_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
482 		}
483 
init_ogg(const std::string & filename)484 		::FLAC__StreamEncoderInitStatus File::init_ogg(const std::string &filename)
485 		{
486 			return init_ogg(filename.c_str());
487 		}
488 
489 		// This is a dummy to satisfy the pure virtual from Stream; the
490 		// read callback will never be called since we are initializing
491 		// with FLAC__stream_decoder_init_FILE() or
492 		// FLAC__stream_decoder_init_file() and those supply the read
493 		// callback internally.
write_callback(const FLAC__byte buffer[],size_t bytes,uint32_t samples,uint32_t current_frame)494 		::FLAC__StreamEncoderWriteStatus File::write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame)
495 		{
496 			(void)buffer, (void)bytes, (void)samples, (void)current_frame;
497 			FLAC__ASSERT(false);
498 			return ::FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; // double protection
499 		}
500 
progress_callback(FLAC__uint64 bytes_written,FLAC__uint64 samples_written,uint32_t frames_written,uint32_t total_frames_estimate)501 		void File::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, uint32_t frames_written, uint32_t total_frames_estimate)
502 		{
503 			(void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
504 		}
505 
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)506 		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)
507 		{
508 			(void)encoder;
509 			FLAC__ASSERT(0 != client_data);
510 			File *instance = reinterpret_cast<File *>(client_data);
511 			FLAC__ASSERT(0 != instance);
512 			instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate);
513 		}
514 
515 	} // namespace Encoder
516 } // namespace FLAC
517