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