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