encoder.h 16.1 KB
Newer Older
Josh Coalson's avatar
Josh Coalson committed
1
/* libOggFLAC++ - Free Lossless Audio Codec + Ogg library
Josh Coalson's avatar
Josh Coalson committed
2
 * Copyright (C) 2002,2003,2004,2005  Josh Coalson
Josh Coalson's avatar
Josh Coalson committed
3
 *
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the Xiph.org Foundation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Josh Coalson's avatar
Josh Coalson committed
30
31
32
33
34
 */

#ifndef OggFLACPP__ENCODER_H
#define OggFLACPP__ENCODER_H

35
36
#include "export.h"

37
38
#include "OggFLAC/file_encoder.h"
#include "OggFLAC/seekable_stream_encoder.h"
Josh Coalson's avatar
Josh Coalson committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "OggFLAC/stream_encoder.h"
#include "decoder.h"
// we only need these for the state abstractions really...
#include "FLAC++/decoder.h"
#include "FLAC++/encoder.h"


/** \file include/OggFLAC++/encoder.h
 *
 *  \brief
 *  This module contains the classes which implement the various
 *  encoders.
 *
 *  See the detailed documentation in the
 *  \link oggflacpp_encoder encoder \endlink module.
 */

/** \defgroup oggflacpp_encoder OggFLAC++/encoder.h: encoder classes
 *  \ingroup oggflacpp
 *
 *  \brief
60
 *  This module describes the three encoder layers provided by libOggFLAC++.
Josh Coalson's avatar
Josh Coalson committed
61
62
 *
 * The libOggFLAC++ encoder classes are object wrappers around their
63
64
 * counterparts in libOggFLAC.  All three encoding layers available in
 * libOggFLAC are also provided here.  The interface is very similar;
Josh Coalson's avatar
Josh Coalson committed
65
 * make sure to read the \link oggflac_encoder libOggFLAC encoder module \endlink.
Josh Coalson's avatar
Josh Coalson committed
66
 *
Josh Coalson's avatar
Josh Coalson committed
67
68
69
70
 * The only real difference here is that instead of passing in C function
 * pointers for callbacks, you inherit from the encoder class and provide
 * implementations for the callbacks in the derived class; because of this
 * there is no need for a 'client_data' property.
Josh Coalson's avatar
Josh Coalson committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 */

namespace OggFLAC {
	namespace Encoder {

		// ============================================================
		//
		//  Equivalent: OggFLAC__StreamEncoder
		//
		// ============================================================

		/** \defgroup oggflacpp_stream_encoder OggFLAC++/encoder.h: stream encoder class
		 *  \ingroup oggflacpp_encoder
		 *
		 *  \brief
Josh Coalson's avatar
Josh Coalson committed
86
87
88
		 *  This class wraps the ::OggFLAC__StreamEncoder.
		 *
		 * See the \link oggflac_stream_encoder libOggFLAC stream encoder module \endlink.
Josh Coalson's avatar
Josh Coalson committed
89
90
91
92
		 *
		 * \{
		 */

Josh Coalson's avatar
Josh Coalson committed
93
		/** This class wraps the ::OggFLAC__StreamEncoder.
Josh Coalson's avatar
Josh Coalson committed
94
		 */
95
		class OggFLACPP_API Stream {
Josh Coalson's avatar
Josh Coalson committed
96
		public:
97
			class OggFLACPP_API State {
Josh Coalson's avatar
Josh Coalson committed
98
99
100
101
			public:
				inline State(::OggFLAC__StreamEncoderState state): state_(state) { }
				inline operator ::OggFLAC__StreamEncoderState() const { return state_; }
				inline const char *as_cstring() const { return ::OggFLAC__StreamEncoderStateString[state_]; }
102
				inline const char *resolved_as_cstring(const Stream &encoder) const { return ::OggFLAC__stream_encoder_get_resolved_state_string(encoder.encoder_); }
Josh Coalson's avatar
Josh Coalson committed
103
104
105
106
107
108
109
110
111
112
			protected:
				::OggFLAC__StreamEncoderState state_;
			};

			Stream();
			virtual ~Stream();

			bool is_valid() const;
			inline operator bool() const { return is_valid(); }

113
			bool set_serial_number(long value);
Josh Coalson's avatar
Josh Coalson committed
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
			bool set_verify(bool value);
			bool set_streamable_subset(bool value);
			bool set_do_mid_side_stereo(bool value);
			bool set_loose_mid_side_stereo(bool value);
			bool set_channels(unsigned value);
			bool set_bits_per_sample(unsigned value);
			bool set_sample_rate(unsigned value);
			bool set_blocksize(unsigned value);
			bool set_max_lpc_order(unsigned value);
			bool set_qlp_coeff_precision(unsigned value);
			bool set_do_qlp_coeff_prec_search(bool value);
			bool set_do_escape_coding(bool value);
			bool set_do_exhaustive_model_search(bool value);
			bool set_min_residual_partition_order(unsigned value);
			bool set_max_residual_partition_order(unsigned value);
			bool set_rice_parameter_search_dist(unsigned value);
			bool set_total_samples_estimate(FLAC__uint64 value);
			bool set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks);

			State    get_state() const;
			FLAC::Encoder::Stream::State get_FLAC_stream_encoder_state() const;
			FLAC::Decoder::Stream::State get_verify_decoder_state() const;
136
			void get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got);
Josh Coalson's avatar
Josh Coalson committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
			bool     get_verify() const;
			bool     get_streamable_subset() const;
			bool     get_do_mid_side_stereo() const;
			bool     get_loose_mid_side_stereo() const;
			unsigned get_channels() const;
			unsigned get_bits_per_sample() const;
			unsigned get_sample_rate() const;
			unsigned get_blocksize() const;
			unsigned get_max_lpc_order() const;
			unsigned get_qlp_coeff_precision() const;
			bool     get_do_qlp_coeff_prec_search() const;
			bool     get_do_escape_coding() const;
			bool     get_do_exhaustive_model_search() const;
			unsigned get_min_residual_partition_order() const;
			unsigned get_max_residual_partition_order() const;
			unsigned get_rice_parameter_search_dist() const;
			FLAC__uint64 get_total_samples_estimate() const;

			State init();

			void finish();

			bool process(const FLAC__int32 * const buffer[], unsigned samples);
			bool process_interleaved(const FLAC__int32 buffer[], unsigned samples);
		protected:
			virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame) = 0;
163
			virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata) = 0;
Josh Coalson's avatar
Josh Coalson committed
164

165
#if (defined _MSC_VER) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96)))
166
167
			// lame hack: some MSVC/GCC versions can't see a protected encoder_ from nested State::resolved_as_cstring()
			friend State;
168
#endif
Josh Coalson's avatar
Josh Coalson committed
169
170
171
			::OggFLAC__StreamEncoder *encoder_;
		private:
			static ::FLAC__StreamEncoderWriteStatus write_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
172
			static void metadata_callback_(const ::OggFLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data);
Josh Coalson's avatar
Josh Coalson committed
173
174
175
176
177
178
179
180

			// Private and undefined so you can't use them:
			Stream(const Stream &);
			void operator=(const Stream &);
		};

		/* \} */

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
		/** \defgroup oggflacpp_seekable_stream_encoder OggFLAC++/encoder.h: seekable stream encoder class
		 *  \ingroup oggflacpp_encoder
		 *
		 *  \brief
		 *  This class wraps the ::OggFLAC__SeekableStreamEncoder.
		 *
		 * See the \link oggflac_seekable_stream_encoder libOggFLAC seekable stream encoder module \endlink.
		 *
		 * \{
		 */

		/** This class wraps the ::OggFLAC__SeekableStreamEncoder.
		 */
		class OggFLACPP_API SeekableStream {
		public:
			class OggFLACPP_API State {
			public:
				inline State(::OggFLAC__SeekableStreamEncoderState state): state_(state) { }
				inline operator ::OggFLAC__SeekableStreamEncoderState() const { return state_; }
				inline const char *as_cstring() const { return ::OggFLAC__SeekableStreamEncoderStateString[state_]; }
				inline const char *resolved_as_cstring(const SeekableStream &encoder) const { return ::OggFLAC__seekable_stream_encoder_get_resolved_state_string(encoder.encoder_); }
			protected:
				::OggFLAC__SeekableStreamEncoderState state_;
			};

			SeekableStream();
			virtual ~SeekableStream();

			bool is_valid() const;
			inline operator bool() const { return is_valid(); }

			bool set_serial_number(long value);
			bool set_verify(bool value);
			bool set_streamable_subset(bool value);
			bool set_do_mid_side_stereo(bool value);
			bool set_loose_mid_side_stereo(bool value);
			bool set_channels(unsigned value);
			bool set_bits_per_sample(unsigned value);
			bool set_sample_rate(unsigned value);
			bool set_blocksize(unsigned value);
			bool set_max_lpc_order(unsigned value);
			bool set_qlp_coeff_precision(unsigned value);
			bool set_do_qlp_coeff_prec_search(bool value);
			bool set_do_escape_coding(bool value);
			bool set_do_exhaustive_model_search(bool value);
			bool set_min_residual_partition_order(unsigned value);
			bool set_max_residual_partition_order(unsigned value);
			bool set_rice_parameter_search_dist(unsigned value);
			bool set_total_samples_estimate(FLAC__uint64 value);
			bool set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks);

			State    get_state() const;
			FLAC::Encoder::Stream::State get_FLAC_stream_encoder_state() const;
			FLAC::Decoder::Stream::State get_verify_decoder_state() const;
			void get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got);
			bool     get_verify() const;
			bool     get_streamable_subset() const;
			bool     get_do_mid_side_stereo() const;
			bool     get_loose_mid_side_stereo() const;
			unsigned get_channels() const;
			unsigned get_bits_per_sample() const;
			unsigned get_sample_rate() const;
			unsigned get_blocksize() const;
			unsigned get_max_lpc_order() const;
			unsigned get_qlp_coeff_precision() const;
			bool     get_do_qlp_coeff_prec_search() const;
			bool     get_do_escape_coding() const;
			bool     get_do_exhaustive_model_search() const;
			unsigned get_min_residual_partition_order() const;
			unsigned get_max_residual_partition_order() const;
			unsigned get_rice_parameter_search_dist() const;
			FLAC__uint64 get_total_samples_estimate() const;

			State init();

			void finish();

			bool process(const FLAC__int32 * const buffer[], unsigned samples);
			bool process_interleaved(const FLAC__int32 buffer[], unsigned samples);
		protected:
261
			virtual ::OggFLAC__SeekableStreamEncoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes) = 0;
262
263
264
265
			virtual ::FLAC__SeekableStreamEncoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset) = 0;
			virtual ::FLAC__SeekableStreamEncoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) = 0;
			virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame) = 0;

266
#if (defined _MSC_VER) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96)))
267
268
			// lame hack: some MSVC/GCC versions can't see a protected encoder_ from nested State::resolved_as_cstring()
			friend State;
269
#endif
270
271
			::OggFLAC__SeekableStreamEncoder *encoder_;
		private:
272
			static ::OggFLAC__SeekableStreamEncoderReadStatus read_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
			static ::FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
			static ::FLAC__SeekableStreamEncoderTellStatus tell_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
			static ::FLAC__StreamEncoderWriteStatus write_callback_(const OggFLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);

			// Private and undefined so you can't use them:
			SeekableStream(const SeekableStream &);
			void operator=(const SeekableStream &);
		};

		/* \} */

		/** \defgroup oggflacpp_file_encoder OggFLAC++/encoder.h: file encoder class
		 *  \ingroup oggflacpp_encoder
		 *
		 *  \brief
		 *  This class wraps the ::OggFLAC__FileEncoder.
		 *
		 * See the \link oggflac_file_encoder libOggFLAC file encoder module \endlink.
		 *
		 * \{
		 */

		/** This class wraps the ::OggFLAC__FileEncoder.
		 */
		class OggFLACPP_API File {
		public:
			class OggFLACPP_API State {
			public:
				inline State(::OggFLAC__FileEncoderState state): state_(state) { }
				inline operator ::OggFLAC__FileEncoderState() const { return state_; }
				inline const char *as_cstring() const { return ::OggFLAC__FileEncoderStateString[state_]; }
				inline const char *resolved_as_cstring(const File &encoder) const { return ::OggFLAC__file_encoder_get_resolved_state_string(encoder.encoder_); }
			protected:
				::OggFLAC__FileEncoderState state_;
			};

			File();
			virtual ~File();

			bool is_valid() const;
			inline operator bool() const { return is_valid(); }

			bool set_serial_number(long value);
			bool set_verify(bool value);
			bool set_streamable_subset(bool value);
			bool set_do_mid_side_stereo(bool value);
			bool set_loose_mid_side_stereo(bool value);
			bool set_channels(unsigned value);
			bool set_bits_per_sample(unsigned value);
			bool set_sample_rate(unsigned value);
			bool set_blocksize(unsigned value);
			bool set_max_lpc_order(unsigned value);
			bool set_qlp_coeff_precision(unsigned value);
			bool set_do_qlp_coeff_prec_search(bool value);
			bool set_do_escape_coding(bool value);
			bool set_do_exhaustive_model_search(bool value);
			bool set_min_residual_partition_order(unsigned value);
			bool set_max_residual_partition_order(unsigned value);
			bool set_rice_parameter_search_dist(unsigned value);
			bool set_total_samples_estimate(FLAC__uint64 value);
			bool set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks);
			bool set_filename(const char *value);

			State    get_state() const;
			SeekableStream::State get_seekable_stream_encoder_state() const;
			FLAC::Encoder::Stream::State get_FLAC_stream_encoder_state() const;
			FLAC::Decoder::Stream::State get_verify_decoder_state() const;
			void get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got);
			bool     get_verify() const;
			bool     get_streamable_subset() const;
			bool     get_do_mid_side_stereo() const;
			bool     get_loose_mid_side_stereo() const;
			unsigned get_channels() const;
			unsigned get_bits_per_sample() const;
			unsigned get_sample_rate() const;
			unsigned get_blocksize() const;
			unsigned get_max_lpc_order() const;
			unsigned get_qlp_coeff_precision() const;
			bool     get_do_qlp_coeff_prec_search() const;
			bool     get_do_escape_coding() const;
			bool     get_do_exhaustive_model_search() const;
			unsigned get_min_residual_partition_order() const;
			unsigned get_max_residual_partition_order() const;
			unsigned get_rice_parameter_search_dist() const;
			FLAC__uint64 get_total_samples_estimate() const;

			State init();

			void finish();

			bool process(const FLAC__int32 * const buffer[], unsigned samples);
			bool process_interleaved(const FLAC__int32 buffer[], unsigned samples);
		protected:
			virtual void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate);

368
#if (defined _MSC_VER) || (defined __GNUG__ && (__GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 96)))
369
370
			// lame hack: some MSVC/GCC versions can't see a protected encoder_ from nested State::resolved_as_cstring()
			friend State;
371
#endif
372
373
374
375
376
377
378
379
380
381
382
			::OggFLAC__FileEncoder *encoder_;
		private:
			static void progress_callback_(const ::OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);

			// Private and undefined so you can't use them:
			File(const Stream &);
			void operator=(const Stream &);
		};

		/* \} */

383
384
	}
}
Josh Coalson's avatar
Josh Coalson committed
385
386

#endif