source: trunk/Packages/uos/uos_opusfile.pas

Last change on this file was 664, checked in by chronos, 3 days ago
  • Added: Ability to play music in background in start screen and in-game. Used uos as audio library.
File size: 20.3 KB
Line 
1{This unit is part of United Openlibraries of Sound (uos)}
2
3{This is the Pascal Wrapper + Dynamic loading of OpusFile library.
4 Load library with of_load() and release with of_unload().
5 License : modified LGPL.
6 Fred van Stappen / fiens@hotmail.com}
7
8unit uos_OpusFile;
9
10{$mode objfpc}{$H+}
11{$PACKRECORDS C}
12{$RANGECHECKS OFF}
13
14interface
15
16uses
17 ctypes, dynlibs, classes, pipes, SysUtils;
18
19type
20 TOpusFile = ^OpusFile;
21 OpusFile = record
22 end;
23
24const
25libop=
26 {$IFDEF unix}
27{$IFDEF darwin}
28 'libopusfile.0.dylib';
29 {$ELSE}
30'libopusfile.so.0';
31 {$ENDIF}
32 {$ELSE}
33 'opusfile.dll';
34 {$ENDIF}
35
36// Error Codes
37const
38 OP_FALSE = -1;
39 OP_HOLE = -3;
40 OP_EREAD = -128;
41 OP_EFAULT = -129;
42 OP_EIMPL = -130;
43 OP_EINVAL = -131;
44 OP_ENOTVORBIS = -132;
45 OP_EBADHEADER = -133;
46 OP_EVERSION = -134;
47 OP_ENOTAUDIO = -135;
48 OP_EBADPACKET = -136;
49 OP_EBADLINK = -137;
50 OP_ENOSEEK = -138;
51 OP_EBADTIMESTAMP = -139;
52
53{
54/**A request did not succeed.*/
55#define OP_FALSE (-1)
56/*Currently not used externally.*/
57#define OP_EOF (-2)
58/**There was a hole in the page sequence numbers (e.g., a page was corrupt or
59 missing).*/
60#define OP_HOLE (-3)
61/**An underlying read, seek, or tell operation failed when it should have
62 succeeded.*/
63#define OP_EREAD (-128)
64/**A <code>NULL</code> pointer was passed where one was unexpected, or an
65 internal memory allocation failed, or an internal library error was
66 encountered.*/
67#define OP_EFAULT (-129)
68/**The stream used a feature that is not implemented, such as an unsupported
69 channel family.*/
70#define OP_EIMPL (-130)
71/**One or more parameters to a function were invalid.*/
72#define OP_EINVAL (-131)
73/**A purported Ogg Opus stream did not begin with an Ogg page, a purported
74 header packet did not start with one of the required strings, "OpusHead" or
75 "OpusTags", or a link in a chained file was encountered that did not
76 contain any logical Opus streams.*/
77#define OP_ENOTFORMAT (-132)
78/**A required header packet was not properly formatted, contained illegal
79 values, or was missing altogether.*/
80#define OP_EBADHEADER (-133)
81/**The ID header contained an unrecognized version number.*/
82#define OP_EVERSION (-134)
83/*Currently not used at all.*/
84#define OP_ENOTAUDIO (-135)
85/**An audio packet failed to decode properly.
86 This is usually caused by a multistream Ogg packet where the durations of
87 the individual Opus packets contained in it are not all the same.*/
88#define OP_EBADPACKET (-136)
89/**We failed to find data we had seen before, or the bitstream structure was
90 sufficiently malformed that seeking to the target destination was
91 impossible.*/
92#define OP_EBADLINK (-137)
93/**An operation that requires seeking was requested on an unseekable stream.*/
94#define OP_ENOSEEK (-138)
95/**The first or last granule position of a link failed basic validity checks.*/
96#define OP_EBADTIMESTAMP (-139)
97}
98
99type
100 TOP_PIC_FORMAT = (OP_PIC_FORMAT_UNKNOWN = -1, OP_PIC_FORMAT_URL, OP_PIC_FORMAT_JPEG,
101 OP_PIC_FORMAT_PNG, OP_PIC_FORMAT_GIF);
102type
103 TOpusHead = THandle;
104 TOpusStream = THandle;
105
106 op_read_func = function (stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
107 op_seek_func = function (stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
108 op_tell_func = function (stream: Pointer): Int64; cdecl;
109 op_close_func = function (stream: Pointer): cint; cdecl;
110
111 TOpusFileCallbacks = record
112 read: op_read_func;
113 seek: op_seek_func;
114 tell: op_tell_func;
115 close: op_close_func;
116 end;
117
118function OpusReadCB(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
119function OpusReadCBuosURL(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
120function OpusReadCBuosMS(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
121function OpusSeekCB(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
122function OpusTellCB(stream: Pointer): Int64; cdecl;
123function OpusCloseCB(stream: Pointer): cint; cdecl;
124function OpusSeekCBMS(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
125function OpusTellCBMS(stream: Pointer): Int64; cdecl;
126
127const
128 op_callbacks: TOpusFileCallbacks = (read: @OpusReadCB;
129 seek: @OpusSeekCB;
130 tell: @OpusTellCB;
131 close: nil);
132
133 uos_callbacks: TOpusFileCallbacks = (read: @OpusReadCBuosURL;
134 seek: @OpusSeekCB;
135 tell: @OpusTellCB;
136 close: nil);
137
138 uos_callbacksms: TOpusFileCallbacks = (read: @OpusReadCBuosms;
139 seek: @OpusSeekCBms;
140 tell: @OpusTellCBms;
141 close: nil);
142
143
144type
145 TOpusMSDecoder = Pointer;
146 op_decode_cb_func = function(ctx: Pointer; decoder: TOpusMSDecoder; pcm : pcfloat; op: Pointer;
147 nsamples, nchannels, format, li: pcint): cint; cdecl;
148 TOpusTags = record
149 user_comments: PPAnsiChar; // The array of comment string vectors
150 comment_lengths: Pcint; // An array of the corresponding length of each vector, in bytes
151 comments: cint; // The total number of comment streams
152 vendor: PAnsiChar; // The null-terminated vendor string. This identifies the software used to encode the stream.
153 end;
154 POpusTags = ^TOpusTags;
155
156 TOpusPictureTag = record
157 Pic_Type: cint; { The picture type according to the ID3v2 APIC frame:
158 <ol start="0">
159 <li>Other</li>
160 <li>32x32 pixels 'file icon' (PNG only)</li>
161 <li>Other file icon</li>
162 <li>Cover (front)</li>
163 <li>Cover (back)</li>
164 <li>Leaflet page</li>
165 <li>Media (e.g. label side of CD)</li>
166 <li>Lead artist/lead performer/soloist</li>
167 <li>Artist/performer</li>
168 <li>Conductor</li>
169 <li>Band/Orchestra</li>
170 <li>Composer</li>
171 <li>Lyricist/text writer</li>
172 <li>Recording Location</li>
173 <li>During recording</li>
174 <li>During performance</li>
175 <li>Movie/video screen capture</li>
176 <li>A bright colored fish</li>
177 <li>Illustration</li>
178 <li>Band/artist logotype</li>
179 <li>Publisher/Studio logotype</li>
180 </ol> }
181 mime_type: PAnsiChar; // The MIME type of the picture, in printable ASCII characters 0x20-0x7E.
182 description: PAnsiChar; // The description of the picture, in UTF-8
183 width: Cardinal;
184 height: Cardinal;
185 depth: Cardinal; // The color depth of the picture in bits-per-pixel
186 colors: Cardinal; // For indexed-color pictures (e.g., GIF), the number of colors used, or 0
187 data_length: Cardinal;
188 data: Pointer;
189 format: TOP_PIC_FORMAT; // The format of the picture data, if known. OP_PIC_FORMAT_UNKNOWN..OP_PIC_FORMAT_GIF
190 end;
191
192var
193
194 op_fopen: function(out cb: TOpusFileCallbacks; path: PAnsiChar; mode: PAnsiChar): TOpusStream; cdecl;
195
196 op_freopen: function(out cb: TOpusFileCallbacks; path: PAnsiChar; mode: PAnsiChar; stream: TOpusStream): TOpusStream;cdecl;
197 op_mem_stream_create: function(out cb: TOpusFileCallbacks; const data; size: cuint): TOpusStream; cdecl;
198
199 opus_head_parse: function(head: TOpusHead; const data; len: cuint): cint;cdecl;
200 opus_granule_sample: function(head: TOpusHead; gp: Int64): Int64;cdecl;
201 opus_tags_parse: function(out tags: TOpusTags; const data; len: cuint): cint;cdecl;
202 opus_tags_copy: function(var dst: TOpusTags; const src: TOpusTags): cint;cdecl;
203 opus_tags_init: procedure(var tags: TOpusTags);cdecl;
204 opus_tags_add: function(var dst: TOpusTags; tag, value: PAnsiChar): cint;cdecl;
205 opus_tags_add_comment: function(var dst: TOpusTags; comment: PAnsiChar): cint;cdecl;
206 opus_tags_set_binary_suffix: function(var tags: TOpusTags; const data; len: cint): cint;cdecl;
207 opus_tags_query: function(const tags: TOpusTags; tag: PAnsiChar; count: cint): cint;cdecl;
208 opus_tags_query_count: function(const tags: TOpusTags; tag: PAnsiChar): cint;cdecl;
209 opus_tags_get_binary_suffix: function(const tags: TOpusTags; out len: cint): cint;cdecl;
210 opus_tags_get_album_gain: function(const tags: TOpusTags; out gain_q8: cint): cint;cdecl;
211 opus_tags_get_track_gain: function(const tags: TOpusTags; out gain_q8: cint): cint;cdecl;
212 opus_tags_clear: procedure(var tags: TOpusTags);cdecl;
213 opus_tagcompare: function(tag_name, comment: PAnsiChar): cint;cdecl;
214 opus_tagncompare: function(tag_name: PAnsiChar; tag_len: cint; comment: PAnsiChar): cint;cdecl;
215 opus_picture_tag_parse: function(out pic: TOpusPictureTag; tag: PAnsiChar): cint;cdecl;
216 opus_picture_tag_init: procedure(var pic: TOpusPictureTag);cdecl;
217 opus_picture_tag_clear: procedure(var pic: TOpusPictureTag);cdecl;
218
219 op_test: function(head: TOpusHead; const initial_data; initial_bytes: cuint): cint;cdecl;
220 op_open_file: function(path: PAnsiChar; out error: cint): TOpusFile;cdecl;
221 op_open_memory: function(const data; const _size: cuint; out error: cint): TOpusFile;cdecl;
222 op_open_callbacks: function(const source; const cb: TOpusFileCallbacks;
223 const initial_data; initial_bytes: cuint; out error: cint): TOpusFile; stdcall; // with cdecl ---> crash in linux, strange ???
224 op_test_file: function(path: PAnsiChar; out error: cint): TOpusFile;cdecl;
225 // op_test_url: function(path: PAnsiChar; out error: cint): TOpusFile;
226 op_test_memory: function(const data; const size: cuint; out error: cint): TOpusFile;cdecl;
227 op_test_callbacks: function(const source; const cb: TOpusFileCallbacks; const initial_data; initial_bytes: cuint;
228 out error: cint): TOpusFile; stdcall;// with cdecl ---> crash in linux, strange ???
229 op_test_open: function(OpusFile: TOpusFile): cint; cdecl;
230 op_free: function(OpusFile: TOpusFile): cint; cdecl;
231
232 op_seekable: function(OpusFile: TOpusFile): cint;cdecl;
233 op_link_count: function(OpusFile: TOpusFile): cint;cdecl;
234 op_serialno: function(OpusFile: TOpusFile; li: pcint): Cardinal;cdecl;
235 op_channel_count: function(OpusFile: TOpusFile; li: pcint): cint;cdecl;
236 op_raw_total: function(OpusFile: TOpusFile; li: pcint): Int64;cdecl;
237 op_pcm_total: function(OpusFile: TOpusFile; li: pcint): Int64;cdecl;
238 op_head: function(OpusFile: TOpusFile; li: pcint): TOpusHead;cdecl;
239 op_tags: function(OpusFile: TOpusFile; li: pcint): POpusTags;cdecl;
240 op_current_link: function(OpusFile: TOpusFile): cint;cdecl;
241 op_bitrate: function(OpusFile: TOpusFile; li: pcint): cint;cdecl;
242 op_bitrate_instant: function(OpusFile: TOpusFile): cint;cdecl;
243 op_raw_tell: function(OpusFile: TOpusFile): Int64;cdecl;
244 op_pcm_tell: function(OpusFile: TOpusFile): Int64;cdecl;
245
246 op_raw_seek: function(OpusFile: TOpusFile; byte_offset: cInt64): cint;cdecl;
247 op_pcm_seek: function(OpusFile: TOpusFile; pcm_offset: cInt64): cint;cdecl;
248
249 op_set_gain_offset: function(OpusFile: TOpusFile; gain_type: cint; gain_offset_q8: cint): cint;cdecl;
250 op_set_dither_enabled: procedure(OpusFile: TOpusFile; enabled: cint);cdecl;
251
252 op_read: function(OpusFile: TOpusFile; pcm : pcint; SampleCount: cint; li: pcint): cint;cdecl;
253 op_read_float: function(OpusFile: TOpusFile; pcm : pcfloat; SampleCount: cint; li: pcint): cint;cdecl;
254 op_read_stereo: function(OpusFile: TOpusFile; pcm : pcint; SampleCount: cint): cint;cdecl;
255 op_read_float_stereo: function(OpusFile: TOpusFile; pcm : pcfloat; SampleCount: cint): cint;cdecl;
256
257 of_Handle:TLibHandle=dynlibs.NilHandle;
258
259 op_Handle:TLibHandle=dynlibs.NilHandle;
260
261 {$IFDEF windows}
262 lc_Handle:TLibHandle=dynlibs.NilHandle;
263 wt_Handle:TLibHandle=dynlibs.NilHandle;
264 og_Handle:TLibHandle=dynlibs.NilHandle;
265 {$endif}
266
267 ReferenceCounter : cardinal = 0;
268
269 function of_IsLoaded : boolean; inline;
270
271 Function of_Load(const libfilename:string) :boolean; // load the lib
272
273 Procedure of_Unload;
274
275implementation
276
277 function of_IsLoaded: boolean;
278begin
279 Result := (of_Handle <> dynlibs.NilHandle);
280end;
281
282Procedure of_Unload;
283begin
284// < Reference counting
285 if ReferenceCounter > 0 then
286 dec(ReferenceCounter);
287 if ReferenceCounter > 0 then
288 exit;
289 // >
290 if of_IsLoaded then
291 begin
292 if of_Handle <> DynLibs.NilHandle then
293 DynLibs.UnloadLibrary(of_Handle);
294 of_Handle:=DynLibs.NilHandle;
295 if op_Handle <> DynLibs.NilHandle then
296 begin
297 DynLibs.UnloadLibrary(op_Handle);
298 op_Handle:=DynLibs.NilHandle;
299 end;
300 {$IFDEF windows}
301 if lc_Handle <> DynLibs.NilHandle then
302 DynLibs.UnloadLibrary(lc_Handle);
303 lc_Handle:=DynLibs.NilHandle;
304 if wt_Handle <> DynLibs.NilHandle then
305 DynLibs.UnloadLibrary(wt_Handle);
306 wt_Handle:=DynLibs.NilHandle;
307 if og_Handle <> DynLibs.NilHandle then
308 DynLibs.UnloadLibrary(og_Handle);
309 og_Handle:=DynLibs.NilHandle;
310 {$endif}
311
312 end;
313end;
314
315Function of_Load (const libfilename:string) :boolean;
316begin
317 Result := False;
318 if of_Handle<>0 then
319begin
320 Inc(ReferenceCounter);
321 result:=true {is it already there ?}
322end else
323begin {go & load the library}
324 if Length(libfilename) = 0 then
325 begin
326 {$IFDEF windows}
327 wt_Handle:= DynLibs.SafeLoadLibrary('libwinpthread-1.dll');
328 lc_Handle:= DynLibs.SafeLoadLibrary('libgcc_s_sjlj-1.dll');
329 og_Handle:= DynLibs.SafeLoadLibrary('libogg-0.dll');
330 op_Handle:= DynLibs.SafeLoadLibrary('libopus-0.dll');
331 {$else}
332 op_Handle:= DynLibs.SafeLoadLibrary('libopus.so');
333 {$endif}
334 of_Handle:=DynLibs.SafeLoadLibrary(libop);
335 end
336 else
337 begin
338 {$IFDEF windows}
339 wt_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libwinpthread-1.dll');
340 lc_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libgcc_s_sjlj-1.dll');
341 og_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libogg-0.dll');
342 op_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libopus-0.dll');
343 {$else}
344 op_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libopus.so');
345 {$endif}
346 of_Handle:=DynLibs.SafeLoadLibrary(libfilename);
347 end;
348
349
350 if of_Handle <> DynLibs.NilHandle then
351begin {now we tie the functions to the VARs from above}
352Pointer(op_fopen):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_fopen'));
353Pointer(op_freopen):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_freopen'));
354Pointer(op_mem_stream_create):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_mem_stream_create'));
355Pointer(opus_head_parse):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_head_parse'));
356Pointer(opus_granule_sample):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_granule_sample'));
357Pointer(opus_tags_parse):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_parse'));
358Pointer(opus_tags_copy):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_copy'));
359Pointer(opus_tags_init):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_init'));
360Pointer(opus_tags_add):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_add'));
361Pointer(opus_tags_add_comment):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_add_comment'));
362Pointer(opus_tags_set_binary_suffix):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_set_binary_suffix'));
363Pointer(opus_tags_query):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_query'));
364Pointer(opus_tags_query_count):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_query_count'));
365Pointer(opus_tags_get_binary_suffix):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_get_binary_suffix'));
366Pointer(opus_tags_get_album_gain):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_get_album_gain'));
367Pointer(opus_tags_get_track_gain):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_get_track_gain'));
368Pointer(opus_tags_clear):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_clear'));
369Pointer(opus_tagcompare):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tagcompare'));
370Pointer(opus_tagncompare):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tagncompare'));
371Pointer(opus_picture_tag_parse):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_picture_tag_parse'));
372Pointer(opus_picture_tag_init):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_picture_tag_init'));
373Pointer(opus_picture_tag_clear):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_picture_tag_clear'));
374Pointer(op_test):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test'));
375Pointer(op_free):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_free'));
376Pointer(op_open_file):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_open_file'));
377Pointer(op_open_memory):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_open_memory'));
378Pointer(op_open_callbacks):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_open_callbacks'));
379Pointer(op_test_file):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_file'));
380//Pointer(op_test_url):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_url'));
381Pointer(op_test_memory):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_memory'));
382Pointer(op_test_callbacks):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_callbacks'));
383Pointer(op_test_open):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_open'));
384Pointer(op_seekable):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_seekable'));
385Pointer(op_link_count):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_link_count'));
386Pointer(op_serialno):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_serialno'));
387Pointer(op_channel_count):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_channel_count'));
388Pointer(op_raw_total):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_raw_total'));
389Pointer(op_pcm_total):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_pcm_total'));
390Pointer(op_head):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_head'));
391Pointer(op_tags):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_tags'));
392Pointer(op_current_link):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_current_link'));
393Pointer(op_bitrate):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_bitrate'));
394Pointer(op_bitrate_instant):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_bitrate_instant'));
395Pointer(op_raw_tell):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_raw_tell'));
396Pointer(op_raw_seek):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_raw_seek'));
397Pointer(op_pcm_seek):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_pcm_seek'));
398Pointer(op_set_gain_offset):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_set_gain_offset'));
399Pointer(op_set_dither_enabled):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_set_dither_enabled'));
400Pointer(op_read):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read'));
401Pointer(op_read_float):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read_float'));
402Pointer(op_read_stereo):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read_stereo'));
403Pointer(op_read_float_stereo):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read_float_stereo'));
404
405end;
406 Result := of_IsLoaded;
407 ReferenceCounter:=1;
408end;
409
410end;
411
412function OpusReadCB(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
413begin
414 if nbytes<>0
415 then
416 result := FileRead(THandle(stream^), Buffer, nbytes)
417 else
418 result := 0;
419end;
420
421function OpusReadCBuosURL(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
422begin
423 if nbytes<>0
424 then
425 result := TInputPipeStream(stream^).read(Buffer, nbytes)
426 else
427 result := 0;
428end;
429
430function OpusReadCBuosMS(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
431begin
432 if nbytes<>0
433 then
434 result := TMemoryStream(stream^).read(Buffer, nbytes)
435 else
436 result := 0;
437end;
438
439function OpusSeekCB(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
440var
441 Seek_Result: Int64;
442begin
443 Seek_Result := FileSeek(THandle(stream^), offset, whence);
444 if Seek_Result=-1
445 then
446 Result := -1
447 else
448 Result := 0;
449end;
450
451function OpusTellCB(stream: Pointer): Int64; cdecl;
452begin
453 Result := FileSeek(THandle(stream^), 0, 1);
454end;
455
456function OpusSeekCBms(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
457var
458 Seek_Result: Int64;
459begin
460 Seek_Result := TMemoryStream(stream^).seek(offset, whence);
461 if Seek_Result=-1
462 then
463 Result := -1
464 else
465 Result := 0;
466end;
467
468function OpusTellCBms(stream: Pointer): Int64; cdecl;
469begin
470Result := TMemoryStream(stream^).seek(0, 1);
471 end;
472
473function OpusCloseCB(stream: Pointer): cint; cdecl;
474begin
475 FileClose(THandle(stream^));
476 Result := 0;
477end;
478
479end.
Note: See TracBrowser for help on using the repository browser.