1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003,2004,2005,2006,2007  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "FLAC++/encoder.h"
33 #include "FLAC++/metadata.h"
34 #include "FLAC/assert.h"
35 
36 #ifdef _MSC_VER
37 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
38 #pragma warning ( disable : 4800 )
39 #endif
40 
41 namespace FLAC {
42 	namespace Encoder {
43 
44 		// ------------------------------------------------------------
45 		//
46 		// Stream
47 		//
48 		// ------------------------------------------------------------
49 
Stream()50 		Stream::Stream():
51 		encoder_(::FLAC__stream_encoder_new())
52 		{ }
53 
~Stream()54 		Stream::~Stream()
55 		{
56 			if(0 != encoder_) {
57 				(void)::FLAC__stream_encoder_finish(encoder_);
58 				::FLAC__stream_encoder_delete(encoder_);
59 			}
60 		}
61 
is_valid() const62 		bool Stream::is_valid() const
63 		{
64 			return 0 != encoder_;
65 		}
66 
set_ogg_serial_number(long value)67 		bool Stream::set_ogg_serial_number(long value)
68 		{
69 			FLAC__ASSERT(is_valid());
70 			return (bool)::FLAC__stream_encoder_set_ogg_serial_number(encoder_, value);
71 		}
72 
set_verify(bool value)73 		bool Stream::set_verify(bool value)
74 		{
75 			FLAC__ASSERT(is_valid());
76 			return (bool)::FLAC__stream_encoder_set_verify(encoder_, value);
77 		}
78 
set_streamable_subset(bool value)79 		bool Stream::set_streamable_subset(bool value)
80 		{
81 			FLAC__ASSERT(is_valid());
82 			return (bool)::FLAC__stream_encoder_set_streamable_subset(encoder_, value);
83 		}
84 
set_channels(unsigned value)85 		bool Stream::set_channels(unsigned value)
86 		{
87 			FLAC__ASSERT(is_valid());
88 			return (bool)::FLAC__stream_encoder_set_channels(encoder_, value);
89 		}
90 
set_bits_per_sample(unsigned value)91 		bool Stream::set_bits_per_sample(unsigned value)
92 		{
93 			FLAC__ASSERT(is_valid());
94 			return (bool)::FLAC__stream_encoder_set_bits_per_sample(encoder_, value);
95 		}
96 
set_sample_rate(unsigned value)97 		bool Stream::set_sample_rate(unsigned value)
98 		{
99 			FLAC__ASSERT(is_valid());
100 			return (bool)::FLAC__stream_encoder_set_sample_rate(encoder_, value);
101 		}
102 
set_compression_level(unsigned value)103 		bool Stream::set_compression_level(unsigned value)
104 		{
105 			FLAC__ASSERT(is_valid());
106 			return (bool)::FLAC__stream_encoder_set_compression_level(encoder_, value);
107 		}
108 
set_blocksize(unsigned value)109 		bool Stream::set_blocksize(unsigned value)
110 		{
111 			FLAC__ASSERT(is_valid());
112 			return (bool)::FLAC__stream_encoder_set_blocksize(encoder_, value);
113 		}
114 
set_do_mid_side_stereo(bool value)115 		bool Stream::set_do_mid_side_stereo(bool value)
116 		{
117 			FLAC__ASSERT(is_valid());
118 			return (bool)::FLAC__stream_encoder_set_do_mid_side_stereo(encoder_, value);
119 		}
120 
set_loose_mid_side_stereo(bool value)121 		bool Stream::set_loose_mid_side_stereo(bool value)
122 		{
123 			FLAC__ASSERT(is_valid());
124 			return (bool)::FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_, value);
125 		}
126 
set_apodization(const char * specification)127 		bool Stream::set_apodization(const char *specification)
128 		{
129 			FLAC__ASSERT(is_valid());
130 			return (bool)::FLAC__stream_encoder_set_apodization(encoder_, specification);
131 		}
132 
set_max_lpc_order(unsigned value)133 		bool Stream::set_max_lpc_order(unsigned value)
134 		{
135 			FLAC__ASSERT(is_valid());
136 			return (bool)::FLAC__stream_encoder_set_max_lpc_order(encoder_, value);
137 		}
138 
set_qlp_coeff_precision(unsigned value)139 		bool Stream::set_qlp_coeff_precision(unsigned value)
140 		{
141 			FLAC__ASSERT(is_valid());
142 			return (bool)::FLAC__stream_encoder_set_qlp_coeff_precision(encoder_, value);
143 		}
144 
set_do_qlp_coeff_prec_search(bool value)145 		bool Stream::set_do_qlp_coeff_prec_search(bool value)
146 		{
147 			FLAC__ASSERT(is_valid());
148 			return (bool)::FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_, value);
149 		}
150 
set_do_escape_coding(bool value)151 		bool Stream::set_do_escape_coding(bool value)
152 		{
153 			FLAC__ASSERT(is_valid());
154 			return (bool)::FLAC__stream_encoder_set_do_escape_coding(encoder_, value);
155 		}
156 
set_do_exhaustive_model_search(bool value)157 		bool Stream::set_do_exhaustive_model_search(bool value)
158 		{
159 			FLAC__ASSERT(is_valid());
160 			return (bool)::FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_, value);
161 		}
162 
set_min_residual_partition_order(unsigned value)163 		bool Stream::set_min_residual_partition_order(unsigned value)
164 		{
165 			FLAC__ASSERT(is_valid());
166 			return (bool)::FLAC__stream_encoder_set_min_residual_partition_order(encoder_, value);
167 		}
168 
set_max_residual_partition_order(unsigned value)169 		bool Stream::set_max_residual_partition_order(unsigned value)
170 		{
171 			FLAC__ASSERT(is_valid());
172 			return (bool)::FLAC__stream_encoder_set_max_residual_partition_order(encoder_, value);
173 		}
174 
set_rice_parameter_search_dist(unsigned value)175 		bool Stream::set_rice_parameter_search_dist(unsigned value)
176 		{
177 			FLAC__ASSERT(is_valid());
178 			return (bool)::FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_, value);
179 		}
180 
set_total_samples_estimate(FLAC__uint64 value)181 		bool Stream::set_total_samples_estimate(FLAC__uint64 value)
182 		{
183 			FLAC__ASSERT(is_valid());
184 			return (bool)::FLAC__stream_encoder_set_total_samples_estimate(encoder_, value);
185 		}
186 
set_metadata(::FLAC__StreamMetadata ** metadata,unsigned num_blocks)187 		bool Stream::set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks)
188 		{
189 			FLAC__ASSERT(is_valid());
190 			return (bool)::FLAC__stream_encoder_set_metadata(encoder_, metadata, num_blocks);
191 		}
192 
set_metadata(FLAC::Metadata::Prototype ** metadata,unsigned num_blocks)193 		bool Stream::set_metadata(FLAC::Metadata::Prototype **metadata, unsigned num_blocks)
194 		{
195 			FLAC__ASSERT(is_valid());
196 #if (defined _MSC_VER) || (defined __BORLANDC__) || (defined __SUNPRO_CC)
197 			// MSVC++ can't handle:
198 			// ::FLAC__StreamMetadata *m[num_blocks];
199 			// so we do this ugly workaround
200 			::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
201 #else
202 			::FLAC__StreamMetadata *m[num_blocks];
203 #endif
204 			for(unsigned 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*>((const ::FLAC__StreamMetadata*)metadata[i]);
207 			}
208 #if (defined _MSC_VER) || (defined __BORLANDC__) || (defined __SUNPRO_CC)
209 			// complete the hack
210 			const bool ok = (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
211 			delete [] m;
212 			return ok;
213 #else
214 			return (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
215 #endif
216 		}
217 
get_state() const218 		Stream::State Stream::get_state() const
219 		{
220 			FLAC__ASSERT(is_valid());
221 			return State(::FLAC__stream_encoder_get_state(encoder_));
222 		}
223 
get_verify_decoder_state() const224 		Decoder::Stream::State Stream::get_verify_decoder_state() const
225 		{
226 			FLAC__ASSERT(is_valid());
227 			return Decoder::Stream::State(::FLAC__stream_encoder_get_verify_decoder_state(encoder_));
228 		}
229 
get_verify_decoder_error_stats(FLAC__uint64 * absolute_sample,unsigned * frame_number,unsigned * channel,unsigned * sample,FLAC__int32 * expected,FLAC__int32 * got)230 		void Stream::get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
231 		{
232 			FLAC__ASSERT(is_valid());
233 			::FLAC__stream_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
234 		}
235 
get_verify() const236 		bool Stream::get_verify() const
237 		{
238 			FLAC__ASSERT(is_valid());
239 			return (bool)::FLAC__stream_encoder_get_verify(encoder_);
240 		}
241 
get_streamable_subset() const242 		bool Stream::get_streamable_subset() const
243 		{
244 			FLAC__ASSERT(is_valid());
245 			return (bool)::FLAC__stream_encoder_get_streamable_subset(encoder_);
246 		}
247 
get_do_mid_side_stereo() const248 		bool Stream::get_do_mid_side_stereo() const
249 		{
250 			FLAC__ASSERT(is_valid());
251 			return (bool)::FLAC__stream_encoder_get_do_mid_side_stereo(encoder_);
252 		}
253 
get_loose_mid_side_stereo() const254 		bool Stream::get_loose_mid_side_stereo() const
255 		{
256 			FLAC__ASSERT(is_valid());
257 			return (bool)::FLAC__stream_encoder_get_loose_mid_side_stereo(encoder_);
258 		}
259 
get_channels() const260 		unsigned Stream::get_channels() const
261 		{
262 			FLAC__ASSERT(is_valid());
263 			return ::FLAC__stream_encoder_get_channels(encoder_);
264 		}
265 
get_bits_per_sample() const266 		unsigned Stream::get_bits_per_sample() const
267 		{
268 			FLAC__ASSERT(is_valid());
269 			return ::FLAC__stream_encoder_get_bits_per_sample(encoder_);
270 		}
271 
get_sample_rate() const272 		unsigned Stream::get_sample_rate() const
273 		{
274 			FLAC__ASSERT(is_valid());
275 			return ::FLAC__stream_encoder_get_sample_rate(encoder_);
276 		}
277 
get_blocksize() const278 		unsigned Stream::get_blocksize() const
279 		{
280 			FLAC__ASSERT(is_valid());
281 			return ::FLAC__stream_encoder_get_blocksize(encoder_);
282 		}
283 
get_max_lpc_order() const284 		unsigned Stream::get_max_lpc_order() const
285 		{
286 			FLAC__ASSERT(is_valid());
287 			return ::FLAC__stream_encoder_get_max_lpc_order(encoder_);
288 		}
289 
get_qlp_coeff_precision() const290 		unsigned Stream::get_qlp_coeff_precision() const
291 		{
292 			FLAC__ASSERT(is_valid());
293 			return ::FLAC__stream_encoder_get_qlp_coeff_precision(encoder_);
294 		}
295 
get_do_qlp_coeff_prec_search() const296 		bool Stream::get_do_qlp_coeff_prec_search() const
297 		{
298 			FLAC__ASSERT(is_valid());
299 			return (bool)::FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder_);
300 		}
301 
get_do_escape_coding() const302 		bool Stream::get_do_escape_coding() const
303 		{
304 			FLAC__ASSERT(is_valid());
305 			return (bool)::FLAC__stream_encoder_get_do_escape_coding(encoder_);
306 		}
307 
get_do_exhaustive_model_search() const308 		bool Stream::get_do_exhaustive_model_search() const
309 		{
310 			FLAC__ASSERT(is_valid());
311 			return (bool)::FLAC__stream_encoder_get_do_exhaustive_model_search(encoder_);
312 		}
313 
get_min_residual_partition_order() const314 		unsigned Stream::get_min_residual_partition_order() const
315 		{
316 			FLAC__ASSERT(is_valid());
317 			return ::FLAC__stream_encoder_get_min_residual_partition_order(encoder_);
318 		}
319 
get_max_residual_partition_order() const320 		unsigned Stream::get_max_residual_partition_order() const
321 		{
322 			FLAC__ASSERT(is_valid());
323 			return ::FLAC__stream_encoder_get_max_residual_partition_order(encoder_);
324 		}
325 
get_rice_parameter_search_dist() const326 		unsigned Stream::get_rice_parameter_search_dist() const
327 		{
328 			FLAC__ASSERT(is_valid());
329 			return ::FLAC__stream_encoder_get_rice_parameter_search_dist(encoder_);
330 		}
331 
get_total_samples_estimate() const332 		FLAC__uint64 Stream::get_total_samples_estimate() const
333 		{
334 			FLAC__ASSERT(is_valid());
335 			return ::FLAC__stream_encoder_get_total_samples_estimate(encoder_);
336 		}
337 
init()338 		::FLAC__StreamEncoderInitStatus Stream::init()
339 		{
340 			FLAC__ASSERT(is_valid());
341 			return ::FLAC__stream_encoder_init_stream(encoder_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
342 		}
343 
init_ogg()344 		::FLAC__StreamEncoderInitStatus Stream::init_ogg()
345 		{
346 			FLAC__ASSERT(is_valid());
347 			return ::FLAC__stream_encoder_init_ogg_stream(encoder_, read_callback_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
348 		}
349 
finish()350 		bool Stream::finish()
351 		{
352 			FLAC__ASSERT(is_valid());
353 			return (bool)::FLAC__stream_encoder_finish(encoder_);
354 		}
355 
process(const FLAC__int32 * const buffer[],unsigned samples)356 		bool Stream::process(const FLAC__int32 * const buffer[], unsigned samples)
357 		{
358 			FLAC__ASSERT(is_valid());
359 			return (bool)::FLAC__stream_encoder_process(encoder_, buffer, samples);
360 		}
361 
process_interleaved(const FLAC__int32 buffer[],unsigned samples)362 		bool Stream::process_interleaved(const FLAC__int32 buffer[], unsigned samples)
363 		{
364 			FLAC__ASSERT(is_valid());
365 			return (bool)::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples);
366 		}
367 
read_callback(FLAC__byte buffer[],size_t * bytes)368 		::FLAC__StreamEncoderReadStatus Stream::read_callback(FLAC__byte buffer[], size_t *bytes)
369 		{
370 			(void)buffer, (void)bytes;
371 			return ::FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED;
372 		}
373 
seek_callback(FLAC__uint64 absolute_byte_offset)374 		::FLAC__StreamEncoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
375 		{
376 			(void)absolute_byte_offset;
377 			return ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
378 		}
379 
tell_callback(FLAC__uint64 * absolute_byte_offset)380 		::FLAC__StreamEncoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
381 		{
382 			(void)absolute_byte_offset;
383 			return ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
384 		}
385 
metadata_callback(const::FLAC__StreamMetadata * metadata)386 		void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
387 		{
388 			(void)metadata;
389 		}
390 
read_callback_(const::FLAC__StreamEncoder * encoder,FLAC__byte buffer[],size_t * bytes,void * client_data)391 		::FLAC__StreamEncoderReadStatus Stream::read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
392 		{
393 			(void)encoder;
394 			FLAC__ASSERT(0 != client_data);
395 			Stream *instance = reinterpret_cast<Stream *>(client_data);
396 			FLAC__ASSERT(0 != instance);
397 			return instance->read_callback(buffer, bytes);
398 		}
399 
write_callback_(const::FLAC__StreamEncoder * encoder,const FLAC__byte buffer[],size_t bytes,unsigned samples,unsigned current_frame,void * client_data)400 		::FLAC__StreamEncoderWriteStatus Stream::write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
401 		{
402 			(void)encoder;
403 			FLAC__ASSERT(0 != client_data);
404 			Stream *instance = reinterpret_cast<Stream *>(client_data);
405 			FLAC__ASSERT(0 != instance);
406 			return instance->write_callback(buffer, bytes, samples, current_frame);
407 		}
408 
seek_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 absolute_byte_offset,void * client_data)409 		::FLAC__StreamEncoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
410 		{
411 			(void)encoder;
412 			FLAC__ASSERT(0 != client_data);
413 			Stream *instance = reinterpret_cast<Stream *>(client_data);
414 			FLAC__ASSERT(0 != instance);
415 			return instance->seek_callback(absolute_byte_offset);
416 		}
417 
tell_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 * absolute_byte_offset,void * client_data)418 		::FLAC__StreamEncoderTellStatus Stream::tell_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
419 		{
420 			(void)encoder;
421 			FLAC__ASSERT(0 != client_data);
422 			Stream *instance = reinterpret_cast<Stream *>(client_data);
423 			FLAC__ASSERT(0 != instance);
424 			return instance->tell_callback(absolute_byte_offset);
425 		}
426 
metadata_callback_(const::FLAC__StreamEncoder * encoder,const::FLAC__StreamMetadata * metadata,void * client_data)427 		void Stream::metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
428 		{
429 			(void)encoder;
430 			FLAC__ASSERT(0 != client_data);
431 			Stream *instance = reinterpret_cast<Stream *>(client_data);
432 			FLAC__ASSERT(0 != instance);
433 			instance->metadata_callback(metadata);
434 		}
435 
436 		// ------------------------------------------------------------
437 		//
438 		// File
439 		//
440 		// ------------------------------------------------------------
441 
File()442 		File::File():
443 			Stream()
444 		{ }
445 
~File()446 		File::~File()
447 		{
448 		}
449 
init(FILE * file)450 		::FLAC__StreamEncoderInitStatus File::init(FILE *file)
451 		{
452 			FLAC__ASSERT(is_valid());
453 			return ::FLAC__stream_encoder_init_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
454 		}
455 
init(const char * filename)456 		::FLAC__StreamEncoderInitStatus File::init(const char *filename)
457 		{
458 			FLAC__ASSERT(is_valid());
459 			return ::FLAC__stream_encoder_init_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
460 		}
461 
init(const std::string & filename)462 		::FLAC__StreamEncoderInitStatus File::init(const std::string &filename)
463 		{
464 			return init(filename.c_str());
465 		}
466 
init_ogg(FILE * file)467 		::FLAC__StreamEncoderInitStatus File::init_ogg(FILE *file)
468 		{
469 			FLAC__ASSERT(is_valid());
470 			return ::FLAC__stream_encoder_init_ogg_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
471 		}
472 
init_ogg(const char * filename)473 		::FLAC__StreamEncoderInitStatus File::init_ogg(const char *filename)
474 		{
475 			FLAC__ASSERT(is_valid());
476 			return ::FLAC__stream_encoder_init_ogg_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
477 		}
478 
init_ogg(const std::string & filename)479 		::FLAC__StreamEncoderInitStatus File::init_ogg(const std::string &filename)
480 		{
481 			return init_ogg(filename.c_str());
482 		}
483 
484 		// This is a dummy to satisfy the pure virtual from Stream; the
485 		// read callback will never be called since we are initializing
486 		// with FLAC__stream_decoder_init_FILE() or
487 		// FLAC__stream_decoder_init_file() and those supply the read
488 		// callback internally.
write_callback(const FLAC__byte buffer[],size_t bytes,unsigned samples,unsigned current_frame)489 		::FLAC__StreamEncoderWriteStatus File::write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame)
490 		{
491 			(void)buffer, (void)bytes, (void)samples, (void)current_frame;
492 			FLAC__ASSERT(false);
493 			return ::FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; // double protection
494 		}
495 
progress_callback(FLAC__uint64 bytes_written,FLAC__uint64 samples_written,unsigned frames_written,unsigned total_frames_estimate)496 		void File::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate)
497 		{
498 			(void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
499 		}
500 
progress_callback_(const::FLAC__StreamEncoder * encoder,FLAC__uint64 bytes_written,FLAC__uint64 samples_written,unsigned frames_written,unsigned total_frames_estimate,void * client_data)501 		void File::progress_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
502 		{
503 			(void)encoder;
504 			FLAC__ASSERT(0 != client_data);
505 			File *instance = reinterpret_cast<File *>(client_data);
506 			FLAC__ASSERT(0 != instance);
507 			instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate);
508 		}
509 
510 	}
511 }
512