1 {
2 Translation of the libmad headers for FreePascal
3 Copyright (C) 2006 by Ivo Steinmann
4 }
5
6 (*
7 * libmad - MPEG audio decoder library
8 * Copyright (C) 2000-2003 Underbit Technologies, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02110-1301, USA.
24 *
25 * If you would like to negotiate alternate licensing terms, you may do
26 * so by contacting: Underbit Technologies, Inc. <info@underbit.com>
27 *)
28
29 unit mad;
30
31 {$mode objfpc}
32 {$MINENUMSIZE 4}
33
34 interface
35
36 uses
37 ctypes;
38
39 {$IFDEF WINDOWS}
40 {$DEFINE DYNLINK}
41 {$ENDIF}
42
43 {.$DEFINE MAD_DISABLE_BUILTIN_DECODER}
44
45 {$IFDEF DYNLINK}
46 const
47 {$IF Defined(WINDOWS)}
48 madlib = 'libmad.dll';
49 {$ELSEIF Defined(UNIX)}
50 madlib = 'libmad.so';
51 {$ELSE}
52 {$MESSAGE ERROR 'DYNLINK not supported'}
53 {$IFEND}
54 {$ELSE}
55 {$LINKLIB mad}
56 {$ENDIF}
57
58
59 (***********************************************************************)
60 (* Header : version.h *)
61 (***********************************************************************)
62
63 const
64 MAD_VERSION_MAJOR = 0;
65 MAD_VERSION_MINOR = 15;
66 MAD_VERSION_PATCH = 1;
67 MAD_VERSION_EXTRA = ' (beta)';
68
MAD_VERSION_STRINGIZEnull69 function MAD_VERSION_STRINGIZE(num: cint): String;
MAD_VERSION_STRINGnull70 function MAD_VERSION_STRING(num: cint): String;
MAD_VERSIONnull71 function MAD_VERSION: String;
72
73 const
74 MAD_PUBLISHYEAR = '2000-2004';
75 MAD_AUTHOR = 'Underbit Technologies, Inc.';
76 MAD_EMAIL = 'info@underbit.com';
77
78
79 (***********************************************************************)
80 (* Header : fixed.h *)
81 (***********************************************************************)
82
83 type
84 mad_fixed_t = csint;
85 mad_fixed64hi_t = csint;
86 mad_fixed64lo_t = cuint;
87 mad_fixed64_t = cslonglong;
88 mad_sample_t = mad_fixed_t;
89
90 {*
91 * Fixed-point format: 0xABBBBBBB
92 * A == whole part (sign + 3 bits)
93 * B == fractional part (28 bits)
94 *
95 * Values are signed two's complement, so the effective range is:
96 * 0x80000000 to 0x7fffffff
97 * -8.0 to +7.9999999962747097015380859375
98 *
99 * The smallest representable value is:
100 * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
101 *
102 * 28 bits of fractional accuracy represent about
103 * 8.6 digits of decimal accuracy.
104 *
105 * Fixed-point numbers can be added or subtracted as normal
106 * integers, but multiplication requires shifting the 64-bit result
107 * from 56 fractional bits back to 28 (and rounding.)
108 *
109 * Changing the definition of MAD_F_FRACBITS is only partially
110 * supported, and must be done with care.
111 *}
112
113 const
114 MAD_F_FRACBITS = 28;
115 // MAD_F_MIN = mad_fixed_t(-$80000000);
116 MAD_F_MAX = mad_fixed_t(+$7fffffff);
117 MAD_F_ONE = mad_fixed_t( $10000000);
118 MAD_F_SCALEBITS = MAD_F_FRACBITS;
119
mad_f_tofixednull120 //function mad_f_tofixed(x: double): mad_fixed_t;
121
122
123 (***********************************************************************)
124 (* Header : bit.h *)
125 (***********************************************************************)
126
127 type
128 mad_bitptr = record
129 byte : ^cuchar;
130 cache : cushort;
131 left : cushort;
132 end;
133
134 procedure mad_bit_init(var bitptr: mad_bitptr; byte: pcuchar); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
135 procedure mad_bit_finish(var bitptr: mad_bitptr);
mad_bit_lengthnull136 function mad_bit_length(var begin_, end_: mad_bitptr): cuint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_bit_bitsleftnull137 function mad_bit_bitsleft(var bitptr: mad_bitptr): cushort;
mad_bit_nextbytenull138 function mad_bit_nextbyte(var bitptr: mad_bitptr): pcuchar; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
139 procedure mad_bit_skip(var bitptr: mad_bitptr); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_bit_readnull140 function mad_bit_read(var bitptr: mad_bitptr; len: cuint): culong; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
141 procedure mad_bit_write(var bitptr: mad_bitptr; len: cuint; value: culong); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_bit_crcnull142 function mad_bit_crc(bitptr: mad_bitptr; len: cuint; init: cushort): cushort; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
143
144
145 (***********************************************************************)
146 (* Header : timer.h *)
147 (***********************************************************************)
148
149 type
150 mad_timer_t = record
151 seconds : cslong; { whole seconds }
152 fraction : culong; { 1/MAD_TIMER_RESOLUTION seconds }
153 end;
154
155 const
156 MAD_TIMER_RESOLUTION = 352800000;
157 mad_timer_zero : mad_timer_t = (seconds:0; fraction:0);
158
159 type
160 mad_units = cuint;
161
162 const
163 MAD_UNITS_HOURS = -2;
164 MAD_UNITS_MINUTES = -1;
165 MAD_UNITS_SECONDS = 0;
166
167 { metric units }
168
169 MAD_UNITS_DECISECONDS = 10;
170 MAD_UNITS_CENTISECONDS = 100;
171 MAD_UNITS_MILLISECONDS = 1000;
172
173 { audio sample units }
174
175 MAD_UNITS_8000_HZ = 8000;
176 MAD_UNITS_11025_HZ = 11025;
177 MAD_UNITS_12000_HZ = 12000;
178
179 MAD_UNITS_16000_HZ = 16000;
180 MAD_UNITS_22050_HZ = 22050;
181 MAD_UNITS_24000_HZ = 24000;
182
183 MAD_UNITS_32000_HZ = 32000;
184 MAD_UNITS_44100_HZ = 44100;
185 MAD_UNITS_48000_HZ = 48000;
186
187 { video frame/field units }
188
189 MAD_UNITS_24_FPS = 24;
190 MAD_UNITS_25_FPS = 25;
191 MAD_UNITS_30_FPS = 30;
192 MAD_UNITS_48_FPS = 48;
193 MAD_UNITS_50_FPS = 50;
194 MAD_UNITS_60_FPS = 60;
195
196 { CD audio frames }
197
198 MAD_UNITS_75_FPS = 75;
199
200 { video drop-frame units }
201
202 MAD_UNITS_23_976_FPS = -24;
203 MAD_UNITS_24_975_FPS = -25;
204 MAD_UNITS_29_97_FPS = -30;
205 MAD_UNITS_47_952_FPS = -48;
206 MAD_UNITS_49_95_FPS = -50;
207 MAD_UNITS_59_94_FPS = -60;
208
209
210 procedure mad_timer_reset(var timer: mad_timer_t);
mad_timer_comparenull211 function mad_timer_compare(timer1: mad_timer_t; timer2: mad_timer_t): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_timer_signnull212 function mad_timer_sign(timer: mad_timer_t): cint;
213 procedure mad_timer_negate(var timer: mad_timer_t); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_timer_absnull214 function mad_timer_abs(timer: mad_timer_t): mad_timer_t; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
215 procedure mad_timer_set(var timer: mad_timer_t; seconds, numer, denom: culong); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
216 procedure mad_timer_add(var timer: mad_timer_t; incr: mad_timer_t); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
217 procedure mad_timer_multiply(var timer: mad_timer_t; scalar: cslong); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_timer_countnull218 function mad_timer_count(timer: mad_timer_t; units: mad_units): cslong; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_timer_fractionnull219 function mad_timer_fraction(timer: mad_timer_t; denom: culong): culong; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
220 procedure mad_timer_string(timer: mad_timer_t; dest, format: pcchar; units, fracunits: mad_units; subparts: culong); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
221
222
223 (***********************************************************************)
224 (* Header : stream.h *)
225 (***********************************************************************)
226
227 type
228 mad_error = (
229 MAD_ERROR_NONE = $0000, { no error }
230
231 MAD_ERROR_BUFLEN = $0001, { input buffer too small (or EOF) }
232 MAD_ERROR_BUFPTR = $0002, { invalid (null) buffer pointer }
233
234 MAD_ERROR_NOMEM = $0031, { not enough memory }
235
236 MAD_ERROR_LOSTSYNC = $0101, { lost synchronization }
237 MAD_ERROR_BADLAYER = $0102, { reserved header layer value }
238 MAD_ERROR_BADBITRATE = $0103, { forbidden bitrate value }
239 MAD_ERROR_BADSAMPLERATE = $0104, { reserved sample frequency value }
240 MAD_ERROR_BADEMPHASIS = $0105, { reserved emphasis value }
241
242 MAD_ERROR_BADCRC = $0201, { CRC check failed }
243 MAD_ERROR_BADBITALLOC = $0211, { forbidden bit allocation value }
244 MAD_ERROR_BADSCALEFACTOR = $0221, { bad scalefactor index }
245 MAD_ERROR_BADFRAMELEN = $0231, { bad frame length }
246 MAD_ERROR_BADBIGVALUES = $0232, { bad big_values count }
247 MAD_ERROR_BADBLOCKTYPE = $0233, { reserved block_type }
248 MAD_ERROR_BADSCFSI = $0234, { bad scalefactor selection info }
249 MAD_ERROR_BADDATAPTR = $0235, { bad main_data_begin pointer }
250 MAD_ERROR_BADPART3LEN = $0236, { bad audio data length }
251 MAD_ERROR_BADHUFFTABLE = $0237, { bad Huffman table select }
252 MAD_ERROR_BADHUFFDATA = $0238, { Huffman data overrun }
253 MAD_ERROR_BADSTEREO = $0239 { incompatible block_type for JS }
254 );
255
MAD_RECOVERABLEnull256 function MAD_RECOVERABLE(error: mad_error) : Boolean;
257
258 type
259 mad_stream = record
260 buffer : pointer; { input bitstream buffer }
261 bufend : pointer; { end of buffer }
262 skiplen : culong; { bytes to skip before next frame }
263 sync : cint; { stream sync found }
264 freerate : culong; { free bitrate (fixed) }
265 this_frame : pointer; { start of current frame }
266 next_frame : pointer; { start of next frame }
267 ptr : mad_bitptr; { current processing bit pointer }
268 anc_ptr : mad_bitptr; { ancillary bits pointer }
269 anc_bitlen : cuint; { number of ancillary bits }
270 main_data : pointer; { Layer III main_data() }
271 md_len : cuint; { bytes in main_data }
272 options : cint; { decoding options (see below) }
273 error : mad_error; { error code (see above) }
274 end;
275
276 const
277 MAD_BUFFER_GUARD = 8;
278 MAD_BUFFER_MDLEN = 511 + 2048 + MAD_BUFFER_GUARD;
279
280 MAD_OPTION_IGNORECRC = $0001; { ignore CRC errors }
281 MAD_OPTION_HALFSAMPLERATE = $0002; { generate PCM at 1/2 sample rate }
282 {$if defined(false)} { not yet implemented }
283 MAD_OPTION_LEFTCHANNEL = $0010; { decode left channel only }
284 MAD_OPTION_RIGHTCHANNEL = $0020; { decode right channel only }
285 MAD_OPTION_SINGLECHANNEL = $0030; { combine channels }
286 {$ifend}
287
288 procedure mad_stream_init(var stream: mad_stream); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
289 procedure mad_stream_finish(var stream: mad_stream); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
290 procedure mad_stream_options(stream: mad_stream; opts: cint);
291 procedure mad_stream_buffer(var stream: mad_stream; buffer: pcuchar; length: culong); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
292 procedure mad_stream_skip(var stream: mad_stream; length: culong); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_stream_syncnull293 function mad_stream_sync(var stream: mad_stream): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_stream_errorstrnull294 function mad_stream_errorstr(var stream: mad_stream): pcchar; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
295
296
297 (***********************************************************************)
298 (* Header : frame.h *)
299 (***********************************************************************)
300
301 type
302 mad_layer = (
303 MAD_LAYER_I = 1, { Layer I }
304 MAD_LAYER_II = 2, { Layer II }
305 MAD_LAYER_III = 3 { Layer III }
306 );
307
308 mad_mode = (
309 MAD_MODE_SINGLE_CHANNEL = 0, { single channel }
310 MAD_MODE_DUAL_CHANNEL = 1, { dual channel }
311 MAD_MODE_JOINT_STEREO = 2, { joint (MS/intensity) stereo }
312 MAD_MODE_STEREO = 3 { normal LR stereo }
313 );
314
315 mad_emphasis = (
316 MAD_EMPHASIS_NONE = 0, { no emphasis }
317 MAD_EMPHASIS_50_15_US = 1, { 50/15 microseconds emphasis }
318 MAD_EMPHASIS_RESERVED = 2, { unknown emphasis }
319 MAD_EMPHASIS_CCITT_J_17 = 3 { CCITT J.17 emphasis }
320 );
321
322 mad_header = record
323 layer : mad_layer; { audio layer (1, 2, or 3) }
324 mode : mad_mode; { channel mode (see above) }
325 mode_extension : cint; { additional mode info }
326 emphasis : mad_emphasis; { de-emphasis to use (see above) }
327 bitrate : culong; { stream bitrate (bps) }
328 samplerate : cuint; { sampling frequency (Hz) }
329 crc_check : cushort; { frame CRC accumulator }
330 crc_target : cushort; { final target CRC checksum }
331 flags : cint; { flags (see below) }
332 private_bits : cint; { private bits (see below) }
333 duration : mad_timer_t; { audio playing time of frame }
334 end;
335
336 mad_overlap = array[0..1, 0..31, 0..17] of mad_fixed_t;
337
338 mad_frame = record
339 header : mad_header; { MPEG audio header }
340 options : cint; { decoding options (from stream) }
341 { synthesis subband filter samples }
342 sbsample : packed array[0..1, 0..35, 0..31] of mad_fixed_t;
343 overlap : ^mad_overlap; { Layer III block overlap data }
344 end;
345
346 const
347 MAD_FLAG_NPRIVATE_III = $0007; { number of Layer III private bits }
348 MAD_FLAG_INCOMPLETE = $0008; { header but not data is decoded }
349
350 MAD_FLAG_PROTECTION = $0010; { frame has CRC protection }
351 MAD_FLAG_COPYRIGHT = $0020; { frame is copyright }
352 MAD_FLAG_ORIGINAL = $0040; { frame is original (else copy) }
353 MAD_FLAG_PADDING = $0080; { frame has additional slot }
354
355 MAD_FLAG_I_STEREO = $0100; { uses intensity joint stereo }
356 MAD_FLAG_MS_STEREO = $0200; { uses middle/side joint stereo }
357 MAD_FLAG_FREEFORMAT = $0400; { uses free format bitrate }
358
359 MAD_FLAG_LSF_EXT = $1000; { lower sampling freq. extension }
360 MAD_FLAG_MC_EXT = $2000; { multichannel audio extension }
361 MAD_FLAG_MPEG_2_5_EXT = $4000; { MPEG 2.5 (unofficial) extension }
362
363 MAD_PRIVATE_HEADER = $0100; { header private bit }
364 MAD_PRIVATE_III = $001f; { Layer III private bits (up to 5) }
365
mad_nchannelsnull366 function mad_nchannels(header: mad_header): cint;
mad_nsbsamplesnull367 function mad_nsbsamples(header: mad_header): cint;
368 procedure mad_header_init(var header: mad_header); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
369 procedure mad_header_finish(var header: mad_header);
mad_header_decodenull370 function mad_header_decode(var header: mad_header; var stream: mad_stream): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
371 procedure mad_frame_init(var frame: mad_frame); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
372 procedure mad_frame_finish(var frame: mad_frame); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_frame_decodenull373 function mad_frame_decode(var frame: mad_frame; var stream: mad_stream): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
374 procedure mad_frame_mute(var frame: mad_frame); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
375
376
377 (***********************************************************************)
378 (* Header : synth.h *)
379 (***********************************************************************)
380
381 type
382 mad_pcm = record
383 samplerate : cuint; { sampling frequency (Hz) }
384 channels : cushort; { number of channels }
385 length : cushort; { number of samples per channel }
386 { PCM output samples [ch][sample] }
387 samples : packed array [0..1, 0..1151] of mad_fixed_t;
388 end;
389
390 mad_synth = record
391 { polyphase filterbank outputs [ch][eo][peo][s][v] }
392 filter : array[0..1, 0..1, 0..1, 0..15, 0..7] of mad_fixed_t;
393 phase : cuint; { current processing phase }
394 pcm : mad_pcm; { PCM output }
395 end;
396
397 const
398 { single channel PCM selector }
399 MAD_PCM_CHANNEL_SINGLE = 0;
400
401 { dual channel PCM selector }
402 MAD_PCM_CHANNEL_DUAL_1 = 0;
403 MAD_PCM_CHANNEL_DUAL_2 = 1;
404
405 { stereo PCM selector }
406 MAD_PCM_CHANNEL_STEREO_LEFT = 0;
407 MAD_PCM_CHANNEL_STEREO_RIGHT = 1;
408
409 procedure mad_synth_init(var synth: mad_synth); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
410 procedure mad_synth_finish(var synth: mad_synth);
411 procedure mad_synth_mute(var synth: mad_synth); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
412 procedure mad_synth_frame(var synth: mad_synth; var frame: mad_frame); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
413
414
415 (***********************************************************************)
416 (* Header : decoder.h *)
417 (***********************************************************************)
418
419 {$IFNDEF MAD_DISABLE_BUILTIN_DECODER}
420 type
421 mad_decoder_mode = (
422 MAD_DECODER_MODE_SYNC = 0,
423 MAD_DECODER_MODE_ASYNC = 1
424 );
425
426 mad_flow = (
427 MAD_FLOW_CONTINUE = $0000, { continue normally }
428 MAD_FLOW_STOP = $0010, { stop decoding normally }
429 MAD_FLOW_BREAK = $0011, { stop decoding and signal an error }
430 MAD_FLOW_IGNORE = $0020 { ignore the current frame }
431 );
432
433 async_struct = record
434 pid : clong;
435 _in : cint;
436 _out : cint;
437 end;
438
439 sync_struct = record
440 stream : mad_stream;
441 frame : mad_frame;
442 synth : mad_synth;
443 end;
444
sernull445 mad_input_func = function(user: Pointer; var stream: mad_stream): mad_flow; cdecl;
sernull446 mad_header_func = function(user: Pointer; var header: mad_header): mad_flow; cdecl;
sernull447 mad_filter_func = function(user: Pointer; var frame: mad_frame): mad_flow; cdecl;
sernull448 mad_output_func = function(user: Pointer; var header: mad_header; var pcm: mad_pcm): mad_flow; cdecl;
sernull449 mad_error_func = function(user: Pointer; var stream: mad_stream; var frame: mad_frame): mad_flow; cdecl;
sernull450 mad_message_func = function(user, msg: Pointer; var l: cuint): mad_flow; cdecl;
451
452 mad_decoder = record
453 mode : mad_decoder_mode;
454 options : cint;
455 async : async_struct;
456 sync : ^sync_struct;
457 data : pointer;
458 InputFunc : mad_input_func;
459 HeaderFunc : mad_header_func;
460 FilterFunc : mad_filter_func;
461 OutputFunc : mad_output_func;
462 ErrorFunc : mad_error_func;
463 MessageFunc : mad_message_func;
464 end;
465
466 procedure mad_decoder_init(var decoder: mad_decoder; user: pointer; Input: mad_input_func; Header: mad_header_func; Filter: mad_filter_func; Output: mad_output_func; Error: mad_error_func; Message: mad_message_func); cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_decoder_finishnull467 function mad_decoder_finish(var decoder: mad_decoder): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_decoder_runnull468 function mad_decoder_run(var decoder: mad_decoder; mode: mad_decoder_mode): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
mad_decoder_messagenull469 function mad_decoder_message(var decoder: mad_decoder; msg: Pointer; var l: cuint): cint; cdecl; external {$IFDEF DYNLINK}madlib{$ENDIF};
470 {$ENDIF}
471
472
473 {
474 Developer of the MAD helpers for FreePascal
475 Copyright (C) 2006 by Ivo Steinmann
476 }
477 {$IFDEF MAD_DISABLE_BUILTIN_DECODER}
478 const
479 MAD_INPUT_BUFFER_SIZE = 5*8192;
480
481 type
sernull482 mad_read_func = function(user: pointer; ptr: pointer; size: cuint): cuint; cdecl;
sernull483 mad_seek_func = function(user: pointer; offset: clong; whence: cint): clong; cdecl;
sernull484 mad_close_func = function(user: pointer): cint; cdecl;
sernull485 mad_tell_func = function(user: pointer): clong; cdecl;
486
487 pmad_decoder = ^mad_decoder;
488 mad_decoder = record
489 inbuf : array[0..MAD_INPUT_BUFFER_SIZE-1] of cuint8;
490 stream : mad_stream;
491 frame : mad_frame;
492 synth : mad_synth;
493 samplecnt : cint;
494 sampleofs : cint;
495 user : pointer;
496 read : mad_read_func;
497 seek : mad_seek_func;
498 close : mad_close_func;
499 tell : mad_tell_func;
500
501 // Userinfo
502 sample_rate : cint;
503 end;
504
mad_decoder_initnull505 function mad_decoder_init(user: pointer; read: mad_read_func; seek: mad_seek_func; close: mad_close_func; tell: mad_tell_func): pmad_decoder;
mad_decoder_readnull506 function mad_decoder_read(decoder: pmad_decoder; buffer: pointer; length: cint): cint;
507 procedure mad_decoder_free(decoder: pmad_decoder);
508 {$ENDIF}
509
510 implementation
511
MAD_VERSION_STRINGIZEnull512 function MAD_VERSION_STRINGIZE(num: cint): String;
513 begin
514 MAD_VERSION_STRINGIZE := '';
515 Str(num, MAD_VERSION_STRINGIZE);
516 end;
517
MAD_VERSION_STRINGnull518 function MAD_VERSION_STRING(num: cint): String;
519 begin
520 MAD_VERSION_STRING := MAD_VERSION_STRINGIZE(num);
521 end;
522
MAD_VERSIONnull523 function MAD_VERSION: String;
524 begin
525 MAD_VERSION :=
526 MAD_VERSION_STRING(MAD_VERSION_MAJOR) + '.' +
527 MAD_VERSION_STRING(MAD_VERSION_MINOR) + '.' +
528 MAD_VERSION_STRING(MAD_VERSION_PATCH) +
529 MAD_VERSION_EXTRA;
530 end;
531
532 {function mad_f_tofixed(x: double): mad_fixed_t;
533 begin
534 Result := mad_fixed_t(x * double(1 shl MAD_F_FRACBITS) + 0.5);
535 end;}
536
537 procedure mad_bit_finish(var bitptr: mad_bitptr);
538 begin
539 end;
540
mad_bit_bitsleftnull541 function mad_bit_bitsleft(var bitptr: mad_bitptr): cushort;
542 begin
543 mad_bit_bitsleft := bitptr.left;
544 end;
545
546 procedure mad_timer_reset(var timer: mad_timer_t);
547 begin
548 timer := mad_timer_zero;
549 end;
550
mad_timer_signnull551 function mad_timer_sign(timer: mad_timer_t): cint;
552 begin
553 mad_timer_sign := mad_timer_compare(timer, mad_timer_zero);
554 end;
555
MAD_RECOVERABLEnull556 function MAD_RECOVERABLE(error: mad_error): Boolean;
557 begin
558 MAD_RECOVERABLE := word(error) and $ff00 > 0;
559 end;
560
561 procedure mad_stream_options(stream: mad_stream; opts: cint);
562 begin
563 stream.options := opts;
564 end;
565
566 procedure mad_header_finish(var header: mad_header);
567 begin
568 FillChar(header, sizeof(mad_header), 0);
569 end;
570
mad_nchannelsnull571 function mad_nchannels(header: mad_header): cint;
572 begin
573 if longword(header.mode) <> 0 then
574 mad_nchannels := 2 else
575 mad_nchannels := 1;
576 end;
577
mad_nsbsamplesnull578 function mad_nsbsamples(header: mad_header): cint;
579 begin
580 if header.layer = MAD_LAYER_I then mad_nsbsamples := 12 else
581 if (header.layer = MAD_LAYER_III) and (header.flags and MAD_FLAG_LSF_EXT > 0)
582 then mad_nsbsamples := 18
583 else mad_nsbsamples := 36;
584 end;
585
586 procedure mad_synth_finish(var synth: mad_synth);
587 begin
588 FillChar(synth, sizeof(mad_synth), 0);
589 end;
590
591 {$IFDEF MAD_DISABLE_BUILTIN_DECODER}
mad_decoder_initnull592 function mad_decoder_init(user: pointer; read: mad_read_func; seek: mad_seek_func; close: mad_close_func; tell: mad_tell_func): pmad_decoder;
593 begin
594 GetMem(Result, Sizeof(mad_decoder));
595 FillChar(Result^, Sizeof(mad_decoder), 0);
596 mad_stream_init(Result^.stream);
597 mad_frame_init(Result^.frame);
598 mad_synth_init(Result^.synth);
599 Result^.user := user;
600 Result^.read := read;
601 Result^.seek := seek;
602 Result^.close := close;
603 Result^.tell := tell;
604 end;
605
606 procedure mad_decoder_free(decoder: pmad_decoder);
607 begin
608 if not Assigned(decoder) then
609 Exit;
610
611 mad_synth_finish(decoder^.synth);
612 mad_frame_finish(decoder^.frame);
613 mad_stream_finish(decoder^.stream);
614 decoder^.close(decoder^.user);
615 FreeMem(decoder);
616 end;
617
mad_decoder_readnull618 function mad_decoder_read(decoder: pmad_decoder; buffer: pointer; length: cint): cint;
619 var
620 ofs, num, i: cint;
621 inbuf_ptr: pointer;
622 len, remaining: cint;
623 begin
624 // check blocksize here!
625
626 ofs := 0;
627 num := length;
628
629 while num > 0 do
630 begin
631 if decoder^.samplecnt = 0 then
632 begin
633 if (decoder^.stream.buffer = nil) or (decoder^.stream.error = MAD_ERROR_BUFLEN) then
634 begin
635 if Assigned(decoder^.stream.next_frame) then
636 begin
637 remaining := ptruint(decoder^.stream.bufend) - ptruint(decoder^.stream.next_frame);
638 inbuf_ptr := pointer(ptruint(@decoder^.inbuf) + remaining);
639 len := MAD_INPUT_BUFFER_SIZE - remaining;
640 Move(decoder^.stream.next_frame^, decoder^.inbuf, remaining);
641 end else begin
642 remaining := 0;
643 len := MAD_INPUT_BUFFER_SIZE;
644 inbuf_ptr := @decoder^.inbuf;
645 end;
646
647 len := decoder^.read(decoder^.user, inbuf_ptr, len);
648 if len <= 0 then
649 Exit(ofs);
650
651 mad_stream_buffer(decoder^.stream, decoder^.inbuf, len+remaining);
652 decoder^.stream.error := MAD_ERROR_NONE;
653 end;
654
655 if mad_frame_decode(decoder^.frame, decoder^.stream) <> 0 then
656 begin
657 if MAD_RECOVERABLE(decoder^.stream.error) or (decoder^.stream.error = MAD_ERROR_BUFLEN) then
658 Continue;
659
660 Exit(ofs);
661 end;
662
663 mad_synth_frame(decoder^.synth, decoder^.frame);
664
665 with decoder^.synth do
666 if pcm.channels = 2 then
667 begin
668 for i := 0 to pcm.length -1 do
669 begin
670 if pcm.samples[0][i] >= MAD_F_ONE then
671 pcm.samples[0][i] := MAD_F_ONE - 1;
672 if pcm.samples[0][i] < -MAD_F_ONE then
673 pcm.samples[0][i] := -MAD_F_ONE;
674 pcm.samples[0][i] := pcm.samples[0][i] shr (MAD_F_FRACBITS + 1 - 16 + 1);
675
676 if pcm.samples[1][i] >= MAD_F_ONE then
677 pcm.samples[1][i] := MAD_F_ONE - 1;
678 if pcm.samples[1][i] < -MAD_F_ONE then
679 pcm.samples[1][i] := -MAD_F_ONE;
680 pcm.samples[1][i] := pcm.samples[1][i] shr (MAD_F_FRACBITS + 1 - 16 + 1);
681 end;
682 end else begin
683 for i := 0 to pcm.length -1 do
684 begin
685 if pcm.samples[0][i] >= MAD_F_ONE then
686 pcm.samples[0][i] := MAD_F_ONE - 1;
687 if pcm.samples[0][i] < -MAD_F_ONE then
688 pcm.samples[0][i] := -MAD_F_ONE;
689 pcm.samples[0][i] := pcm.samples[0][i] shr (MAD_F_FRACBITS + 1 - 16 + 1);
690 pcm.samples[1][i] := pcm.samples[0][i];
691 end;
692 end;
693
694 decoder^.sampleofs := 0;
695 decoder^.samplecnt := decoder^.synth.pcm.length;
696 decoder^.sample_rate := decoder^.synth.pcm.samplerate;
697 end;
698
699 len := num div 4;
700 if len > decoder^.samplecnt then
701 len := decoder^.samplecnt;
702
703 for i := 0 to len - 1 do
704 begin
705 pcint16(ptruint(buffer) + ofs + 0)^ := decoder^.synth.pcm.samples[0][decoder^.sampleofs];
706 pcint16(ptruint(buffer) + ofs + 2)^ := decoder^.synth.pcm.samples[1][decoder^.sampleofs];
707
708 Inc(decoder^.sampleofs);
709 Dec(decoder^.samplecnt);
710 ofs := ofs + 4;
711 num := num - 4;
712 end;
713 end;
714
715 Result := ofs;
716 end;
717 {$ENDIF}
718
719 end.
720