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 #ifndef FLACPP__ENCODER_H 34*600f14f4SXin Li #define FLACPP__ENCODER_H 35*600f14f4SXin Li 36*600f14f4SXin Li #include "export.h" 37*600f14f4SXin Li 38*600f14f4SXin Li #include "FLAC/stream_encoder.h" 39*600f14f4SXin Li #include "decoder.h" 40*600f14f4SXin Li #include "metadata.h" 41*600f14f4SXin Li 42*600f14f4SXin Li 43*600f14f4SXin Li /** \file include/FLAC++/encoder.h 44*600f14f4SXin Li * 45*600f14f4SXin Li * \brief 46*600f14f4SXin Li * This module contains the classes which implement the various 47*600f14f4SXin Li * encoders. 48*600f14f4SXin Li * 49*600f14f4SXin Li * See the detailed documentation in the 50*600f14f4SXin Li * \link flacpp_encoder encoder \endlink module. 51*600f14f4SXin Li */ 52*600f14f4SXin Li 53*600f14f4SXin Li /** \defgroup flacpp_encoder FLAC++/encoder.h: encoder classes 54*600f14f4SXin Li * \ingroup flacpp 55*600f14f4SXin Li * 56*600f14f4SXin Li * \brief 57*600f14f4SXin Li * This module describes the encoder layers provided by libFLAC++. 58*600f14f4SXin Li * 59*600f14f4SXin Li * The libFLAC++ encoder classes are object wrappers around their 60*600f14f4SXin Li * counterparts in libFLAC. All encoding layers available in 61*600f14f4SXin Li * libFLAC are also provided here. The interface is very similar; 62*600f14f4SXin Li * make sure to read the \link flac_encoder libFLAC encoder module \endlink. 63*600f14f4SXin Li * 64*600f14f4SXin Li * There are only two significant differences here. First, instead of 65*600f14f4SXin Li * passing in C function pointers for callbacks, you inherit from the 66*600f14f4SXin Li * encoder class and provide implementations for the callbacks in your 67*600f14f4SXin Li * derived class; because of this there is no need for a 'client_data' 68*600f14f4SXin Li * property. 69*600f14f4SXin Li * 70*600f14f4SXin Li * Second, there are two stream encoder classes. FLAC::Encoder::Stream 71*600f14f4SXin Li * is used for the same cases that FLAC__stream_encoder_init_stream() / 72*600f14f4SXin Li * FLAC__stream_encoder_init_ogg_stream() are used, and FLAC::Encoder::File 73*600f14f4SXin Li * is used for the same cases that 74*600f14f4SXin Li * FLAC__stream_encoder_init_FILE() and FLAC__stream_encoder_init_file() / 75*600f14f4SXin Li * FLAC__stream_encoder_init_ogg_FILE() and FLAC__stream_encoder_init_ogg_file() 76*600f14f4SXin Li * are used. 77*600f14f4SXin Li */ 78*600f14f4SXin Li 79*600f14f4SXin Li namespace FLAC { 80*600f14f4SXin Li namespace Encoder { 81*600f14f4SXin Li 82*600f14f4SXin Li /** \ingroup flacpp_encoder 83*600f14f4SXin Li * \brief 84*600f14f4SXin Li * This class wraps the ::FLAC__StreamEncoder. If you are 85*600f14f4SXin Li * encoding to a file, FLAC::Encoder::File may be more 86*600f14f4SXin Li * convenient. 87*600f14f4SXin Li * 88*600f14f4SXin Li * The usage of this class is similar to FLAC__StreamEncoder, 89*600f14f4SXin Li * except instead of providing callbacks to 90*600f14f4SXin Li * FLAC__stream_encoder_init*_stream(), you will inherit from this 91*600f14f4SXin Li * class and override the virtual callback functions with your 92*600f14f4SXin Li * own implementations, then call init() or init_ogg(). The rest of 93*600f14f4SXin Li * the calls work the same as in the C layer. 94*600f14f4SXin Li * 95*600f14f4SXin Li * Only the write callback is mandatory. The others are 96*600f14f4SXin Li * optional; this class provides default implementations that do 97*600f14f4SXin Li * nothing. In order for some STREAMINFO and SEEKTABLE data to 98*600f14f4SXin Li * be written properly, you must override seek_callback() and 99*600f14f4SXin Li * tell_callback(); see FLAC__stream_encoder_init_stream() as to 100*600f14f4SXin Li * why. 101*600f14f4SXin Li */ 102*600f14f4SXin Li class FLACPP_API Stream { 103*600f14f4SXin Li public: 104*600f14f4SXin Li /** This class is a wrapper around FLAC__StreamEncoderState. 105*600f14f4SXin Li */ 106*600f14f4SXin Li class FLACPP_API State { 107*600f14f4SXin Li public: State(::FLAC__StreamEncoderState state)108*600f14f4SXin Li inline State(::FLAC__StreamEncoderState state): state_(state) { } FLAC__StreamEncoderState()109*600f14f4SXin Li inline operator ::FLAC__StreamEncoderState() const { return state_; } as_cstring()110*600f14f4SXin Li inline const char *as_cstring() const { return ::FLAC__StreamEncoderStateString[state_]; } resolved_as_cstring(const Stream & encoder)111*600f14f4SXin Li inline const char *resolved_as_cstring(const Stream &encoder) const { return ::FLAC__stream_encoder_get_resolved_state_string(encoder.encoder_); } 112*600f14f4SXin Li protected: 113*600f14f4SXin Li ::FLAC__StreamEncoderState state_; 114*600f14f4SXin Li }; 115*600f14f4SXin Li 116*600f14f4SXin Li Stream(); 117*600f14f4SXin Li virtual ~Stream(); 118*600f14f4SXin Li 119*600f14f4SXin Li //@{ 120*600f14f4SXin Li /** Call after construction to check that the object was created 121*600f14f4SXin Li * successfully. If not, use get_state() to find out why not. 122*600f14f4SXin Li * 123*600f14f4SXin Li */ 124*600f14f4SXin Li virtual bool is_valid() const; 125*600f14f4SXin Li inline operator bool() const { return is_valid(); } ///< See is_valid() 126*600f14f4SXin Li //@} 127*600f14f4SXin Li 128*600f14f4SXin Li virtual bool set_ogg_serial_number(long value); ///< See FLAC__stream_encoder_set_ogg_serial_number() 129*600f14f4SXin Li virtual bool set_verify(bool value); ///< See FLAC__stream_encoder_set_verify() 130*600f14f4SXin Li virtual bool set_streamable_subset(bool value); ///< See FLAC__stream_encoder_set_streamable_subset() 131*600f14f4SXin Li virtual bool set_channels(uint32_t value); ///< See FLAC__stream_encoder_set_channels() 132*600f14f4SXin Li virtual bool set_bits_per_sample(uint32_t value); ///< See FLAC__stream_encoder_set_bits_per_sample() 133*600f14f4SXin Li virtual bool set_sample_rate(uint32_t value); ///< See FLAC__stream_encoder_set_sample_rate() 134*600f14f4SXin Li virtual bool set_compression_level(uint32_t value); ///< See FLAC__stream_encoder_set_compression_level() 135*600f14f4SXin Li virtual bool set_blocksize(uint32_t value); ///< See FLAC__stream_encoder_set_blocksize() 136*600f14f4SXin Li virtual bool set_do_mid_side_stereo(bool value); ///< See FLAC__stream_encoder_set_do_mid_side_stereo() 137*600f14f4SXin Li virtual bool set_loose_mid_side_stereo(bool value); ///< See FLAC__stream_encoder_set_loose_mid_side_stereo() 138*600f14f4SXin Li virtual bool set_apodization(const char *specification); ///< See FLAC__stream_encoder_set_apodization() 139*600f14f4SXin Li virtual bool set_max_lpc_order(uint32_t value); ///< See FLAC__stream_encoder_set_max_lpc_order() 140*600f14f4SXin Li virtual bool set_qlp_coeff_precision(uint32_t value); ///< See FLAC__stream_encoder_set_qlp_coeff_precision() 141*600f14f4SXin Li virtual bool set_do_qlp_coeff_prec_search(bool value); ///< See FLAC__stream_encoder_set_do_qlp_coeff_prec_search() 142*600f14f4SXin Li virtual bool set_do_escape_coding(bool value); ///< See FLAC__stream_encoder_set_do_escape_coding() 143*600f14f4SXin Li virtual bool set_do_exhaustive_model_search(bool value); ///< See FLAC__stream_encoder_set_do_exhaustive_model_search() 144*600f14f4SXin Li virtual bool set_min_residual_partition_order(uint32_t value); ///< See FLAC__stream_encoder_set_min_residual_partition_order() 145*600f14f4SXin Li virtual bool set_max_residual_partition_order(uint32_t value); ///< See FLAC__stream_encoder_set_max_residual_partition_order() 146*600f14f4SXin Li virtual bool set_rice_parameter_search_dist(uint32_t value); ///< See FLAC__stream_encoder_set_rice_parameter_search_dist() 147*600f14f4SXin Li virtual bool set_total_samples_estimate(FLAC__uint64 value); ///< See FLAC__stream_encoder_set_total_samples_estimate() 148*600f14f4SXin Li virtual bool set_metadata(::FLAC__StreamMetadata **metadata, uint32_t num_blocks); ///< See FLAC__stream_encoder_set_metadata() 149*600f14f4SXin Li virtual bool set_metadata(FLAC::Metadata::Prototype **metadata, uint32_t num_blocks); ///< See FLAC__stream_encoder_set_metadata() 150*600f14f4SXin Li virtual bool set_limit_min_bitrate(bool value); ///< See FLAC__stream_encoder_set_limit_min_bitrate() 151*600f14f4SXin Li 152*600f14f4SXin Li /* get_state() is not virtual since we want subclasses to be able to return their own state */ 153*600f14f4SXin Li State get_state() const; ///< See FLAC__stream_encoder_get_state() 154*600f14f4SXin Li virtual Decoder::Stream::State get_verify_decoder_state() const; ///< See FLAC__stream_encoder_get_verify_decoder_state() 155*600f14f4SXin Li virtual void 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); ///< See FLAC__stream_encoder_get_verify_decoder_error_stats() 156*600f14f4SXin Li virtual bool get_verify() const; ///< See FLAC__stream_encoder_get_verify() 157*600f14f4SXin Li virtual bool get_streamable_subset() const; ///< See FLAC__stream_encoder_get_streamable_subset() 158*600f14f4SXin Li virtual bool get_do_mid_side_stereo() const; ///< See FLAC__stream_encoder_get_do_mid_side_stereo() 159*600f14f4SXin Li virtual bool get_loose_mid_side_stereo() const; ///< See FLAC__stream_encoder_get_loose_mid_side_stereo() 160*600f14f4SXin Li virtual uint32_t get_channels() const; ///< See FLAC__stream_encoder_get_channels() 161*600f14f4SXin Li virtual uint32_t get_bits_per_sample() const; ///< See FLAC__stream_encoder_get_bits_per_sample() 162*600f14f4SXin Li virtual uint32_t get_sample_rate() const; ///< See FLAC__stream_encoder_get_sample_rate() 163*600f14f4SXin Li virtual uint32_t get_blocksize() const; ///< See FLAC__stream_encoder_get_blocksize() 164*600f14f4SXin Li virtual uint32_t get_max_lpc_order() const; ///< See FLAC__stream_encoder_get_max_lpc_order() 165*600f14f4SXin Li virtual uint32_t get_qlp_coeff_precision() const; ///< See FLAC__stream_encoder_get_qlp_coeff_precision() 166*600f14f4SXin Li virtual bool get_do_qlp_coeff_prec_search() const; ///< See FLAC__stream_encoder_get_do_qlp_coeff_prec_search() 167*600f14f4SXin Li virtual bool get_do_escape_coding() const; ///< See FLAC__stream_encoder_get_do_escape_coding() 168*600f14f4SXin Li virtual bool get_do_exhaustive_model_search() const; ///< See FLAC__stream_encoder_get_do_exhaustive_model_search() 169*600f14f4SXin Li virtual uint32_t get_min_residual_partition_order() const; ///< See FLAC__stream_encoder_get_min_residual_partition_order() 170*600f14f4SXin Li virtual uint32_t get_max_residual_partition_order() const; ///< See FLAC__stream_encoder_get_max_residual_partition_order() 171*600f14f4SXin Li virtual uint32_t get_rice_parameter_search_dist() const; ///< See FLAC__stream_encoder_get_rice_parameter_search_dist() 172*600f14f4SXin Li virtual FLAC__uint64 get_total_samples_estimate() const; ///< See FLAC__stream_encoder_get_total_samples_estimate() 173*600f14f4SXin Li virtual bool get_limit_min_bitrate() const; ///< See FLAC__stream_encoder_get_limit_min_bitrate() 174*600f14f4SXin Li 175*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init(); ///< See FLAC__stream_encoder_init_stream() 176*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init_ogg(); ///< See FLAC__stream_encoder_init_ogg_stream() 177*600f14f4SXin Li 178*600f14f4SXin Li virtual bool finish(); ///< See FLAC__stream_encoder_finish() 179*600f14f4SXin Li 180*600f14f4SXin Li virtual bool process(const FLAC__int32 * const buffer[], uint32_t samples); ///< See FLAC__stream_encoder_process() 181*600f14f4SXin Li virtual bool process_interleaved(const FLAC__int32 buffer[], uint32_t samples); ///< See FLAC__stream_encoder_process_interleaved() 182*600f14f4SXin Li protected: 183*600f14f4SXin Li /// See FLAC__StreamEncoderReadCallback 184*600f14f4SXin Li virtual ::FLAC__StreamEncoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); 185*600f14f4SXin Li 186*600f14f4SXin Li /// See FLAC__StreamEncoderWriteCallback 187*600f14f4SXin Li virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame) = 0; 188*600f14f4SXin Li 189*600f14f4SXin Li /// See FLAC__StreamEncoderSeekCallback 190*600f14f4SXin Li virtual ::FLAC__StreamEncoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); 191*600f14f4SXin Li 192*600f14f4SXin Li /// See FLAC__StreamEncoderTellCallback 193*600f14f4SXin Li virtual ::FLAC__StreamEncoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); 194*600f14f4SXin Li 195*600f14f4SXin Li /// See FLAC__StreamEncoderMetadataCallback 196*600f14f4SXin Li virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata); 197*600f14f4SXin Li 198*600f14f4SXin Li #if (defined __BORLANDC__) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96))) || (defined __SUNPRO_CC) 199*600f14f4SXin Li // lame hack: some compilers can't see a protected encoder_ from nested State::resolved_as_cstring() 200*600f14f4SXin Li friend State; 201*600f14f4SXin Li #endif 202*600f14f4SXin Li ::FLAC__StreamEncoder *encoder_; 203*600f14f4SXin Li 204*600f14f4SXin Li static ::FLAC__StreamEncoderReadStatus read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); 205*600f14f4SXin Li static ::FLAC__StreamEncoderWriteStatus write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data); 206*600f14f4SXin Li static ::FLAC__StreamEncoderSeekStatus seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); 207*600f14f4SXin Li static ::FLAC__StreamEncoderTellStatus tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); 208*600f14f4SXin Li static void metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data); 209*600f14f4SXin Li private: 210*600f14f4SXin Li // Private and undefined so you can't use them: 211*600f14f4SXin Li Stream(const Stream &); 212*600f14f4SXin Li void operator=(const Stream &); 213*600f14f4SXin Li }; 214*600f14f4SXin Li 215*600f14f4SXin Li /** \ingroup flacpp_encoder 216*600f14f4SXin Li * \brief 217*600f14f4SXin Li * This class wraps the ::FLAC__StreamEncoder. If you are 218*600f14f4SXin Li * not encoding to a file, you may need to use 219*600f14f4SXin Li * FLAC::Encoder::Stream. 220*600f14f4SXin Li * 221*600f14f4SXin Li * The usage of this class is similar to FLAC__StreamEncoder, 222*600f14f4SXin Li * except instead of providing callbacks to 223*600f14f4SXin Li * FLAC__stream_encoder_init*_FILE() or 224*600f14f4SXin Li * FLAC__stream_encoder_init*_file(), you will inherit from this 225*600f14f4SXin Li * class and override the virtual callback functions with your 226*600f14f4SXin Li * own implementations, then call init() or init_ogg(). The rest 227*600f14f4SXin Li * of the calls work the same as in the C layer. 228*600f14f4SXin Li * 229*600f14f4SXin Li * There are no mandatory callbacks; all the callbacks from 230*600f14f4SXin Li * FLAC::Encoder::Stream are implemented here fully and support 231*600f14f4SXin Li * full post-encode STREAMINFO and SEEKTABLE updating. There is 232*600f14f4SXin Li * only an optional progress callback which you may override to 233*600f14f4SXin Li * get periodic reports on the progress of the encode. 234*600f14f4SXin Li */ 235*600f14f4SXin Li class FLACPP_API File: public Stream { 236*600f14f4SXin Li public: 237*600f14f4SXin Li File(); 238*600f14f4SXin Li virtual ~File(); 239*600f14f4SXin Li 240*600f14f4SXin Li using Stream::init; 241*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init(FILE *file); ///< See FLAC__stream_encoder_init_FILE() 242*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init(const char *filename); ///< See FLAC__stream_encoder_init_file() 243*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init(const std::string &filename); ///< See FLAC__stream_encoder_init_file() 244*600f14f4SXin Li using Stream::init_ogg; 245*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init_ogg(FILE *file); ///< See FLAC__stream_encoder_init_ogg_FILE() 246*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init_ogg(const char *filename); ///< See FLAC__stream_encoder_init_ogg_file() 247*600f14f4SXin Li virtual ::FLAC__StreamEncoderInitStatus init_ogg(const std::string &filename); ///< See FLAC__stream_encoder_init_ogg_file() 248*600f14f4SXin Li protected: 249*600f14f4SXin Li /// See FLAC__StreamEncoderProgressCallback 250*600f14f4SXin Li virtual void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, uint32_t frames_written, uint32_t total_frames_estimate); 251*600f14f4SXin Li 252*600f14f4SXin Li /// This is a dummy implementation to satisfy the pure virtual in Stream that is actually supplied internally by the C layer 253*600f14f4SXin Li virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame); 254*600f14f4SXin Li private: 255*600f14f4SXin Li static void 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); 256*600f14f4SXin Li 257*600f14f4SXin Li // Private and undefined so you can't use them: 258*600f14f4SXin Li File(const Stream &); 259*600f14f4SXin Li void operator=(const Stream &); 260*600f14f4SXin Li }; 261*600f14f4SXin Li 262*600f14f4SXin Li } 263*600f14f4SXin Li } 264*600f14f4SXin Li 265*600f14f4SXin Li #endif 266