Files
lazarus-ccr/components/acs/Src/fileformats/general/vorbiscodec.pas

481 lines
15 KiB
ObjectPascal
Raw Normal View History

(*
delphi/kylix headers for oggvorbis software codec.
translated from codec.h header
by andrei borovsky, acs@compiler4.net
the original c/c++ headers and libraries (c) copyright 1994-2001
by the xiphophorus company http://www.xiph.org/
*)
{
$Log: vorbiscodec.pas,v $
Revision 1.1 2005/12/29 20:46:00 z0m3ie
fixed some problems with vorbis in lazarus
Revision 1.1 2005/12/19 18:36:56 z0m3ie
*** empty log message ***
Revision 1.1 2005/09/12 22:04:53 z0m3ie
modified structure again, fileformats are now in an sperat folder.
all File In/Out classes are capsulated from TFileIn and TFileOut
Revision 1.1 2005/08/25 20:18:00 z0m3ie
Version 2.4 restructure
TCDPlayer removed (fits not in component structure)
TMP3ToWavConverter removed (fits not in component structure)
Revision 1.2 2005/08/22 20:17:01 z0m3ie
changed Headers to log
changed mail adress
}
{$IFDEF FPC}
{$IFDEF WIN32}
{$PACKRECORDS C}
{$ENDIF WIN32}
{$ENDIF WIN32}
unit vorbiscodec;
{$ifdef fpc}
{$mode delphi}
{$endif}
interface
uses
ACS_Procs,
{$IFDEF LINUX}
baseunix,dl,
{$ENDIF}
{$IFDEF WIN32}
Windows,
{$ENDIF}
ogg;
type
PVORBIS_INFO = ^VORBIS_INFO;
VORBIS_INFO = record
version: Integer;
channels: Integer;
rate: LongInt;
(* 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: LongInt;
bitrate_nominal: LongInt;
bitrate_lower: LongInt;
bitrate_window: LongInt;
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: Integer;
vi: PVORBIS_INFO;
pcm: PPFLOAT;
pcmret: PPFLOAT;
pcm_storage: Integer;
pcm_current: Integer;
pcm_returned: Integer;
preextrapolate: Integer;
eofflag: Integer;
lW: LongInt;
W: LongInt;
nW: LongInt;
centerW: LongInt;
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;
PALLOC_CHAIN = ^ALLOC_CHAIN;
ALLOC_CHAIN = record
ptr: Pointer;
next: PALLOC_CHAIN;
end;
VORBIS_BLOCK = record
// necessary stream state for linking to the framing abstraction
pcm: PPFLOAT;
// this is a pointer into local storage
opb: OGGPACK_BUFFER;
lW: LongInt;
W: LongInt;
nW: LongInt;
pcmend: Integer;
mode: Integer;
eofflag: Integer;
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: LongInt;
localalloc: LongInt;
totaluse: LongInt;
reap: PALLOC_CHAIN;
// bitmetrics for the frame
glue_bits: LongInt;
time_bits: LongInt;
floor_bits: LongInt;
res_bits: LongInt;
internal: 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. *)
(* 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: PPChar;
comment_lengths: PInteger;
comments: Integer;
vendor: PChar;
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
const
{$IFDEF LINUX}
LibvorbisPath = 'libvorbis.so*'; //'/usr/lib/libvorbis.so';
{$DEFINE SEARCH_LIBS}
{$ENDIF}
{$IFDEF WIN32}
LibvorbisPath = 'vorbis.dll';
{$ENDIF}
var
LibvorbisLoaded : Boolean = False;
type
vorbis_info_init_t = procedure(var vi: VORBIS_INFO); cdecl;
vorbis_info_clear_t = procedure(var vi: VORBIS_INFO); cdecl;
vorbis_info_blocksize_t = function(var vi: VORBIS_INFO;
zo: Integer): Integer; cdecl;
vorbis_comment_init_t = procedure(var vc: VORBIS_COMMENT); cdecl;
vorbis_comment_add_t = procedure(var vc: VORBIS_COMMENT;
comment: PChar); cdecl;
vorbis_comment_add_tag_t = procedure(var vc: VORBIS_COMMENT;
tag: PChar;
contents: PChar); cdecl;
vorbis_comment_query_t = function(var vc: VORBIS_COMMENT;
tag: PChar;
count: Integer): PChar; cdecl;
vorbis_comment_query_count_t = function(var vc: VORBIS_COMMENT;
tag: PChar): Integer; cdecl;
vorbis_comment_clear_t = procedure(var vc: VORBIS_COMMENT) cdecl;
vorbis_block_init_t = function(var v: VORBIS_DSP_STATE;
var vb: VORBIS_BLOCK): Integer; cdecl;
vorbis_block_clear_t = function(var vb: VORBIS_BLOCK): Integer; cdecl;
vorbis_dsp_clear_t = procedure(var v: VORBIS_DSP_STATE); cdecl;
// Vorbis PRIMITIVES: analysis/DSP layer
vorbis_analysis_init_t = function(var v: VORBIS_DSP_STATE;
var vi: VORBIS_INFO): Integer; cdecl;
vorbis_commentheader_out_t = function(var vc: VORBIS_COMMENT;
var op: OGG_PACKET): Integer; cdecl;
vorbis_analysis_headerout_t = function(var v: VORBIS_DSP_STATE;
var vc: VORBIS_COMMENT;
var op: OGG_PACKET;
var op_comm: OGG_PACKET;
var op_code: OGG_PACKET): Integer; cdecl;
vorbis_analysis_buffer_t = function(var v: VORBIS_DSP_STATE;
vals: Integer): PPFLOAT; cdecl;
vorbis_analysis_wrote_t = function(var v: VORBIS_DSP_STATE;
vals: Integer): Integer; cdecl;
vorbis_analysis_blockout_t = function(var v: VORBIS_DSP_STATE;
var vb: VORBIS_BLOCK): Integer; cdecl;
vorbis_analysis_t = function(var vb: VORBIS_BLOCK;
op: POGG_PACKET): Integer; cdecl;
vorbis_bitrate_addblock_t = function(var vb: VORBIS_BLOCK): Integer; cdecl;
vorbis_bitrate_flushpacket_t = function(var vd: VORBIS_DSP_STATE;
var op: OGG_PACKET): Integer; cdecl;
// Vorbis PRIMITIVES: synthesis layer
vorbis_synthesis_headerin_t = function(var vi: VORBIS_INFO;
var vc: VORBIS_COMMENT;
var op: OGG_PACKET): Integer; cdecl;
vorbis_synthesis_init_t = function(var v: VORBIS_DSP_STATE;
var vi: VORBIS_INFO): Integer; cdecl;
vorbis_synthesis_t = function(var vb: VORBIS_BLOCK;
var op: OGG_PACKET): Integer; cdecl;
vorbis_synthesis_blockin_t = function(var v: VORBIS_DSP_STATE;
var vb: VORBIS_BLOCK): Integer; cdecl;
vorbis_synthesis_pcmout_t = function(var v: VORBIS_DSP_STATE;
var pcm: PPFLOAT): Integer; cdecl;
vorbis_synthesis_read_t = function(var v: VORBIS_DSP_STATE;
samples: Integer): Integer; cdecl;
vorbis_packet_blocksize_t = function(var vi: VORBIS_INFO;
var op: OGG_PACKET): LongInt; cdecl;
var
vorbis_info_init : vorbis_info_init_t;
vorbis_info_clear : vorbis_info_clear_t;
vorbis_info_blocksize : vorbis_info_blocksize_t;
vorbis_comment_init : vorbis_comment_init_t;
vorbis_comment_add : vorbis_comment_add_t;
vorbis_comment_add_tag : vorbis_comment_add_tag_t;
vorbis_comment_query : vorbis_comment_query_t;
vorbis_comment_query_count : vorbis_comment_query_count_t;
vorbis_comment_clear : vorbis_comment_clear_t;
vorbis_block_init : vorbis_block_init_t;
vorbis_block_clear : vorbis_block_clear_t;
vorbis_dsp_clear : vorbis_dsp_clear_t;
vorbis_analysis_init : vorbis_analysis_init_t;
vorbis_commentheader_out : vorbis_commentheader_out_t;
vorbis_analysis_headerout : vorbis_analysis_headerout_t;
vorbis_analysis_buffer : vorbis_analysis_buffer_t;
vorbis_analysis_wrote : vorbis_analysis_wrote_t;
vorbis_analysis_blockout : vorbis_analysis_blockout_t;
vorbis_analysis : vorbis_analysis_t;
vorbis_bitrate_addblock : vorbis_bitrate_addblock_t;
vorbis_bitrate_flushpacket : vorbis_bitrate_flushpacket_t;
vorbis_synthesis_headerin : vorbis_synthesis_headerin_t;
vorbis_synthesis_init : vorbis_synthesis_init_t;
vorbis_synthesis : vorbis_synthesis_t;
vorbis_synthesis_blockin : vorbis_synthesis_blockin_t;
vorbis_synthesis_pcmout : vorbis_synthesis_pcmout_t;
vorbis_synthesis_read : vorbis_synthesis_read_t;
vorbis_packet_blocksize : vorbis_packet_blocksize_t;
// Vorbis 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;
implementation
{$IFDEF LINUX}
var
Libhandle : Pointer;
{$IFDEF SEARCH_LIBS}
Path : String;
{$ENDIF}
initialization
{$IFDEF SEARCH_LIBS}
Libhandle := nil;
Path := FindLibs(LibvorbisPath);
if Path <> '' then Libhandle := dlopen(@Path[1], RTLD_NOW or RTLD_GLOBAL);
{$ELSE}
Libhandle := dlopen(LibvorbisPath, RTLD_NOW or RTLD_GLOBAL);
{$ENDIF}
if Libhandle <> nil then
begin
LibvorbisLoaded := True;
vorbis_info_init := dlsym(Libhandle, 'vorbis_info_init');
vorbis_info_clear := dlsym(Libhandle, 'vorbis_info_clear');
vorbis_info_blocksize := dlsym(Libhandle, 'vorbis_info_blocksize');
vorbis_comment_init := dlsym(Libhandle, 'vorbis_comment_init');
vorbis_comment_add := dlsym(Libhandle, 'vorbis_comment_add');
vorbis_comment_add_tag := dlsym(Libhandle, 'vorbis_comment_add_tag');
vorbis_comment_query := dlsym(Libhandle, 'vorbis_comment_query');
vorbis_comment_query_count := dlsym(Libhandle, 'vorbis_comment_query_count');
vorbis_comment_clear := dlsym(Libhandle, 'vorbis_comment_clear');
vorbis_block_init := dlsym(Libhandle, 'vorbis_block_init');
vorbis_block_clear := dlsym(Libhandle, 'vorbis_block_clear');
vorbis_dsp_clear := dlsym(Libhandle, 'vorbis_dsp_clear');
vorbis_analysis_init := dlsym(Libhandle, 'vorbis_analysis_init');
vorbis_commentheader_out := dlsym(Libhandle, 'vorbis_commentheader_out');
vorbis_analysis_headerout := dlsym(Libhandle, 'vorbis_analysis_headerout');
vorbis_analysis_buffer := dlsym(Libhandle, 'vorbis_analysis_buffer');
vorbis_analysis_wrote := dlsym(Libhandle, 'vorbis_analysis_wrote');
vorbis_analysis_blockout := dlsym(Libhandle, 'vorbis_analysis_blockout');
vorbis_analysis := dlsym(Libhandle, 'vorbis_analysis');
vorbis_bitrate_addblock := dlsym(Libhandle, 'vorbis_bitrate_addblock');
vorbis_bitrate_flushpacket := dlsym(Libhandle, 'vorbis_bitrate_flushpacket');
vorbis_synthesis_headerin := dlsym(Libhandle, 'vorbis_synthesis_headerin');
vorbis_synthesis_init := dlsym(Libhandle, 'vorbis_synthesis_init');
vorbis_synthesis := dlsym(Libhandle, 'vorbis_synthesis');
vorbis_synthesis_blockin := dlsym(Libhandle, 'vorbis_synthesis_blockin');
vorbis_synthesis_pcmout := dlsym(Libhandle, 'vorbis_synthesis_pcmout');
vorbis_synthesis_read := dlsym(Libhandle, 'vorbis_synthesis_read');
vorbis_packet_blocksize := dlsym(Libhandle, 'vorbis_packet_blocksize');
end;
finalization
if libhandle <> nil then dlclose(libhandle);
{$ENDIF}
{$IFDEF WIN32}
var
Libhandle : HMODULE;
initialization
Libhandle := LoadLibraryEx(LibvorbisPath, 0, 0);
if Libhandle <> 0 then
begin
LibvorbisLoaded := True;
vorbis_info_init := GetProcAddress(Libhandle, 'vorbis_info_init');
vorbis_info_clear := GetProcAddress(Libhandle, 'vorbis_info_clear');
vorbis_info_blocksize := GetProcAddress(Libhandle, 'vorbis_info_blocksize');
vorbis_comment_init := GetProcAddress(Libhandle, 'vorbis_comment_init');
vorbis_comment_add := GetProcAddress(Libhandle, 'vorbis_comment_add');
vorbis_comment_add_tag := GetProcAddress(Libhandle, 'vorbis_comment_add_tag');
vorbis_comment_query := GetProcAddress(Libhandle, 'vorbis_comment_query');
vorbis_comment_query_count := GetProcAddress(Libhandle, 'vorbis_comment_query_count');
vorbis_comment_clear := GetProcAddress(Libhandle, 'vorbis_comment_clear');
vorbis_block_init := GetProcAddress(Libhandle, 'vorbis_block_init');
vorbis_block_clear := GetProcAddress(Libhandle, 'vorbis_block_clear');
vorbis_dsp_clear := GetProcAddress(Libhandle, 'vorbis_dsp_clear');
vorbis_analysis_init := GetProcAddress(Libhandle, 'vorbis_analysis_init');
vorbis_commentheader_out := GetProcAddress(Libhandle, 'vorbis_commentheader_out');
vorbis_analysis_headerout := GetProcAddress(Libhandle, 'vorbis_analysis_headerout');
vorbis_analysis_buffer := GetProcAddress(Libhandle, 'vorbis_analysis_buffer');
vorbis_analysis_wrote := GetProcAddress(Libhandle, 'vorbis_analysis_wrote');
vorbis_analysis_blockout := GetProcAddress(Libhandle, 'vorbis_analysis_blockout');
vorbis_analysis := GetProcAddress(Libhandle, 'vorbis_analysis');
vorbis_bitrate_addblock := GetProcAddress(Libhandle, 'vorbis_bitrate_addblock');
vorbis_bitrate_flushpacket := GetProcAddress(Libhandle, 'vorbis_bitrate_flushpacket');
vorbis_synthesis_headerin := GetProcAddress(Libhandle, 'vorbis_synthesis_headerin');
vorbis_synthesis_init := GetProcAddress(Libhandle, 'vorbis_synthesis_init');
vorbis_synthesis := GetProcAddress(Libhandle, 'vorbis_synthesis');
vorbis_synthesis_blockin := GetProcAddress(Libhandle, 'vorbis_synthesis_blockin');
vorbis_synthesis_pcmout := GetProcAddress(Libhandle, 'vorbis_synthesis_pcmout');
vorbis_synthesis_read := GetProcAddress(Libhandle, 'vorbis_synthesis_read');
vorbis_packet_blocksize := GetProcAddress(Libhandle, 'vorbis_packet_blocksize');
end;
finalization
if Libhandle <> 0 then FreeLibrary(Libhandle);
{$ENDIF}
end.