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