seekable_stream_decoder.cpp 9.83 KB
Newer Older
Josh Coalson's avatar
Josh Coalson committed
1
/* libFLAC++ - Free Lossless Audio Codec 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
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
Josh Coalson's avatar
Josh Coalson committed
7
 *
8
9
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
Josh Coalson's avatar
Josh Coalson committed
10
 *
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * - 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
 */

#include "FLAC++/decoder.h"
#include "FLAC/assert.h"

35
36
37
38
39
#ifdef _MSC_VER
// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
#pragma warning ( disable : 4800 )
#endif

Josh Coalson's avatar
Josh Coalson committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
namespace FLAC {
	namespace Decoder {

		SeekableStream::SeekableStream():
		decoder_(::FLAC__seekable_stream_decoder_new())
		{ }

		SeekableStream::~SeekableStream()
		{
			if(0 != decoder_) {
				(void) ::FLAC__seekable_stream_decoder_finish(decoder_);
				::FLAC__seekable_stream_decoder_delete(decoder_);
			}
		}

		bool SeekableStream::is_valid() const
		{
			return 0 != decoder_;
		}

		bool SeekableStream::set_md5_checking(bool value)
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
63
			return (bool)::FLAC__seekable_stream_decoder_set_md5_checking(decoder_, value);
Josh Coalson's avatar
Josh Coalson committed
64
65
		}

66
		bool SeekableStream::set_metadata_respond(::FLAC__MetadataType type)
Josh Coalson's avatar
Josh Coalson committed
67
68
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
69
			return (bool)::FLAC__seekable_stream_decoder_set_metadata_respond(decoder_, type);
Josh Coalson's avatar
Josh Coalson committed
70
71
72
73
74
		}

		bool SeekableStream::set_metadata_respond_application(const FLAC__byte id[4])
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
75
			return (bool)::FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder_, id);
Josh Coalson's avatar
Josh Coalson committed
76
77
78
79
80
		}

		bool SeekableStream::set_metadata_respond_all()
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
81
			return (bool)::FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder_);
Josh Coalson's avatar
Josh Coalson committed
82
83
		}

84
		bool SeekableStream::set_metadata_ignore(::FLAC__MetadataType type)
Josh Coalson's avatar
Josh Coalson committed
85
86
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
87
			return (bool)::FLAC__seekable_stream_decoder_set_metadata_ignore(decoder_, type);
Josh Coalson's avatar
Josh Coalson committed
88
89
90
91
92
		}

		bool SeekableStream::set_metadata_ignore_application(const FLAC__byte id[4])
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
93
			return (bool)::FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder_, id);
Josh Coalson's avatar
Josh Coalson committed
94
95
96
97
98
		}

		bool SeekableStream::set_metadata_ignore_all()
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
99
			return (bool)::FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder_);
Josh Coalson's avatar
Josh Coalson committed
100
101
102
103
104
105
106
107
		}

		SeekableStream::State SeekableStream::get_state() const
		{
			FLAC__ASSERT(is_valid());
			return State(::FLAC__seekable_stream_decoder_get_state(decoder_));
		}

Josh Coalson's avatar
Josh Coalson committed
108
109
110
111
112
113
		Stream::State SeekableStream::get_stream_decoder_state() const
		{
			FLAC__ASSERT(is_valid());
			return Stream::State(::FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder_));
		}

Josh Coalson's avatar
Josh Coalson committed
114
115
116
		bool SeekableStream::get_md5_checking() const
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
117
			return (bool)::FLAC__seekable_stream_decoder_get_md5_checking(decoder_);
Josh Coalson's avatar
Josh Coalson committed
118
119
		}

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
		unsigned SeekableStream::get_channels() const
		{
			FLAC__ASSERT(is_valid());
			return ::FLAC__seekable_stream_decoder_get_channels(decoder_);
		}

		::FLAC__ChannelAssignment SeekableStream::get_channel_assignment() const
		{
			FLAC__ASSERT(is_valid());
			return ::FLAC__seekable_stream_decoder_get_channel_assignment(decoder_);
		}

		unsigned SeekableStream::get_bits_per_sample() const
		{
			FLAC__ASSERT(is_valid());
			return ::FLAC__seekable_stream_decoder_get_bits_per_sample(decoder_);
		}

		unsigned SeekableStream::get_sample_rate() const
		{
			FLAC__ASSERT(is_valid());
			return ::FLAC__seekable_stream_decoder_get_sample_rate(decoder_);
		}

		unsigned SeekableStream::get_blocksize() const
		{
			FLAC__ASSERT(is_valid());
			return ::FLAC__seekable_stream_decoder_get_blocksize(decoder_);
		}

Josh Coalson's avatar
Josh Coalson committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
		SeekableStream::State SeekableStream::init()
		{
			FLAC__ASSERT(is_valid());
			::FLAC__seekable_stream_decoder_set_read_callback(decoder_, read_callback_);
			::FLAC__seekable_stream_decoder_set_seek_callback(decoder_, seek_callback_);
			::FLAC__seekable_stream_decoder_set_tell_callback(decoder_, tell_callback_);
			::FLAC__seekable_stream_decoder_set_length_callback(decoder_, length_callback_);
			::FLAC__seekable_stream_decoder_set_eof_callback(decoder_, eof_callback_);
			::FLAC__seekable_stream_decoder_set_write_callback(decoder_, write_callback_);
			::FLAC__seekable_stream_decoder_set_metadata_callback(decoder_, metadata_callback_);
			::FLAC__seekable_stream_decoder_set_error_callback(decoder_, error_callback_);
			::FLAC__seekable_stream_decoder_set_client_data(decoder_, (void*)this);
			return State(::FLAC__seekable_stream_decoder_init(decoder_));
		}

		bool SeekableStream::finish()
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
168
			return (bool)::FLAC__seekable_stream_decoder_finish(decoder_);
Josh Coalson's avatar
Josh Coalson committed
169
170
		}

171
172
173
174
175
176
177
178
179
180
181
182
		bool SeekableStream::flush()
		{
			FLAC__ASSERT(is_valid());
			return (bool)::FLAC__seekable_stream_decoder_flush(decoder_);
		}

		bool SeekableStream::reset()
		{
			FLAC__ASSERT(is_valid());
			return (bool)::FLAC__seekable_stream_decoder_reset(decoder_);
		}

Josh Coalson's avatar
Josh Coalson committed
183
		bool SeekableStream::process_single()
Josh Coalson's avatar
Josh Coalson committed
184
185
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
186
			return (bool)::FLAC__seekable_stream_decoder_process_single(decoder_);
Josh Coalson's avatar
Josh Coalson committed
187
188
		}

Josh Coalson's avatar
Josh Coalson committed
189
		bool SeekableStream::process_until_end_of_metadata()
Josh Coalson's avatar
Josh Coalson committed
190
191
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
192
			return (bool)::FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder_);
Josh Coalson's avatar
Josh Coalson committed
193
194
		}

Josh Coalson's avatar
Josh Coalson committed
195
		bool SeekableStream::process_until_end_of_stream()
Josh Coalson's avatar
Josh Coalson committed
196
197
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
198
			return (bool)::FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder_);
Josh Coalson's avatar
Josh Coalson committed
199
200
		}

201
202
203
204
205
206
		bool SeekableStream::skip_single_frame()
		{
			FLAC__ASSERT(is_valid());
			return (bool)::FLAC__seekable_stream_decoder_skip_single_frame(decoder_);
		}

Josh Coalson's avatar
Josh Coalson committed
207
208
209
		bool SeekableStream::seek_absolute(FLAC__uint64 sample)
		{
			FLAC__ASSERT(is_valid());
Josh Coalson's avatar
Josh Coalson committed
210
			return (bool)::FLAC__seekable_stream_decoder_seek_absolute(decoder_, sample);
Josh Coalson's avatar
Josh Coalson committed
211
212
		}

Josh Coalson's avatar
Josh Coalson committed
213
		::FLAC__SeekableStreamDecoderReadStatus SeekableStream::read_callback_(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
Josh Coalson's avatar
Josh Coalson committed
214
215
216
217
218
219
220
221
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			return instance->read_callback(buffer, bytes);
		}

Josh Coalson's avatar
Josh Coalson committed
222
		::FLAC__SeekableStreamDecoderSeekStatus SeekableStream::seek_callback_(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
Josh Coalson's avatar
Josh Coalson committed
223
224
225
226
227
228
229
230
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			return instance->seek_callback(absolute_byte_offset);
		}

Josh Coalson's avatar
Josh Coalson committed
231
		::FLAC__SeekableStreamDecoderTellStatus SeekableStream::tell_callback_(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
Josh Coalson's avatar
Josh Coalson committed
232
233
234
235
236
237
238
239
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			return instance->tell_callback(absolute_byte_offset);
		}

Josh Coalson's avatar
Josh Coalson committed
240
		::FLAC__SeekableStreamDecoderLengthStatus SeekableStream::length_callback_(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
Josh Coalson's avatar
Josh Coalson committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			return instance->length_callback(stream_length);
		}

		FLAC__bool SeekableStream::eof_callback_(const ::FLAC__SeekableStreamDecoder *decoder, void *client_data)
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			return instance->eof_callback();
		}

Josh Coalson's avatar
Josh Coalson committed
258
		::FLAC__StreamDecoderWriteStatus SeekableStream::write_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
Josh Coalson's avatar
Josh Coalson committed
259
260
261
262
263
264
265
266
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			return instance->write_callback(frame, buffer);
		}

267
		void SeekableStream::metadata_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
Josh Coalson's avatar
Josh Coalson committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			instance->metadata_callback(metadata);
		}

		void SeekableStream::error_callback_(const ::FLAC__SeekableStreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data)
		{
			(void) decoder;
			FLAC__ASSERT(0 != client_data);
			SeekableStream *instance = reinterpret_cast<SeekableStream *>(client_data);
			FLAC__ASSERT(0 != instance);
			instance->error_callback(status);
		}

285
286
	}
}