summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5dacd86)
raw | patch | inline | side by side (parent: 5dacd86)
author | fgsfds <pvt.fgsfds@gmail.com> | |
Tue, 3 Sep 2019 01:28:35 +0000 (04:28 +0300) | ||
committer | fgsfds <pvt.fgsfds@gmail.com> | |
Tue, 3 Sep 2019 01:28:43 +0000 (04:28 +0300) |
src/engine/e_soundfile_ogg.pas | [new file with mode: 0644] | patch | blob |
src/game/Doom2DF.lpr | patch | blob | history | |
src/lib/vorbis/ogg.pas | [new file with mode: 0644] | patch | blob |
src/lib/vorbis/vorbis.pas | [new file with mode: 0644] | patch | blob |
diff --git a/src/engine/e_soundfile_ogg.pas b/src/engine/e_soundfile_ogg.pas
--- /dev/null
@@ -0,0 +1,300 @@
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit e_soundfile_ogg;
+
+interface
+
+uses e_soundfile, vorbis, classes;
+
+type
+ // OGG Vorbis loader
+
+ TOGGLoader = class (TSoundLoader)
+ public
+ function Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean; override; overload;
+ function Load(FName: string; SStreaming: Boolean): Boolean; override; overload;
+ function SetPosition(Pos: LongWord): Boolean; override;
+ function FillBuffer(Buf: Pointer; Len: LongWord): LongWord; override;
+ function GetAll(var OutPtr: Pointer): LongWord; override;
+ procedure Free(); override;
+
+ private
+ FOgg: OggVorbis_File;
+ FData: TStream;
+ FBuf: Pointer;
+ FTotal: LongWord;
+ FOpen: Boolean;
+
+ function LoadStream(Stream: TStream; SStreaming: Boolean): Boolean;
+ function LoadEntireStream(): Pointer;
+ end;
+
+ TOGGLoaderFactory = class (TSoundLoaderFactory)
+ public
+ function MatchHeader(Data: Pointer; Len: LongWord): Boolean; override;
+ function MatchExtension(FName: string): Boolean; override;
+ function GetLoader(): TSoundLoader; override;
+ end;
+
+implementation
+
+uses sysutils, utils, e_log, xstreams, ogg, ctypes;
+
+(* Reader functions for ov_callbacks *)
+
+function streamSeek(h: Pointer; off: ogg_int64_t; whence: cint): cint; cdecl;
+var
+ S: TStream;
+begin
+ Result := -1;
+ if h = nil then Exit;
+ S:= TStream(h);
+ try
+ case whence of
+ 0: s.Seek(off, soBeginning); // SEEK_SET
+ 1: s.Seek(off, soCurrent); // SEEK_CUR
+ 2: s.Seek(off, soEnd); // SEEK_END
+ end;
+ Result := 0;
+ except
+ Result := -1;
+ end;
+end;
+
+function streamRead(buf: Pointer; sz, nmemb: csize_t; h: Pointer): csize_t; cdecl;
+var
+ S: TStream;
+begin
+ Result := 0;
+ if h = nil then Exit;
+ S:= TStream(h);
+ try
+ Result := S.Read(buf^, sz*nmemb) div sz;
+ except
+ Result := 0;
+ end;
+end;
+
+function streamTell(h: Pointer): clong; cdecl;
+var
+ S: TStream;
+begin
+ Result := -1;
+ if h = nil then Exit;
+ S := TStream(h);
+ Result := S.Position;
+end;
+
+var
+ oggIO: ov_callbacks = (
+ read: streamRead;
+ seek: streamSeek;
+ close: nil; // the loader's gonna handle that
+ tell: streamTell;
+ );
+
+(* TOGGLoaderFactory *)
+
+function TOGGLoaderFactory.MatchHeader(Data: Pointer; Len: LongWord): Boolean;
+const
+ OGG_HEADER = $5367674F; // 'OggS'
+begin
+ if Len < 27 then // header is at least 27 bytes
+ begin
+ Result := False;
+ exit;
+ end;
+ Result := (PLongWord(Data)^ = OGG_HEADER);
+end;
+
+function TOGGLoaderFactory.MatchExtension(FName: string): Boolean;
+begin
+ Result := GetFilenameExt(FName) = '.ogg';
+end;
+
+function TOGGLoaderFactory.GetLoader(): TSoundLoader;
+begin
+ Result := TOGGLoader.Create();
+end;
+
+(* TOGGLoader *)
+
+function TOGGLoader.LoadEntireStream(): Pointer;
+var
+ Samples: ogg_int64_t;
+ Ret: clong;
+begin
+ Result := nil;
+
+ Samples := ov_pcm_total(FOgg, -1);
+ if Samples < 0 then Exit;
+
+ FTotal := Samples * 2 * FFormat.Channels;
+ Result := GetMem(FTotal);
+ if Result = nil then Exit;
+
+ Ret := ov_read_ext(FOgg, Result, FTotal, False, 2, True);
+ if Ret < 0 then
+ begin
+ FreeMem(Result);
+ Result := nil;
+ end
+ else
+ FTotal := Ret;
+end;
+
+function TOGGLoader.LoadStream(Stream: TStream; SStreaming: Boolean): Boolean;
+var
+ Ret, Bit: clong;
+ Info: pvorbis_info;
+ FullBuf: Pointer;
+begin
+ Result := False;
+
+ Ret := ov_open_callbacks(Stream, FOgg, nil, 0, oggIO);
+ if Ret < 0 then
+ begin
+ e_LogWriteln('OGG: Load(Data) failed: ov_open_callbacks failed');
+ Exit;
+ end;
+
+ Info := ov_info(FOgg, -1);
+ if Info = nil then
+ begin
+ e_LogWriteln('OGG: Load(Data) failed: ov_info returned NULL');
+ ov_clear(FOgg);
+ Exit;
+ end;
+
+ FFormat.SampleRate := Info^.rate;
+ FFormat.Channels := Info^.channels;
+ FFormat.SampleBits := 16;
+
+ if not SStreaming then
+ begin
+ FullBuf := LoadEntireStream();
+
+ if FullBuf = nil then
+ begin
+ e_LogWriteln('OGG: Load(Data) failed: couldn''t allocate for non-streaming chunk');
+ ov_clear(FOgg);
+ FTotal := 0;
+ Exit;
+ end;
+
+ ov_clear(FOgg);
+ Stream.Destroy();
+
+ FreeMem(FBuf);
+ FBuf := FullBuf;
+ end
+ else
+ begin
+ FTotal := 0;
+ FOpen := True;
+ FData := Stream;
+ end;
+
+ FStreaming := SStreaming;
+ Result := True;
+end;
+
+function TOGGLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
+var
+ S: TStream;
+begin
+ Result := False;
+
+ // TODO: have to make a dupe here because Data gets deallocated after loading
+ // this is obviously very shit
+ FBuf := GetMem(Len);
+ if FBuf = nil then Exit;
+ Move(Data^, FBuf^, Len);
+
+ S := TSFSMemoryStreamRO.Create(FBuf, Len{, True});
+ Result := LoadStream(S, SStreaming);
+
+ if not Result and (S <> nil) then
+ begin
+ S.Destroy();
+ FreeMem(FBuf);
+ FBuf := nil;
+ end;
+end;
+
+function TOGGLoader.Load(FName: string; SStreaming: Boolean): Boolean;
+var
+ S: TStream = nil;
+begin
+ Result := False;
+
+ try
+ S := openDiskFileRO(FName);
+ Result := LoadStream(S, SStreaming);
+ except
+ on E: Exception do
+ e_LogWritefln('OGG: ERROR: could not read file `%s`: %s', [FName, E.Message]);
+ end;
+
+ if not Result and (S <> nil) then
+ S.Destroy();
+end;
+
+function TOGGLoader.SetPosition(Pos: LongWord): Boolean;
+begin
+ Result := False;
+ if not FOpen or (ov_seekable(FOgg) = 0) then Exit;
+ Result := ov_pcm_seek(FOgg, Pos) = 0;
+end;
+
+function TOGGLoader.FillBuffer(Buf: Pointer; Len: LongWord): LongWord;
+var
+ Ret: clong;
+begin
+ Result := 0;
+ if not FOpen or not FStreaming then Exit;
+ Ret := ov_read_ext(FOgg, Buf, Len, False, 2, True);
+ if Ret < 0 then Exit;
+ Result := Ret;
+end;
+
+function TOGGLoader.GetAll(var OutPtr: Pointer): LongWord;
+begin
+ Result := 0;
+ if FStreaming or (FTotal = 0) then Exit;
+ Result := FTotal;
+ OutPtr := FBuf;
+end;
+
+procedure TOGGLoader.Free();
+begin
+ if FOpen then
+ ov_clear(FOgg);
+ if FData <> nil then
+ FData.Destroy();
+ if FBuf <> nil then
+ FreeMem(FBuf);
+ FData := nil;
+ FBuf := nil;
+ FOpen := False;
+ FTotal := 0;
+ FStreaming := False;
+end;
+
+initialization
+ e_AddSoundLoader(TOGGLoaderFactory.Create());
+end.
diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr
index 9277239bbda6ce8dce35792842adea6f05382be7..cd61dfefbf0ab826d393d10d69b6b65e8e51e21c 100644 (file)
--- a/src/game/Doom2DF.lpr
+++ b/src/game/Doom2DF.lpr
AL in '../lib/openal/al.pas',
e_soundfile in '../engine/e_soundfile.pas',
e_soundfile_wav in '../engine/e_soundfile_wav.pas',
+ {$IFDEF USE_VORBIS}
+ ogg in '../lib/vorbis/ogg.pas',
+ vorbis in '../lib/vorbis/vorbis.pas',
+ e_soundfile_ogg in '../engine/e_soundfile_ogg.pas',
+ {$ENDIF}
{$IFDEF USE_FLUIDSYNTH}
fluidsynth in '../lib/fluidsynth/fluidsynth.pas',
e_soundfile_fluid in '../engine/e_soundfile_fluid.pas',
diff --git a/src/lib/vorbis/ogg.pas b/src/lib/vorbis/ogg.pas
--- /dev/null
+++ b/src/lib/vorbis/ogg.pas
@@ -0,0 +1,215 @@
+{
+ Translation of the ogg headers for FreePascal
+ Copyright (C) 2006 by Ivo Steinmann
+}
+
+(********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************)
+
+unit ogg;
+
+{$MODE OBJFPC}
+{$MINENUMSIZE 4}
+{$PACKRECORDS C}
+
+interface
+
+uses
+ ctypes;
+
+{$IF DEFINED(WINDOWS)}
+ {$IFDEF VORBIS_WINDOZE_STATIC}
+ {$LINKLIB libogg.a}
+ {$ELSE}
+ {$DEFINE OGG_DYNAMIC}
+ const ogglib = 'libogg-0.dll';
+ {$ENDIF}
+{$ELSEIF DEFINED(UNIX)}
+ {$DEFINE OGG_DYNAMIC}
+ const ogglib = 'libogg.so';
+{$ELSE}
+ {$ERROR libogg not supported on this platform. Fix it!}
+{$ENDIF}
+
+(***********************************************************************)
+(* Header : os_types.h *)
+(***********************************************************************)
+type
+ ogg_int64_t = cint64; pogg_int64_t = ^ogg_int64_t;
+ ogg_int32_t = cint32; pogg_int32_t = ^ogg_int32_t;
+ ogg_uint32_t = cuint32; pogg_uint32_t = ^ogg_uint32_t;
+ ogg_int16_t = cint16; pogg_int16_t = ^ogg_int16_t;
+ ogg_uint16_t = cuint16; pogg_uint16_t = ^ogg_uint16_t;
+
+
+(***********************************************************************)
+(* Header : ogg.h *)
+(***********************************************************************)
+type
+ poggpack_buffer = ^oggpack_buffer;
+ oggpack_buffer = record
+ endbyte : clong;
+ endbit : cint;
+ buffer : pcuchar;
+ ptr : pcuchar;
+ storage : clong;
+ end;
+
+{ ogg_page is used to encapsulate the data in one Ogg bitstream page }
+
+ pogg_page = ^ogg_page;
+ ogg_page = record
+ header : pcuchar;
+ header_len : clong;
+ body : pcuchar;
+ body_len : clong;
+ end;
+
+{ ogg_stream_state contains the current encode/decode state of a logical Ogg bitstream }
+
+ pogg_stream_state = ^ogg_stream_state;
+ ogg_stream_state = record
+ body_data : pcuchar; { bytes from packet bodies }
+ body_storage : clong; { storage elements allocated }
+ body_fill : clong; { elements stored; fill mark }
+ body_returned : clong; { elements of fill returned }
+
+ lacing_vals : pcint; { The values that will go to the segment table }
+ granule_vals : pogg_int64_t; { granulepos values for headers. Not compact this way, but it is simple coupled to the lacing fifo }
+
+ lacing_storage : clong;
+ lacing_fill : clong;
+ lacing_packet : clong;
+ lacing_returned : clong;
+
+ header : array[0..281] of cuchar; { working space for header encode }
+ header_fill : cint;
+
+ e_o_s : cint; { set when we have buffered the last packet in the logical bitstream }
+ b_o_s : cint; { set after we've written the initial page of a logical bitstream }
+
+ serialno : clong;
+ pageno : clong;
+ packetno : ogg_int64_t; { sequence number for decode; the framing knows where there's a hole in the data,
+ but we need coupling so that the codec (which is in a seperate abstraction layer) also knows about the gap }
+ granulepos : ogg_int64_t;
+ end;
+
+{ ogg_packet is used to encapsulate the data and metadata belonging to a single raw Ogg/Vorbis packet }
+
+ pogg_packet = ^ogg_packet;
+ ogg_packet = record
+ packet : pcuchar;
+ bytes : clong;
+ b_o_s : clong;
+ e_o_s : clong;
+
+ granulepos : ogg_int64_t;
+ packetno : ogg_int64_t; { sequence number for decode; the framing knows where there's a hole in the data,
+ but we need coupling so that the codec (which is in a seperate abstraction layer) also knows about the gap }
+ end;
+
+ ogg_sync_state = record
+ data : pcuchar;
+ storage : cint;
+ fill : cint;
+ returned : cint;
+
+ unsynced : cint;
+ headerbytes : cint;
+ bodybytes : cint;
+ end;
+
+{ Ogg BITSTREAM PRIMITIVES: bitstream }
+
+procedure oggpack_writeinit(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_writetrunc(var b: oggpack_buffer; bits: clong); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_writealign(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_writecopy(var b: oggpack_buffer; source: pointer; bits: clong); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_reset(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_writeclear(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_readinit(var b: oggpack_buffer; buf: pointer; bytes: cint); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_write(var b: oggpack_buffer; value: culong; bits: cint); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_look(var b: oggpack_buffer; bits: cint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_look1(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_adv(var b: oggpack_buffer; bits: cint); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpack_adv1(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_read(var b: oggpack_buffer; bits: cint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_read1(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_bytes(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_bits(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpack_get_buffer(var b: oggpack_buffer): pointer; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+procedure oggpackB_writeinit(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_writetrunc(var b: oggpack_buffer; bits: clong); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_writealign(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_writecopy(var b: oggpack_buffer; source: pointer; bits: clong); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_reset(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_writeclear(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_readinit(var b: oggpack_buffer; buf: pointer; bytes: cint); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_write(var b: oggpack_buffer; value: culong; bits: cint); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_look(var b: oggpack_buffer; bits: cint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_look1(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_adv(var b: oggpack_buffer; bits: cint); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+procedure oggpackB_adv1(var b: oggpack_buffer); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_read(var b: oggpack_buffer; bits: cint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_read1(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_bytes(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_bits(var b: oggpack_buffer): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function oggpackB_get_buffer(var b: oggpack_buffer): pointer; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+{ ogglib BITSTREAM PRIMITIVES: encoding }
+
+function ogg_stream_packetin(var os: ogg_stream_state; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_pageout(var os: ogg_stream_state; var op: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_flush(var os: ogg_stream_state; var op: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+{ ogglib BITSTREAM PRIMITIVES: decoding }
+
+function ogg_sync_init(var oy: ogg_sync_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_sync_clear(var oy: ogg_sync_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_sync_reset(var oy: ogg_sync_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_sync_destroy(var oy: ogg_sync_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+function ogg_sync_buffer(var oy: ogg_sync_state; size: clong): pointer; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_sync_wrote(var oy: ogg_sync_state; bytes: clong): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_sync_pageseek(var oy: ogg_sync_state; var og: ogg_page): pointer; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_sync_pageout(var oy: ogg_sync_state; var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_pagein(var os: ogg_stream_state; var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_packetout(var os: ogg_stream_state; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_packetpeek(var os: ogg_stream_state; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+{ ogglib BITSTREAM PRIMITIVES: general }
+
+function ogg_stream_init(var os: ogg_stream_state; serialno: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_clear(var os: ogg_stream_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_reset(var os: ogg_stream_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_reset_serialno(var os: ogg_stream_state; serialno: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_destroy(var os: ogg_stream_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_stream_eos(var os: ogg_stream_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+procedure ogg_page_checksum_set(var og: ogg_page); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+function ogg_page_version(var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_continued(var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_bos(var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_eos(var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_granulepos(var og: ogg_page): ogg_int64_t; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_serialno(var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_pageno(var og: ogg_page): clong; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+function ogg_page_packets(var og: ogg_page): cint; cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+procedure ogg_packet_clear(var op: ogg_packet); cdecl; external {$IFDEF OGG_DYNAMIC}ogglib{$ENDIF};
+
+implementation
+
+end.
diff --git a/src/lib/vorbis/vorbis.pas b/src/lib/vorbis/vorbis.pas
--- /dev/null
@@ -0,0 +1,449 @@
+{
+ Translation of the vorbis headers for FreePascal
+ Copyright (C) 2006 by Ivo Steinmann
+}
+
+(********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************)
+
+unit vorbis;
+
+{$MODE OBJFPC}
+{$MINENUMSIZE 4}
+{$PACKRECORDS C}
+
+interface
+
+uses
+ ctypes, ogg;
+
+{$IF DEFINED(WINDOWS)}
+ {$IFDEF VORBIS_WINDOZE_STATIC}
+ {$LINKLIB libvorbis.a}
+ {$LINKLIB libvorbisfile.a}
+ {$ELSE}
+ {$DEFINE OGG_DYNAMIC}
+ const vorbislib = 'libvorbis-0.dll';
+ const vorbisfilelib = 'libvorbisfile-3.dll';
+ {$ENDIF}
+{$ELSEIF DEFINED(UNIX)}
+ {$DEFINE OGG_DYNAMIC}
+ const vorbislib = 'libvorbis.so';
+ const vorbisfilelib = 'libvorbisfile.so';
+{$ELSE}
+ {$ERROR libvorbis not supported on this platform. Fix it!}
+{$ENDIF}
+
+(***********************************************************************)
+(* Header : codec.h *)
+(***********************************************************************)
+
+type
+ ppcfloat = ^pcfloat;
+
+ pvorbis_info = ^vorbis_info;
+ vorbis_info = record
+ version : cint;
+ channels : cint;
+ rate : clong;
+
+ { The below bitrate declarations are *hints*.
+ Combinations of the three values carry the following implications:
+
+ all three set to the same value:
+ implies a fixed rate bitstream
+ only nominal set:
+ implies a VBR stream that averages the nominal bitrate. No hard
+ upper/lower limit
+ upper and or lower set:
+ implies a VBR bitstream that obeys the bitrate limits. nominal
+ may also be set to give a nominal rate.
+ none set:
+ the coder does not care to speculate.
+ }
+
+ bitrate_upper : clong;
+ bitrate_nominal : clong;
+ bitrate_lower : clong;
+ bitrate_window : clong;
+ codec_setup : pointer;
+ end;
+
+{ vorbis_dsp_state buffers the current vorbis audio analysis/synthesis state. The DSP state belongs to a specific logical bitstream }
+
+ pvorbis_dsp_state = ^vorbis_dsp_state;
+ vorbis_dsp_state = record
+ analysisp : cint;
+ vi : pvorbis_info;
+
+ pcm : ppcfloat;
+ pcmret : ppcfloat;
+ pcm_storage : cint;
+ pcm_current : cint;
+ pcm_returned : cint;
+
+ preextrapolate : cint;
+ eofflag : cint;
+
+ lW : clong;
+ W : clong;
+ nW : clong;
+ centerW : clong;
+
+ granulepos : ogg_int64_t;
+ sequence : ogg_int64_t;
+
+ glue_bits : ogg_int64_t;
+ time_bits : ogg_int64_t;
+ floor_bits : ogg_int64_t;
+ res_bits : ogg_int64_t;
+
+ backend_state : pointer;
+ end;
+
+{ vorbis_block is a single block of data to be processed as part of
+ the analysis/synthesis stream; it belongs to a specific logical
+ bitstream, but is independant from other vorbis_blocks belonging to
+ that logical bitstream. }
+
+ palloc_chain = ^alloc_chain;
+ alloc_chain = record
+ ptr : pointer;
+ next : palloc_chain;
+ end;
+
+ pvorbis_block = ^vorbis_block;
+ vorbis_block = record
+ { necessary stream state for linking to the framing abstraction }
+ pcm : ppcfloat; { this is a pointer into local storage }
+ opb : oggpack_buffer;
+
+ lW : clong;
+ W : clong;
+ nW : clong;
+ pcmend : cint;
+ mode : cint;
+
+ eofflag : cint;
+ granulepos : ogg_int64_t;
+ sequence : ogg_int64_t;
+ vd : pvorbis_dsp_state; { For read-only access of configuration }
+
+ { local storage to avoid remallocing; it's up to the mapping to structure it }
+ localstore : pointer;
+ localtop : clong;
+ localalloc : clong;
+ totaluse : clong;
+ reap : palloc_chain;
+
+ { bitmetrics for the frame }
+ glue_bits : clong;
+ time_bits : clong;
+ floor_bits : clong;
+ res_bits : clong;
+
+ internal : pointer;
+ end;
+
+{ vorbis_info contains all the setup information specific to the
+ specific compression/decompression mode in progress (eg,
+ psychoacoustic settings, channel setup, options, codebook
+ etc). vorbis_info and substructures are in backends.h. }
+
+{ the comments are not part of vorbis_info so that vorbis_info can be static storage }
+
+ pvorbis_comment = ^vorbis_comment;
+ vorbis_comment = record
+ { unlimited user comment fields. libvorbis writes 'libvorbis' whatever vendor is set to in encode }
+ user_comments : ^pcchar;
+ comment_lengths : pcint;
+ comments : cint;
+ vendor : pcchar;
+ end;
+
+
+{ libvorbis encodes in two abstraction layers; first we perform DSP
+ and produce a packet (see docs/analysis.txt). The packet is then
+ coded into a framed OggSquish bitstream by the second layer (see
+ docs/framing.txt). Decode is the reverse process; we sync/frame
+ the bitstream and extract individual packets, then decode the
+ packet back into PCM audio.
+
+ The extra framing/packetizing is used in streaming formats, such as
+ files. Over the net (such as with UDP), the framing and
+ packetization aren't necessary as they're provided by the transport
+ and the streaming layer is not used }
+
+{ Vorbis PRIMITIVES: general }
+
+procedure vorbis_info_init(var vi: vorbis_info); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+procedure vorbis_info_clear(var vi: vorbis_info); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_info_blocksize(var vi: vorbis_info; zo: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+procedure vorbis_comment_init(var vc: vorbis_comment); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+procedure vorbis_comment_add(var vc: vorbis_comment; comment: pchar); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+procedure vorbis_comment_add_tag(var vc: vorbis_comment; tag: pchar; contents: pchar); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_comment_query(var vc: vorbis_comment; tag: pchar; count: cint): pchar; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_comment_query_count(var vc: vorbis_comment; tag: pchar): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+procedure vorbis_comment_clear(var vc: vorbis_comment); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+function vorbis_block_init(var v: vorbis_dsp_state; var vb: vorbis_block): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_block_clear(var vb: vorbis_block): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+procedure vorbis_dsp_clear(var v: vorbis_dsp_state); cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_granule_time(var v: vorbis_dsp_state; granulepos: ogg_int64_t): cdouble; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+{ vorbislib PRIMITIVES: analysis/DSP layer }
+
+function vorbis_analysis_init(var v: vorbis_dsp_state; var vi: vorbis_info): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_commentheader_out(var vc: vorbis_comment; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_analysis_headerout(var v:vorbis_dsp_state; var vc: vorbis_comment; var op: ogg_packet; var op_comm: ogg_packet; var op_code: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_analysis_buffer(var v: vorbis_dsp_state; vals: cint): ppcfloat; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_analysis_wrote(var v: vorbis_dsp_state; vals: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_analysis_blockout(var v: vorbis_dsp_state; var vb: vorbis_block): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_analysis(var vb: vorbis_block; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+function vorbis_bitrate_addblock(var vb: vorbis_block): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_bitrate_flushpacket(var vd: vorbis_dsp_state; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+{ vorbislib PRIMITIVES: synthesis layer }
+
+function vorbis_synthesis_headerin(var vi: vorbis_info; var vc: vorbis_comment; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+function vorbis_synthesis_init(var v: vorbis_dsp_state; var vi: vorbis_info): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_restart(var v: vorbis_dsp_state): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis(var vb: vorbis_block; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_trackonly(var vb: vorbis_block; var op: ogg_packet): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_blockin(var v: vorbis_dsp_state; var vb: vorbis_block): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_pcmout(var v: vorbis_dsp_state; var pcm: ppcfloat): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_lapout(var v: vorbis_dsp_state; var pcm: ppcfloat): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_read(var v: vorbis_dsp_state; samples: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_packet_blocksize(var vi: vorbis_info; var op: ogg_packet): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+function vorbis_synthesis_halfrate(var v: vorbis_info; flag: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+function vorbis_synthesis_halfrate_p(var v: vorbis_info): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbislib{$ENDIF};
+
+{ vorbislib ERRORS and return codes }
+Const
+ OV_FALSE = -1;
+ OV_EOF = -2;
+ OV_HOLE = -3;
+
+ OV_EREAD = -128;
+ OV_EFAULT = -129;
+ OV_EIMPL = -130;
+ OV_EINVAL = -131;
+ OV_ENOTVORBIS = -132;
+ OV_EBADHEADER = -133;
+ OV_EVERSION = -134;
+ OV_ENOTAUDIO = -135;
+ OV_EBADPACKET = -136;
+ OV_EBADLINK = -137;
+ OV_ENOSEEK = -138;
+
+
+(***********************************************************************)
+(* Header : vorbisfile.h *)
+(***********************************************************************)
+
+type
+
+{* The function prototypes for the callbacks are basically the same as for
+
+ * the stdio functions fread, fseek, fclose, ftell.
+ * The one difference is that the FILE * arguments have been replaced with
+ * a void * - this is to be used as a pointer to whatever internal data these
+ * functions might need. In the stdio case, it's just a FILE * cast to a void *
+ *
+ * If you use other functions, check the docs for these functions and return
+ * the right values. For seek_func(), you *MUST* return -1 if the stream is
+ * unseekable
+ *}
+
+ read_func = function(ptr: pointer; size, nmemb: csize_t; datasource: pointer): csize_t; cdecl;
+ seek_func = function(datasource: pointer; offset: ogg_int64_t; whence: cint): cint; cdecl;
+ close_func = function(datasource: pointer): cint; cdecl;
+ tell_func = function(datasource: pointer): clong; cdecl;
+
+ pov_callbacks = ^ov_callbacks;
+ ov_callbacks = record
+ read : read_func;
+ seek : seek_func;
+ close : close_func;
+ tell : tell_func;
+ end;
+
+const
+ NOTOPEN = 0;
+ PARTOPEN = 1;
+ OPENED = 2;
+ STREAMSET = 3;
+ INITSET = 4;
+
+type
+ POggVorbis_File = ^OggVorbis_File;
+ OggVorbis_File = record
+ datasource : pointer; { pointer to a FILE *, etc. }
+ seekable : cint;
+ offset : ogg_int64_t;
+ end_ : ogg_int64_t;
+ oy : ogg_sync_state;
+
+ { If the FILE handle isn't seekable (eg, a pipe), only the current stream appears }
+ links : cint;
+ offsets : pogg_int64_t;
+ dataoffsets : pogg_int64_t;
+ serialnos : pclong;
+ pcmlengths : pogg_int64_t; { overloaded to maintain binary compatability; x2 size, stores both beginning and end values }
+ vi : pvorbis_info;
+ vc : pvorbis_comment;
+
+ { Decoding working state local storage }
+ pcm_offset : ogg_int64_t;
+ ready_state : cint;
+ current_serialno: clong;
+ current_link : cint;
+
+ bittrack : cdouble;
+ samptrack : cdouble;
+
+ os : ogg_stream_state; { take physical pages, weld into a logical stream of packets }
+ vd : vorbis_dsp_state; { central working state for the packet->PCM decoder }
+ vb : vorbis_block; { local working space for packet->PCM decode }
+
+ callbacks : ov_callbacks;
+ end;
+
+
+function ov_clear(var vf: OggVorbis_File): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_open(f: pointer; var vf: OggVorbis_File; initial: pointer; ibytes: clong): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_open_callbacks(datasource: pointer; var vf: OggVorbis_File; initial: pointer; ibytes: clong; callbacks: ov_callbacks): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_test(f: pointer; var vf: OggVorbis_File; initial: pointer; ibytes: clong): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_test_callbacks(datasource: pointer; var vf: OggVorbis_File; initial: pointer; ibytes: clong; callbacks: ov_callbacks): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_test_open(var vf: OggVorbis_File): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_bitrate(var vf: OggVorbis_File; i: cint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_bitrate_instant(var vf: OggVorbis_File): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_streams(var vf: OggVorbis_File): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_seekable(var vf: OggVorbis_File): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_serialnumber(var vf: OggVorbis_File; i: cint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_raw_total(var vf: OggVorbis_File; i: cint): ogg_int64_t; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_pcm_total(var vf: OggVorbis_File; i: cint): ogg_int64_t; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_time_total(var vf: OggVorbis_File; i: cint): cdouble; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_raw_seek(var vf: OggVorbis_File; pos: ogg_int64_t): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_pcm_seek(var vf: OggVorbis_File; pos: ogg_int64_t): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_pcm_seek_page(var vf: OggVorbis_File; pos: ogg_int64_t): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_time_seek(var vf: OggVorbis_File; pos: cdouble): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_time_seek_page(var vf: OggVorbis_File; pos: cdouble): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_raw_seek_lap(var vf: OggVorbis_File; pos: ogg_int64_t): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_pcm_seek_lap(var vf: OggVorbis_File; pos: ogg_int64_t): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_pcm_seek_page_lap(var vf: OggVorbis_File; pos: ogg_int64_t): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_time_seek_lap(var vf: OggVorbis_File; pos: cdouble): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_time_seek_page_lap(var vf: OggVorbis_File; pos: cdouble): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_raw_tell(var vf: OggVorbis_File): ogg_int64_t; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_pcm_tell(var vf: OggVorbis_File): ogg_int64_t; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_time_tell(var vf: OggVorbis_File): cdouble; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_info(var vf: OggVorbis_File; link: cint): pvorbis_info; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_comment(var vf: OggVorbis_File; link: cint): pvorbis_comment; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_read_float(var vf: OggVorbis_File; var pcm_channels: ppcfloat; samples: cint; bitstream: pcint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_read(var vf: OggVorbis_File; buffer: pointer; length: cint; bigendianp: cbool; word: cint; sgned: cbool; bitstream: pcint): clong; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_crosslap(var vf1: OggVorbis_File; var vf2: OggVorbis_File): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+function ov_halfrate(var vf: OggVorbis_File; flag: cint): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+function ov_halfrate_p(var vf: OggVorbis_File): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisfilelib{$ENDIF};
+
+
+{
+ Developer of the A52 helpers for FreePascal
+ Copyright (C) 2006 by Ivo Steinmann
+}
+
+function ov_read_ext(var vf: OggVorbis_File; buffer: pointer; length: cint; bigendianp: cbool; word: cint; sgned: cbool): clong;
+
+(***********************************************************************)
+(* Header : vorbisenc.h *)
+(***********************************************************************)
+
+const
+ OV_ECTL_RATEMANAGE_GET = $10;
+
+ OV_ECTL_RATEMANAGE_SET = $11;
+ OV_ECTL_RATEMANAGE_AVG = $12;
+ OV_ECTL_RATEMANAGE_HARD = $13;
+
+ OV_ECTL_LOWPASS_GET = $20;
+ OV_ECTL_LOWPASS_SET = $21;
+
+ OV_ECTL_IBLOCK_GET = $30;
+ OV_ECTL_IBLOCK_SET = $31;
+
+type
+ povectl_ratemanage_arg = ^ovectl_ratemanage_arg;
+ ovectl_ratemanage_arg = record
+ management_active : cint;
+
+ bitrate_hard_min : clong;
+ bitrate_hard_max : clong;
+ bitrate_hard_window : cdouble;
+
+ bitrate_av_lo : clong;
+ bitrate_av_hi : clong;
+ bitrate_av_window : cdouble;
+ bitrate_av_window_center : cdouble;
+ end;
+
+// function vorbis_encode_init(var vi: vorbis_info; channels, rate, max_bitrate, nominal_bitrate, min_bitrate: clong): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisenclib{$ENDIF};
+// function vorbis_encode_setup_managed(var vi: vorbis_info; channels, rate, max_bitrate, nominal_bitrate, min_bitrate: clong): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisenclib{$ENDIF};
+// function vorbis_encode_setup_vbr(var vi: vorbis_info; channels, rate: clong; quality: cfloat): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisenclib{$ENDIF};
+// (* quality level from 0. (lo) to 1. (hi) *)
+// function vorbis_encode_init_vbr(var vi: vorbis_info; channels, rate: clong; base_quality: cfloat): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisenclib{$ENDIF};
+// function vorbis_encode_setup_init(var vi: vorbis_info): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisenclib{$ENDIF};
+// function vorbis_encode_ctl(var vi: vorbis_info; number: cint; arg: pointer): cint; cdecl; external {$IFDEF OGG_DYNAMIC}vorbisenclib{$ENDIF};
+
+implementation
+
+function ov_read_ext(var vf: OggVorbis_File; buffer: pointer; length: cint; bigendianp: cbool; word: cint; sgned: cbool): clong;
+var
+ ofs: cint;
+ Num: cint;
+ Res: cint;
+begin
+ // check blocksize here!
+ {if length mod 4 <> 0 then
+ Exit(0);}
+
+ ofs := 0;
+ num := length;
+
+ while num > 0 do
+ begin
+ res := ov_read(vf, buffer + ofs, num, bigendianp, word, sgned, nil);
+ if res < 0 then
+ Exit(res);
+
+ if res = 0 then
+ Break;
+
+ ofs := ofs + res;
+ num := num - res;
+ end;
+
+ Result := ofs;
+end;
+
+end.
+