1 | {This unit is part of United Openlibraries of Sound (uos)}
|
---|
2 |
|
---|
3 | {This is the Dynamic loading version of FAAD2 Pascal Wrapper.
|
---|
4 | mcwNeAACDec.pas, mcwMP4FF.pas, mcwAAC.pas
|
---|
5 | By Franklyn A. Harlow Feb 2016
|
---|
6 | License : modified LGPL.
|
---|
7 | mcw* merged into uos_aac by Fred van Stappen / fiens@hotmail.com }
|
---|
8 |
|
---|
9 | unit uos_aac;
|
---|
10 |
|
---|
11 | {$mode objfpc}{$H+}
|
---|
12 | {$PACKRECORDS C}
|
---|
13 |
|
---|
14 | interface
|
---|
15 |
|
---|
16 | uses
|
---|
17 | Classes, SysUtils, ctypes, math,
|
---|
18 | dynlibs;
|
---|
19 |
|
---|
20 | const
|
---|
21 |
|
---|
22 | {$IFDEF unix}
|
---|
23 | {$IFDEF darwin}
|
---|
24 | libaa= 'libfaad.2.dylib';
|
---|
25 | libm4= 'libmp4ff.0.dylib';
|
---|
26 | {$ELSE}
|
---|
27 | libaa= 'libfaad.so.2';
|
---|
28 | libm4= 'libmp4ff.so.0.0.0';
|
---|
29 | {$ENDIF}
|
---|
30 | {$ELSE}
|
---|
31 | libaa= 'Faad2.dll';
|
---|
32 | libm4= 'mp4ff.dll';
|
---|
33 | {$ENDIF}
|
---|
34 |
|
---|
35 | //////////// from mcwMP4FF.pas By Franklyn A. Harlow
|
---|
36 | type
|
---|
37 |
|
---|
38 | ArSingle = array of Single;
|
---|
39 | PArSingle = ^ArSingle;
|
---|
40 |
|
---|
41 | read_callback_t = function(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
---|
42 | write_callback_t = function(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
---|
43 | seek_callback_t = function(user_data : Pointer; Position : cInt64) : LongWord; cdecl;
|
---|
44 | truncate_callback_t = function(user_data : Pointer) : LongWord; cdecl;
|
---|
45 |
|
---|
46 | mp4ff_callback_t = record
|
---|
47 | read : read_callback_t;
|
---|
48 | write : write_callback_t;
|
---|
49 | seek : seek_callback_t;
|
---|
50 | truncate : truncate_callback_t;
|
---|
51 | user_data : Pointer;
|
---|
52 | end;
|
---|
53 | p_mp4ff_callback_t = ^mp4ff_callback_t;
|
---|
54 |
|
---|
55 | mp4ff_t = pointer;
|
---|
56 | int32_t = LongInt;
|
---|
57 | int64_t = cInt64;
|
---|
58 | uint32_t = LongWord;
|
---|
59 |
|
---|
60 | var
|
---|
61 | mp4ff_open_read : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl;
|
---|
62 | mp4ff_open_read_metaonly : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl;
|
---|
63 | mp4ff_close : procedure(f : mp4ff_t); cdecl;
|
---|
64 | mp4ff_get_sample_duration : function(f : mp4ff_t; track, sample : int32_t) : int32_t; cdecl;
|
---|
65 | mp4ff_get_sample_duration_use_offsets : function(f : mp4ff_t; track, sample : int32_t) : int32_t; cdecl;
|
---|
66 | mp4ff_get_sample_position : function(f : mp4ff_t; track, sample : int32_t) : int64_t; cdecl;
|
---|
67 | mp4ff_get_sample_offset : function(f : mp4ff_t; track, sample : int32_t) : int32_t; cdecl;
|
---|
68 | mp4ff_find_sample : function(f : mp4ff_t; track : int32_t; offset : int64_t; var toskip : int32_t) : int32_t; cdecl;
|
---|
69 | mp4ff_find_sample_use_offsets : function(f : mp4ff_t; track : int32_t; offset : int64_t; var toskip : int32_t) : int32_t; cdecl;
|
---|
70 | mp4ff_set_sample_position : function(f : mp4ff_t; track : int32_t; sample : int64_t) : int32_t; cdecl;
|
---|
71 | mp4ff_read_sample : function(f : mp4ff_t; track, sample : int32_t; var audio_buffer : pcfloat; var bytes : LongWord) : int32_t; cdecl;
|
---|
72 | mp4ff_read_sample_v2 : function(f : mp4ff_t; track, sample : int32_t; buffer : pcfloat): int32_t; cdecl; //returns 0 on error, number of bytes read on success, use mp4ff_read_sample_getsize_t = function() to check buffer size needed
|
---|
73 | mp4ff_read_sample_getsize : function(f : mp4ff_t; track, sample : Integer) : int32_t; cdecl; //returns 0 on error, buffer size needed for mp4ff_read_sample_v2_t = function() on success
|
---|
74 | mp4ff_get_decoder_config : function(f : mp4ff_t; track : Integer; var ppBuf : pcfloat; var pBufSize : LongWord) : int32_t; cdecl;
|
---|
75 | mp4ff_free_decoder_config : procedure(Buf : pcfloat); cdecl;
|
---|
76 | mp4ff_get_track_type : function(f : mp4ff_t; const track : Integer) : int32_t; cdecl;
|
---|
77 | mp4ff_total_tracks : function(f : mp4ff_t) : int32_t; cdecl;
|
---|
78 | mp4ff_num_samples : function(f : mp4ff_t; track : Integer) : int32_t; cdecl;
|
---|
79 | mp4ff_time_scale : function(f : mp4ff_t; track : Integer) : int32_t; cdecl;
|
---|
80 | mp4ff_get_avg_bitrate : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
---|
81 | mp4ff_get_max_bitrate : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
---|
82 | mp4ff_get_track_duration : function(f : mp4ff_t; track : int32_t) : int64_t; cdecl; //returns _t = function(-1) if unknown
|
---|
83 | mp4ff_get_track_duration_use_offsets : function(f : mp4ff_t; track : int32_t) : Integer; cdecl; //returns _t = function(-1) if unknown
|
---|
84 | mp4ff_get_sample_rate : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
---|
85 | mp4ff_get_channel_count : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
---|
86 | mp4ff_get_audio_type : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
---|
87 | mp4ff_meta_get_num_items : function(f : mp4ff_t) : Integer; cdecl;
|
---|
88 | mp4ff_meta_get_by_index : function(f : mp4ff_t; index : LongWord; var item, value : PChar) : Integer; cdecl;
|
---|
89 | mp4ff_meta_get_title : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
90 | mp4ff_meta_get_artist : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
91 | mp4ff_meta_get_writer : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
92 | mp4ff_meta_get_album : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
93 | mp4ff_meta_get_date : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
94 | mp4ff_meta_get_tool : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
95 | mp4ff_meta_get_comment : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
96 | mp4ff_meta_get_genre : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
97 | mp4ff_meta_get_track : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
98 | mp4ff_meta_get_disc : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
99 | mp4ff_meta_get_totaltracks : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
100 | mp4ff_meta_get_totaldiscs : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
101 | mp4ff_meta_get_compilation : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
102 | mp4ff_meta_get_tempo : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
103 | mp4ff_meta_get_coverart : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
---|
104 |
|
---|
105 | function GetAACTrack(infile : mp4ff_t) : Integer;
|
---|
106 | procedure Loadmp4ff(mp4ff : AnsiString);
|
---|
107 | procedure UnLoadMp4ff;
|
---|
108 | Function isMp4ffLoaded : Boolean;
|
---|
109 |
|
---|
110 | //////////// from mcwNeAACDec.pas by Franklyn A. Harlow
|
---|
111 | Const
|
---|
112 | { object types for AAC }
|
---|
113 | MAIN = 1;
|
---|
114 | LC = 2;
|
---|
115 | SSR = 3;
|
---|
116 | LTP = 4;
|
---|
117 | HE_AAC = 5;
|
---|
118 | ER_LC = 17;
|
---|
119 | ER_LTP = 19;
|
---|
120 | LD = 23;
|
---|
121 | { special object type for DRM }
|
---|
122 | DRM_ER_LC = 27;
|
---|
123 | { header types }
|
---|
124 | RAW = 0;
|
---|
125 | ADIF = 1;
|
---|
126 | ADTS = 2;
|
---|
127 | LATM = 3;
|
---|
128 | { SBR signalling }
|
---|
129 | NO_SBR = 0;
|
---|
130 | SBR_UPSAMPLED = 1;
|
---|
131 | SBR_DOWNSAMPLED = 2;
|
---|
132 | NO_SBR_UPSAMPLED = 3;
|
---|
133 | { library output formats }
|
---|
134 | FAAD_FMT_16BIT = 1;
|
---|
135 | FAAD_FMT_24BIT = 2;
|
---|
136 | FAAD_FMT_32BIT = 3;
|
---|
137 | FAAD_FMT_FLOAT = 4;
|
---|
138 | FAAD_FMT_FIXED = FAAD_FMT_FLOAT;
|
---|
139 | FAAD_FMT_DOUBLE = 5;
|
---|
140 | { Capabilities }
|
---|
141 | { Can decode LC }
|
---|
142 | LC_DEC_CAP = 1 shl 0;
|
---|
143 | { Can decode MAIN }
|
---|
144 | MAIN_DEC_CAP = 1 shl 1;
|
---|
145 | { Can decode LTP }
|
---|
146 | LTP_DEC_CAP = 1 shl 2;
|
---|
147 | { Can decode LD }
|
---|
148 | LD_DEC_CAP = 1 shl 3;
|
---|
149 | { Can decode ER }
|
---|
150 | ERROR_RESILIENCE_CAP = 1 shl 4;
|
---|
151 | { Fixed point }
|
---|
152 | FIXED_POINT_CAP = 1 shl 5;
|
---|
153 | { Channel definitions }
|
---|
154 | FRONT_CHANNEL_CENTER = 1;
|
---|
155 | FRONT_CHANNEL_LEFT = 2;
|
---|
156 | FRONT_CHANNEL_RIGHT = 3;
|
---|
157 | SIDE_CHANNEL_LEFT = 4;
|
---|
158 | SIDE_CHANNEL_RIGHT = 5;
|
---|
159 | BACK_CHANNEL_LEFT = 6;
|
---|
160 | BACK_CHANNEL_RIGHT = 7;
|
---|
161 | BACK_CHANNEL_CENTER = 8;
|
---|
162 | LFE_CHANNEL = 9;
|
---|
163 | UNKNOWN_CHANNEL = 0;
|
---|
164 | { DRM channel definitions }
|
---|
165 | DRMCH_MONO = 1;
|
---|
166 | DRMCH_STEREO = 2;
|
---|
167 | DRMCH_SBR_MONO = 3;
|
---|
168 | DRMCH_SBR_STEREO = 4;
|
---|
169 | DRMCH_SBR_PS_STEREO = 5;
|
---|
170 | { A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel,
|
---|
171 | so at least so much bytes per channel should be available in this stream }
|
---|
172 | { 6144 bits/channel }
|
---|
173 | FAAD_MIN_STREAMSIZE = 768;
|
---|
174 |
|
---|
175 | Type
|
---|
176 | PNeAACDec = Pointer;
|
---|
177 |
|
---|
178 | NeAAC_byte = {$IFDEF FPC}{$IFDEF CPU64}cuint32 {$ELSE}Byte {$ENDIF}{$ELSE}Byte {$ENDIF};
|
---|
179 | NeAAC_word = {$IFDEF FPC}{$IFDEF CPU64}cuint64{$ELSE}Word {$ENDIF}{$ELSE}Word {$ENDIF};
|
---|
180 | NeAAC_longword = {$IFDEF FPC}{$IFDEF CPU64}culong {$ELSE}LongWord{$ENDIF}{$ELSE}LongWord{$ENDIF};
|
---|
181 |
|
---|
182 | NeAACDecConfiguration = record
|
---|
183 | defObjectType : NeAAC_byte;
|
---|
184 | defSampleRate : NeAAC_longword;
|
---|
185 | outputFormat : NeAAC_byte;
|
---|
186 | downMatrix : NeAAC_byte;
|
---|
187 | useOldADTSFormat : NeAAC_byte;
|
---|
188 | dontUpSampleImplicitSBR : NeAAC_byte;
|
---|
189 | end;
|
---|
190 | TNeAACDecConfiguration = NeAACDecConfiguration;
|
---|
191 | PNeAACDecConfiguration = ^NeAACDecConfiguration;
|
---|
192 |
|
---|
193 | NeAACDecFrameInfo = record
|
---|
194 | bytesconsumed : NeAAC_longword;
|
---|
195 | samples : NeAAC_longword;
|
---|
196 | channels : NeAAC_byte;
|
---|
197 | error : NeAAC_byte;
|
---|
198 | samplerate : NeAAC_longword;
|
---|
199 | sbr : NeAAC_byte; //* SBR: 0: off, 1: on; upsample, 2: on; downsampled, 3: off; upsampled */
|
---|
200 | object_type : NeAAC_byte; //* MPEG-4 ObjectType */
|
---|
201 | header_type : NeAAC_byte; //* AAC header type; MP4 will be signalled as RAW also */
|
---|
202 | num_front_channels : NeAAC_byte; //* multichannel configuration */
|
---|
203 | num_side_channels : NeAAC_byte;
|
---|
204 | num_back_channels : NeAAC_byte;
|
---|
205 | num_lfe_channels : NeAAC_byte;
|
---|
206 | channel_position : array[0..63] of NeAAC_byte;
|
---|
207 | ps : NeAAC_byte; //* PS: 0: off, 1: on */
|
---|
208 | end;
|
---|
209 | TNeAACDecFrameInfo = NeAACDecFrameInfo;
|
---|
210 | PNeAACDecFrameInfo = ^NeAACDecFrameInfo;
|
---|
211 |
|
---|
212 | mp4AudioSpecificConfig = record
|
---|
213 | objectTypeIndex : NeAAC_byte;
|
---|
214 | samplingFrequencyIndex : NeAAC_byte;
|
---|
215 | samplingFrequency : NeAAC_longword;
|
---|
216 | channelsConfiguration : NeAAC_byte;
|
---|
217 | frameLengthFlag : NeAAC_byte; //* GA Specific Info */
|
---|
218 | dependsOnCoreCoder : NeAAC_byte;
|
---|
219 | coreCoderDelay : NeAAC_word;
|
---|
220 | extensionFlag : NeAAC_byte;
|
---|
221 | aacSectionDataResilienceFlag : NeAAC_byte;
|
---|
222 | aacScalefactorDataResilienceFlag : NeAAC_byte;
|
---|
223 | aacSpectralDataResilienceFlag : NeAAC_byte;
|
---|
224 | epConfig : NeAAC_byte;
|
---|
225 | sbr_present_flag : NeAAC_byte;
|
---|
226 | forceUpSampling : NeAAC_byte;
|
---|
227 | downSampledSBR : NeAAC_byte;
|
---|
228 | end;
|
---|
229 | Tmp4AudioSpecificConfig = mp4AudioSpecificConfig;
|
---|
230 | Pmp4AudioSpecificConfig = ^mp4AudioSpecificConfig;
|
---|
231 |
|
---|
232 | var
|
---|
233 | NeAACDecGetErrorMessage : function(ErrorCode : Byte) : PChar; cdecl;
|
---|
234 | NeAACDecGetCapabilities : function : LongWord; cdecl;
|
---|
235 | NeAACDecOpen : function : PNeAACDec; cdecl;
|
---|
236 | NeAACDecGetCurrentConfiguration : function( hDecoder : PNeAACDec) : PNeAACDecConfiguration; cdecl;
|
---|
237 | NeAACDecSetConfiguration : function( hDecoder : PNeAACDec; pConfig : PNeAACDecConfiguration) : Byte; cdecl;
|
---|
238 | NeAACDecInit : function( hDecoder : PNeAACDec; pBuffer : pcfloat; lwBufferLength : LongWord; var lwSampleRate : LongWord; var Channels : Byte) : LongInt; cdecl;
|
---|
239 | NeAACDecInit2 : function( hDecoder : PNeAACDec; pBuffer : pcfloat; SizeOfDecoderSpecificInfo : LongWord; var lwSampleRate : LongWord; var Channels : Byte) : Byte; cdecl;
|
---|
240 | NeAACDecPostSeekReset : procedure(hDecoder : PNeAACDec; Frame : LongInt); cdecl;
|
---|
241 | NeAACDecClose : procedure(hDecoder : PNeAACDec); cdecl;
|
---|
242 | NeAACDecDecode : function( hDecoder : PNeAACDec; hInfo : PNeAACDecFrameInfo; pBuffer : pcfloat; lwBufferLength : LongWord) : Pointer; cdecl;
|
---|
243 | NeAACDecDecode2 : function( hDecoder : PNeAACDec; hInfo : PNeAACDecFrameInfo; pBuffer : pcfloat; lwBufferLength : LongWord; var pSampleBuf : Pointer; lwSampleBufSize : LongWord) : Pointer; cdecl;
|
---|
244 | NeAACDecAudioSpecificConfig : function( pBuffer : pcfloat; lwBufferLength : LongWord; var mp4ASC : mp4AudioSpecificConfig) : Byte; cdecl;
|
---|
245 |
|
---|
246 | procedure LoadNeAAC(NeAAC : AnsiString);
|
---|
247 | Procedure UnLoadNeAAC;
|
---|
248 | Function Is_NeAAC_Loaded : Boolean;
|
---|
249 |
|
---|
250 | //////////////////
|
---|
251 |
|
---|
252 | // from mcwAAC.pas from Franklyn A. Harlow
|
---|
253 | Const
|
---|
254 | kNeAAC_OK = 1;
|
---|
255 | kNeAAC_FAIL = 0;
|
---|
256 |
|
---|
257 | Type
|
---|
258 |
|
---|
259 | TAACIdata = array[0..2024*1024-1] of byte;
|
---|
260 |
|
---|
261 | TAACInfo = class(TObject)
|
---|
262 | public
|
---|
263 | // libfaad control interface...
|
---|
264 | fsStream : TFileStream;
|
---|
265 | pDecoder : PNeAACDec;
|
---|
266 | hMP4 : mp4ff_t;
|
---|
267 |
|
---|
268 | // output interface setup...
|
---|
269 | Channels : longword; // stereo = 2
|
---|
270 | BitsPerSample : longword; // ie short/smallint = 16
|
---|
271 | SampleRate : longword; // Frequency = 44100
|
---|
272 | outputFormat : byte; // See FAAD_FMT_16BIT etc...
|
---|
273 |
|
---|
274 | Bitrate : longword; // 256000 = 256
|
---|
275 |
|
---|
276 | TotalTime : double; // Length in Seconds
|
---|
277 |
|
---|
278 | {$if not defined(fs32bit)}
|
---|
279 | TotalSamples : cint64;
|
---|
280 | Size : cint64; // in frames
|
---|
281 | Position : cint64; // in frames
|
---|
282 | {$else}
|
---|
283 | TotalSamples : cint;
|
---|
284 | Size : cint; // in frames
|
---|
285 | Position : cint; // in frames
|
---|
286 | {$endif}
|
---|
287 |
|
---|
288 | // UoS interface
|
---|
289 | pData : pcfloat;
|
---|
290 | lwDataLen : longword;
|
---|
291 |
|
---|
292 | // tag info...
|
---|
293 | Artist : AnsiString;
|
---|
294 | AlbumArtist : AnsiString;
|
---|
295 | Album : AnsiString;
|
---|
296 | Title : AnsiString;
|
---|
297 | Date : AnsiString;
|
---|
298 | Genre : AnsiString;
|
---|
299 | Track : AnsiString;
|
---|
300 | Comment : AnsiString;
|
---|
301 |
|
---|
302 | // internal data...
|
---|
303 | cbs : mp4ff_callback_t;
|
---|
304 | _Buf : TAACIdata;
|
---|
305 | BufTmp : TAACIdata;
|
---|
306 | fTrack : longint;
|
---|
307 | fTimescale : longword; // Not actually used
|
---|
308 |
|
---|
309 | fBufStart : longword;
|
---|
310 | fBufEnd : longword;
|
---|
311 | End;
|
---|
312 |
|
---|
313 | Function aa_load(mp4ff, NeAAC: AnsiString): Boolean;
|
---|
314 | Procedure aa_Unload;
|
---|
315 | Function isLibAACLoaded : Boolean;
|
---|
316 |
|
---|
317 | Function MP4OpenFile(fName : String; OutputFormat : Byte) : TAACInfo;
|
---|
318 | Procedure MP4CloseFile(var AACI: TAACInfo);
|
---|
319 | procedure MP4GetData(var AACI: TAACInfo; var Buffer: pcfloat; var Bytes: longword);
|
---|
320 | function MP4Seek(var AACI: TAACInfo; var SampleNum: longint) : Boolean;
|
---|
321 |
|
---|
322 | implementation
|
---|
323 |
|
---|
324 | var
|
---|
325 | // hNeAAC: {$IFDEF MSWINDOWS}longword{$ELSE}{$IFDEF CPU32}longword{$ELSE}PtrInt{$ENDIF}{$ENDIF};
|
---|
326 | hNeAAC:TLibHandle=dynlibs.NilHandle;
|
---|
327 | NeAACLoaded : Boolean;
|
---|
328 | Mp4ffLoaded : Boolean = False;
|
---|
329 | hMp4ff:TLibHandle=dynlibs.NilHandle;
|
---|
330 |
|
---|
331 | //////////// from mcwNeAACDec.pas By Franklyn A. Harlow
|
---|
332 |
|
---|
333 | function CBMP4Read(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
---|
334 | begin
|
---|
335 | try
|
---|
336 | Result := LongWord(TAACInfo(user_data).fsStream.Read(buffer^, Integer(length)));
|
---|
337 | except
|
---|
338 | Result := 0;
|
---|
339 | end;
|
---|
340 | end;
|
---|
341 |
|
---|
342 | function CBMP4Write(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
---|
343 | begin
|
---|
344 | try
|
---|
345 | Result := LongWord(TAACInfo(user_data).fsStream.Write(buffer^, Integer(length)));
|
---|
346 | TAACInfo(user_data).fsStream.Position:=0;
|
---|
347 | except
|
---|
348 | Result := 0;
|
---|
349 | end;
|
---|
350 | end;
|
---|
351 |
|
---|
352 | function CBMP4Seek(user_data : Pointer; Position : Int64) : LongWord; cdecl;
|
---|
353 | begin
|
---|
354 | try
|
---|
355 | Result := LongWord(TAACInfo(user_data).fsStream.Seek(Position, soBeginning));
|
---|
356 | except
|
---|
357 | Result := 0;
|
---|
358 | end;
|
---|
359 | end;
|
---|
360 |
|
---|
361 | function CBMP4Truncate(user_data : Pointer) : LongWord; cdecl;
|
---|
362 | begin
|
---|
363 | Result := 0;
|
---|
364 | end;
|
---|
365 |
|
---|
366 | //////////// from mcwAAC.pas By Franklyn A. Harlow
|
---|
367 |
|
---|
368 | Function aa_load(mp4ff, NeAAC: AnsiString): Boolean;
|
---|
369 | Begin
|
---|
370 | // Safe To Call Multiple times, actual load of Lib checks to see if it is already loaded &
|
---|
371 | // returns true if it is...
|
---|
372 | LoadNeAAC(NeAAC);
|
---|
373 |
|
---|
374 | Loadmp4ff(mp4ff);
|
---|
375 |
|
---|
376 | Result:= Is_NeAAC_Loaded And isMp4ffLoaded;
|
---|
377 | End;
|
---|
378 |
|
---|
379 | Procedure aa_Unload;
|
---|
380 | Begin
|
---|
381 | UnLoadNeAAC();
|
---|
382 | UnLoadMp4ff();
|
---|
383 | End;
|
---|
384 |
|
---|
385 | Function isLibAACLoaded : Boolean;
|
---|
386 | Begin
|
---|
387 | Result:= Is_NeAAC_Loaded And isMp4ffLoaded;
|
---|
388 | end;
|
---|
389 |
|
---|
390 | Function isFileAAC(fName : AnsiString): Boolean;
|
---|
391 | Begin
|
---|
392 | Result:= LowerCase(ExtractFileExt(fName)) = '.m4a';
|
---|
393 | end;
|
---|
394 |
|
---|
395 | Function MP4OpenFile(fName : String; OutputFormat : Byte) : TAACInfo;
|
---|
396 | Var
|
---|
397 | pConfig : PNeAACDecConfiguration;
|
---|
398 | mp4ASC : mp4AudioSpecificConfig;
|
---|
399 |
|
---|
400 | pBuf : pcfloat;
|
---|
401 | lwBufSize : longword;
|
---|
402 | lwBufSize2 : longword;
|
---|
403 | lwSampleRate : longword;
|
---|
404 | bChannels : byte;
|
---|
405 |
|
---|
406 | bRet : Byte;
|
---|
407 | iRet : LongInt;
|
---|
408 | pID3 : PAnsiChar;
|
---|
409 | f : Double;
|
---|
410 | Begin
|
---|
411 | Result:= nil;
|
---|
412 | if not FileExists(fName) then
|
---|
413 | Exit;
|
---|
414 | if Not isFileAAC(fName) then
|
---|
415 | Exit;
|
---|
416 | // writeln('MP4OpenFileBegin');
|
---|
417 |
|
---|
418 | Result:= TAACInfo.Create;
|
---|
419 | // writeln('MP4OpenFile3');
|
---|
420 |
|
---|
421 | Result.fsStream:= TFileStream.Create(fName, fmOpenRead or fmShareDenyWrite);
|
---|
422 |
|
---|
423 | sleep(1);
|
---|
424 |
|
---|
425 | // writeln('MP4OpenFile4');
|
---|
426 | Result.cbs.read := @CBMP4Read;
|
---|
427 | Result.cbs.write := @CBMP4Write;
|
---|
428 | Result.cbs.seek := @CBMP4Seek;
|
---|
429 | Result.cbs.truncate := @CBMP4Truncate;
|
---|
430 | Result.cbs.user_data := Pointer(Result);
|
---|
431 | // writeln('MP4OpenFile5');
|
---|
432 |
|
---|
433 | Result.pDecoder := NeAACDecOpen();
|
---|
434 | // writeln('MP4OpenFile6');
|
---|
435 |
|
---|
436 | pConfig := NeAACDecGetCurrentConfiguration(Result.pDecoder);
|
---|
437 | // writeln('MP4OpenFile7');
|
---|
438 | pConfig^.defObjectType := LC;
|
---|
439 | pConfig^.defSampleRate := 44100;
|
---|
440 | pConfig^.outputFormat := OutputFormat; // FAAD_FMT_FLOAT FAAD_FMT_16BIT FAAD_FMT_32BIT
|
---|
441 | pConfig^.downMatrix := 1;
|
---|
442 | pConfig^.dontUpSampleImplicitSBR := 0;
|
---|
443 |
|
---|
444 | NeAACDecSetConfiguration(Result.pDecoder, pConfig) ;
|
---|
445 |
|
---|
446 | pConfig := NeAACDecGetCurrentConfiguration(Result.pDecoder);
|
---|
447 | // writeln('MP4OpenFile9');
|
---|
448 |
|
---|
449 | case pConfig^.outputFormat of
|
---|
450 | FAAD_FMT_16BIT : Result.BitsPerSample := 16;
|
---|
451 | FAAD_FMT_24BIT : Result.BitsPerSample := 24;
|
---|
452 | FAAD_FMT_32BIT : Result.BitsPerSample := 32;
|
---|
453 | FAAD_FMT_FLOAT : Result.BitsPerSample := 32;
|
---|
454 | FAAD_FMT_DOUBLE: Result.BitsPerSample := 64;
|
---|
455 | end;
|
---|
456 | // writeln('MP4OpenFile10');
|
---|
457 | Result.outputFormat:= pConfig^.outputFormat;
|
---|
458 |
|
---|
459 | Result.hMP4 := mp4ff_open_read(@Result.cbs);
|
---|
460 | // writeln('MP4OpenFile11');
|
---|
461 |
|
---|
462 | Result.fTrack := GetAACTrack(Result.hMP4);
|
---|
463 | // writeln('MP4OpenFile12');
|
---|
464 |
|
---|
465 | pBuf:= nil;
|
---|
466 | iRet:= mp4ff_get_decoder_config(Result.hMP4, Result.fTrack, pBuf, lwBufSize);
|
---|
467 | // writeln('MP4OpenFile13');
|
---|
468 |
|
---|
469 | lwBufSize2:= lwBufSize;
|
---|
470 | // writeln('MP4OpenFile14');
|
---|
471 |
|
---|
472 | bRet:= NeAACDecInit2(Result.pDecoder, pBuf, lwBufSize, lwSampleRate, bChannels);
|
---|
473 | // writeln('MP4OpenFile15');
|
---|
474 |
|
---|
475 | Result.SampleRate := mp4ff_get_sample_rate(Result.hMP4, Result.fTrack);
|
---|
476 | Result.Channels := mp4ff_get_channel_count(Result.hMP4, Result.fTrack);
|
---|
477 | Result.fTimescale := mp4ff_time_scale(Result.hMP4, Result.fTrack);
|
---|
478 | Result.Bitrate := mp4ff_get_avg_bitrate(Result.hMP4, Result.fTrack);
|
---|
479 | Result.Size := mp4ff_num_samples(Result.hMP4, Result.fTrack);
|
---|
480 | // writeln('MP4OpenFile16');
|
---|
481 |
|
---|
482 | if pBuf <> nil then
|
---|
483 | begin
|
---|
484 | bRet:= NeAACDecAudioSpecificConfig(pBuf, lwBufSize2, mp4ASC);
|
---|
485 | // writeln('MP4OpenFile17');
|
---|
486 |
|
---|
487 | if bRet <> 0 then
|
---|
488 | Begin
|
---|
489 | // unix x64, NeAACDecAudioSpecificConfig Fails correct read,
|
---|
490 | // But if both previous SampleRates match, we'll use them...
|
---|
491 | {$IFDEF unix}{$IFDEF CPU64}
|
---|
492 | if Result.SampleRate = lwSampleRate then
|
---|
493 | Begin
|
---|
494 | mp4ASC.sbr_present_flag := 0;
|
---|
495 | mp4ASC.samplingFrequency := lwSampleRate;
|
---|
496 | End;
|
---|
497 | {$ENDIF}{$ENDIF}
|
---|
498 | End;
|
---|
499 | // writeln('MP4OpenFile18');
|
---|
500 | mp4ff_free_decoder_config(pBuf);
|
---|
501 | // writeln('MP4OpenFile19');
|
---|
502 | end;
|
---|
503 |
|
---|
504 | f := 1024.0;
|
---|
505 | if mp4ASC.sbr_present_flag = 1 then
|
---|
506 | f := f * 2.0;
|
---|
507 | Result.TotalTime := Result.Size * (f-1.0) / mp4ASC.samplingFrequency;
|
---|
508 | { ...End}
|
---|
509 | Result.TotalSamples := Trunc(Result.TotalTime * mp4ASC.samplingFrequency);
|
---|
510 | // writeln('MP4OpenFile20');
|
---|
511 | if mp4ASC.samplingFrequency > Result.SampleRate then
|
---|
512 | Result.SampleRate:= mp4ASC.samplingFrequency;
|
---|
513 |
|
---|
514 | Result.Artist:= '';
|
---|
515 | iRet:= mp4ff_meta_get_writer(Result.hMP4, pID3);
|
---|
516 | if iRet = 1 then
|
---|
517 | Result.Artist:= pID3;
|
---|
518 |
|
---|
519 | Result.AlbumArtist:= '';
|
---|
520 | iRet:= mp4ff_meta_get_artist(Result.hMP4, pID3);
|
---|
521 | if iRet = 1 then
|
---|
522 | Result.AlbumArtist:= pID3;
|
---|
523 |
|
---|
524 | Result.Album:= '';
|
---|
525 | iRet:= mp4ff_meta_get_album(Result.hMP4, pID3);
|
---|
526 | if iRet = 1 then
|
---|
527 | Result.Album:= pID3;
|
---|
528 |
|
---|
529 | Result.Title:= '';
|
---|
530 | iRet:= mp4ff_meta_get_title(Result.hMP4, pID3);
|
---|
531 | if iRet = 1 then
|
---|
532 | Result.Title:= pID3;
|
---|
533 |
|
---|
534 | Result.Date:= '';
|
---|
535 | iRet:= mp4ff_meta_get_date(Result.hMP4, pID3);
|
---|
536 | if iRet = 1 then
|
---|
537 | Result.Date:= pID3;
|
---|
538 |
|
---|
539 | Result.Genre:= '';
|
---|
540 | iRet:= mp4ff_meta_get_genre(Result.hMP4, pID3);
|
---|
541 | if iRet = 1 then
|
---|
542 | Result.Genre:= pID3;
|
---|
543 |
|
---|
544 | Result.Track:= '';
|
---|
545 | iRet:= mp4ff_meta_get_track(Result.hMP4, pID3);
|
---|
546 | if iRet = 1 then
|
---|
547 | Result.Track:= pID3;
|
---|
548 |
|
---|
549 | Result.Comment:= '';
|
---|
550 | iRet:= mp4ff_meta_get_comment(Result.hMP4, pID3);
|
---|
551 | if iRet = 1 then
|
---|
552 | Result.Comment:= pID3;
|
---|
553 |
|
---|
554 | Result.Position := 0;
|
---|
555 | Result.fBufStart := 0;
|
---|
556 | Result.fBufEnd := 0;
|
---|
557 | // writeln('MP4OpenFile End');
|
---|
558 | end;
|
---|
559 |
|
---|
560 | Procedure MP4CloseFile(var AACI: TAACInfo);
|
---|
561 | Begin
|
---|
562 | // writeln('MP4CloseFile1');
|
---|
563 | NeAACDecClose(AACI.pDecoder);
|
---|
564 | sleep(50);
|
---|
565 | // writeln('MP4CloseFile2');
|
---|
566 | mp4ff_close(AACI.hMP4);
|
---|
567 | // writeln('MP4CloseFile3');
|
---|
568 | sleep(50);
|
---|
569 | end;
|
---|
570 |
|
---|
571 | procedure MP4GetData(var AACI: TAACInfo; var Buffer: pcfloat; var Bytes: longword);
|
---|
572 | var
|
---|
573 | ReqBytes : longword;
|
---|
574 | CurBufSize : longword;
|
---|
575 | NewSampleBuf : Pointer;
|
---|
576 | NewBytesRead : longword;
|
---|
577 | NewBytesDecoded : longword;
|
---|
578 |
|
---|
579 | Function readNextSample(var audioBuf : pcfloat; var audioSize : longword): longword;
|
---|
580 | Begin
|
---|
581 | audioSize := 0;
|
---|
582 | Result:= 0;
|
---|
583 | audioBuf := nil;
|
---|
584 | // writeln('readNextSample');
|
---|
585 | if AACI.Position > AACI.Size then
|
---|
586 | Begin
|
---|
587 | Result:= 0;
|
---|
588 | Exit;
|
---|
589 | end;
|
---|
590 | Result := mp4ff_read_sample(AACI.hMP4, AACI.fTrack, AACI.Position, audioBuf, audioSize);
|
---|
591 | Inc(AACI.Position);
|
---|
592 | end;
|
---|
593 |
|
---|
594 | Function getNextChunk(var SampBuf : Pointer; var NBR : longword) : longword;
|
---|
595 | Var
|
---|
596 | pAB : pcfloat;
|
---|
597 | iAB : longword;
|
---|
598 | frameInfo: NeAACDecFrameInfo;
|
---|
599 | Begin
|
---|
600 | NBR:= 0;
|
---|
601 | // writeln('getNextChunk');
|
---|
602 | Result:= 0;
|
---|
603 | Result:= readNextSample(pAB, iAB);
|
---|
604 | if Result = 0 then Exit;
|
---|
605 | SampBuf := NeAACDecDecode(AACI.pDecoder, @frameInfo, pAB, iAB);
|
---|
606 | if pAB <> nil then
|
---|
607 | mp4ff_free_decoder_config(pAB);
|
---|
608 |
|
---|
609 | NBR:= frameInfo.samples * (AACI.BitsPerSample div 8);
|
---|
610 | end;
|
---|
611 |
|
---|
612 | begin
|
---|
613 | // writeln('MP4GetData1');
|
---|
614 | ReqBytes:= Bytes;
|
---|
615 | // writeln('MP4GetDataBegin1-2');
|
---|
616 | CurBufSize:= AACI.fBufEnd - AACI.fBufStart;
|
---|
617 |
|
---|
618 | While ReqBytes > CurBufSize do
|
---|
619 | Begin
|
---|
620 | // writeln('MP4GetData31');
|
---|
621 | // We need to put more data into Buffer...
|
---|
622 |
|
---|
623 | // If We Have Left Over Data...
|
---|
624 | if CurBufSize > 0 then
|
---|
625 | Begin
|
---|
626 | // Save Existing Left over data..
|
---|
627 | Move(AACI._Buf[AACI.fBufStart], AACI.BufTmp[0], CurBufSize);
|
---|
628 | // Put Existing Data to Start of buffer...
|
---|
629 | Move(AACI.BufTmp[0], AACI._Buf[0], CurBufSize);
|
---|
630 | end;
|
---|
631 |
|
---|
632 | // writeln('MP4GetData32');
|
---|
633 | // because we reshuffled buffers, AACI.fBufStart is now 0
|
---|
634 | AACI.fBufStart:= 0;
|
---|
635 | NewSampleBuf := nil;
|
---|
636 | // Read next block of data
|
---|
637 |
|
---|
638 | NewBytesRead:= getNextChunk(NewSampleBuf, NewBytesDecoded);
|
---|
639 |
|
---|
640 | // writeln('MP4GetData322');
|
---|
641 | if NewBytesRead = 0 then
|
---|
642 | begin
|
---|
643 | Buffer := nil;
|
---|
644 | Bytes := 0;
|
---|
645 | Exit;
|
---|
646 | end;
|
---|
647 | // writeln('MP4GetData33');
|
---|
648 | // Append new data to buffer
|
---|
649 | Move(NewSampleBuf^, AACI._Buf[CurBufSize], NewBytesDecoded);
|
---|
650 | // Update current unprocessed data count
|
---|
651 | CurBufSize:= CurBufSize + NewBytesDecoded;
|
---|
652 | // writeln('MP4GetData34');
|
---|
653 | end;
|
---|
654 |
|
---|
655 | // writeln('MP4GetData4');
|
---|
656 |
|
---|
657 | // set AACI.fBufEnd to last valid data byte in buffer
|
---|
658 | AACI.fBufEnd:= CurBufSize;
|
---|
659 |
|
---|
660 | // writeln('MP4GetData5');
|
---|
661 |
|
---|
662 | // If requested Byte count is more tha what we have, reduce requested count..
|
---|
663 | if Bytes > AACI.fBufEnd - AACI.fBufStart then
|
---|
664 | Bytes := AACI.fBufEnd - AACI.fBufStart;
|
---|
665 |
|
---|
666 | // writeln('MP4GetData6');
|
---|
667 |
|
---|
668 | // pass data back to calling function/procedure
|
---|
669 | Buffer := @AACI._Buf[AACI.fBufStart];
|
---|
670 |
|
---|
671 | // writeln('MP4GetData7');
|
---|
672 |
|
---|
673 | Inc(AACI.fBufStart, Bytes);
|
---|
674 |
|
---|
675 | // writeln('MP4GetData8');
|
---|
676 |
|
---|
677 | end;
|
---|
678 |
|
---|
679 | function MP4Seek(var AACI: TAACInfo; var SampleNum: longint) : Boolean;
|
---|
680 | begin
|
---|
681 | Result := False;
|
---|
682 | if (AACI.Size = 0) or (AACI.TotalSamples = 0) then
|
---|
683 | Exit;
|
---|
684 |
|
---|
685 | if SampleNum > AACI.TotalSamples then
|
---|
686 | SampleNum := AACI.TotalSamples;
|
---|
687 |
|
---|
688 | AACI.Position:= Trunc(SampleNum / AACI.TotalSamples * AACI.Size);
|
---|
689 | Result := True;
|
---|
690 | end;
|
---|
691 |
|
---|
692 | procedure LoadNeAAC(NeAAC : AnsiString);
|
---|
693 | var
|
---|
694 | thelib: string;
|
---|
695 | Begin
|
---|
696 | if Length(NeAAC) = 0 then thelib := libaa else thelib := NeAAC;
|
---|
697 | hNeAAC:= DynLibs.SafeLoadLibrary(PChar(thelib));
|
---|
698 | NeAACLoaded:= hNeAAC <> dynlibs.NilHandle;
|
---|
699 |
|
---|
700 | Pointer(NeAACDecGetErrorMessage) :=
|
---|
701 | GetProcAddress(hNeAAC, PChar('NeAACDecGetErrorMessage'));
|
---|
702 | Pointer(NeAACDecGetCapabilities) :=
|
---|
703 | GetProcAddress(hNeAAC, PChar('NeAACDecGetCapabilities'));
|
---|
704 | Pointer(NeAACDecOpen) :=
|
---|
705 | GetProcAddress(hNeAAC, PChar('NeAACDecOpen'));
|
---|
706 | Pointer(NeAACDecGetCurrentConfiguration) :=
|
---|
707 | GetProcAddress(hNeAAC, PChar('NeAACDecGetCurrentConfiguration'));
|
---|
708 | Pointer(NeAACDecSetConfiguration) :=
|
---|
709 | GetProcAddress(hNeAAC, PChar('NeAACDecSetConfiguration'));
|
---|
710 | Pointer(NeAACDecInit) :=
|
---|
711 | GetProcAddress(hNeAAC, PChar('NeAACDecInit'));
|
---|
712 | Pointer(NeAACDecInit2) :=
|
---|
713 | GetProcAddress(hNeAAC, PChar('NeAACDecInit2'));
|
---|
714 | Pointer(NeAACDecPostSeekReset) :=
|
---|
715 | GetProcAddress(hNeAAC, PChar('NeAACDecPostSeekReset'));
|
---|
716 | Pointer(NeAACDecClose) :=
|
---|
717 | GetProcAddress(hNeAAC, PChar('NeAACDecClose'));
|
---|
718 | Pointer(NeAACDecDecode) :=
|
---|
719 | GetProcAddress(hNeAAC, PChar('NeAACDecDecode'));
|
---|
720 | Pointer(NeAACDecDecode2) :=
|
---|
721 | GetProcAddress(hNeAAC, PChar('NeAACDecDecode2'));
|
---|
722 | Pointer(NeAACDecPostSeekReset) :=
|
---|
723 | GetProcAddress(hNeAAC, PChar('NeAACDecPostSeekReset'));
|
---|
724 | Pointer(NeAACDecAudioSpecificConfig) :=
|
---|
725 | GetProcAddress(hNeAAC, PChar('NeAACDecAudioSpecificConfig'));
|
---|
726 | end;
|
---|
727 |
|
---|
728 | Procedure UnLoadNeAAC;
|
---|
729 | Begin
|
---|
730 | if NeAACLoaded then
|
---|
731 | DynLibs.UnloadLibrary(hNeAAC);
|
---|
732 | NeAACLoaded:= False;
|
---|
733 | end;
|
---|
734 |
|
---|
735 | Function Is_NeAAC_Loaded : Boolean;
|
---|
736 | Begin
|
---|
737 | Result:= NeAACLoaded;
|
---|
738 | end;
|
---|
739 |
|
---|
740 | ////////////////////////////// from mcwMP4FF.pas by Franklyn A. Harlow
|
---|
741 |
|
---|
742 | function GetAACTrack(infile : mp4ff_t) : Integer;
|
---|
743 | var
|
---|
744 | i, rc, numTracks : Integer;
|
---|
745 | buff : pcfloat;
|
---|
746 | buff_size : LongWord;
|
---|
747 | mp4ASC : mp4AudioSpecificConfig;
|
---|
748 | begin
|
---|
749 | numTracks := mp4ff_total_tracks(infile);
|
---|
750 | for i := 0 to numTracks - 1 do
|
---|
751 | begin
|
---|
752 | buff := nil;
|
---|
753 | buff_size:=0;
|
---|
754 | mp4ff_get_decoder_config(infile, i, buff, buff_size);
|
---|
755 | if buff <> nil then
|
---|
756 | begin
|
---|
757 | rc := NeAACDecAudioSpecificConfig(buff, buff_size, mp4ASC);
|
---|
758 | mp4ff_free_decoder_config(buff);
|
---|
759 | if rc < 0 then
|
---|
760 | continue;
|
---|
761 | Result := i;
|
---|
762 | Exit;
|
---|
763 | end;
|
---|
764 | end;
|
---|
765 | Result := -1;
|
---|
766 | end;
|
---|
767 |
|
---|
768 | procedure UnLoadMp4ff;
|
---|
769 | begin
|
---|
770 | if Mp4ffLoaded then
|
---|
771 |
|
---|
772 | DynLibs.UnloadLibrary(hMp4ff);
|
---|
773 |
|
---|
774 | Mp4ffLoaded := False;
|
---|
775 | end;
|
---|
776 |
|
---|
777 | Function isMp4ffLoaded : Boolean;
|
---|
778 | Begin
|
---|
779 | Result:= Mp4ffLoaded;
|
---|
780 | end;
|
---|
781 |
|
---|
782 |
|
---|
783 | procedure Loadmp4ff(mp4ff : AnsiString);
|
---|
784 | var
|
---|
785 | thelib: string;
|
---|
786 | begin
|
---|
787 | if Mp4ffLoaded then
|
---|
788 | Exit;
|
---|
789 | if Length(mp4ff) = 0 then thelib := libm4 else thelib := mp4ff;
|
---|
790 | hMp4ff := DynLibs.SafeLoadLibrary(PChar(thelib));
|
---|
791 | Mp4ffLoaded := hMp4ff <> dynlibs.NilHandle;
|
---|
792 |
|
---|
793 | // writeln('hMp4ff' + inttostr(hMp4ff));
|
---|
794 |
|
---|
795 | Pointer(mp4ff_open_read) :=
|
---|
796 | GetProcAddress(hMp4ff, pchar('mp4ff_open_read'));
|
---|
797 |
|
---|
798 | // if Pointer(mp4ff_open_read) <> nil then
|
---|
799 | // writeln('mp4ff_open_read OK') else
|
---|
800 | // writeln('mp4ff_open_read NOT OK');
|
---|
801 |
|
---|
802 | Pointer(mp4ff_open_read_metaonly) :=
|
---|
803 | GetProcAddress(hMp4ff, PChar('mp4ff_open_read_metaonly'));
|
---|
804 | Pointer(mp4ff_close) :=
|
---|
805 | GetProcAddress(hMp4ff, PChar('mp4ff_close'));
|
---|
806 | Pointer(mp4ff_get_sample_duration) :=
|
---|
807 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_duration'));
|
---|
808 | Pointer(mp4ff_get_sample_duration_use_offsets) :=
|
---|
809 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_duration_use_offsets'));
|
---|
810 | Pointer(mp4ff_get_sample_position) :=
|
---|
811 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_position'));
|
---|
812 | Pointer(mp4ff_get_sample_offset) :=
|
---|
813 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_offset'));
|
---|
814 | Pointer(mp4ff_find_sample) :=
|
---|
815 | GetProcAddress(hMp4ff, PChar('mp4ff_find_sample'));
|
---|
816 |
|
---|
817 | Pointer(mp4ff_find_sample_use_offsets) :=
|
---|
818 | GetProcAddress(hMp4ff, PChar('mp4ff_find_sample_use_offsets'));
|
---|
819 | Pointer(mp4ff_set_sample_position) :=
|
---|
820 | GetProcAddress(hMp4ff, PChar('mp4ff_set_sample_position'));
|
---|
821 | Pointer(mp4ff_read_sample) :=
|
---|
822 | GetProcAddress(hMp4ff, PChar('mp4ff_read_sample'));
|
---|
823 | Pointer(mp4ff_read_sample_v2) :=
|
---|
824 | GetProcAddress(hMp4ff, PChar('mp4ff_read_sample_v2'));
|
---|
825 | Pointer(mp4ff_read_sample_getsize) :=
|
---|
826 | GetProcAddress(hMp4ff, PChar('mp4ff_read_sample_getsize'));
|
---|
827 | Pointer(mp4ff_get_sample_position) :=
|
---|
828 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_position'));
|
---|
829 | Pointer(mp4ff_get_sample_offset) :=
|
---|
830 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_offset'));
|
---|
831 | Pointer(mp4ff_find_sample) :=
|
---|
832 | GetProcAddress(hMp4ff, PChar('mp4ff_find_sample'));
|
---|
833 |
|
---|
834 | Pointer(mp4ff_get_decoder_config) :=
|
---|
835 | GetProcAddress(hMp4ff, PChar('mp4ff_get_decoder_config'));
|
---|
836 | Pointer(mp4ff_get_track_type) :=
|
---|
837 | GetProcAddress(hMp4ff, PChar('mp4ff_get_track_type'));
|
---|
838 | Pointer(mp4ff_total_tracks) :=
|
---|
839 | GetProcAddress(hMp4ff, PChar('mp4ff_total_tracks'));
|
---|
840 | Pointer(mp4ff_num_samples) :=
|
---|
841 | GetProcAddress(hMp4ff, PChar('mp4ff_num_samples'));
|
---|
842 | Pointer(mp4ff_time_scale) :=
|
---|
843 | GetProcAddress(hMp4ff, PChar('mp4ff_time_scale'));
|
---|
844 | Pointer(mp4ff_get_avg_bitrate) :=
|
---|
845 | GetProcAddress(hMp4ff, PChar('mp4ff_get_avg_bitrate'));
|
---|
846 | Pointer(mp4ff_get_max_bitrate) :=
|
---|
847 | GetProcAddress(hMp4ff, PChar('mp4ff_get_max_bitrate'));
|
---|
848 | Pointer(mp4ff_get_track_duration) :=
|
---|
849 | GetProcAddress(hMp4ff, PChar('mp4ff_get_track_duration'));
|
---|
850 |
|
---|
851 | Pointer(mp4ff_get_track_duration_use_offsets) :=
|
---|
852 | GetProcAddress(hMp4ff, PChar('mp4ff_get_track_duration_use_offsets'));
|
---|
853 | Pointer(mp4ff_get_sample_rate) :=
|
---|
854 | GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_rate'));
|
---|
855 | Pointer(mp4ff_get_channel_count) :=
|
---|
856 | GetProcAddress(hMp4ff, PChar('mp4ff_get_channel_count'));
|
---|
857 | Pointer(mp4ff_get_audio_type) :=
|
---|
858 | GetProcAddress(hMp4ff, PChar('mp4ff_get_audio_type'));
|
---|
859 | Pointer(mp4ff_free_decoder_config) :=
|
---|
860 | GetProcAddress(hMp4ff, PChar('mp4ff_free_decoder_config'));
|
---|
861 | Pointer(mp4ff_meta_get_num_items) :=
|
---|
862 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_num_items'));
|
---|
863 | Pointer(mp4ff_meta_get_by_index) :=
|
---|
864 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_by_index'));
|
---|
865 | Pointer(mp4ff_meta_get_title) :=
|
---|
866 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_title'));
|
---|
867 |
|
---|
868 | Pointer(mp4ff_meta_get_artist) :=
|
---|
869 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_artist'));
|
---|
870 | Pointer(mp4ff_meta_get_writer) :=
|
---|
871 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_writer'));
|
---|
872 | Pointer(mp4ff_meta_get_album) :=
|
---|
873 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_album'));
|
---|
874 | Pointer(mp4ff_meta_get_date) :=
|
---|
875 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_date'));
|
---|
876 | Pointer(mp4ff_meta_get_tool) :=
|
---|
877 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_tool'));
|
---|
878 | Pointer(mp4ff_meta_get_comment) :=
|
---|
879 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_comment'));
|
---|
880 | Pointer(mp4ff_meta_get_genre) :=
|
---|
881 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_genre'));
|
---|
882 | Pointer(mp4ff_meta_get_track) :=
|
---|
883 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_track'));
|
---|
884 |
|
---|
885 | Pointer(mp4ff_meta_get_disc) :=
|
---|
886 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_disc'));
|
---|
887 | Pointer(mp4ff_meta_get_totaltracks) :=
|
---|
888 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_totaltracks'));
|
---|
889 | Pointer(mp4ff_meta_get_totaldiscs) :=
|
---|
890 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_totaldiscs'));
|
---|
891 | Pointer(mp4ff_meta_get_compilation) :=
|
---|
892 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_compilation'));
|
---|
893 | Pointer(mp4ff_meta_get_tempo) :=
|
---|
894 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_tempo'));
|
---|
895 | Pointer(mp4ff_meta_get_coverart) :=
|
---|
896 | GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_coverart'));
|
---|
897 |
|
---|
898 | end;
|
---|
899 |
|
---|
900 | initialization
|
---|
901 | NeAACLoaded:= False;
|
---|
902 | SetExceptionMask(GetExceptionMask + [exZeroDivide] + [exInvalidOp] +
|
---|
903 | [exDenormalized] + [exOverflow] + [exPrecision]);
|
---|
904 |
|
---|
905 | finalization
|
---|
906 | end.
|
---|