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