Implements Module Player working in Form
* Implements Embedding .xm music in Final Application
This commit is contained in:
47
UOS/src/laz_uos.lpk
Normal file
47
UOS/src/laz_uos.lpk
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<Package Version="5">
|
||||
<PathDelim Value="\"/>
|
||||
<Name Value="laz_uos"/>
|
||||
<Author Value="Fred van Stappen"/>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
</CompilerOptions>
|
||||
<Description Value="uos : United OpenLib of Sound.
|
||||
uos unifies the best open-source audio libraries.
|
||||
For fpc, fpGUI, MSEgui and LCL.
|
||||
With uos you can:
|
||||
Listen to mp3, ogg, wav, flac, m4a, opus, cda ... audio files.
|
||||
Deal with 16, 32 integer or float 32 bit resolution.
|
||||
Do internet audio streaming.
|
||||
Record all types of input into wav file with 16 or 32 bit resolution.
|
||||
Add DSP effects and filters, however many you want and record it.
|
||||
Listen to multiple input and output.
|
||||
Produce sound from built-in synthesizer.
|
||||
uos can use:
|
||||
PortAudio, SndFile, Mpg123, Faad, Mp4ff, Opus, OpusFile audio libraries and
|
||||
SoundTouch, Bs2b audio-effect libraries.
|
||||
|
||||
Included in the package:
|
||||
Examples fpGUI, MSEgui, LCL and console.
|
||||
Binaries of libraries for Linux, arm-Rapsberry Pi, Windows, Mac osX, FreeBSD."/>
|
||||
<License Value="GNU Library or "Lesser" General Public License (LGPL)"/>
|
||||
<Version Major="1"/>
|
||||
<CompatibilityMode Value="True"/>
|
||||
<RequiredPkgs Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="FCL"/>
|
||||
</Item1>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
<UnitPath Value="$(PkgOutDir)"/>
|
||||
</UsageOptions>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
</Package>
|
||||
</CONFIG>
|
||||
12
UOS/src/laz_uos.pas
Normal file
12
UOS/src/laz_uos.pas
Normal file
@@ -0,0 +1,12 @@
|
||||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit laz_uos;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
6
UOS/src/lib/x86_64-win64/laz_uos.compiled
Normal file
6
UOS/src/lib/x86_64-win64/laz_uos.compiled
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<Lazarus Version="4.0"/>
|
||||
<Compiler Value="C:\lazarus\fpc\3.2.2\bin\x86_64-win64\fpc.exe" Date="1520657216"/>
|
||||
<Params Value="-MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -FuC:\Users\indrajith\Documents\projects\package-search\package-zerch\UOS\src\ -FuC:\lazarus\packager\units\x86_64-win64 -FUC:\Users\indrajith\Documents\projects\package-search\package-zerch\UOS\src\lib\x86_64-win64\ laz_uos.pas"/>
|
||||
</CONFIG>
|
||||
BIN
UOS/src/lib/x86_64-win64/laz_uos.ppu
Normal file
BIN
UOS/src/lib/x86_64-win64/laz_uos.ppu
Normal file
Binary file not shown.
12754
UOS/src/uos.pas
Normal file
12754
UOS/src/uos.pas
Normal file
File diff suppressed because it is too large
Load Diff
906
UOS/src/uos_aac.pas
Normal file
906
UOS/src/uos_aac.pas
Normal file
@@ -0,0 +1,906 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading version of FAAD2 Pascal Wrapper.
|
||||
mcwNeAACDec.pas, mcwMP4FF.pas, mcwAAC.pas
|
||||
By Franklyn A. Harlow Feb 2016
|
||||
License : modified LGPL.
|
||||
mcw* merged into uos_aac by Fred van Stappen / fiens@hotmail.com }
|
||||
|
||||
unit uos_aac;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ctypes, math,
|
||||
dynlibs;
|
||||
|
||||
const
|
||||
|
||||
{$IFDEF unix}
|
||||
{$IFDEF darwin}
|
||||
libaa= 'libfaad.2.dylib';
|
||||
libm4= 'libmp4ff.0.dylib';
|
||||
{$ELSE}
|
||||
libaa= 'libfaad.so.2';
|
||||
libm4= 'libmp4ff.so.0.0.0';
|
||||
{$ENDIF}
|
||||
{$ELSE}
|
||||
libaa= 'Faad2.dll';
|
||||
libm4= 'mp4ff.dll';
|
||||
{$ENDIF}
|
||||
|
||||
//////////// from mcwMP4FF.pas By Franklyn A. Harlow
|
||||
type
|
||||
|
||||
ArSingle = array of Single;
|
||||
PArSingle = ^ArSingle;
|
||||
|
||||
read_callback_t = function(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
||||
write_callback_t = function(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
||||
seek_callback_t = function(user_data : Pointer; Position : cInt64) : LongWord; cdecl;
|
||||
truncate_callback_t = function(user_data : Pointer) : LongWord; cdecl;
|
||||
|
||||
mp4ff_callback_t = record
|
||||
read : read_callback_t;
|
||||
write : write_callback_t;
|
||||
seek : seek_callback_t;
|
||||
truncate : truncate_callback_t;
|
||||
user_data : Pointer;
|
||||
end;
|
||||
p_mp4ff_callback_t = ^mp4ff_callback_t;
|
||||
|
||||
mp4ff_t = pointer;
|
||||
int32_t = LongInt;
|
||||
int64_t = cInt64;
|
||||
uint32_t = LongWord;
|
||||
|
||||
var
|
||||
mp4ff_open_read : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl;
|
||||
mp4ff_open_read_metaonly : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl;
|
||||
mp4ff_close : procedure(f : mp4ff_t); cdecl;
|
||||
mp4ff_get_sample_duration : function(f : mp4ff_t; track, sample : int32_t) : int32_t; cdecl;
|
||||
mp4ff_get_sample_duration_use_offsets : function(f : mp4ff_t; track, sample : int32_t) : int32_t; cdecl;
|
||||
mp4ff_get_sample_position : function(f : mp4ff_t; track, sample : int32_t) : int64_t; cdecl;
|
||||
mp4ff_get_sample_offset : function(f : mp4ff_t; track, sample : int32_t) : int32_t; cdecl;
|
||||
mp4ff_find_sample : function(f : mp4ff_t; track : int32_t; offset : int64_t; var toskip : int32_t) : int32_t; cdecl;
|
||||
mp4ff_find_sample_use_offsets : function(f : mp4ff_t; track : int32_t; offset : int64_t; var toskip : int32_t) : int32_t; cdecl;
|
||||
mp4ff_set_sample_position : function(f : mp4ff_t; track : int32_t; sample : int64_t) : int32_t; cdecl;
|
||||
mp4ff_read_sample : function(f : mp4ff_t; track, sample : int32_t; var audio_buffer : pcfloat; var bytes : LongWord) : int32_t; cdecl;
|
||||
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
|
||||
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
|
||||
mp4ff_get_decoder_config : function(f : mp4ff_t; track : Integer; var ppBuf : pcfloat; var pBufSize : LongWord) : int32_t; cdecl;
|
||||
mp4ff_free_decoder_config : procedure(Buf : pcfloat); cdecl;
|
||||
mp4ff_get_track_type : function(f : mp4ff_t; const track : Integer) : int32_t; cdecl;
|
||||
mp4ff_total_tracks : function(f : mp4ff_t) : int32_t; cdecl;
|
||||
mp4ff_num_samples : function(f : mp4ff_t; track : Integer) : int32_t; cdecl;
|
||||
mp4ff_time_scale : function(f : mp4ff_t; track : Integer) : int32_t; cdecl;
|
||||
mp4ff_get_avg_bitrate : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
||||
mp4ff_get_max_bitrate : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
||||
mp4ff_get_track_duration : function(f : mp4ff_t; track : int32_t) : int64_t; cdecl; //returns _t = function(-1) if unknown
|
||||
mp4ff_get_track_duration_use_offsets : function(f : mp4ff_t; track : int32_t) : Integer; cdecl; //returns _t = function(-1) if unknown
|
||||
mp4ff_get_sample_rate : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
||||
mp4ff_get_channel_count : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
||||
mp4ff_get_audio_type : function(f : mp4ff_t; track : int32_t) : uint32_t; cdecl;
|
||||
mp4ff_meta_get_num_items : function(f : mp4ff_t) : Integer; cdecl;
|
||||
mp4ff_meta_get_by_index : function(f : mp4ff_t; index : LongWord; var item, value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_title : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_artist : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_writer : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_album : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_date : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_tool : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_comment : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_genre : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_track : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_disc : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_totaltracks : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_totaldiscs : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_compilation : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_tempo : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
mp4ff_meta_get_coverart : function(f : mp4ff_t; var value : PChar) : Integer; cdecl;
|
||||
|
||||
function GetAACTrack(infile : mp4ff_t) : Integer;
|
||||
procedure Loadmp4ff(mp4ff : AnsiString);
|
||||
procedure UnLoadMp4ff;
|
||||
Function isMp4ffLoaded : Boolean;
|
||||
|
||||
//////////// from mcwNeAACDec.pas by Franklyn A. Harlow
|
||||
Const
|
||||
{ object types for AAC }
|
||||
MAIN = 1;
|
||||
LC = 2;
|
||||
SSR = 3;
|
||||
LTP = 4;
|
||||
HE_AAC = 5;
|
||||
ER_LC = 17;
|
||||
ER_LTP = 19;
|
||||
LD = 23;
|
||||
{ special object type for DRM }
|
||||
DRM_ER_LC = 27;
|
||||
{ header types }
|
||||
RAW = 0;
|
||||
ADIF = 1;
|
||||
ADTS = 2;
|
||||
LATM = 3;
|
||||
{ SBR signalling }
|
||||
NO_SBR = 0;
|
||||
SBR_UPSAMPLED = 1;
|
||||
SBR_DOWNSAMPLED = 2;
|
||||
NO_SBR_UPSAMPLED = 3;
|
||||
{ library output formats }
|
||||
FAAD_FMT_16BIT = 1;
|
||||
FAAD_FMT_24BIT = 2;
|
||||
FAAD_FMT_32BIT = 3;
|
||||
FAAD_FMT_FLOAT = 4;
|
||||
FAAD_FMT_FIXED = FAAD_FMT_FLOAT;
|
||||
FAAD_FMT_DOUBLE = 5;
|
||||
{ Capabilities }
|
||||
{ Can decode LC }
|
||||
LC_DEC_CAP = 1 shl 0;
|
||||
{ Can decode MAIN }
|
||||
MAIN_DEC_CAP = 1 shl 1;
|
||||
{ Can decode LTP }
|
||||
LTP_DEC_CAP = 1 shl 2;
|
||||
{ Can decode LD }
|
||||
LD_DEC_CAP = 1 shl 3;
|
||||
{ Can decode ER }
|
||||
ERROR_RESILIENCE_CAP = 1 shl 4;
|
||||
{ Fixed point }
|
||||
FIXED_POINT_CAP = 1 shl 5;
|
||||
{ Channel definitions }
|
||||
FRONT_CHANNEL_CENTER = 1;
|
||||
FRONT_CHANNEL_LEFT = 2;
|
||||
FRONT_CHANNEL_RIGHT = 3;
|
||||
SIDE_CHANNEL_LEFT = 4;
|
||||
SIDE_CHANNEL_RIGHT = 5;
|
||||
BACK_CHANNEL_LEFT = 6;
|
||||
BACK_CHANNEL_RIGHT = 7;
|
||||
BACK_CHANNEL_CENTER = 8;
|
||||
LFE_CHANNEL = 9;
|
||||
UNKNOWN_CHANNEL = 0;
|
||||
{ DRM channel definitions }
|
||||
DRMCH_MONO = 1;
|
||||
DRMCH_STEREO = 2;
|
||||
DRMCH_SBR_MONO = 3;
|
||||
DRMCH_SBR_STEREO = 4;
|
||||
DRMCH_SBR_PS_STEREO = 5;
|
||||
{ A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel,
|
||||
so at least so much bytes per channel should be available in this stream }
|
||||
{ 6144 bits/channel }
|
||||
FAAD_MIN_STREAMSIZE = 768;
|
||||
|
||||
Type
|
||||
PNeAACDec = Pointer;
|
||||
|
||||
NeAAC_byte = {$IFDEF FPC}{$IFDEF CPU64}cuint32 {$ELSE}Byte {$ENDIF}{$ELSE}Byte {$ENDIF};
|
||||
NeAAC_word = {$IFDEF FPC}{$IFDEF CPU64}cuint64{$ELSE}Word {$ENDIF}{$ELSE}Word {$ENDIF};
|
||||
NeAAC_longword = {$IFDEF FPC}{$IFDEF CPU64}culong {$ELSE}LongWord{$ENDIF}{$ELSE}LongWord{$ENDIF};
|
||||
|
||||
NeAACDecConfiguration = record
|
||||
defObjectType : NeAAC_byte;
|
||||
defSampleRate : NeAAC_longword;
|
||||
outputFormat : NeAAC_byte;
|
||||
downMatrix : NeAAC_byte;
|
||||
useOldADTSFormat : NeAAC_byte;
|
||||
dontUpSampleImplicitSBR : NeAAC_byte;
|
||||
end;
|
||||
TNeAACDecConfiguration = NeAACDecConfiguration;
|
||||
PNeAACDecConfiguration = ^NeAACDecConfiguration;
|
||||
|
||||
NeAACDecFrameInfo = record
|
||||
bytesconsumed : NeAAC_longword;
|
||||
samples : NeAAC_longword;
|
||||
channels : NeAAC_byte;
|
||||
error : NeAAC_byte;
|
||||
samplerate : NeAAC_longword;
|
||||
sbr : NeAAC_byte; //* SBR: 0: off, 1: on; upsample, 2: on; downsampled, 3: off; upsampled */
|
||||
object_type : NeAAC_byte; //* MPEG-4 ObjectType */
|
||||
header_type : NeAAC_byte; //* AAC header type; MP4 will be signalled as RAW also */
|
||||
num_front_channels : NeAAC_byte; //* multichannel configuration */
|
||||
num_side_channels : NeAAC_byte;
|
||||
num_back_channels : NeAAC_byte;
|
||||
num_lfe_channels : NeAAC_byte;
|
||||
channel_position : array[0..63] of NeAAC_byte;
|
||||
ps : NeAAC_byte; //* PS: 0: off, 1: on */
|
||||
end;
|
||||
TNeAACDecFrameInfo = NeAACDecFrameInfo;
|
||||
PNeAACDecFrameInfo = ^NeAACDecFrameInfo;
|
||||
|
||||
mp4AudioSpecificConfig = record
|
||||
objectTypeIndex : NeAAC_byte;
|
||||
samplingFrequencyIndex : NeAAC_byte;
|
||||
samplingFrequency : NeAAC_longword;
|
||||
channelsConfiguration : NeAAC_byte;
|
||||
frameLengthFlag : NeAAC_byte; //* GA Specific Info */
|
||||
dependsOnCoreCoder : NeAAC_byte;
|
||||
coreCoderDelay : NeAAC_word;
|
||||
extensionFlag : NeAAC_byte;
|
||||
aacSectionDataResilienceFlag : NeAAC_byte;
|
||||
aacScalefactorDataResilienceFlag : NeAAC_byte;
|
||||
aacSpectralDataResilienceFlag : NeAAC_byte;
|
||||
epConfig : NeAAC_byte;
|
||||
sbr_present_flag : NeAAC_byte;
|
||||
forceUpSampling : NeAAC_byte;
|
||||
downSampledSBR : NeAAC_byte;
|
||||
end;
|
||||
Tmp4AudioSpecificConfig = mp4AudioSpecificConfig;
|
||||
Pmp4AudioSpecificConfig = ^mp4AudioSpecificConfig;
|
||||
|
||||
var
|
||||
NeAACDecGetErrorMessage : function(ErrorCode : Byte) : PChar; cdecl;
|
||||
NeAACDecGetCapabilities : function : LongWord; cdecl;
|
||||
NeAACDecOpen : function : PNeAACDec; cdecl;
|
||||
NeAACDecGetCurrentConfiguration : function( hDecoder : PNeAACDec) : PNeAACDecConfiguration; cdecl;
|
||||
NeAACDecSetConfiguration : function( hDecoder : PNeAACDec; pConfig : PNeAACDecConfiguration) : Byte; cdecl;
|
||||
NeAACDecInit : function( hDecoder : PNeAACDec; pBuffer : pcfloat; lwBufferLength : LongWord; var lwSampleRate : LongWord; var Channels : Byte) : LongInt; cdecl;
|
||||
NeAACDecInit2 : function( hDecoder : PNeAACDec; pBuffer : pcfloat; SizeOfDecoderSpecificInfo : LongWord; var lwSampleRate : LongWord; var Channels : Byte) : Byte; cdecl;
|
||||
NeAACDecPostSeekReset : procedure(hDecoder : PNeAACDec; Frame : LongInt); cdecl;
|
||||
NeAACDecClose : procedure(hDecoder : PNeAACDec); cdecl;
|
||||
NeAACDecDecode : function( hDecoder : PNeAACDec; hInfo : PNeAACDecFrameInfo; pBuffer : pcfloat; lwBufferLength : LongWord) : Pointer; cdecl;
|
||||
NeAACDecDecode2 : function( hDecoder : PNeAACDec; hInfo : PNeAACDecFrameInfo; pBuffer : pcfloat; lwBufferLength : LongWord; var pSampleBuf : Pointer; lwSampleBufSize : LongWord) : Pointer; cdecl;
|
||||
NeAACDecAudioSpecificConfig : function( pBuffer : pcfloat; lwBufferLength : LongWord; var mp4ASC : mp4AudioSpecificConfig) : Byte; cdecl;
|
||||
|
||||
procedure LoadNeAAC(NeAAC : AnsiString);
|
||||
Procedure UnLoadNeAAC;
|
||||
Function Is_NeAAC_Loaded : Boolean;
|
||||
|
||||
//////////////////
|
||||
|
||||
// from mcwAAC.pas from Franklyn A. Harlow
|
||||
Const
|
||||
kNeAAC_OK = 1;
|
||||
kNeAAC_FAIL = 0;
|
||||
|
||||
Type
|
||||
|
||||
TAACIdata = array[0..2024*1024-1] of byte;
|
||||
|
||||
TAACInfo = class(TObject)
|
||||
public
|
||||
// libfaad control interface...
|
||||
fsStream : TFileStream;
|
||||
pDecoder : PNeAACDec;
|
||||
hMP4 : mp4ff_t;
|
||||
|
||||
// output interface setup...
|
||||
Channels : longword; // stereo = 2
|
||||
BitsPerSample : longword; // ie short/smallint = 16
|
||||
SampleRate : longword; // Frequency = 44100
|
||||
outputFormat : byte; // See FAAD_FMT_16BIT etc...
|
||||
|
||||
Bitrate : longword; // 256000 = 256
|
||||
|
||||
TotalTime : double; // Length in Seconds
|
||||
|
||||
{$if not defined(fs32bit)}
|
||||
TotalSamples : cint64;
|
||||
Size : cint64; // in frames
|
||||
Position : cint64; // in frames
|
||||
{$else}
|
||||
TotalSamples : cint;
|
||||
Size : cint; // in frames
|
||||
Position : cint; // in frames
|
||||
{$endif}
|
||||
|
||||
// UoS interface
|
||||
pData : pcfloat;
|
||||
lwDataLen : longword;
|
||||
|
||||
// tag info...
|
||||
Artist : AnsiString;
|
||||
AlbumArtist : AnsiString;
|
||||
Album : AnsiString;
|
||||
Title : AnsiString;
|
||||
Date : AnsiString;
|
||||
Genre : AnsiString;
|
||||
Track : AnsiString;
|
||||
Comment : AnsiString;
|
||||
|
||||
// internal data...
|
||||
cbs : mp4ff_callback_t;
|
||||
_Buf : TAACIdata;
|
||||
BufTmp : TAACIdata;
|
||||
fTrack : longint;
|
||||
fTimescale : longword; // Not actually used
|
||||
|
||||
fBufStart : longword;
|
||||
fBufEnd : longword;
|
||||
End;
|
||||
|
||||
Function aa_load(mp4ff, NeAAC: AnsiString): Boolean;
|
||||
Procedure aa_Unload;
|
||||
Function isLibAACLoaded : Boolean;
|
||||
|
||||
Function MP4OpenFile(fName : String; OutputFormat : Byte) : TAACInfo;
|
||||
Procedure MP4CloseFile(var AACI: TAACInfo);
|
||||
procedure MP4GetData(var AACI: TAACInfo; var Buffer: pcfloat; var Bytes: longword);
|
||||
function MP4Seek(var AACI: TAACInfo; var SampleNum: longint) : Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
// hNeAAC: {$IFDEF MSWINDOWS}longword{$ELSE}{$IFDEF CPU32}longword{$ELSE}PtrInt{$ENDIF}{$ENDIF};
|
||||
hNeAAC:TLibHandle=dynlibs.NilHandle;
|
||||
NeAACLoaded : Boolean;
|
||||
Mp4ffLoaded : Boolean = False;
|
||||
hMp4ff:TLibHandle=dynlibs.NilHandle;
|
||||
|
||||
//////////// from mcwNeAACDec.pas By Franklyn A. Harlow
|
||||
|
||||
function CBMP4Read(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
||||
begin
|
||||
try
|
||||
Result := LongWord(TAACInfo(user_data).fsStream.Read(buffer^, Integer(length)));
|
||||
except
|
||||
Result := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CBMP4Write(user_data : Pointer; buffer : pcfloat; length : LongWord) : LongWord; cdecl;
|
||||
begin
|
||||
try
|
||||
Result := LongWord(TAACInfo(user_data).fsStream.Write(buffer^, Integer(length)));
|
||||
TAACInfo(user_data).fsStream.Position:=0;
|
||||
except
|
||||
Result := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CBMP4Seek(user_data : Pointer; Position : Int64) : LongWord; cdecl;
|
||||
begin
|
||||
try
|
||||
Result := LongWord(TAACInfo(user_data).fsStream.Seek(Position, soBeginning));
|
||||
except
|
||||
Result := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CBMP4Truncate(user_data : Pointer) : LongWord; cdecl;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
//////////// from mcwAAC.pas By Franklyn A. Harlow
|
||||
|
||||
Function aa_load(mp4ff, NeAAC: AnsiString): Boolean;
|
||||
Begin
|
||||
// Safe To Call Multiple times, actual load of Lib checks to see if it is already loaded &
|
||||
// returns true if it is...
|
||||
LoadNeAAC(NeAAC);
|
||||
|
||||
Loadmp4ff(mp4ff);
|
||||
|
||||
Result:= Is_NeAAC_Loaded And isMp4ffLoaded;
|
||||
End;
|
||||
|
||||
Procedure aa_Unload;
|
||||
Begin
|
||||
UnLoadNeAAC();
|
||||
UnLoadMp4ff();
|
||||
End;
|
||||
|
||||
Function isLibAACLoaded : Boolean;
|
||||
Begin
|
||||
Result:= Is_NeAAC_Loaded And isMp4ffLoaded;
|
||||
end;
|
||||
|
||||
Function isFileAAC(fName : AnsiString): Boolean;
|
||||
Begin
|
||||
Result:= LowerCase(ExtractFileExt(fName)) = '.m4a';
|
||||
end;
|
||||
|
||||
Function MP4OpenFile(fName : String; OutputFormat : Byte) : TAACInfo;
|
||||
Var
|
||||
pConfig : PNeAACDecConfiguration;
|
||||
mp4ASC : mp4AudioSpecificConfig;
|
||||
|
||||
pBuf : pcfloat;
|
||||
lwBufSize : longword;
|
||||
lwBufSize2 : longword;
|
||||
lwSampleRate : longword;
|
||||
bChannels : byte;
|
||||
|
||||
bRet : Byte;
|
||||
iRet : LongInt;
|
||||
pID3 : PAnsiChar;
|
||||
f : Double;
|
||||
Begin
|
||||
Result:= nil;
|
||||
if not FileExists(fName) then
|
||||
Exit;
|
||||
if Not isFileAAC(fName) then
|
||||
Exit;
|
||||
// writeln('MP4OpenFileBegin');
|
||||
|
||||
Result:= TAACInfo.Create;
|
||||
// writeln('MP4OpenFile3');
|
||||
|
||||
Result.fsStream:= TFileStream.Create(fName, fmOpenRead or fmShareDenyWrite);
|
||||
|
||||
sleep(1);
|
||||
|
||||
// writeln('MP4OpenFile4');
|
||||
Result.cbs.read := @CBMP4Read;
|
||||
Result.cbs.write := @CBMP4Write;
|
||||
Result.cbs.seek := @CBMP4Seek;
|
||||
Result.cbs.truncate := @CBMP4Truncate;
|
||||
Result.cbs.user_data := Pointer(Result);
|
||||
// writeln('MP4OpenFile5');
|
||||
|
||||
Result.pDecoder := NeAACDecOpen();
|
||||
// writeln('MP4OpenFile6');
|
||||
|
||||
pConfig := NeAACDecGetCurrentConfiguration(Result.pDecoder);
|
||||
// writeln('MP4OpenFile7');
|
||||
pConfig^.defObjectType := LC;
|
||||
pConfig^.defSampleRate := 44100;
|
||||
pConfig^.outputFormat := OutputFormat; // FAAD_FMT_FLOAT FAAD_FMT_16BIT FAAD_FMT_32BIT
|
||||
pConfig^.downMatrix := 1;
|
||||
pConfig^.dontUpSampleImplicitSBR := 0;
|
||||
|
||||
NeAACDecSetConfiguration(Result.pDecoder, pConfig) ;
|
||||
|
||||
pConfig := NeAACDecGetCurrentConfiguration(Result.pDecoder);
|
||||
// writeln('MP4OpenFile9');
|
||||
|
||||
case pConfig^.outputFormat of
|
||||
FAAD_FMT_16BIT : Result.BitsPerSample := 16;
|
||||
FAAD_FMT_24BIT : Result.BitsPerSample := 24;
|
||||
FAAD_FMT_32BIT : Result.BitsPerSample := 32;
|
||||
FAAD_FMT_FLOAT : Result.BitsPerSample := 32;
|
||||
FAAD_FMT_DOUBLE: Result.BitsPerSample := 64;
|
||||
end;
|
||||
// writeln('MP4OpenFile10');
|
||||
Result.outputFormat:= pConfig^.outputFormat;
|
||||
|
||||
Result.hMP4 := mp4ff_open_read(@Result.cbs);
|
||||
// writeln('MP4OpenFile11');
|
||||
|
||||
Result.fTrack := GetAACTrack(Result.hMP4);
|
||||
// writeln('MP4OpenFile12');
|
||||
|
||||
pBuf:= nil;
|
||||
iRet:= mp4ff_get_decoder_config(Result.hMP4, Result.fTrack, pBuf, lwBufSize);
|
||||
// writeln('MP4OpenFile13');
|
||||
|
||||
lwBufSize2:= lwBufSize;
|
||||
// writeln('MP4OpenFile14');
|
||||
|
||||
bRet:= NeAACDecInit2(Result.pDecoder, pBuf, lwBufSize, lwSampleRate, bChannels);
|
||||
// writeln('MP4OpenFile15');
|
||||
|
||||
Result.SampleRate := mp4ff_get_sample_rate(Result.hMP4, Result.fTrack);
|
||||
Result.Channels := mp4ff_get_channel_count(Result.hMP4, Result.fTrack);
|
||||
Result.fTimescale := mp4ff_time_scale(Result.hMP4, Result.fTrack);
|
||||
Result.Bitrate := mp4ff_get_avg_bitrate(Result.hMP4, Result.fTrack);
|
||||
Result.Size := mp4ff_num_samples(Result.hMP4, Result.fTrack);
|
||||
// writeln('MP4OpenFile16');
|
||||
|
||||
if pBuf <> nil then
|
||||
begin
|
||||
bRet:= NeAACDecAudioSpecificConfig(pBuf, lwBufSize2, mp4ASC);
|
||||
// writeln('MP4OpenFile17');
|
||||
|
||||
if bRet <> 0 then
|
||||
Begin
|
||||
// unix x64, NeAACDecAudioSpecificConfig Fails correct read,
|
||||
// But if both previous SampleRates match, we'll use them...
|
||||
{$IFDEF unix}{$IFDEF CPU64}
|
||||
if Result.SampleRate = lwSampleRate then
|
||||
Begin
|
||||
mp4ASC.sbr_present_flag := 0;
|
||||
mp4ASC.samplingFrequency := lwSampleRate;
|
||||
End;
|
||||
{$ENDIF}{$ENDIF}
|
||||
End;
|
||||
// writeln('MP4OpenFile18');
|
||||
mp4ff_free_decoder_config(pBuf);
|
||||
// writeln('MP4OpenFile19');
|
||||
end;
|
||||
|
||||
f := 1024.0;
|
||||
if mp4ASC.sbr_present_flag = 1 then
|
||||
f := f * 2.0;
|
||||
Result.TotalTime := Result.Size * (f-1.0) / mp4ASC.samplingFrequency;
|
||||
{ ...End}
|
||||
Result.TotalSamples := Trunc(Result.TotalTime * mp4ASC.samplingFrequency);
|
||||
// writeln('MP4OpenFile20');
|
||||
if mp4ASC.samplingFrequency > Result.SampleRate then
|
||||
Result.SampleRate:= mp4ASC.samplingFrequency;
|
||||
|
||||
Result.Artist:= '';
|
||||
iRet:= mp4ff_meta_get_writer(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Artist:= pID3;
|
||||
|
||||
Result.AlbumArtist:= '';
|
||||
iRet:= mp4ff_meta_get_artist(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.AlbumArtist:= pID3;
|
||||
|
||||
Result.Album:= '';
|
||||
iRet:= mp4ff_meta_get_album(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Album:= pID3;
|
||||
|
||||
Result.Title:= '';
|
||||
iRet:= mp4ff_meta_get_title(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Title:= pID3;
|
||||
|
||||
Result.Date:= '';
|
||||
iRet:= mp4ff_meta_get_date(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Date:= pID3;
|
||||
|
||||
Result.Genre:= '';
|
||||
iRet:= mp4ff_meta_get_genre(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Genre:= pID3;
|
||||
|
||||
Result.Track:= '';
|
||||
iRet:= mp4ff_meta_get_track(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Track:= pID3;
|
||||
|
||||
Result.Comment:= '';
|
||||
iRet:= mp4ff_meta_get_comment(Result.hMP4, pID3);
|
||||
if iRet = 1 then
|
||||
Result.Comment:= pID3;
|
||||
|
||||
Result.Position := 0;
|
||||
Result.fBufStart := 0;
|
||||
Result.fBufEnd := 0;
|
||||
// writeln('MP4OpenFile End');
|
||||
end;
|
||||
|
||||
Procedure MP4CloseFile(var AACI: TAACInfo);
|
||||
Begin
|
||||
// writeln('MP4CloseFile1');
|
||||
NeAACDecClose(AACI.pDecoder);
|
||||
sleep(50);
|
||||
// writeln('MP4CloseFile2');
|
||||
mp4ff_close(AACI.hMP4);
|
||||
// writeln('MP4CloseFile3');
|
||||
sleep(50);
|
||||
end;
|
||||
|
||||
procedure MP4GetData(var AACI: TAACInfo; var Buffer: pcfloat; var Bytes: longword);
|
||||
var
|
||||
ReqBytes : longword;
|
||||
CurBufSize : longword;
|
||||
NewSampleBuf : Pointer;
|
||||
NewBytesRead : longword;
|
||||
NewBytesDecoded : longword;
|
||||
|
||||
Function readNextSample(var audioBuf : pcfloat; var audioSize : longword): longword;
|
||||
Begin
|
||||
audioSize := 0;
|
||||
Result:= 0;
|
||||
audioBuf := nil;
|
||||
// writeln('readNextSample');
|
||||
if AACI.Position > AACI.Size then
|
||||
Begin
|
||||
Result:= 0;
|
||||
Exit;
|
||||
end;
|
||||
Result := mp4ff_read_sample(AACI.hMP4, AACI.fTrack, AACI.Position, audioBuf, audioSize);
|
||||
Inc(AACI.Position);
|
||||
end;
|
||||
|
||||
Function getNextChunk(var SampBuf : Pointer; var NBR : longword) : longword;
|
||||
Var
|
||||
pAB : pcfloat;
|
||||
iAB : longword;
|
||||
frameInfo: NeAACDecFrameInfo;
|
||||
Begin
|
||||
NBR:= 0;
|
||||
// writeln('getNextChunk');
|
||||
Result:= 0;
|
||||
Result:= readNextSample(pAB, iAB);
|
||||
if Result = 0 then Exit;
|
||||
SampBuf := NeAACDecDecode(AACI.pDecoder, @frameInfo, pAB, iAB);
|
||||
if pAB <> nil then
|
||||
mp4ff_free_decoder_config(pAB);
|
||||
|
||||
NBR:= frameInfo.samples * (AACI.BitsPerSample div 8);
|
||||
end;
|
||||
|
||||
begin
|
||||
// writeln('MP4GetData1');
|
||||
ReqBytes:= Bytes;
|
||||
// writeln('MP4GetDataBegin1-2');
|
||||
CurBufSize:= AACI.fBufEnd - AACI.fBufStart;
|
||||
|
||||
While ReqBytes > CurBufSize do
|
||||
Begin
|
||||
// writeln('MP4GetData31');
|
||||
// We need to put more data into Buffer...
|
||||
|
||||
// If We Have Left Over Data...
|
||||
if CurBufSize > 0 then
|
||||
Begin
|
||||
// Save Existing Left over data..
|
||||
Move(AACI._Buf[AACI.fBufStart], AACI.BufTmp[0], CurBufSize);
|
||||
// Put Existing Data to Start of buffer...
|
||||
Move(AACI.BufTmp[0], AACI._Buf[0], CurBufSize);
|
||||
end;
|
||||
|
||||
// writeln('MP4GetData32');
|
||||
// because we reshuffled buffers, AACI.fBufStart is now 0
|
||||
AACI.fBufStart:= 0;
|
||||
NewSampleBuf := nil;
|
||||
// Read next block of data
|
||||
|
||||
NewBytesRead:= getNextChunk(NewSampleBuf, NewBytesDecoded);
|
||||
|
||||
// writeln('MP4GetData322');
|
||||
if NewBytesRead = 0 then
|
||||
begin
|
||||
Buffer := nil;
|
||||
Bytes := 0;
|
||||
Exit;
|
||||
end;
|
||||
// writeln('MP4GetData33');
|
||||
// Append new data to buffer
|
||||
Move(NewSampleBuf^, AACI._Buf[CurBufSize], NewBytesDecoded);
|
||||
// Update current unprocessed data count
|
||||
CurBufSize:= CurBufSize + NewBytesDecoded;
|
||||
// writeln('MP4GetData34');
|
||||
end;
|
||||
|
||||
// writeln('MP4GetData4');
|
||||
|
||||
// set AACI.fBufEnd to last valid data byte in buffer
|
||||
AACI.fBufEnd:= CurBufSize;
|
||||
|
||||
// writeln('MP4GetData5');
|
||||
|
||||
// If requested Byte count is more tha what we have, reduce requested count..
|
||||
if Bytes > AACI.fBufEnd - AACI.fBufStart then
|
||||
Bytes := AACI.fBufEnd - AACI.fBufStart;
|
||||
|
||||
// writeln('MP4GetData6');
|
||||
|
||||
// pass data back to calling function/procedure
|
||||
Buffer := @AACI._Buf[AACI.fBufStart];
|
||||
|
||||
// writeln('MP4GetData7');
|
||||
|
||||
Inc(AACI.fBufStart, Bytes);
|
||||
|
||||
// writeln('MP4GetData8');
|
||||
|
||||
end;
|
||||
|
||||
function MP4Seek(var AACI: TAACInfo; var SampleNum: longint) : Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if (AACI.Size = 0) or (AACI.TotalSamples = 0) then
|
||||
Exit;
|
||||
|
||||
if SampleNum > AACI.TotalSamples then
|
||||
SampleNum := AACI.TotalSamples;
|
||||
|
||||
AACI.Position:= Trunc(SampleNum / AACI.TotalSamples * AACI.Size);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure LoadNeAAC(NeAAC : AnsiString);
|
||||
var
|
||||
thelib: string;
|
||||
Begin
|
||||
if Length(NeAAC) = 0 then thelib := libaa else thelib := NeAAC;
|
||||
hNeAAC:= DynLibs.SafeLoadLibrary(PChar(thelib));
|
||||
NeAACLoaded:= hNeAAC <> dynlibs.NilHandle;
|
||||
|
||||
Pointer(NeAACDecGetErrorMessage) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecGetErrorMessage'));
|
||||
Pointer(NeAACDecGetCapabilities) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecGetCapabilities'));
|
||||
Pointer(NeAACDecOpen) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecOpen'));
|
||||
Pointer(NeAACDecGetCurrentConfiguration) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecGetCurrentConfiguration'));
|
||||
Pointer(NeAACDecSetConfiguration) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecSetConfiguration'));
|
||||
Pointer(NeAACDecInit) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecInit'));
|
||||
Pointer(NeAACDecInit2) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecInit2'));
|
||||
Pointer(NeAACDecPostSeekReset) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecPostSeekReset'));
|
||||
Pointer(NeAACDecClose) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecClose'));
|
||||
Pointer(NeAACDecDecode) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecDecode'));
|
||||
Pointer(NeAACDecDecode2) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecDecode2'));
|
||||
Pointer(NeAACDecPostSeekReset) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecPostSeekReset'));
|
||||
Pointer(NeAACDecAudioSpecificConfig) :=
|
||||
GetProcAddress(hNeAAC, PChar('NeAACDecAudioSpecificConfig'));
|
||||
end;
|
||||
|
||||
Procedure UnLoadNeAAC;
|
||||
Begin
|
||||
if NeAACLoaded then
|
||||
DynLibs.UnloadLibrary(hNeAAC);
|
||||
NeAACLoaded:= False;
|
||||
end;
|
||||
|
||||
Function Is_NeAAC_Loaded : Boolean;
|
||||
Begin
|
||||
Result:= NeAACLoaded;
|
||||
end;
|
||||
|
||||
////////////////////////////// from mcwMP4FF.pas by Franklyn A. Harlow
|
||||
|
||||
function GetAACTrack(infile : mp4ff_t) : Integer;
|
||||
var
|
||||
i, rc, numTracks : Integer;
|
||||
buff : pcfloat;
|
||||
buff_size : LongWord;
|
||||
mp4ASC : mp4AudioSpecificConfig;
|
||||
begin
|
||||
numTracks := mp4ff_total_tracks(infile);
|
||||
for i := 0 to numTracks - 1 do
|
||||
begin
|
||||
buff := nil;
|
||||
buff_size:=0;
|
||||
mp4ff_get_decoder_config(infile, i, buff, buff_size);
|
||||
if buff <> nil then
|
||||
begin
|
||||
rc := NeAACDecAudioSpecificConfig(buff, buff_size, mp4ASC);
|
||||
mp4ff_free_decoder_config(buff);
|
||||
if rc < 0 then
|
||||
continue;
|
||||
Result := i;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
procedure UnLoadMp4ff;
|
||||
begin
|
||||
if Mp4ffLoaded then
|
||||
|
||||
DynLibs.UnloadLibrary(hMp4ff);
|
||||
|
||||
Mp4ffLoaded := False;
|
||||
end;
|
||||
|
||||
Function isMp4ffLoaded : Boolean;
|
||||
Begin
|
||||
Result:= Mp4ffLoaded;
|
||||
end;
|
||||
|
||||
|
||||
procedure Loadmp4ff(mp4ff : AnsiString);
|
||||
var
|
||||
thelib: string;
|
||||
begin
|
||||
if Mp4ffLoaded then
|
||||
Exit;
|
||||
if Length(mp4ff) = 0 then thelib := libm4 else thelib := mp4ff;
|
||||
hMp4ff := DynLibs.SafeLoadLibrary(PChar(thelib));
|
||||
Mp4ffLoaded := hMp4ff <> dynlibs.NilHandle;
|
||||
|
||||
// writeln('hMp4ff' + inttostr(hMp4ff));
|
||||
|
||||
Pointer(mp4ff_open_read) :=
|
||||
GetProcAddress(hMp4ff, pchar('mp4ff_open_read'));
|
||||
|
||||
// if Pointer(mp4ff_open_read) <> nil then
|
||||
// writeln('mp4ff_open_read OK') else
|
||||
// writeln('mp4ff_open_read NOT OK');
|
||||
|
||||
Pointer(mp4ff_open_read_metaonly) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_open_read_metaonly'));
|
||||
Pointer(mp4ff_close) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_close'));
|
||||
Pointer(mp4ff_get_sample_duration) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_duration'));
|
||||
Pointer(mp4ff_get_sample_duration_use_offsets) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_duration_use_offsets'));
|
||||
Pointer(mp4ff_get_sample_position) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_position'));
|
||||
Pointer(mp4ff_get_sample_offset) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_offset'));
|
||||
Pointer(mp4ff_find_sample) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_find_sample'));
|
||||
|
||||
Pointer(mp4ff_find_sample_use_offsets) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_find_sample_use_offsets'));
|
||||
Pointer(mp4ff_set_sample_position) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_set_sample_position'));
|
||||
Pointer(mp4ff_read_sample) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_read_sample'));
|
||||
Pointer(mp4ff_read_sample_v2) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_read_sample_v2'));
|
||||
Pointer(mp4ff_read_sample_getsize) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_read_sample_getsize'));
|
||||
Pointer(mp4ff_get_sample_position) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_position'));
|
||||
Pointer(mp4ff_get_sample_offset) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_offset'));
|
||||
Pointer(mp4ff_find_sample) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_find_sample'));
|
||||
|
||||
Pointer(mp4ff_get_decoder_config) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_decoder_config'));
|
||||
Pointer(mp4ff_get_track_type) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_track_type'));
|
||||
Pointer(mp4ff_total_tracks) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_total_tracks'));
|
||||
Pointer(mp4ff_num_samples) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_num_samples'));
|
||||
Pointer(mp4ff_time_scale) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_time_scale'));
|
||||
Pointer(mp4ff_get_avg_bitrate) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_avg_bitrate'));
|
||||
Pointer(mp4ff_get_max_bitrate) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_max_bitrate'));
|
||||
Pointer(mp4ff_get_track_duration) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_track_duration'));
|
||||
|
||||
Pointer(mp4ff_get_track_duration_use_offsets) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_track_duration_use_offsets'));
|
||||
Pointer(mp4ff_get_sample_rate) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_sample_rate'));
|
||||
Pointer(mp4ff_get_channel_count) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_channel_count'));
|
||||
Pointer(mp4ff_get_audio_type) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_get_audio_type'));
|
||||
Pointer(mp4ff_free_decoder_config) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_free_decoder_config'));
|
||||
Pointer(mp4ff_meta_get_num_items) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_num_items'));
|
||||
Pointer(mp4ff_meta_get_by_index) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_by_index'));
|
||||
Pointer(mp4ff_meta_get_title) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_title'));
|
||||
|
||||
Pointer(mp4ff_meta_get_artist) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_artist'));
|
||||
Pointer(mp4ff_meta_get_writer) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_writer'));
|
||||
Pointer(mp4ff_meta_get_album) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_album'));
|
||||
Pointer(mp4ff_meta_get_date) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_date'));
|
||||
Pointer(mp4ff_meta_get_tool) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_tool'));
|
||||
Pointer(mp4ff_meta_get_comment) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_comment'));
|
||||
Pointer(mp4ff_meta_get_genre) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_genre'));
|
||||
Pointer(mp4ff_meta_get_track) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_track'));
|
||||
|
||||
Pointer(mp4ff_meta_get_disc) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_disc'));
|
||||
Pointer(mp4ff_meta_get_totaltracks) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_totaltracks'));
|
||||
Pointer(mp4ff_meta_get_totaldiscs) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_totaldiscs'));
|
||||
Pointer(mp4ff_meta_get_compilation) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_compilation'));
|
||||
Pointer(mp4ff_meta_get_tempo) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_tempo'));
|
||||
Pointer(mp4ff_meta_get_coverart) :=
|
||||
GetProcAddress(hMp4ff, PChar('mp4ff_meta_get_coverart'));
|
||||
|
||||
end;
|
||||
|
||||
initialization
|
||||
NeAACLoaded:= False;
|
||||
SetExceptionMask(GetExceptionMask + [exZeroDivide] + [exInvalidOp] +
|
||||
[exDenormalized] + [exOverflow] + [exPrecision]);
|
||||
|
||||
finalization
|
||||
end.
|
||||
394
UOS/src/uos_bs2b.pas
Normal file
394
UOS/src/uos_bs2b.pas
Normal file
@@ -0,0 +1,394 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading Pascal Wrapper of
|
||||
bs2b library of Boris Mikhaylov
|
||||
Load library with bs_load() and release with bs_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com
|
||||
}
|
||||
|
||||
|
||||
unit uos_bs2b;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, dynlibs, ctypes, math;
|
||||
|
||||
const
|
||||
libsb=
|
||||
{$IFDEF unix}
|
||||
'libbs2b.so.0';
|
||||
{$ELSE}
|
||||
'bs2b.dll';
|
||||
{$ENDIF}
|
||||
|
||||
{ Minimum/maximum sample rate (Hz) }
|
||||
BS2B_MINSRATE = 2000;
|
||||
BS2B_MAXSRATE = 384000;
|
||||
|
||||
{ Minimum/maximum cut frequency (Hz) }
|
||||
{ bs2b_set_level_fcut() }
|
||||
BS2B_MINFCUT = 300;
|
||||
BS2B_MAXFCUT = 2000;
|
||||
|
||||
{ Minimum/maximum feed level (dB * 10 @ low frequencies) }
|
||||
{ bs2b_set_level_feed() }
|
||||
{ 1 dB }
|
||||
BS2B_MINFEED = 10;
|
||||
{ 15 dB }
|
||||
BS2B_MAXFEED = 150;
|
||||
|
||||
const
|
||||
|
||||
// for using with bs2b_set_level
|
||||
|
||||
BS2B_HIGH_CLEVEL = (CInt32(700)) or ((CInt32(30)) shl 16);
|
||||
BS2B_MIDDLE_CLEVEL = (CInt32(500)) or ((CInt32(45)) shl 16);
|
||||
BS2B_LOW_CLEVEL = (CInt32(360)) or ((CInt32(60)) shl 16);
|
||||
{ Easy crossfeed levels (Obsolete) }
|
||||
BS2B_HIGH_ECLEVEL = (CInt32(700)) or ((CInt32(60)) shl 16);
|
||||
BS2B_MIDDLE_ECLEVEL = (CInt32(500)) or ((CInt32(72)) shl 16);
|
||||
BS2B_LOW_ECLEVEL = (CInt32(360)) or ((CInt32(84)) shl 16);
|
||||
|
||||
BS2B_DEFAULT_CLEVEL = (CInt32(700)) or ((CInt32(45)) shl 16);
|
||||
BS2B_CMOY_CLEVEL =(CInt32(700)) or ((CInt32(60)) shl 16);
|
||||
BS2B_JMEIER_CLEVEL = (CInt32(650)) or ((CInt32(95)) shl 16);
|
||||
|
||||
{ Default sample rate (Hz) }
|
||||
const
|
||||
BS2B_DEFAULT_SRATE = 44100;
|
||||
|
||||
{ A delay at low frequency by microseconds according to cut frequency }
|
||||
function bs2b_level_delay(fcut : longint) : longint;
|
||||
|
||||
{ Crossfeed level }
|
||||
{ Sample rate (Hz) }
|
||||
{ Lowpass IIR filter coefficients }
|
||||
{ Highboost IIR filter coefficients }
|
||||
{ Global gain against overloading }
|
||||
{ Buffer of last filtered sample: [0] 1-st channel, [1] 2-d channel }
|
||||
type
|
||||
Tt_bs2bdp = ^Tt_bs2bd;
|
||||
Tt_bs2bd = packed record
|
||||
level : CInt32;
|
||||
srate : CInt32;
|
||||
a0_lo : CDouble;
|
||||
b1_lo : CDouble;
|
||||
a0_hi : CDouble;
|
||||
a1_hi : CDouble;
|
||||
b1_hi : CDouble;
|
||||
gain : CDouble;
|
||||
lfs : packed record
|
||||
asis : array[0..1] of cdouble;
|
||||
lo : array[0..1] of cdouble;
|
||||
hi : array[0..1] of cdouble;
|
||||
end;
|
||||
end;
|
||||
|
||||
////// Dynamic load : Vars that will hold our dynamically loaded functions...
|
||||
// *************************** functions *******************************
|
||||
|
||||
var
|
||||
{ Open }
|
||||
bs2b_open : function():Tt_bs2bdp; cdecl;
|
||||
|
||||
{ Close }
|
||||
bs2b_close : procedure(bs2bdp:Tt_bs2bdp); cdecl;
|
||||
|
||||
{ Sets a new coefficients by new crossfeed value.
|
||||
* level = ( fcut | feed << 16 ) )
|
||||
* where 'feed' is crossfeeding level at low frequencies (dB * 10)
|
||||
* and 'fcut' is cut frecuency (Hz)
|
||||
}
|
||||
bs2b_set_level : procedure(bs2bdp:Tt_bs2bdp; level: CInt32); cdecl;
|
||||
|
||||
{ Return a current crossfeed level value. }
|
||||
bs2b_get_level : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
|
||||
|
||||
{ Sets a new coefficients by new cut frecuency value (Hz). }
|
||||
bs2b_set_level_fcut : procedure(bs2bdp:Tt_bs2bdp; fcut: CInt32); cdecl;
|
||||
|
||||
{ Return a current cut frecuency value (Hz). }
|
||||
bs2b_get_level_fcut : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
|
||||
|
||||
{ Sets a new coefficients by new crossfeeding level value (dB * 10). }
|
||||
bs2b_set_level_feed : procedure(bs2bdp:Tt_bs2bdp; feed: CInt32); cdecl;
|
||||
|
||||
{ Return a current crossfeeding level value (dB * 10). }
|
||||
bs2b_get_level_feed : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
|
||||
|
||||
{ Return a current delay value at low frequencies (micro seconds). }
|
||||
bs2b_get_level_delay : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
|
||||
|
||||
{ Clear buffers and sets a new coefficients with new sample rate value.
|
||||
* srate - sample rate by Hz. }
|
||||
bs2b_set_srate : procedure(bs2bdp:Tt_bs2bdp; srate: CInt32); cdecl;
|
||||
|
||||
{ Return current sample rate value }
|
||||
bs2b_get_srate : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
|
||||
|
||||
{ Clear buffer }
|
||||
bs2b_clear : procedure(bs2bdp:Tt_bs2bdp); cdecl;
|
||||
|
||||
{ Return 1 if buffer is clear }
|
||||
bs2b_is_clear : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
|
||||
|
||||
{ Return bs2b version string }
|
||||
(* Const before declarator ignored *)
|
||||
bs2b_runtime_version : function():pchar; cdecl;
|
||||
|
||||
{ Return bs2b version integer }
|
||||
bs2b_runtime_version_int : function(): CInt32; cdecl;
|
||||
|
||||
{ 'bs2b_cross_feed_*' crossfeeds buffer of 'n' stereo samples
|
||||
* pointed by 'sample'.
|
||||
* sample[i] - first channel,
|
||||
* sample[i+1] - second channel.
|
||||
* Where 'i' is ( i = 0; i < n * 2; i += 2 )
|
||||
}
|
||||
{ sample poits to double floats native endians }
|
||||
bs2b_cross_feed_d : procedure(bs2bdp:Tt_bs2bdp; var sample:Cdouble; n: CInt32); cdecl;
|
||||
|
||||
{ sample poits to double floats big endians }
|
||||
bs2b_cross_feed_dbe : procedure(bs2bdp:Tt_bs2bdp; var sample:Cdouble; n: CInt32); cdecl;
|
||||
|
||||
{ sample poits to double floats little endians }
|
||||
bs2b_cross_feed_dle : procedure(bs2bdp:Tt_bs2bdp; var sample:Cdouble; n: CInt32); cdecl;
|
||||
|
||||
{ sample poits to floats native endians }
|
||||
bs2b_cross_feed_f : procedure(bs2bdp:Tt_bs2bdp; var sample:Cfloat; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to floats big endians }
|
||||
bs2b_cross_feed_fbe : procedure(bs2bdp:Tt_bs2bdp; var sample:Cfloat; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to floats little endians }
|
||||
bs2b_cross_feed_fle : procedure(bs2bdp:Tt_bs2bdp; var sample:cfloat; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 32bit signed integers native endians }
|
||||
bs2b_cross_feed_s32 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 32bit unsigned integers native endians }
|
||||
bs2b_cross_feed_u32 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 32bit signed integers big endians }
|
||||
bs2b_cross_feed_s32be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 32bit unsigned integers big endians }
|
||||
bs2b_cross_feed_u32be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 32bit signed integers little endians }
|
||||
bs2b_cross_feed_s32le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 32bit unsigned integers little endians }
|
||||
bs2b_cross_feed_u32le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
|
||||
|
||||
{ sample poits to 16bit signed integers native endians }
|
||||
bs2b_cross_feed_s16 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt16; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 16bit unsigned integers native endians }
|
||||
bs2b_cross_feed_u16 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 16bit signed integers big endians }
|
||||
bs2b_cross_feed_s16be : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
|
||||
|
||||
{ sample poits to 16bit unsigned integers big endians }
|
||||
bs2b_cross_feed_u16be : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
|
||||
|
||||
{ sample poits to 16bit signed integers little endians }
|
||||
bs2b_cross_feed_s16le : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
|
||||
|
||||
{ sample poits to 16bit unsigned integers little endians }
|
||||
bs2b_cross_feed_u16le : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
|
||||
|
||||
{ sample poits to 8bit signed integers }
|
||||
bs2b_cross_feed_s8 : procedure(bs2bdp:Tt_bs2bdp; var sample:cint8; n:cint); cdecl;
|
||||
|
||||
{ sample poits to 8bit unsigned integers }
|
||||
bs2b_cross_feed_u8 : procedure(bs2bdp:Tt_bs2bdp; var sample:cint8; n:cint); cdecl;
|
||||
|
||||
{ sample poits to 24bit signed integers native endians }
|
||||
bs2b_cross_feed_s24 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 24bit unsigned integers native endians }
|
||||
bs2b_cross_feed_u24 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 24bit signed integers be endians }
|
||||
bs2b_cross_feed_s24be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 24bit unsigned integers be endians }
|
||||
bs2b_cross_feed_u24be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 24bit signed integers little endians }
|
||||
bs2b_cross_feed_s24le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
{ sample poits to 24bit unsigned integers little endians }
|
||||
bs2b_cross_feed_u24le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
|
||||
|
||||
function bs_IsLoaded() : boolean; inline;
|
||||
|
||||
Function bs_Load(const libfilename:string) :boolean; // load the lib
|
||||
|
||||
Procedure bs_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
implementation
|
||||
|
||||
function bs2b_level_delay(fcut : longint) : longint;
|
||||
begin
|
||||
result:=floor((18700/fcut)*10);
|
||||
end;
|
||||
|
||||
var
|
||||
bs_Handle :TLibHandle=dynlibs.NilHandle;
|
||||
{$IFDEF windows} // try load dependency if not in /windows/system32/
|
||||
gc_Handle :TLibHandle=dynlibs.NilHandle;
|
||||
{$endif}
|
||||
ReferenceCounter : cardinal = 0; // Reference counter
|
||||
|
||||
function bs_IsLoaded(): boolean;
|
||||
begin
|
||||
Result := (bs_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Procedure bs_Unload();
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if bs_IsLoaded() then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(bs_Handle);
|
||||
bs_Handle:=DynLibs.NilHandle;
|
||||
{$IFDEF windows}
|
||||
if gc_Handle <> DynLibs.NilHandle then begin
|
||||
DynLibs.UnloadLibrary(gc_Handle);
|
||||
gc_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
{$endif}
|
||||
bs2b_open:=nil;
|
||||
bs2b_close:=nil;
|
||||
bs2b_set_level:=nil;
|
||||
bs2b_get_level:=nil;
|
||||
bs2b_set_level_fcut:=nil;
|
||||
bs2b_get_level_fcut:=nil;
|
||||
bs2b_set_level_feed:=nil;
|
||||
bs2b_get_level_feed:=nil;
|
||||
bs2b_get_level_delay:=nil;
|
||||
bs2b_set_srate:=nil;
|
||||
bs2b_get_srate:=nil;
|
||||
bs2b_clear:=nil;
|
||||
bs2b_is_clear:=nil;
|
||||
bs2b_runtime_version:=nil;
|
||||
bs2b_runtime_version_int:=nil;
|
||||
bs2b_cross_feed_d:=nil;
|
||||
bs2b_cross_feed_dbe:=nil;
|
||||
bs2b_cross_feed_dle:=nil;
|
||||
bs2b_cross_feed_f:=nil;
|
||||
bs2b_cross_feed_fbe:=nil;
|
||||
bs2b_cross_feed_fle:=nil;
|
||||
bs2b_cross_feed_s32:=nil;
|
||||
bs2b_cross_feed_u32:=nil;
|
||||
bs2b_cross_feed_s32be:=nil;
|
||||
bs2b_cross_feed_u32be:=nil;
|
||||
bs2b_cross_feed_s32le:=nil;
|
||||
bs2b_cross_feed_u32le:=nil;
|
||||
bs2b_cross_feed_s16:=nil;
|
||||
bs2b_cross_feed_u16:=nil;
|
||||
bs2b_cross_feed_s16be:=nil;
|
||||
bs2b_cross_feed_u16be:=nil;
|
||||
bs2b_cross_feed_s16le:=nil;
|
||||
bs2b_cross_feed_u16le:=nil;
|
||||
bs2b_cross_feed_s8:=nil;
|
||||
bs2b_cross_feed_u8:=nil;
|
||||
bs2b_cross_feed_s24:=nil;
|
||||
bs2b_cross_feed_u24:=nil;
|
||||
bs2b_cross_feed_s24be:=nil;
|
||||
bs2b_cross_feed_u24be:=nil;
|
||||
bs2b_cross_feed_s24le:=nil;
|
||||
bs2b_cross_feed_u24le:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function bs_Load(const libfilename:string) :boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if bs_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else begin {go & load the library}
|
||||
if Length(libfilename) = 0 then
|
||||
begin
|
||||
{$IFDEF windows}
|
||||
gc_Handle:= DynLibs.SafeLoadLibrary('libgcc_s_dw2-1.dll');
|
||||
{$endif}
|
||||
bs_Handle:=DynLibs.SafeLoadLibrary(libsb);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{$IFDEF windows}
|
||||
gc_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libgcc_s_dw2-1.dll');
|
||||
{$endif}
|
||||
|
||||
bs_Handle:=DynLibs.SafeLoadLibrary(libfilename);
|
||||
end;
|
||||
|
||||
if bs_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
|
||||
pointer(bs2b_open):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_open'));
|
||||
pointer(bs2b_close):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_close'));
|
||||
pointer(bs2b_set_level):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_level'));
|
||||
pointer(bs2b_get_level):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level'));
|
||||
pointer(bs2b_set_level_fcut):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_level_fcut'));
|
||||
pointer(bs2b_get_level_fcut):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level_fcut'));
|
||||
pointer(bs2b_set_level_feed):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_level_feed'));
|
||||
pointer(bs2b_get_level_feed):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level_feed'));
|
||||
pointer(bs2b_get_level_delay):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level_delay'));
|
||||
pointer(bs2b_set_srate):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_srate'));
|
||||
pointer(bs2b_get_srate):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_srate'));
|
||||
pointer(bs2b_clear):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_clear'));
|
||||
pointer(bs2b_is_clear):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_is_clear'));
|
||||
pointer(bs2b_runtime_version):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_runtime_version'));
|
||||
pointer(bs2b_runtime_version_int):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_runtime_version_int'));
|
||||
pointer(bs2b_cross_feed_d):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_d'));
|
||||
pointer(bs2b_cross_feed_dbe):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_dbe'));
|
||||
pointer(bs2b_cross_feed_dle):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_dle'));
|
||||
pointer(bs2b_cross_feed_f):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_f'));
|
||||
pointer(bs2b_cross_feed_fbe):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_fbe'));
|
||||
pointer(bs2b_cross_feed_fle):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_fle'));
|
||||
pointer(bs2b_cross_feed_s32):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s32'));
|
||||
pointer(bs2b_cross_feed_u32):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u32'));
|
||||
pointer(bs2b_cross_feed_s32be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s32be'));
|
||||
pointer(bs2b_cross_feed_u32be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u32be'));
|
||||
pointer(bs2b_cross_feed_s32le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s32le'));
|
||||
pointer(bs2b_cross_feed_u32le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u32le'));
|
||||
pointer(bs2b_cross_feed_s16):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s16'));
|
||||
pointer(bs2b_cross_feed_u16):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u16'));
|
||||
pointer(bs2b_cross_feed_s16be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s16be'));
|
||||
pointer(bs2b_cross_feed_u16be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u16be'));
|
||||
pointer(bs2b_cross_feed_s16le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s16le'));
|
||||
pointer(bs2b_cross_feed_u16le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u16le'));
|
||||
pointer(bs2b_cross_feed_s8):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s8'));
|
||||
pointer(bs2b_cross_feed_u8):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u8'));
|
||||
pointer(bs2b_cross_feed_s24):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s24'));
|
||||
pointer(bs2b_cross_feed_u24):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u24'));
|
||||
pointer(bs2b_cross_feed_s24be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s24be'));
|
||||
pointer(bs2b_cross_feed_u24be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u24be'));
|
||||
pointer(bs2b_cross_feed_s24le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s24le'));
|
||||
pointer(bs2b_cross_feed_u24le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u24le'));
|
||||
end;
|
||||
Result := bs_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
797
UOS/src/uos_cdrom.pas
Normal file
797
UOS/src/uos_cdrom.pas
Normal file
@@ -0,0 +1,797 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
{
|
||||
From CDRom, CDromLinux, CDRomWindows
|
||||
By Franklyn A. Harlow Feb 2016
|
||||
License : modified LGPL.
|
||||
Merged by Fred van Stappen fiens/hotmail.com }
|
||||
|
||||
unit uos_cdrom;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$IFDEF FPC}cdrom,{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
Windows,
|
||||
{$ENDIF}
|
||||
{$IFDEF unix}
|
||||
baseunix,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, math;
|
||||
|
||||
Const
|
||||
CDROM_OK = 0;
|
||||
CDROM_UNKNOWNERR = -1;
|
||||
|
||||
CD_FRAMESIZE_RAW = 2352;
|
||||
BUF_SIZE = 75 * CD_FRAMESIZE_RAW; // 75 frames - 1 sec
|
||||
|
||||
kCDDA_Base = 'cdda://sr';
|
||||
kCDDA_Track = 'Track%20';
|
||||
kCDDA_TrackWin = 'Track';
|
||||
|
||||
Type
|
||||
TCDDATrackType = (cdtAudio, cdtData, cdtMixed);
|
||||
Tmsf = record
|
||||
min : Byte;
|
||||
sec : Byte;
|
||||
Frame : Byte;
|
||||
end;
|
||||
TCDDAPosition = record
|
||||
Track : LongInt;
|
||||
msf : Tmsf;
|
||||
end;
|
||||
TCDDATrackInfo = record
|
||||
TrackLength : Tmsf;
|
||||
TrackType : TCDDATrackType;
|
||||
end;
|
||||
TCDStatus = (cdsNotReady, cdsReady, cdsPlaying, cdsPaused);
|
||||
TCDDATOCEntry = record
|
||||
dwStartSector : LongInt; // Start sector of the track
|
||||
btFlag : Byte; // Track flags (i.e. data or audio track)
|
||||
btTrackNumber : Byte; // Track number
|
||||
end;
|
||||
|
||||
PCDROMInfo = ^TCDROMInfo;
|
||||
TCDROMInfo = Record
|
||||
|
||||
Channels : longword; // stereo = 2
|
||||
BitsPerSample : longword; // ie short/smallint = 16
|
||||
SampleRate : longword; // Frequency = 44100
|
||||
TotalSamples : Int64;
|
||||
TotalTime : LongWord; // Seconds
|
||||
pData : pByte;
|
||||
pDataLen : longword;
|
||||
Size : Int64;
|
||||
Position : Int64;
|
||||
StartPos : TCDDAPosition;
|
||||
EndPos : TCDDAPosition;
|
||||
BufStart : LongWord;
|
||||
BufEnd : LongWord;
|
||||
BufSize : LongInt;
|
||||
Buf : array[1..BUF_SIZE*2] of Byte;
|
||||
BufTmp : array[1..BUF_SIZE*2] of Byte;
|
||||
fHandleVaild : longint; // 0< : Impossible, 0: Not Valid, >0 : Valid/Available
|
||||
CurrentPosition : Tmsf; // Current Position Of Track Being Read
|
||||
{$IFDEF LIBCDRIP}
|
||||
Opened : LongInt;
|
||||
Busy : Boolean;
|
||||
CurrentDrive : LongInt;
|
||||
EnableJitterCorrection : Boolean;
|
||||
LastJitterErrors : LongInt;
|
||||
ReadSectors : LongInt;
|
||||
OverlapSectors : LongInt;
|
||||
CompareSectors : LongInt;
|
||||
MultiReadCount : LongInt;
|
||||
Paranoid : Boolean;
|
||||
ParanoiaMode : LongInt;
|
||||
LockTray : Boolean;
|
||||
Status : TCDStatus;
|
||||
RipSize : LongInt;
|
||||
{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
hCDROM : longword; // CDROM CreateFile Handle
|
||||
{$ENDIF}
|
||||
{$IFDEF unix}
|
||||
hCDROM : longint; // CDROM fpOpen Handle
|
||||
{$ENDIF}
|
||||
End;
|
||||
|
||||
Const
|
||||
EndOfDisc : TCDDAPosition = (Track : 100; msf : (min : 0; sec : 0; frame : 0));
|
||||
|
||||
Function Frames2MSF(Frames : LongInt) : Tmsf;
|
||||
Function MSF2Frames(const msf : Tmsf) : LongInt;
|
||||
Function AddressToSectors (msf : Tmsf): int64;
|
||||
|
||||
Function LoadCDROM(Lib : AnsiString): LongWord;
|
||||
Function UnloadCDROM: LongWord;
|
||||
Function isCDROMLoaded : Boolean;
|
||||
|
||||
Function CDROM_GetFileNameDrive(FileName : AnsiString): Byte;
|
||||
Function CDROM_GetFileNameTrack(FileName : AnsiString): Byte;
|
||||
|
||||
Function CDROM_OpenFile(FileName : AnsiString): PCDROMInfo;
|
||||
Function CDROM_Open(Drive, Track : Byte): PCDROMInfo;
|
||||
Function CDROM_Close(var pCDROMI: PCDROMInfo): LongWord;
|
||||
Function CDROM_GetData(var pCDROMI: PCDROMInfo; var pData: Pointer; var DataLength: longword): LongWord;
|
||||
|
||||
Function GetSystemCDRoms: AnsiString;
|
||||
|
||||
implementation
|
||||
|
||||
Function LoadCDROM(Lib : AnsiString): LongWord;
|
||||
Begin
|
||||
Result:= 32767;
|
||||
end;
|
||||
|
||||
Function UnloadCDROM: LongWord;
|
||||
Begin
|
||||
Result:= 32767;
|
||||
end;
|
||||
|
||||
Function isCDROMLoaded : Boolean;
|
||||
Begin
|
||||
Result:= True;
|
||||
end;
|
||||
|
||||
{$IFDEF unix}
|
||||
Const
|
||||
CDROM_LBA = $01; // 'logical block': first frame is #0
|
||||
CDROM_MSF = $02; // 'minute-second-frame': binary, not bcd here!
|
||||
CDROM_DATA_TRACK = $40;
|
||||
CDROM_LEADOUT = $AA;
|
||||
|
||||
CDROMREADTOCHDR = $5305; // Read TOC header
|
||||
CDROMREADTOCENTRY = $5306; // Read TOC entry
|
||||
CDROMREADAUDIO = $530E; // (struct cdrom_read_audio)
|
||||
CDROM_DRIVE_STATUS = $5326; // Get tray position, etc.
|
||||
CDROM_DISC_STATUS = $5327; // Get disc type, etc.
|
||||
|
||||
CDS_NO_DISC = 1;
|
||||
CDS_TRAY_OPEN = 2;
|
||||
CDS_DRIVE_NOT_READY = 3;
|
||||
CDS_DISC_OK = 4;
|
||||
|
||||
CDS_AUDIO = 100;
|
||||
CDS_MIXED = 105;
|
||||
|
||||
type
|
||||
cdrom_addr = record
|
||||
case Word of
|
||||
1: (msf: Tmsf;);
|
||||
2: (lba: longint;);
|
||||
end;
|
||||
cdrom_read_audio = record
|
||||
addr : cdrom_addr; // frame address
|
||||
addr_format : Byte; // CDROM_LBA or CDROM_MSF
|
||||
nframes : LongInt; // number of 2352-byte-frames to read at once
|
||||
buf : PByte; // frame buffer (size: nframes*2352 bytes)
|
||||
end;
|
||||
cdrom_tocentry = record
|
||||
cdte_track : Byte;
|
||||
cdte_adr_ctrl : Byte;
|
||||
cdte_format : Byte;
|
||||
cdte_addr : cdrom_addr;
|
||||
cdte_datamode : Byte;
|
||||
end;
|
||||
cdrom_tochdr = record
|
||||
cdth_trk0: Byte; // start track
|
||||
cdth_trk1: Byte; // end track
|
||||
end;
|
||||
|
||||
// ********************** Private Linux SUPPORT Functions **************************************************************
|
||||
function GetTrackInfo(hCDROM: LongInt; Track : LongInt): TCDDATrackInfo;
|
||||
var
|
||||
Entry : cdrom_tocentry;
|
||||
TOC : cdrom_tochdr;
|
||||
F1 : LongInt;
|
||||
F2 : LongInt;
|
||||
Ret : LongInt;
|
||||
begin
|
||||
Ret:= fpioctl(hCDROM, CDROMREADTOCHDR, @TOC);
|
||||
if Ret <> 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.GetTrackInfo.fpioctl(CDROMREADTOCHDR) Error : ' + IntToStr(Ret));
|
||||
|
||||
Entry.cdte_format := CDROM_MSF;
|
||||
Entry.cdte_track := Track + TOC.cdth_trk0 - 1;
|
||||
|
||||
Ret:= fpioctl(hCDROM, CDROMREADTOCENTRY, @Entry);
|
||||
if Ret <> 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.GetTrackInfo.fpioctl(CDROMREADTOCENTRY) Error : ' + IntToStr(Ret));
|
||||
|
||||
F1 := MSF2Frames(Entry.cdte_addr.msf);
|
||||
|
||||
if (Entry.cdte_adr_ctrl and CDROM_DATA_TRACK) <> 0 then
|
||||
Result.TrackType := cdtData
|
||||
else
|
||||
Result.TrackType := cdtAudio;
|
||||
|
||||
if Entry.cdte_track < toc.cdth_trk1 then
|
||||
Inc(Entry.cdte_track)
|
||||
else
|
||||
Entry.cdte_track := CDROM_LEADOUT;
|
||||
|
||||
Ret:= fpioctl(hCDROM, CDROMREADTOCENTRY, @Entry);
|
||||
if Ret <> 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.GetTrackInfo.fpioctl(CDROMREADTOCENTRY) #2 Error : ' + IntToStr(Ret));
|
||||
|
||||
F2 := MSF2Frames(Entry.cdte_addr.msf);
|
||||
Result.TrackLength:= Frames2MSF(F2 - F1);
|
||||
end;
|
||||
|
||||
function GetTrackMSF(hCDROM, Track : LongInt): Tmsf;
|
||||
var
|
||||
entry : cdrom_tocentry;
|
||||
hdr : cdrom_tochdr;
|
||||
Ret : LongInt;
|
||||
begin
|
||||
Ret:= fpioctl(hCDROM, CDROMREADTOCHDR, @hdr);
|
||||
if Ret <> 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.GetTrackMSF.fpioctl(CDROMREADTOCHDR) Error : ' + IntToStr(Ret));
|
||||
|
||||
entry.cdte_format := CDROM_MSF;
|
||||
entry.cdte_track := Track + hdr.cdth_trk0 - 1;
|
||||
if entry.cdte_track > hdr.cdth_trk1 then
|
||||
entry.cdte_track := CDROM_LEADOUT;
|
||||
|
||||
Ret:= fpioctl(hCDROM, CDROMREADTOCENTRY, @entry);
|
||||
if Ret <> 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.GetTrackMSF.fpioctl(CDROMREADTOCENTRY) Error : ' + IntToStr(Ret));
|
||||
|
||||
Result := entry.cdte_addr.msf;
|
||||
end;
|
||||
|
||||
function GetPosMSF(hCDROM: LongInt; Pos : TCDDAPosition): Tmsf;
|
||||
var
|
||||
msf1 : Tmsf;
|
||||
frames : longint;
|
||||
begin
|
||||
msf1 := GetTrackMSF(hCDROM, Pos.Track);
|
||||
frames := MSF2Frames(msf1);
|
||||
frames := frames + MSF2Frames(Pos.msf);
|
||||
Result := Frames2MSF(frames);
|
||||
end;
|
||||
|
||||
function GetSize(pCDROMI: PCDROMInfo): Int64;
|
||||
var
|
||||
F1 : LongWord;
|
||||
F2 : LongWord;
|
||||
begin
|
||||
F1:= (((pCDROMI^.StartPos.msf.min * 60) + pCDROMI^.StartPos.msf.sec) * 75) + pCDROMI^.StartPos.msf.Frame;
|
||||
F2:= (((pCDROMI^.EndPos.msf.min * 60) + pCDROMI^.EndPos.msf.sec) * 75) + pCDROMI^.EndPos.msf.Frame;
|
||||
Result := (F2 - F1) * CD_FRAMESIZE_RAW;
|
||||
end;
|
||||
// *********************************************************************************************************************
|
||||
|
||||
Function CDROM_GetFileNameDrive(FileName : AnsiString): Byte;
|
||||
Begin
|
||||
Result:= 255; // Assume Error
|
||||
if Copy(FileName, 1, Length(kCDDA_Base)) = kCDDA_Base then
|
||||
Result:= StrToIntDef(FileName[10], 256);
|
||||
end;
|
||||
|
||||
Function CDROM_GetFileNameTrack(FileName : AnsiString): Byte;
|
||||
Var
|
||||
s : AnsiString;
|
||||
Begin
|
||||
Result:= 0;
|
||||
if Pos(kCDDA_Track, FileName) > 0 then
|
||||
Begin
|
||||
s:= Copy(FileName, Pos(kCDDA_Track, FileName) + Length(kCDDA_Track), Length(FileName));
|
||||
s:= Copy(s, 1, Pos('.', s) -1);
|
||||
Result:= StrToIntDef(s, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
Function CDROM_OpenFile(FileName : AnsiString): PCDROMInfo;
|
||||
Var
|
||||
Drive, Track : Byte;
|
||||
Begin
|
||||
Result:= CDROM_Open(CDROM_GetFileNameDrive(FileName),
|
||||
CDROM_GetFileNameTrack(FileName));
|
||||
end;
|
||||
|
||||
Function CDROM_Open(Drive, Track : Byte): PCDROMInfo;
|
||||
Var
|
||||
CDRomPath : AnsiString;
|
||||
slCDROMS : TStringList;
|
||||
|
||||
Res : longint;
|
||||
Data : longint;
|
||||
CDTI : TCDDATrackInfo;
|
||||
CDTrackCount : LongInt;
|
||||
CDTOC : Array of TTocEntry;
|
||||
Begin
|
||||
Result:= nil;
|
||||
if (Drive = 255) or (Track < 1) then
|
||||
Exit;
|
||||
|
||||
New(Result);
|
||||
|
||||
// Read Only, CDROMI uses constants and ignores changes to these...
|
||||
Result^.Channels := 2;
|
||||
Result^.BitsPerSample:= 16;
|
||||
Result^.SampleRate := 44100;
|
||||
|
||||
CDRomPath:= '/dev/sr' + IntToStr(Drive);
|
||||
slCDROMS := TStringList.Create;
|
||||
Try
|
||||
slCDROMS.Text:= GetSystemCDRoms;
|
||||
if slCDROMS.IndexOf(CDRomPath) = -1 then
|
||||
raise Exception.Create('mcwCDROM_Linux.CDROM_Open.GetSystemCDRoms Error : ' + CDRomPath + ' Not Found.');
|
||||
finally
|
||||
slCDROMS.Free;
|
||||
end;
|
||||
|
||||
Result^.hCDROM:= fpopen(PAnsiChar(CDRomPath), O_RDONLY or O_NONBLOCK);;
|
||||
if Result^.hCDROM < 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.CDROM_Open.fpopen Error : (' + IntToStr(Result^.hCDROM) + ') On ' + CDRomPath);
|
||||
|
||||
// What State Is CDROM in ?
|
||||
Res:= fpioctl(Result^.hCDROM, CDROM_DRIVE_STATUS, @Data);
|
||||
if Res <> CDS_DISC_OK then
|
||||
Begin
|
||||
CDROM_Close(Result);
|
||||
Dispose(Result);
|
||||
Result:= nil;
|
||||
Exit;
|
||||
end;
|
||||
// CDRom OK, What Kind Of Disk Do We Have?
|
||||
Res := fpioctl(Result^.hCDROM, CDROM_DISC_STATUS, @Data);
|
||||
if (Res <> CDS_AUDIO) And (Res <> CDS_MIXED) Then
|
||||
Begin
|
||||
CDROM_Close(Result);
|
||||
Dispose(Result);
|
||||
Result:= nil;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
CDTI := GetTrackInfo(Result^.hCDROM, Track);
|
||||
if CDTI.TrackType = cdtData then
|
||||
raise Exception.Create('mcwCDROM_Linux.CDROM_Open : Trying to rip a data track');
|
||||
|
||||
Result^.StartPos.Track := Track;
|
||||
Result^.StartPos.msf := GetTrackMSF(Result^.hCDROM, Result^.StartPos.Track);
|
||||
Result^.EndPos.Track := Track +1;
|
||||
Result^.EndPos.msf := GetTrackMSF(Result^.hCDROM, Result^.EndPos.Track);
|
||||
|
||||
CDTrackCount := cdrom.ReadCDTOC(CDRomPath, CDTOC);
|
||||
|
||||
if (Result^.EndPos.Track in [1..CDTrackCount]) = False then
|
||||
raise Exception.Create('mcwCDROM_Linux.CDROM_Open : The end track out of range' + #13 +
|
||||
IntToStr(Result^.EndPos.Track) + ' Requested, 1..' + IntToStr(CDTrackCount) + ' Allowed...');
|
||||
|
||||
Result^.CurrentPosition := Result^.StartPos.msf;
|
||||
Result^.Position := 0;
|
||||
Result^.Size := GetSize(Result);
|
||||
Result^.BufStart := 1;
|
||||
Result^.BufEnd := 0;
|
||||
Result^.BufSize := BUF_SIZE;
|
||||
Result^.TotalSamples := Result^.Size div 4;
|
||||
Result^.TotalTime := floor(Result^.TotalSamples / 44100);
|
||||
|
||||
Inc(Result^.fHandleVaild);
|
||||
|
||||
end;
|
||||
|
||||
Function CDROM_Close(var pCDROMI: PCDROMInfo): LongWord;
|
||||
Begin
|
||||
Result := CDROM_UNKNOWNERR;
|
||||
if pCDROMI^.fHandleVaild = 1 then
|
||||
fpclose(pCDROMI^.hCDROM);
|
||||
if pCDROMI^.fHandleVaild > 0 then
|
||||
Dec(pCDROMI^.fHandleVaild);
|
||||
Result := CDROM_OK;
|
||||
end;
|
||||
|
||||
Function CDROM_GetData(var pCDROMI: PCDROMInfo; var pData: Pointer; var DataLength: longword): LongWord;
|
||||
var
|
||||
ReqLen : LongWord;
|
||||
ReqFrames : LongInt;
|
||||
cdaudio : cdrom_read_audio;
|
||||
Ret : LongWord;
|
||||
Res : LongInt;
|
||||
TmpCount : longword;
|
||||
Procedure getNextChunk;
|
||||
Begin
|
||||
TmpCount:= 0;
|
||||
|
||||
// Have We Reached End On Track ?
|
||||
if MSF2Frames(pCDROMI^.CurrentPosition) >= MSF2Frames(pCDROMI^.EndPos.msf) then
|
||||
Begin
|
||||
pCDROMI^.BufEnd := 0;
|
||||
pCDROMI^.BufStart := 0;
|
||||
Exit;
|
||||
End;
|
||||
|
||||
// This is not first call
|
||||
if pCDROMI^.BufEnd > 0 then
|
||||
Begin
|
||||
// Copy Leftover Data to Start of buffer...
|
||||
TmpCount:= pCDROMI^.BufEnd - pCDROMI^.BufStart;
|
||||
Move(pCDROMI^.Buf[pCDROMI^.BufStart], pCDROMI^.BufTmp[1], TmpCount);
|
||||
Move(pCDROMI^.BufTmp[1], pCDROMI^.Buf[1], TmpCount);
|
||||
End;
|
||||
|
||||
ReqFrames:= 75; // BUF_SIZE = 1 Sec Worth Data = 75 Frames = In Bytes
|
||||
if MSF2Frames(pCDROMI^.CurrentPosition) + ReqFrames > MSF2Frames(pCDROMI^.EndPos.msf) then
|
||||
ReqFrames:= MSF2Frames(pCDROMI^.EndPos.msf) - MSF2Frames(pCDROMI^.CurrentPosition);
|
||||
|
||||
// *** Rip Next Chunk ******************************************
|
||||
cdaudio.nframes := ReqFrames; // BUF_SIZE = 1 Sec Worth Data = 75 Frames = In Bytes
|
||||
cdaudio.addr_format := CDROM_MSF;
|
||||
cdaudio.addr.msf := pCDROMI^.CurrentPosition;
|
||||
cdaudio.buf := @pCDROMI^.Buf[TmpCount +1];
|
||||
|
||||
Res:= fpioctl(pCDROMI^.hCDROM, CDROMREADAUDIO, @cdaudio);
|
||||
if Res <> 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.CDROM_GetData.getNextChunk.fpioctl(CDROMREADAUDIO) Error : ' + IntToStr(fpgeterrno));
|
||||
|
||||
pCDROMI^.CurrentPosition:= Frames2MSF(MSF2Frames(pCDROMI^.CurrentPosition) + cdaudio.nframes);
|
||||
|
||||
Ret := cdaudio.nframes * CD_FRAMESIZE_RAW;
|
||||
// *** End Rip Next Chunk ***************************************
|
||||
|
||||
pCDROMI^.BufEnd:= TmpCount + Ret + 1;
|
||||
pCDROMI^.BufStart := 1;
|
||||
end;
|
||||
|
||||
begin
|
||||
// PortAudio expects exact amount of data, anything less causes "Blips"
|
||||
|
||||
// pCDROMI.BufStart = Start Byte of Current Valid, Not Sent Buffer...
|
||||
// pCDROMI.BufEnd = Last Byte of Current Valid, Not sent Buffer...
|
||||
|
||||
ReqLen:= DataLength;
|
||||
|
||||
if pCDROMI^.fHandleVaild = 0 then
|
||||
raise Exception.Create('mcwCDROM_Linux.CDROM_GetData Error : Call To GetData Without Vaild CDROM Handle.');
|
||||
|
||||
// We don't read CDROM every call, only when we need new data...
|
||||
if (pCDROMI^.BufStart + ReqLen) > pCDROMI^.BufEnd then
|
||||
getNextChunk;
|
||||
|
||||
// is the amount in buffer less than what was requested...
|
||||
if DataLength > (pCDROMI^.BufEnd - pCDROMI^.BufStart + 1) then
|
||||
DataLength := pCDROMI^.BufEnd - pCDROMI^.BufStart + 1;
|
||||
|
||||
// Have We Finished Reading Track ?
|
||||
if pCDROMI^.BufEnd = 0 then
|
||||
DataLength:= 0;
|
||||
|
||||
pData:= @pCDROMI^.Buf[pCDROMI^.BufStart];
|
||||
|
||||
If DataLength > 0 Then
|
||||
Begin
|
||||
Inc(pCDROMI^.BufStart, DataLength);
|
||||
Inc(pCDROMI^.Position, DataLength);
|
||||
end;
|
||||
|
||||
Result:= DataLength;
|
||||
end;
|
||||
{$ENDIF}
|
||||
//////////////////////
|
||||
{$IFDEF MSWINDOWS}
|
||||
const
|
||||
CDDA = 2;
|
||||
IOCTL_CDROM_READ_TOC = $00024000;
|
||||
IOCTL_CDROM_RAW_READ = $0002403E;
|
||||
IOCTL_STORAGE_CHECK_VERIFY2 = $0002D0800;
|
||||
MAXIMUM_NUMBER_TRACKS = 100;
|
||||
CB_CDROMSECTOR = 2048;
|
||||
|
||||
Type
|
||||
_TRACK_DATA = record
|
||||
Reserved : UCHAR;
|
||||
Control_and_Adr: UCHAR;
|
||||
TrackNumber : UCHAR;
|
||||
Reserved1 : UCHAR;
|
||||
Address : array[0..3] of UCHAR;
|
||||
end;
|
||||
TRACK_DATA = _TRACK_DATA;
|
||||
PTRACK_DATA = ^_TRACK_DATA;
|
||||
_CDROM_TOC = record
|
||||
Length : WORD;
|
||||
FirstTrack : UCHAR;
|
||||
LastTrack : UCHAR;
|
||||
TrackData : array[0..(MAXIMUM_NUMBER_TRACKS)-1] of TRACK_DATA;
|
||||
end;
|
||||
CDROM_TOC = _CDROM_TOC;
|
||||
PCDROM_TOC = ^_CDROM_TOC;
|
||||
RAW_READ_INFO = record
|
||||
DiskOffset : Int64;
|
||||
SectorCount : Cardinal;
|
||||
TrackMode : Cardinal;
|
||||
end;
|
||||
|
||||
Function fpgeterrno(): LongWord;
|
||||
Begin
|
||||
Result:= GetLastOSError;
|
||||
end;
|
||||
|
||||
// ********************** Private Windows SUPPORT Functions ************************************************************
|
||||
function GetTrackMSF(Table: CDROM_TOC; Track : LongInt): Tmsf;
|
||||
begin
|
||||
Result.min := Table.TrackData[Track -1].Address[1];
|
||||
Result.sec := Table.TrackData[Track -1].Address[2];
|
||||
Result.Frame:= Table.TrackData[Track -1].Address[3];
|
||||
end;
|
||||
|
||||
function GetPosMSF(Table: CDROM_TOC; Pos : TCDDAPosition): Tmsf;
|
||||
var
|
||||
msf1 : Tmsf;
|
||||
frames : longint;
|
||||
begin
|
||||
msf1 := GetTrackMSF(Table, Pos.Track);
|
||||
frames := MSF2Frames(msf1);
|
||||
frames := frames + MSF2Frames(Pos.msf);
|
||||
Result := Frames2MSF(frames);
|
||||
end;
|
||||
|
||||
function GetSize(pCDROMI: PCDROMInfo): Int64;
|
||||
var
|
||||
F1 : LongWord;
|
||||
F2 : LongWord;
|
||||
begin
|
||||
F1:= (((pCDROMI^.StartPos.msf.min * 60) + pCDROMI^.StartPos.msf.sec) * 75) + pCDROMI^.StartPos.msf.Frame;
|
||||
F2:= (((pCDROMI^.EndPos.msf.min * 60) + pCDROMI^.EndPos.msf.sec) * 75) + pCDROMI^.EndPos.msf.Frame;
|
||||
Result := (F2 - F1) * CD_FRAMESIZE_RAW;
|
||||
end;
|
||||
// *********************************************************************************************************************
|
||||
|
||||
Function CDROM_GetFileNameDrive(FileName : AnsiString): Byte;
|
||||
Var
|
||||
driveLetter : Char;
|
||||
drive : Char;
|
||||
cdromcount : Byte;
|
||||
found : Boolean;
|
||||
Begin
|
||||
found := False;
|
||||
driveLetter:= FileName[1];
|
||||
cdromcount := 255;
|
||||
For drive := 'A' to 'Z' do
|
||||
if GetDriveType(PChar(drive + ':\')) = DRIVE_CDROM then
|
||||
Begin
|
||||
Inc(cdromcount);
|
||||
if drive = driveLetter then
|
||||
Begin
|
||||
found:= True;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if not found then
|
||||
raise Exception.Create('CDROM (BDROM) Drive Not Found !');
|
||||
Result := cdromcount;
|
||||
end;
|
||||
|
||||
Function CDROM_GetFileNameTrack(FileName : AnsiString): Byte;
|
||||
Var
|
||||
s : AnsiString;
|
||||
Begin
|
||||
// This works on Win7...
|
||||
s := Copy(Filename, Pos(kCDDA_TrackWin, Filename) + 5, Length(Filename));
|
||||
s := Copy(s, 1, Pos('.', s) -1);
|
||||
Result:= StrToIntDef(s , 0);
|
||||
end;
|
||||
|
||||
Function CDROM_OpenFile(FileName : AnsiString): PCDROMInfo;
|
||||
Var
|
||||
Drive, Track : Byte;
|
||||
Begin
|
||||
Result:= CDROM_Open(CDROM_GetFileNameDrive(FileName),
|
||||
CDROM_GetFileNameTrack(FileName));
|
||||
end;
|
||||
|
||||
Function CDROM_Open(Drive, Track : Byte): PCDROMInfo;
|
||||
Var
|
||||
CDRomPath : AnsiString;
|
||||
Table : CDROM_TOC;
|
||||
BytesRead : LongWord;
|
||||
Ret : BOOL;
|
||||
flags : longword;
|
||||
// Index : LongInt;
|
||||
Begin
|
||||
Result:= nil;
|
||||
if (Drive = 255) or (Track < 1) then
|
||||
Exit;
|
||||
|
||||
New(Result);
|
||||
|
||||
// Read Only, CDROMI uses constants and ignores changes to these...
|
||||
Result^.Channels := 2;
|
||||
Result^.BitsPerSample:= 16;
|
||||
Result^.SampleRate := 44100;
|
||||
|
||||
CDRomPath:= UpperCase('\\.\CDROM') + IntToStr(Drive);
|
||||
flags := longword(GENERIC_READ);
|
||||
|
||||
Result^.hCDROM:= CreateFileA(PAnsiChar(CDRomPath), Flags, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
|
||||
if (Result^.hCDROM = INVALID_HANDLE_VALUE) then
|
||||
raise Exception.Create('mcwCDROM_Win.CDROM_Open.CreateFileA Error : (' + IntToStr(Result^.hCDROM) + ') On ' + CDRomPath);
|
||||
|
||||
// What State Is CDROM in ?
|
||||
Ret:= DeviceIoControl(Result^.hCDROM, IOCTL_STORAGE_CHECK_VERIFY2, nil, 0, nil, 0, BytesRead, nil);
|
||||
if Not Ret then
|
||||
Begin
|
||||
CDROM_Close(Result);
|
||||
Dispose(Result);
|
||||
Result:= nil;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Ret:= DeviceIoControl(Result^.hCDROM, IOCTL_CDROM_READ_TOC, nil, 0, @Table, sizeof(Table), BytesRead, nil);
|
||||
if Ret = False then
|
||||
raise Exception.Create('mcwCDROM_Win.CDROM_Open.DeviceIoControl(IOCTL_CDROM_READ_TOC) Error ');
|
||||
|
||||
Result^.StartPos.Track := Track;
|
||||
Result^.StartPos.msf := GetTrackMSF(Table, Result^.StartPos.Track);
|
||||
Result^.EndPos.Track := Track +1;
|
||||
Result^.EndPos.msf := GetTrackMSF(Table, Result^.EndPos.Track);
|
||||
Result^.CurrentPosition := Result^.StartPos.msf;
|
||||
Result^.Position := 0;
|
||||
Result^.Size := GetSize(Result);
|
||||
Result^.BufStart := 1;
|
||||
Result^.BufEnd := 0;
|
||||
Result^.BufSize := BUF_SIZE;
|
||||
Result^.TotalSamples := Result^.Size div 4;
|
||||
Result^.TotalTime := floor(Result^.TotalSamples / 44100);
|
||||
|
||||
Inc(Result^.fHandleVaild);
|
||||
end;
|
||||
|
||||
Function CDROM_Close(var pCDROMI: PCDROMInfo): LongWord;
|
||||
Begin
|
||||
Result := CDROM_UNKNOWNERR;
|
||||
if pCDROMI^.fHandleVaild = 1 then
|
||||
CloseHandle(pCDROMI^.hCDROM);
|
||||
if pCDROMI^.fHandleVaild > 0 then
|
||||
Dec(pCDROMI^.fHandleVaild);
|
||||
Result := CDROM_OK;
|
||||
end;
|
||||
|
||||
Function CDROM_GetData(var pCDROMI: PCDROMInfo; var pData: Pointer; var DataLength: longword): LongWord;
|
||||
var
|
||||
ReqLen : LongWord;
|
||||
ReqFrames : LongInt;
|
||||
Info : RAW_READ_INFO;
|
||||
BytesRead : LongWord;
|
||||
Address : Int64;
|
||||
Ret : LongWord;
|
||||
Res : BOOL;
|
||||
TmpCount : longword;
|
||||
Procedure getNextChunk;
|
||||
Begin
|
||||
TmpCount:= 0;
|
||||
|
||||
// Have We Reached End On Track ?
|
||||
if MSF2Frames(pCDROMI^.CurrentPosition) >= MSF2Frames(pCDROMI^.EndPos.msf) then
|
||||
Begin
|
||||
pCDROMI^.BufEnd := 0;
|
||||
pCDROMI^.BufStart := 0;
|
||||
Exit;
|
||||
End;
|
||||
|
||||
// This is not first call
|
||||
if pCDROMI^.BufEnd > 0 then
|
||||
Begin
|
||||
// Copy Leftover Data to Start of buffer...
|
||||
TmpCount:= pCDROMI^.BufEnd - pCDROMI^.BufStart;
|
||||
Move(pCDROMI^.Buf[pCDROMI^.BufStart], pCDROMI^.BufTmp[1], TmpCount);
|
||||
Move(pCDROMI^.BufTmp[1], pCDROMI^.Buf[1], TmpCount);
|
||||
End;
|
||||
// While Linux Can deal With 75 Frame Request, Windows Only 20 (?)
|
||||
ReqFrames:= 20; // BUF_SIZE = 1 Sec Worth Data = 75 Frames = In Bytes
|
||||
if MSF2Frames(pCDROMI^.CurrentPosition) + ReqFrames > MSF2Frames(pCDROMI^.EndPos.msf) then
|
||||
ReqFrames:= MSF2Frames(pCDROMI^.EndPos.msf) - MSF2Frames(pCDROMI^.CurrentPosition);
|
||||
|
||||
// *** Rip Next Chunk ******************************************
|
||||
Address:= AddressToSectors(pCDROMI^.CurrentPosition);
|
||||
|
||||
Info.TrackMode := CDDA;
|
||||
Info.SectorCount:= ReqFrames;
|
||||
Info.DiskOffset := Address * CB_CDROMSECTOR;
|
||||
|
||||
Res:= DeviceIoControl(pCDROMI^.hCDROM,
|
||||
IOCTL_CDROM_RAW_READ,
|
||||
@Info,
|
||||
sizeof(Info),
|
||||
@pCDROMI^.Buf[TmpCount +1],
|
||||
ReqFrames * CD_FRAMESIZE_RAW,
|
||||
BytesRead,
|
||||
nil);
|
||||
if Res = False then
|
||||
raise Exception.Create('mcwCDROM_Win.CDROM_GetData.getNextChunk.fpioctl(CDROMREADAUDIO) Error : ' + IntToStr(fpgeterrno));
|
||||
|
||||
pCDROMI^.CurrentPosition:= Frames2MSF(MSF2Frames(pCDROMI^.CurrentPosition) + ReqFrames);
|
||||
|
||||
Ret := BytesRead; // Should Be The same as "ReqFrames * CD_FRAMESIZE_RAW"
|
||||
// *** End Rip Next Chunk ***************************************
|
||||
|
||||
pCDROMI^.BufEnd:= TmpCount + Ret + 1;
|
||||
pCDROMI^.BufStart := 1;
|
||||
end;
|
||||
|
||||
begin
|
||||
// PortAudio expects exact amount of data, anything less causes "Blips"
|
||||
|
||||
// pCDROMI.BufStart = Start Byte of Current Valid, Not Sent Buffer...
|
||||
// pCDROMI.BufEnd = Last Byte of Current Valid, Not sent Buffer...
|
||||
|
||||
ReqLen:= DataLength;
|
||||
|
||||
if pCDROMI^.fHandleVaild = 0 then
|
||||
raise Exception.Create('mcwCDROM_Win.CDROM_GetData Error : Call To GetData Without Vaild CDROM Handle.');
|
||||
|
||||
// We don't read CDROM every call, only when we need new data...
|
||||
if (pCDROMI^.BufStart + ReqLen) > pCDROMI^.BufEnd then
|
||||
getNextChunk;
|
||||
|
||||
// is the amount in buffer less than what was requested...
|
||||
if DataLength > (pCDROMI^.BufEnd - pCDROMI^.BufStart + 1) then
|
||||
DataLength := pCDROMI^.BufEnd - pCDROMI^.BufStart + 1;
|
||||
|
||||
// Have We Finished Reading Track ?
|
||||
if pCDROMI^.BufEnd = 0 then
|
||||
DataLength:= 0;
|
||||
|
||||
pData:= @pCDROMI^.Buf[pCDROMI^.BufStart];
|
||||
|
||||
If DataLength > 0 Then
|
||||
Begin
|
||||
Inc(pCDROMI^.BufStart, DataLength);
|
||||
Inc(pCDROMI^.Position, DataLength);
|
||||
end;
|
||||
|
||||
Result:= DataLength;
|
||||
end;
|
||||
{$ENDIF}
|
||||
/////////////////////
|
||||
|
||||
Function GetSystemCDRoms: AnsiString;
|
||||
var
|
||||
Index : longint;
|
||||
Ret : LongInt;
|
||||
Devices : Array of string;
|
||||
sl : TStringList;
|
||||
begin
|
||||
Result:= '';
|
||||
sl:= TStringList.Create;
|
||||
|
||||
SetLength(Devices, 99);
|
||||
Ret:= cdrom.GetCDRomDevices(Devices);
|
||||
If Ret > 0 Then
|
||||
For Index := 0 To Ret -1 do
|
||||
sl.Add(Devices[Index]);
|
||||
|
||||
Result:= sl.Text;
|
||||
sl.Free;
|
||||
end;
|
||||
|
||||
// ********************** Common Linux/Windows SUPPORT Functions *******************************************************
|
||||
Function Frames2MSF(Frames : LongInt) : Tmsf;
|
||||
var
|
||||
Temp : Integer;
|
||||
begin
|
||||
Temp := Frames div 75;
|
||||
Result.min := Temp div 60;
|
||||
Result.sec := Temp mod 60;
|
||||
Result.Frame := Frames mod 75;
|
||||
end;
|
||||
|
||||
function MSF2Frames(const msf : Tmsf) : LongInt;
|
||||
begin
|
||||
Result := ((msf.min * 60) + msf.sec) * 75 + msf.Frame;
|
||||
end;
|
||||
|
||||
Function AddressToSectors (msf : Tmsf): int64;
|
||||
begin
|
||||
Result:= MSF2Frames(msf) - 150;
|
||||
end;
|
||||
|
||||
// *********************************************************************************************************************
|
||||
|
||||
end.
|
||||
|
||||
35
UOS/src/uos_define.inc
Normal file
35
UOS/src/uos_define.inc
Normal file
@@ -0,0 +1,35 @@
|
||||
{ United Openlibraries of Sound (uos)
|
||||
License : modified LGPL.
|
||||
Fred van Stappen fiens@hotmail.com }
|
||||
|
||||
// Compiler definitions
|
||||
|
||||
{.$DEFINE uos_debug} // uncomment for debugging. For console and Unix applications only.
|
||||
|
||||
{.$DEFINE consoleapp} // if FPC version < 2.7.1 uncomment for console application
|
||||
{.$DEFINE library} // uncomment for building uos library (native and java)
|
||||
{.$DEFINE java} // uncomment for building uos java library
|
||||
{.$DEFINE fpgui} // uncomment if FPC version < 2.7.1 and using fpGUI widget
|
||||
{.$DEFINE mse} // uncomment when using a mse project, use mse mseThread in place of fpc TThread.
|
||||
{.$DEFINE usequeue} // uncomment to use Thread.Queue instead of Thread.Synchronize for fpc threads, better for LCL widgets.
|
||||
|
||||
{$DEFINE portaudio} // uncomment to enable portaudio In/Out sound port
|
||||
|
||||
{$DEFINE sndfile} // uncomment to enable sndfile (wav, ogg, flac audio file)
|
||||
{$DEFINE mpg123} // uncomment to enable mpg123 (mp3 audio file)
|
||||
{$DEFINE neaac} // uncomment to enable neaac (m4a audio file)
|
||||
{$DEFINE fdkaac} // uncomment to enable aacdecoder (acc audio webstream)
|
||||
{$DEFINE opus} // uncomment to enable opus (opus audio file)
|
||||
{$DEFINE xmp} // uncomment to enable xmp (mod, it, mods, audio file)
|
||||
{.$DEFINE cdrom} // uncomment to enable cdrom audio decoder (cda)
|
||||
|
||||
{$DEFINE soundtouch} // uncomment to enable Soundtouch tempo plugin
|
||||
{$DEFINE bs2b} // uncomment to enable bs2b stereo to binaural plugin
|
||||
|
||||
{$DEFINE webstream} // uncomment to enable Internet Audio Streaming
|
||||
|
||||
{.$DEFINE shout} // uncomment to enable IceCast-Shout audio web server.
|
||||
|
||||
{$DEFINE noiseremoval} // uncomment to enable Noise Removal DSP
|
||||
|
||||
{$DEFINE synthesizer} // uncomment to enable Synthesizer
|
||||
1201
UOS/src/uos_dsp_noiseremoval.pas
Normal file
1201
UOS/src/uos_dsp_noiseremoval.pas
Normal file
File diff suppressed because it is too large
Load Diff
328
UOS/src/uos_dsp_utils.pas
Normal file
328
UOS/src/uos_dsp_utils.pas
Normal file
@@ -0,0 +1,328 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
{
|
||||
This unit uses part of Pascal Audio IO package.
|
||||
(paio_channelhelper, pa_ringbuffer, pa_utils)
|
||||
Copyright (c) 2016 by Andrew Haines.
|
||||
|
||||
Fred van Stappen fiens@hotmail.com
|
||||
}
|
||||
|
||||
unit uos_dsp_utils;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$interfaces corba}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
|
||||
const
|
||||
AUDIO_BUFFER_SIZE = 8192;
|
||||
AUDIO_BUFFER_FLOAT_SAMPLES = AUDIO_BUFFER_SIZE div 4;
|
||||
|
||||
type
|
||||
PPSingle = ^PSingle;
|
||||
TSingleArray = array of Single;
|
||||
TChannelArray = array of TSingleArray;
|
||||
|
||||
{ TRingBuffer }
|
||||
|
||||
TRingBuffer = class
|
||||
private
|
||||
FMem: PByte;
|
||||
FWritePos: Integer;
|
||||
FReadPos: Integer;
|
||||
FUsedSpace: Integer;
|
||||
FTotalSpace: Integer;
|
||||
function GetFreeSpace: Integer;
|
||||
public
|
||||
constructor Create(ASize: Integer);
|
||||
destructor Destroy; override;
|
||||
function Write(const ASource; ASize: Integer): Integer;
|
||||
function Read(var ADest; ASize: Integer): Integer;
|
||||
property FreeSpace: Integer read GetFreeSpace;
|
||||
property UsedSpace: Integer read FUsedSpace;
|
||||
|
||||
end;
|
||||
|
||||
type
|
||||
IPAIODataIOInterface = interface
|
||||
['IPAIODataIOInterface']
|
||||
procedure WriteDataIO(ASender: IPAIODataIOInterface; AData: PSingle; ASamples: Integer);
|
||||
end;
|
||||
|
||||
{ TPAIOChannelHelper }
|
||||
|
||||
TPAIOChannelHelper = class(IPAIODataIOInterface)
|
||||
private
|
||||
FOutputs: TList;
|
||||
FTarget: IPAIODataIOInterface; // where we will send plexed data.
|
||||
FBuffers: TChannelArray;
|
||||
FPos: array of Integer;
|
||||
// called by the individual channel objects.
|
||||
procedure WriteDataIO(ASender: IPAIODataIOInterface; AData: PSingle; ASamples: Integer);
|
||||
procedure AllocateBuffers;
|
||||
procedure SendDataToTarget;
|
||||
public
|
||||
constructor Create(APlexedTarget: IPAIODataIOInterface);
|
||||
destructor Destroy; override;
|
||||
property Outputs: TList read FOutputs;// of IPAIOSplitterJoinerInterface. Each is a channel in order.
|
||||
procedure Write(AData: PSingle; ASamples: Integer); // this expects interleaved data.
|
||||
end;
|
||||
|
||||
function NewChannelArray(AChannels: Integer; ASamplesPerChannel: Integer): TChannelArray;
|
||||
function SplitChannels(AData: PSingle; ASamples: Integer; AChannels: Integer): TChannelArray;
|
||||
function JoinChannels(AChannelData: TChannelArray; ASamples: Integer = -1): TSingleArray;
|
||||
function JoinChannels(AChannelData: PPSingle; AChannels: Integer; ASamples: Integer): TSingleArray;
|
||||
|
||||
function Min(A,B: Integer): Integer;
|
||||
function Max(A,B: Integer): Integer;
|
||||
|
||||
implementation
|
||||
|
||||
{ TPAIOChannelHelper }
|
||||
|
||||
procedure TPAIOChannelHelper.WriteDataIO(ASender: IPAIODataIOInterface; AData: PSingle; ASamples: Integer);
|
||||
var
|
||||
BufIndex: Integer;
|
||||
BufSize, WCount: Integer;
|
||||
Written: Integer = 0;
|
||||
begin
|
||||
BufIndex := FOutputs.IndexOf(Pointer(ASender));
|
||||
|
||||
if BufIndex = -1 then
|
||||
raise Exception.Create('Trying to write data from an unknown instance');
|
||||
|
||||
AllocateBuffers;
|
||||
|
||||
BufSize := Length(FBuffers[0]);
|
||||
|
||||
While ASamples > 0 do
|
||||
begin
|
||||
WCount := Min(BufSize-FPos[BufIndex], ASamples);
|
||||
Move(AData[Written], FBuffers[BufIndex][0], WCount*SizeOf(Single));
|
||||
Inc(Written, WCount);
|
||||
Dec(ASamples, WCount);
|
||||
Inc(FPos[BufIndex], WCount);
|
||||
|
||||
if BufIndex = High(FBuffers) then
|
||||
SendDataToTarget;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPAIOChannelHelper.AllocateBuffers;
|
||||
begin
|
||||
if Length(FBuffers) <> FOutputs.Count then
|
||||
begin
|
||||
SetLength(FBuffers, 0);
|
||||
FBuffers := NewChannelArray(FOutputs.Count, AUDIO_BUFFER_SIZE*2);
|
||||
SetLength(FPos, FOutputs.Count);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPAIOChannelHelper.SendDataToTarget;
|
||||
var
|
||||
Plexed: TSingleArray;
|
||||
HighestCount: Integer = 0;
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to High(FPos) do
|
||||
if FPos[i] > HighestCount then
|
||||
HighestCount:=FPos[i];
|
||||
Plexed := JoinChannels(FBuffers, HighestCount);
|
||||
|
||||
FTarget.WriteDataIO(Self, @Plexed[0], Length(Plexed));
|
||||
|
||||
for i := 0 to High(FPos) do
|
||||
Dec(FPos[i], HighestCount);
|
||||
end;
|
||||
|
||||
constructor TPAIOChannelHelper.Create(APlexedTarget: IPAIODataIOInterface);
|
||||
begin
|
||||
FOutputs := TList.Create;
|
||||
FTarget := APlexedTarget;
|
||||
end;
|
||||
|
||||
destructor TPAIOChannelHelper.Destroy;
|
||||
begin
|
||||
FOutputs.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TPAIOChannelHelper.Write(AData: PSingle; ASamples: Integer);
|
||||
var
|
||||
Channels: TChannelArray;
|
||||
i: Integer;
|
||||
Pos: Integer = 0;
|
||||
WCount: Integer;
|
||||
begin
|
||||
AllocateBuffers;
|
||||
Channels := SplitChannels(AData, ASamples, Outputs.Count);
|
||||
while ASamples > 0 do
|
||||
begin
|
||||
WCount := Min(1024, ASamples div Outputs.Count);
|
||||
for i := 0 to Outputs.Count-1 do
|
||||
begin
|
||||
IPAIODataIOInterface(Outputs.Items[i]).WriteDataIO(Self, @Channels[i][Pos], WCount);
|
||||
end;
|
||||
Dec(ASamples, WCount * Outputs.Count);
|
||||
Inc(Pos, WCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TRingBuffer }
|
||||
|
||||
function TRingBuffer.GetFreeSpace: Integer;
|
||||
begin
|
||||
Result := FTotalSpace-FUsedSpace;
|
||||
end;
|
||||
|
||||
constructor TRingBuffer.Create(ASize: Integer);
|
||||
begin
|
||||
FMem:=Getmem(ASize);
|
||||
FTotalSpace:=ASize;
|
||||
end;
|
||||
|
||||
destructor TRingBuffer.Destroy;
|
||||
begin
|
||||
Freemem(FMem);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TRingBuffer.Write(const ASource; ASize: Integer): Integer;
|
||||
var
|
||||
EOB: Integer; // end of buffer
|
||||
WSize: Integer;
|
||||
WTotal: Integer = 0;
|
||||
begin
|
||||
if FUsedSpace = 0 then
|
||||
begin
|
||||
// give the best chance of not splitting the data at buffer end.
|
||||
FWritePos:=0;
|
||||
FReadPos:=0;
|
||||
end;
|
||||
if ASize > FreeSpace then
|
||||
raise Exception.Create('Ring buffer overflow');
|
||||
Result := ASize;
|
||||
Inc(FUsedSpace, ASize);
|
||||
while ASize > 0 do
|
||||
begin
|
||||
EOB := FTotalSpace - FWritePos;
|
||||
WSize := Min(ASize, EOB);
|
||||
Move(PByte(@ASource)[WTotal], FMem[FWritePos], WSize);
|
||||
Inc(FWritePos, WSize);
|
||||
Dec(ASize, WSize);
|
||||
|
||||
if FWritePos >= FTotalSpace then
|
||||
FWritePos:= 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TRingBuffer.Read(var ADest; ASize: Integer): Integer;
|
||||
var
|
||||
EOB: Integer; // end of buffer
|
||||
RSize: Integer;
|
||||
RTotal: Integer = 0;
|
||||
begin
|
||||
if ASize > UsedSpace then
|
||||
raise Exception.Create('Ring buffer underflow');
|
||||
ASize := Min(ASize, UsedSpace);
|
||||
Result := ASize;
|
||||
|
||||
Dec(FUsedSpace, ASize);
|
||||
while ASize > 0 do
|
||||
begin
|
||||
EOB := FTotalSpace - FReadPos;
|
||||
RSize := Min(EOB, ASize);
|
||||
Move(FMem[FReadPos], PByte(@ADest)[RTotal],RSize);
|
||||
Dec(ASize, RSize);
|
||||
Inc(FReadPos, RSize);
|
||||
if FReadPos >= FTotalSpace then
|
||||
FReadPos:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function Min(A,B: Integer): Integer;
|
||||
begin
|
||||
if A < B then Exit(A);
|
||||
Result := B;
|
||||
end;
|
||||
|
||||
function Max(A,B: Integer): Integer;
|
||||
begin
|
||||
if A > B then Exit(A);
|
||||
Result := B;
|
||||
end;
|
||||
|
||||
function NewChannelArray(AChannels: Integer; ASamplesPerChannel: Integer): TChannelArray;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
SetLength(Result, AChannels);
|
||||
for i := 0 to AChannels-1 do
|
||||
SetLength(Result[i], ASamplesPerChannel);
|
||||
end;
|
||||
|
||||
// Samples is total samples not samples per channel.
|
||||
// So Samples = 1000 if 2 Channels have 500 each
|
||||
function SplitChannels(AData: PSingle; ASamples: Integer; AChannels: Integer): TChannelArray;
|
||||
var
|
||||
SamplesPerChannel: Integer;
|
||||
i, j: Integer;
|
||||
begin
|
||||
SamplesPerChannel:=ASamples div AChannels;
|
||||
//SetLength(Result, AChannels);
|
||||
Result := NewChannelArray(AChannels, SamplesPerChannel);
|
||||
for i := 0 to AChannels-1 do
|
||||
begin
|
||||
//SetLength(Result[i], SamplesPerChannel);
|
||||
for j := 0 to SamplesPerChannel-1 do
|
||||
begin
|
||||
Result[i][j] := AData[j*AChannels+i];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function JoinChannels(AChannelData: TChannelArray; ASamples: Integer): TSingleArray;
|
||||
var
|
||||
i: Integer;
|
||||
j: Integer;
|
||||
Samples: Integer;
|
||||
begin
|
||||
if Length(AChannelData) > 0 then
|
||||
begin
|
||||
if ASamples <> -1 then
|
||||
Samples := ASamples
|
||||
else
|
||||
Samples := Length(AChannelData[0]);
|
||||
|
||||
SetLength(Result, Length(AChannelData) * Samples);
|
||||
for i := 0 to High(AChannelData) do
|
||||
for j := 0 to Samples-1 do
|
||||
Result[j*Length(AChannelData)+i] := AChannelData[i][j];
|
||||
end
|
||||
else
|
||||
SetLength(Result, 0);
|
||||
end;
|
||||
|
||||
function JoinChannels(AChannelData: PPSingle; AChannels: Integer;
|
||||
ASamples: Integer): TSingleArray;
|
||||
var
|
||||
i: Integer;
|
||||
j: Integer;
|
||||
begin
|
||||
if ASamples > 0 then
|
||||
begin
|
||||
SetLength(Result, AChannels * ASamples);
|
||||
for i := 0 to AChannels-1 do
|
||||
for j := 0 to ASamples-1 do
|
||||
Result[j*AChannels+i] := AChannelData[i][j];
|
||||
end
|
||||
else
|
||||
SetLength(Result, 0);
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
1495
UOS/src/uos_fdkaacdecoder.pas
Normal file
1495
UOS/src/uos_fdkaacdecoder.pas
Normal file
File diff suppressed because it is too large
Load Diff
2547
UOS/src/uos_flat.pas
Normal file
2547
UOS/src/uos_flat.pas
Normal file
File diff suppressed because it is too large
Load Diff
158
UOS/src/uos_httpgetthread.pas
Normal file
158
UOS/src/uos_httpgetthread.pas
Normal file
@@ -0,0 +1,158 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{ This is HTTP Thread Getter
|
||||
created by Andrew Haines -> andrewd207@aol.com
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com}
|
||||
|
||||
unit uos_httpgetthread;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
SysUtils,
|
||||
Pipes;
|
||||
|
||||
type
|
||||
|
||||
{ TThreadHttpGetter }
|
||||
|
||||
TThreadHttpGetter = class(TThread)
|
||||
private
|
||||
FOutStream: TOutputPipeStream;
|
||||
FWantedURL: string;
|
||||
FIcyMetaInt: int64;
|
||||
FOnIcyMetaInt: TNotifyEvent;
|
||||
property OnIcyMetaInt: TNotifyEvent read FOnIcyMetaInt write FOnIcyMetaInt;
|
||||
procedure DoIcyMetaInt;
|
||||
function GetRedirectURL(AResponseStrings: TStrings): string;
|
||||
procedure Headers(Sender: TObject);
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
FIsRunning: Boolean;
|
||||
ICYenabled: Boolean;
|
||||
property IcyMetaInt: int64 read FIcyMetaInt;
|
||||
property IsRunning: Boolean read FIsRunning;
|
||||
constructor Create(AWantedURL: string; AOutputStream: TOutputPipeStream);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
fphttpclient,
|
||||
openssl, { This implements the procedure InitSSLInterface }
|
||||
opensslsockets;
|
||||
|
||||
{ TThreadHttpGetter }
|
||||
|
||||
function TThreadHttpGetter.GetRedirectURL(AResponseStrings: TStrings): string;
|
||||
var
|
||||
S: string;
|
||||
F: integer;
|
||||
Search: string = 'location:';
|
||||
begin
|
||||
Result := '';
|
||||
for S in AResponseStrings do
|
||||
begin
|
||||
// WriteLn(S);
|
||||
F := Pos(Search, Lowercase(s));
|
||||
|
||||
if F > 0 then
|
||||
begin
|
||||
Inc(F, Length(Search));
|
||||
Exit(Trim(Copy(S, F, Length(S) - F + 1)));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TThreadHttpGetter.DoIcyMetaInt;
|
||||
begin
|
||||
if Assigned(FOnIcyMetaInt) then
|
||||
FOnIcyMetaInt(Self);
|
||||
end;
|
||||
|
||||
procedure TThreadHttpGetter.Headers(Sender: TObject);
|
||||
begin
|
||||
FIcyMetaInt := StrToInt64Def(TFPHTTPClient(Sender).GetHeader(TFPHTTPClient(Sender).ResponseHeaders, 'icy-metaint'), 0);
|
||||
if (FIcyMetaInt > 0) and (FOnIcyMetaInt <> nil) then
|
||||
Synchronize(@DoIcyMetaInt);
|
||||
end;
|
||||
|
||||
procedure TThreadHttpGetter.Execute;
|
||||
var
|
||||
Http: TFPHTTPClient;
|
||||
URL: string;
|
||||
err: shortint = 0;
|
||||
begin
|
||||
URL := FWantedURL;
|
||||
if pos(' ', URL) > 0 then
|
||||
FIsRunning := False
|
||||
else
|
||||
begin
|
||||
InitSSLInterface;
|
||||
Http := TFPHTTPClient.Create(nil);
|
||||
http.AllowRedirect := True;
|
||||
http.IOTimeout := 2000;
|
||||
repeat
|
||||
try
|
||||
Http.RequestHeaders.Clear;
|
||||
if ICYenabled = True then
|
||||
Http.OnHeaders := @Headers;
|
||||
// writeln(' avant http.get');
|
||||
Http.Get(URL, FOutStream);
|
||||
// writeln(' apres http.get');
|
||||
except
|
||||
on e: EHTTPClient do
|
||||
begin
|
||||
// writeln(' Http.ResponseStatusCode ' +inttostr(Http.ResponseStatusCode));
|
||||
if (Http.ResponseStatusCode > 399) or (Http.ResponseStatusCode < 1) then // not accessible
|
||||
begin
|
||||
FIsRunning := False;
|
||||
break;
|
||||
end;
|
||||
if Http.ResponseStatusCode = 302 then
|
||||
begin
|
||||
URL := GetRedirectURL(Http.ResponseHeaders);
|
||||
if URL <> '' then
|
||||
Continue;
|
||||
end
|
||||
else
|
||||
Break;
|
||||
// raise E;
|
||||
end;
|
||||
on e: Exception do
|
||||
begin
|
||||
// WriteLn(e.Message);
|
||||
end
|
||||
else
|
||||
// Raise;
|
||||
Break;
|
||||
end;
|
||||
Break;
|
||||
until (False);
|
||||
try
|
||||
//FOutStream.Free;
|
||||
Http.Free;
|
||||
finally
|
||||
// make sure this is set to false when done
|
||||
FIsRunning := False;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TThreadHttpGetter.Create(AWantedURL: string; AOutputStream: TOutputPipeStream);
|
||||
begin
|
||||
inherited Create(True);
|
||||
ICYenabled := False;
|
||||
FIsRunning := True;
|
||||
FWantedURL := AWantedURL;
|
||||
FOutStream := AOutputStream;
|
||||
// Start;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
573
UOS/src/uos_jni.pas
Normal file
573
UOS/src/uos_jni.pas
Normal file
@@ -0,0 +1,573 @@
|
||||
unit uos_jni;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$packrecords c}
|
||||
{$endif}
|
||||
|
||||
{$macro on}
|
||||
{$ifdef mswindows}
|
||||
{$define jnicall:=stdcall}
|
||||
{$else}
|
||||
{$define jnicall:=cdecl}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
(*
|
||||
* Manifest constants.
|
||||
*)
|
||||
const JNI_FALSE=0;
|
||||
JNI_TRUE=1;
|
||||
|
||||
JNI_VERSION_1_1=$00010001;
|
||||
JNI_VERSION_1_2=$00010002;
|
||||
JNI_VERSION_1_4=$00010004;
|
||||
JNI_VERSION_1_6=$00010006;
|
||||
|
||||
JNI_OK=0; // no error
|
||||
JNI_ERR=-1; // generic error
|
||||
JNI_EDETACHED=-2; // thread detached from the VM
|
||||
JNI_EVERSION=-3; // JNI version error
|
||||
|
||||
JNI_COMMIT=1; // copy content, do not free buffer
|
||||
JNI_ABORT=2; // free buffer w/o copying back
|
||||
|
||||
(*
|
||||
* Type definitions.
|
||||
*)
|
||||
type va_list=pointer;
|
||||
|
||||
jboolean=byte; // unsigned 8 bits
|
||||
jbyte=shortint; // signed 8 bits
|
||||
jchar=word; // unsigned 16 bits
|
||||
jshort=smallint; // signed 16 bits
|
||||
jint=longint; // signed 32 bits
|
||||
jlong=int64; // signed 64 bits
|
||||
jfloat=single; // 32-bit IEEE 754
|
||||
jdouble=double; // 64-bit IEEE 754
|
||||
|
||||
jsize=jint; // "cardinal indices and sizes"
|
||||
|
||||
Pjboolean=^jboolean;
|
||||
Pjbyte=^jbyte;
|
||||
Pjchar=^jchar;
|
||||
Pjshort=^jshort;
|
||||
Pjint=^jint;
|
||||
Pjlong=^jlong;
|
||||
Pjfloat=^jfloat;
|
||||
Pjdouble=^jdouble;
|
||||
|
||||
Pjsize=^jsize;
|
||||
|
||||
// Reference type
|
||||
jobject=pointer;
|
||||
jclass=jobject;
|
||||
jstring=jobject;
|
||||
jarray=jobject;
|
||||
jobjectArray=jarray;
|
||||
jbooleanArray=jarray;
|
||||
jbyteArray=jarray;
|
||||
jcharArray=jarray;
|
||||
jshortArray=jarray;
|
||||
jintArray=jarray;
|
||||
jlongArray=jarray;
|
||||
jfloatArray=jarray;
|
||||
jdoubleArray=jarray;
|
||||
jthrowable=jobject;
|
||||
jweak=jobject;
|
||||
jref=jobject;
|
||||
|
||||
PPointer=^pointer;
|
||||
Pjobject=^jobject;
|
||||
Pjclass=^jclass;
|
||||
Pjstring=^jstring;
|
||||
Pjarray=^jarray;
|
||||
PjobjectArray=^jobjectArray;
|
||||
PjbooleanArray=^jbooleanArray;
|
||||
PjbyteArray=^jbyteArray;
|
||||
PjcharArray=^jcharArray;
|
||||
PjshortArray=^jshortArray;
|
||||
PjintArray=^jintArray;
|
||||
PjlongArray=^jlongArray;
|
||||
PjfloatArray=^jfloatArray;
|
||||
PjdoubleArray=^jdoubleArray;
|
||||
Pjthrowable=^jthrowable;
|
||||
Pjweak=^jweak;
|
||||
Pjref=^jref;
|
||||
|
||||
_jfieldID=record // opaque structure
|
||||
end;
|
||||
jfieldID=^_jfieldID;// field IDs
|
||||
PjfieldID=^jfieldID;
|
||||
|
||||
_jmethodID=record // opaque structure
|
||||
end;
|
||||
jmethodID=^_jmethodID;// method IDs
|
||||
PjmethodID=^jmethodID;
|
||||
|
||||
PJNIInvokeInterface=^JNIInvokeInterface;
|
||||
|
||||
Pjvalue=^jvalue;
|
||||
jvalue={$ifdef packedrecords}packed{$endif} record
|
||||
case integer of
|
||||
0:(z:jboolean);
|
||||
1:(b:jbyte);
|
||||
2:(c:jchar);
|
||||
3:(s:jshort);
|
||||
4:(i:jint);
|
||||
5:(j:jlong);
|
||||
6:(f:jfloat);
|
||||
7:(d:jdouble);
|
||||
8:(l:jobject);
|
||||
end;
|
||||
|
||||
jobjectRefType=(
|
||||
JNIInvalidRefType=0,
|
||||
JNILocalRefType=1,
|
||||
JNIGlobalRefType=2,
|
||||
JNIWeakGlobalRefType=3);
|
||||
|
||||
PJNINativeMethod=^JNINativeMethod;
|
||||
JNINativeMethod={$ifdef packedrecords}packed{$endif} record
|
||||
name:pchar;
|
||||
signature:pchar;
|
||||
fnPtr:pointer;
|
||||
end;
|
||||
|
||||
PJNINativeInterface=^JNINativeInterface;
|
||||
|
||||
_JNIEnv={$ifdef packedrecords}packed{$endif} record
|
||||
functions:PJNINativeInterface;
|
||||
end;
|
||||
|
||||
_JavaVM={$ifdef packedrecords}packed{$endif} record
|
||||
functions:PJNIInvokeInterface;
|
||||
end;
|
||||
|
||||
C_JNIEnv=^JNINativeInterface;
|
||||
JNIEnv=^JNINativeInterface;
|
||||
JavaVM=^JNIInvokeInterface;
|
||||
|
||||
PPJNIEnv=^PJNIEnv;
|
||||
PJNIEnv=^JNIEnv;
|
||||
|
||||
PPJavaVM=^PJavaVM;
|
||||
PJavaVM=^JavaVM;
|
||||
|
||||
JNINativeInterface={$ifdef packedrecords}packed{$endif} record
|
||||
reserved0:pointer;
|
||||
reserved1:pointer;
|
||||
reserved2:pointer;
|
||||
reserved3:pointer;
|
||||
|
||||
GetVersion:function(Env:PJNIEnv):JInt; jnicall;
|
||||
DefineClass:function(Env:PJNIEnv;const Name:pchar;Loader:JObject;const Buf:PJByte;Len:JSize):JClass; jnicall;
|
||||
FindClass:function(Env:PJNIEnv;const Name:pchar):JClass; jnicall;
|
||||
|
||||
// Reflection Support
|
||||
FromReflectedMethod:function(Env:PJNIEnv;Method:JObject):JMethodID; jnicall;
|
||||
FromReflectedField:function(Env:PJNIEnv;Field:JObject):JFieldID; jnicall;
|
||||
ToReflectedMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;IsStatic:JBoolean):JObject; jnicall;
|
||||
|
||||
GetSuperclass:function(Env:PJNIEnv;Sub:JClass):JClass; jnicall;
|
||||
IsAssignableFrom:function(Env:PJNIEnv;Sub:JClass;Sup:JClass):JBoolean; jnicall;
|
||||
|
||||
// Reflection Support
|
||||
ToReflectedField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;IsStatic:JBoolean):JObject; jnicall;
|
||||
|
||||
Throw:function(Env:PJNIEnv;Obj:JThrowable):JInt; jnicall;
|
||||
ThrowNew:function(Env:PJNIEnv;AClass:JClass;const Msg:pchar):JInt; jnicall;
|
||||
ExceptionOccurred:function(Env:PJNIEnv):JThrowable; jnicall;
|
||||
ExceptionDescribe:procedure(Env:PJNIEnv); jnicall;
|
||||
ExceptionClear:procedure(Env:PJNIEnv); jnicall;
|
||||
FatalError:procedure(Env:PJNIEnv;const Msg:pchar); jnicall;
|
||||
|
||||
// Local Reference Management
|
||||
PushLocalFrame:function(Env:PJNIEnv;Capacity:JInt):JInt; jnicall;
|
||||
PopLocalFrame:function(Env:PJNIEnv;Result:JObject):JObject; jnicall;
|
||||
|
||||
NewGlobalRef:function(Env:PJNIEnv;LObj:JObject):JObject; jnicall;
|
||||
DeleteGlobalRef:procedure(Env:PJNIEnv;GRef:JObject); jnicall;
|
||||
DeleteLocalRef:procedure(Env:PJNIEnv;Obj:JObject); jnicall;
|
||||
IsSameObject:function(Env:PJNIEnv;Obj1:JObject;Obj2:JObject):JBoolean; jnicall;
|
||||
|
||||
// Local Reference Management
|
||||
NewLocalRef:function(Env:PJNIEnv;Ref:JObject):JObject; jnicall;
|
||||
EnsureLocalCapacity:function(Env:PJNIEnv;Capacity:JInt):JObject; jnicall;
|
||||
|
||||
AllocObject:function(Env:PJNIEnv;AClass:JClass):JObject; jnicall;
|
||||
NewObject:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JObject; jnicall;
|
||||
NewObjectV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JObject; jnicall;
|
||||
NewObjectA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JObject; jnicall;
|
||||
|
||||
GetObjectClass:function(Env:PJNIEnv;Obj:JObject):JClass; jnicall;
|
||||
IsInstanceOf:function(Env:PJNIEnv;Obj:JObject;AClass:JClass):JBoolean; jnicall;
|
||||
|
||||
GetMethodID:function(Env:PJNIEnv;AClass:JClass;const Name:pchar;const Sig:pchar):JMethodID; jnicall;
|
||||
|
||||
CallObjectMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JObject; jnicall;
|
||||
CallObjectMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JObject; jnicall;
|
||||
CallObjectMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JObject; jnicall;
|
||||
|
||||
CallBooleanMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JBoolean; jnicall;
|
||||
CallBooleanMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JBoolean; jnicall;
|
||||
CallBooleanMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JBoolean; jnicall;
|
||||
|
||||
CallByteMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JByte; jnicall;
|
||||
CallByteMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JByte; jnicall;
|
||||
CallByteMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JByte; jnicall;
|
||||
|
||||
CallCharMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JChar; jnicall;
|
||||
CallCharMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JChar; jnicall;
|
||||
CallCharMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JChar; jnicall;
|
||||
|
||||
CallShortMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JShort; jnicall;
|
||||
CallShortMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JShort; jnicall;
|
||||
CallShortMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JShort; jnicall;
|
||||
|
||||
CallIntMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JInt; jnicall;
|
||||
CallIntMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JInt; jnicall;
|
||||
CallIntMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JInt; jnicall;
|
||||
|
||||
CallLongMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JLong; jnicall;
|
||||
CallLongMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JLong; jnicall;
|
||||
CallLongMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JLong; jnicall;
|
||||
|
||||
CallFloatMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JFloat; jnicall;
|
||||
CallFloatMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JFloat; jnicall;
|
||||
CallFloatMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JFloat; jnicall;
|
||||
|
||||
CallDoubleMethod:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID):JDouble; jnicall;
|
||||
CallDoubleMethodV:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list):JDouble; jnicall;
|
||||
CallDoubleMethodA:function(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue):JDouble; jnicall;
|
||||
|
||||
CallVoidMethod:procedure(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID); jnicall;
|
||||
CallVoidMethodV:procedure(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:va_list); jnicall;
|
||||
CallVoidMethodA:procedure(Env:PJNIEnv;Obj:JObject;MethodID:JMethodID;Args:PJValue); jnicall;
|
||||
|
||||
CallNonvirtualObjectMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JObject; jnicall;
|
||||
CallNonvirtualObjectMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JObject; jnicall;
|
||||
CallNonvirtualObjectMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JObject; jnicall;
|
||||
|
||||
CallNonvirtualBooleanMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JBoolean; jnicall;
|
||||
CallNonvirtualBooleanMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JBoolean; jnicall;
|
||||
CallNonvirtualBooleanMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JBoolean; jnicall;
|
||||
|
||||
CallNonvirtualByteMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JByte; jnicall;
|
||||
CallNonvirtualByteMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JByte; jnicall;
|
||||
CallNonvirtualByteMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JByte; jnicall;
|
||||
|
||||
CallNonvirtualCharMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JChar; jnicall;
|
||||
CallNonvirtualCharMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JChar; jnicall;
|
||||
CallNonvirtualCharMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JChar; jnicall;
|
||||
|
||||
CallNonvirtualShortMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JShort; jnicall;
|
||||
CallNonvirtualShortMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JShort; jnicall;
|
||||
CallNonvirtualShortMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JShort; jnicall;
|
||||
|
||||
CallNonvirtualIntMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JInt; jnicall;
|
||||
CallNonvirtualIntMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JInt; jnicall;
|
||||
CallNonvirtualIntMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JInt; jnicall;
|
||||
|
||||
CallNonvirtualLongMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JLong; jnicall;
|
||||
CallNonvirtualLongMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JLong; jnicall;
|
||||
CallNonvirtualLongMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JLong; jnicall;
|
||||
|
||||
CallNonvirtualFloatMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JFloat; jnicall;
|
||||
CallNonvirtualFloatMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JFloat; jnicall;
|
||||
CallNonvirtualFloatMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JFloat; jnicall;
|
||||
|
||||
CallNonvirtualDoubleMethod:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID):JDouble; jnicall;
|
||||
CallNonvirtualDoubleMethodV:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list):JDouble; jnicall;
|
||||
CallNonvirtualDoubleMethodA:function(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue):JDouble; jnicall;
|
||||
|
||||
CallNonvirtualVoidMethod:procedure(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID); jnicall;
|
||||
CallNonvirtualVoidMethodV:procedure(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:va_list); jnicall;
|
||||
CallNonvirtualVoidMethodA:procedure(Env:PJNIEnv;Obj:JObject;AClass:JClass;MethodID:JMethodID;Args:PJValue); jnicall;
|
||||
|
||||
GetFieldID:function(Env:PJNIEnv;AClass:JClass;const Name:pchar;const Sig:pchar):JFieldID; jnicall;
|
||||
|
||||
GetObjectField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JObject; jnicall;
|
||||
GetBooleanField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JBoolean; jnicall;
|
||||
GetByteField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JByte; jnicall;
|
||||
GetCharField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JChar; jnicall;
|
||||
GetShortField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JShort; jnicall;
|
||||
GetIntField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JInt; jnicall;
|
||||
GetLongField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JLong; jnicall;
|
||||
GetFloatField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JFloat; jnicall;
|
||||
GetDoubleField:function(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID):JDouble; jnicall;
|
||||
|
||||
SetObjectField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JObject); jnicall;
|
||||
SetBooleanField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JBoolean); jnicall;
|
||||
SetByteField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JByte); jnicall;
|
||||
SetCharField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JChar); jnicall;
|
||||
SetShortField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JShort); jnicall;
|
||||
SetIntField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JInt); jnicall;
|
||||
SetLongField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JLong); jnicall;
|
||||
SetFloatField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JFloat); jnicall;
|
||||
SetDoubleField:procedure(Env:PJNIEnv;Obj:JObject;FieldID:JFieldID;Val:JDouble); jnicall;
|
||||
|
||||
GetStaticMethodID:function(Env:PJNIEnv;AClass:JClass;const Name:pchar;const Sig:pchar):JMethodID; jnicall;
|
||||
|
||||
CallStaticObjectMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JObject; jnicall;
|
||||
CallStaticObjectMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JObject; jnicall;
|
||||
CallStaticObjectMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JObject; jnicall;
|
||||
|
||||
CallStaticBooleanMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JBoolean; jnicall;
|
||||
CallStaticBooleanMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JBoolean; jnicall;
|
||||
CallStaticBooleanMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JBoolean; jnicall;
|
||||
|
||||
CallStaticByteMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JByte; jnicall;
|
||||
CallStaticByteMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JByte; jnicall;
|
||||
CallStaticByteMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JByte; jnicall;
|
||||
|
||||
CallStaticCharMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JChar; jnicall;
|
||||
CallStaticCharMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JChar; jnicall;
|
||||
CallStaticCharMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JChar; jnicall;
|
||||
|
||||
CallStaticShortMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JShort; jnicall;
|
||||
CallStaticShortMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JShort; jnicall;
|
||||
CallStaticShortMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JShort; jnicall;
|
||||
|
||||
CallStaticIntMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JInt; jnicall;
|
||||
CallStaticIntMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JInt; jnicall;
|
||||
CallStaticIntMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JInt; jnicall;
|
||||
|
||||
CallStaticLongMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JLong; jnicall;
|
||||
CallStaticLongMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JLong; jnicall;
|
||||
CallStaticLongMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JLong; jnicall;
|
||||
|
||||
CallStaticFloatMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JFloat; jnicall;
|
||||
CallStaticFloatMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JFloat; jnicall;
|
||||
CallStaticFloatMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JFloat; jnicall;
|
||||
|
||||
CallStaticDoubleMethod:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID):JDouble; jnicall;
|
||||
CallStaticDoubleMethodV:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list):JDouble; jnicall;
|
||||
CallStaticDoubleMethodA:function(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue):JDouble; jnicall;
|
||||
|
||||
CallStaticVoidMethod:procedure(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID); jnicall;
|
||||
CallStaticVoidMethodV:procedure(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:va_list); jnicall;
|
||||
CallStaticVoidMethodA:procedure(Env:PJNIEnv;AClass:JClass;MethodID:JMethodID;Args:PJValue); jnicall;
|
||||
|
||||
GetStaticFieldID:function(Env:PJNIEnv;AClass:JClass;const Name:pchar;const Sig:pchar):JFieldID; jnicall;
|
||||
GetStaticObjectField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JObject; jnicall;
|
||||
GetStaticBooleanField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JBoolean; jnicall;
|
||||
GetStaticByteField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JByte; jnicall;
|
||||
GetStaticCharField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JChar; jnicall;
|
||||
GetStaticShortField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JShort; jnicall;
|
||||
GetStaticIntField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JInt; jnicall;
|
||||
GetStaticLongField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JLong; jnicall;
|
||||
GetStaticFloatField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JFloat; jnicall;
|
||||
GetStaticDoubleField:function(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID):JDouble; jnicall;
|
||||
|
||||
SetStaticObjectField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JObject); jnicall;
|
||||
SetStaticBooleanField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JBoolean); jnicall;
|
||||
SetStaticByteField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JByte); jnicall;
|
||||
SetStaticCharField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JChar); jnicall;
|
||||
SetStaticShortField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JShort); jnicall;
|
||||
SetStaticIntField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JInt); jnicall;
|
||||
SetStaticLongField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JLong); jnicall;
|
||||
SetStaticFloatField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JFloat); jnicall;
|
||||
SetStaticDoubleField:procedure(Env:PJNIEnv;AClass:JClass;FieldID:JFieldID;Val:JDouble); jnicall;
|
||||
|
||||
NewString:function(Env:PJNIEnv;const Unicode:PJChar;Len:JSize):JString; jnicall;
|
||||
GetStringLength:function(Env:PJNIEnv;Str:JString):JSize; jnicall;
|
||||
GetStringChars:function(Env:PJNIEnv;Str:JString;IsCopy:PJBoolean):PJChar; jnicall;
|
||||
ReleaseStringChars:procedure(Env:PJNIEnv;Str:JString;const Chars:PJChar); jnicall;
|
||||
|
||||
NewStringUTF:function(Env:PJNIEnv;const UTF:pchar):JString; jnicall;
|
||||
GetStringUTFLength:function(Env:PJNIEnv;Str:JString):JSize; jnicall;
|
||||
GetStringUTFChars:function(Env:PJNIEnv;Str:JString;IsCopy:PJBoolean):pchar; jnicall;
|
||||
ReleaseStringUTFChars:procedure(Env:PJNIEnv;Str:JString;const Chars:pchar); jnicall;
|
||||
|
||||
GetArrayLength:function(Env:PJNIEnv;AArray:JArray):JSize; jnicall;
|
||||
|
||||
NewObjectArray:function(Env:PJNIEnv;Len:JSize;AClass:JClass;Init:JObject):JObjectArray; jnicall;
|
||||
GetObjectArrayElement:function(Env:PJNIEnv;AArray:JObjectArray;Index:JSize):JObject; jnicall;
|
||||
SetObjectArrayElement:procedure(Env:PJNIEnv;AArray:JObjectArray;Index:JSize;Val:JObject); jnicall;
|
||||
|
||||
NewBooleanArray:function(Env:PJNIEnv;Len:JSize):JBooleanArray; jnicall;
|
||||
NewByteArray:function(Env:PJNIEnv;Len:JSize):JByteArray; jnicall;
|
||||
NewCharArray:function(Env:PJNIEnv;Len:JSize):JCharArray; jnicall;
|
||||
NewShortArray:function(Env:PJNIEnv;Len:JSize):JShortArray; jnicall;
|
||||
NewIntArray:function(Env:PJNIEnv;Len:JSize):JIntArray; jnicall;
|
||||
NewLongArray:function(Env:PJNIEnv;Len:JSize):JLongArray; jnicall;
|
||||
NewFloatArray:function(Env:PJNIEnv;Len:JSize):JFloatArray; jnicall;
|
||||
NewDoubleArray:function(Env:PJNIEnv;Len:JSize):JDoubleArray; jnicall;
|
||||
|
||||
GetBooleanArrayElements:function(Env:PJNIEnv;AArray:JBooleanArray;IsCopy:PJBoolean):PJBoolean; jnicall;
|
||||
GetByteArrayElements:function(Env:PJNIEnv;AArray:JByteArray;IsCopy:PJBoolean):PJByte; jnicall;
|
||||
GetCharArrayElements:function(Env:PJNIEnv;AArray:JCharArray;IsCopy:PJBoolean):PJChar; jnicall;
|
||||
GetShortArrayElements:function(Env:PJNIEnv;AArray:JShortArray;IsCopy:PJBoolean):PJShort; jnicall;
|
||||
GetIntArrayElements:function(Env:PJNIEnv;AArray:JIntArray;IsCopy:PJBoolean):PJInt; jnicall;
|
||||
GetLongArrayElements:function(Env:PJNIEnv;AArray:JLongArray;IsCopy:PJBoolean):PJLong; jnicall;
|
||||
GetFloatArrayElements:function(Env:PJNIEnv;AArray:JFloatArray;IsCopy:PJBoolean):PJFloat; jnicall;
|
||||
GetDoubleArrayElements:function(Env:PJNIEnv;AArray:JDoubleArray;IsCopy:PJBoolean):PJDouble; jnicall;
|
||||
|
||||
ReleaseBooleanArrayElements:procedure(Env:PJNIEnv;AArray:JBooleanArray;Elems:PJBoolean;Mode:JInt); jnicall;
|
||||
ReleaseByteArrayElements:procedure(Env:PJNIEnv;AArray:JByteArray;Elems:PJByte;Mode:JInt); jnicall;
|
||||
ReleaseCharArrayElements:procedure(Env:PJNIEnv;AArray:JCharArray;Elems:PJChar;Mode:JInt); jnicall;
|
||||
ReleaseShortArrayElements:procedure(Env:PJNIEnv;AArray:JShortArray;Elems:PJShort;Mode:JInt); jnicall;
|
||||
ReleaseIntArrayElements:procedure(Env:PJNIEnv;AArray:JIntArray;Elems:PJInt;Mode:JInt); jnicall;
|
||||
ReleaseLongArrayElements:procedure(Env:PJNIEnv;AArray:JLongArray;Elems:PJLong;Mode:JInt); jnicall;
|
||||
ReleaseFloatArrayElements:procedure(Env:PJNIEnv;AArray:JFloatArray;Elems:PJFloat;Mode:JInt); jnicall;
|
||||
ReleaseDoubleArrayElements:procedure(Env:PJNIEnv;AArray:JDoubleArray;Elems:PJDouble;Mode:JInt); jnicall;
|
||||
|
||||
GetBooleanArrayRegion:procedure(Env:PJNIEnv;AArray:JBooleanArray;Start:JSize;Len:JSize;Buf:PJBoolean); jnicall;
|
||||
GetByteArrayRegion:procedure(Env:PJNIEnv;AArray:JByteArray;Start:JSize;Len:JSize;Buf:PJByte); jnicall;
|
||||
GetCharArrayRegion:procedure(Env:PJNIEnv;AArray:JCharArray;Start:JSize;Len:JSize;Buf:PJChar); jnicall;
|
||||
GetShortArrayRegion:procedure(Env:PJNIEnv;AArray:JShortArray;Start:JSize;Len:JSize;Buf:PJShort); jnicall;
|
||||
GetIntArrayRegion:procedure(Env:PJNIEnv;AArray:JIntArray;Start:JSize;Len:JSize;Buf:PJInt); jnicall;
|
||||
GetLongArrayRegion:procedure(Env:PJNIEnv;AArray:JLongArray;Start:JSize;Len:JSize;Buf:PJLong); jnicall;
|
||||
GetFloatArrayRegion:procedure(Env:PJNIEnv;AArray:JFloatArray;Start:JSize;Len:JSize;Buf:PJFloat); jnicall;
|
||||
GetDoubleArrayRegion:procedure(Env:PJNIEnv;AArray:JDoubleArray;Start:JSize;Len:JSize;Buf:PJDouble); jnicall;
|
||||
|
||||
SetBooleanArrayRegion:procedure(Env:PJNIEnv;AArray:JBooleanArray;Start:JSize;Len:JSize;Buf:PJBoolean); jnicall;
|
||||
SetByteArrayRegion:procedure(Env:PJNIEnv;AArray:JByteArray;Start:JSize;Len:JSize;Buf:PJByte); jnicall;
|
||||
SetCharArrayRegion:procedure(Env:PJNIEnv;AArray:JCharArray;Start:JSize;Len:JSize;Buf:PJChar); jnicall;
|
||||
SetShortArrayRegion:procedure(Env:PJNIEnv;AArray:JShortArray;Start:JSize;Len:JSize;Buf:PJShort); jnicall;
|
||||
SetIntArrayRegion:procedure(Env:PJNIEnv;AArray:JIntArray;Start:JSize;Len:JSize;Buf:PJInt); jnicall;
|
||||
SetLongArrayRegion:procedure(Env:PJNIEnv;AArray:JLongArray;Start:JSize;Len:JSize;Buf:PJLong); jnicall;
|
||||
SetFloatArrayRegion:procedure(Env:PJNIEnv;AArray:JFloatArray;Start:JSize;Len:JSize;Buf:PJFloat); jnicall;
|
||||
SetDoubleArrayRegion:procedure(Env:PJNIEnv;AArray:JDoubleArray;Start:JSize;Len:JSize;Buf:PJDouble); jnicall;
|
||||
|
||||
RegisterNatives:function(Env:PJNIEnv;AClass:JClass;const Methods:PJNINativeMethod;NMethods:JInt):JInt; jnicall;
|
||||
UnregisterNatives:function(Env:PJNIEnv;AClass:JClass):JInt; jnicall;
|
||||
|
||||
MonitorEnter:function(Env:PJNIEnv;Obj:JObject):JInt; jnicall;
|
||||
MonitorExit:function(Env:PJNIEnv;Obj:JObject):JInt; jnicall;
|
||||
|
||||
GetJavaVM:function(Env:PJNIEnv;VM:PJavaVM):JInt; jnicall;
|
||||
|
||||
// String Operations
|
||||
GetStringRegion:procedure(Env:PJNIEnv;Str:JString;Start:JSize;Len:JSize;Buf:PJChar); jnicall;
|
||||
GetStringUTFRegion:procedure(Env:PJNIEnv;Str:JString;Start:JSize;Len:JSize;Buf:pchar); jnicall;
|
||||
|
||||
// Array Operations
|
||||
GetPrimitiveArrayCritical:function(Env:PJNIEnv;AArray:JArray;IsCopy:PJBoolean):pointer; jnicall;
|
||||
ReleasePrimitiveArrayCritical:procedure(Env:PJNIEnv;AArray:JArray;CArray:pointer;Mode:JInt); jnicall;
|
||||
|
||||
// String Operations
|
||||
GetStringCritical:function(Env:PJNIEnv;Str:JString;IsCopy:PJBoolean):PJChar; jnicall;
|
||||
ReleaseStringCritical:procedure(Env:PJNIEnv;Str:JString;CString:PJChar); jnicall;
|
||||
|
||||
// Weak Global References
|
||||
NewWeakGlobalRef:function(Env:PJNIEnv;Obj:JObject):JWeak; jnicall;
|
||||
DeleteWeakGlobalRef:procedure(Env:PJNIEnv;Ref:JWeak); jnicall;
|
||||
|
||||
// Exceptions
|
||||
ExceptionCheck:function(Env:PJNIEnv):JBoolean; jnicall;
|
||||
|
||||
// J2SDK1_4
|
||||
NewDirectByteBuffer:function(Env:PJNIEnv;Address:pointer;Capacity:JLong):JObject; jnicall;
|
||||
GetDirectBufferAddress:function(Env:PJNIEnv;Buf:JObject):pointer; jnicall;
|
||||
GetDirectBufferCapacity:function(Env:PJNIEnv;Buf:JObject):JLong; jnicall;
|
||||
|
||||
// added in JNI 1.6
|
||||
GetObjectRefType:function(Env:PJNIEnv;AObject:JObject):jobjectRefType; jnicall;
|
||||
end;
|
||||
|
||||
JNIInvokeInterface={$ifdef packedrecords}packed{$endif} record
|
||||
reserved0:pointer;
|
||||
reserved1:pointer;
|
||||
reserved2:pointer;
|
||||
|
||||
DestroyJavaVM:function(PVM:PJavaVM):JInt; jnicall;
|
||||
AttachCurrentThread:function(PVM:PJavaVM;PEnv:PPJNIEnv;Args:pointer):JInt; jnicall;
|
||||
DetachCurrentThread:function(PVM:PJavaVM):JInt; jnicall;
|
||||
GetEnv:function(PVM:PJavaVM;PEnv:Ppointer;Version:JInt):JInt; jnicall;
|
||||
AttachCurrentThreadAsDaemon:function(PVM:PJavaVM;PEnv:PPJNIEnv;Args:pointer):JInt; jnicall;
|
||||
end;
|
||||
|
||||
JavaVMAttachArgs={$ifdef packedrecords}packed{$endif} record
|
||||
version:jint; // must be >= JNI_VERSION_1_2
|
||||
name:pchar; // NULL or name of thread as modified UTF-8 str
|
||||
group:jobject; // global ref of a ThreadGroup object, or NULL
|
||||
end;
|
||||
|
||||
(**
|
||||
* JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no
|
||||
* longer supported.)
|
||||
*)
|
||||
|
||||
PJavaVMOption=^JavaVMOption;
|
||||
JavaVMOption={$ifdef packedrecords}packed{$endif} record
|
||||
optionString:pchar;
|
||||
extraInfo:pointer;
|
||||
end;
|
||||
|
||||
JavaVMInitArgs={$ifdef packedrecords}packed{$endif} record
|
||||
version:jint; // use JNI_VERSION_1_2 or later
|
||||
nOptions:jint;
|
||||
options:PJavaVMOption;
|
||||
ignoreUnrecognized:Pjboolean;
|
||||
end;
|
||||
|
||||
(*
|
||||
* VM initialization functions.
|
||||
*
|
||||
* Note these are the only symbols exported for JNI by the VM.
|
||||
*)
|
||||
{$ifdef jniexternals}
|
||||
function JNI_GetDefaultJavaVMInitArgs(p:pointer):jint; jnicall;external 'jni' name 'JNI_GetDefaultJavaVMInitArgs';
|
||||
function JNI_CreateJavaVM(vm:PPJavaVM;AEnv:PPJNIEnv;p:pointer):jint; jnicall;external 'jni' name 'JNI_CreateJavaVM';
|
||||
function JNI_GetCreatedJavaVMs(vm:PPJavaVM;ASize:jsize;p:Pjsize):jint; jnicall;external 'jni' name 'JNI_GetCreatedJavaVMs';
|
||||
{$endif}
|
||||
|
||||
(*
|
||||
* Prototypes for functions exported by loadable shared libs. These are
|
||||
* called by JNI, not provided by JNI.
|
||||
*)
|
||||
|
||||
const curVM:PJavaVM=nil;
|
||||
curEnv:PJNIEnv=nil;
|
||||
|
||||
(*
|
||||
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; jnicall;
|
||||
procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); jnicall;
|
||||
*)
|
||||
|
||||
(* Helper Routines *)
|
||||
function JNI_JStringToString( PEnv : PJNIEnv; JStr : JString ) : string;
|
||||
function JNI_StringToJString( PEnv : PJNIEnv; const AString : PAnsiChar ) : JString;
|
||||
|
||||
implementation
|
||||
|
||||
function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; jnicall;
|
||||
begin
|
||||
curVM:=vm;
|
||||
result:=JNI_VERSION_1_6;
|
||||
end;
|
||||
|
||||
procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); jnicall;
|
||||
begin
|
||||
end;
|
||||
|
||||
function JNI_JStringToString( PEnv : PJNIEnv; JStr : JString ) : string;
|
||||
var
|
||||
IsCopy: PJBoolean;
|
||||
Chars: PAnsiChar;
|
||||
begin
|
||||
if JStr = nil then
|
||||
begin
|
||||
Result := '';
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Chars := PEnv^.GetStringUTFChars(PEnv, JStr, IsCopy);
|
||||
if Chars = nil then
|
||||
Result := ''
|
||||
else
|
||||
begin
|
||||
Result := string(Chars);
|
||||
PEnv^.ReleaseStringUTFChars(PEnv, JStr, Chars);
|
||||
end;
|
||||
end;
|
||||
|
||||
function JNI_StringToJString( PEnv : PJNIEnv; const AString : PAnsiChar ) : JString;
|
||||
begin
|
||||
Result := PEnv^.NewStringUTF( PEnv, PAnsiChar( AString ) );
|
||||
end;
|
||||
|
||||
end.
|
||||
785
UOS/src/uos_libsndfile.pas
Normal file
785
UOS/src/uos_libsndfile.pas
Normal file
@@ -0,0 +1,785 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading version with reference counting of LibSndFile.pas.
|
||||
Load the library with sf_load() and release with sf_unload().
|
||||
Thanks to Phoenix for sf_open_virtual (TMemoryStream as input)
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com }
|
||||
|
||||
unit uos_libsndfile;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKENUM 4}(* use 4-byte enums *)
|
||||
{$PACKRECORDS C}(* C/C++-compatible record packing *)
|
||||
{$MACRO ON}//don't know whatfor !
|
||||
{$ELSE}
|
||||
{$MINENUMSIZE 4}(* use 4-byte enums *)
|
||||
{** MINENUMSIZE is equivalent to Z+}
|
||||
{$ENDIF}
|
||||
|
||||
{$LONGSTRINGS ON}
|
||||
{** LONGSTRINGS is equivalent to H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs, classes,
|
||||
ctypes;
|
||||
|
||||
const
|
||||
libsf=
|
||||
{$IFDEF unix}
|
||||
{$IFDEF darwin}
|
||||
'libsndfile.1.dylib';
|
||||
{$ELSE}
|
||||
'libsndfile.so.1';
|
||||
{$ENDIF}
|
||||
{$ELSE}
|
||||
'sndfile.dll';
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
PMemoryStream = ^TMemoryStream;
|
||||
|
||||
type
|
||||
{$IF Defined(MSWINDOWS)}
|
||||
off_t = int64;
|
||||
{$ELSE}
|
||||
off_t = clonglong;
|
||||
size_t = culong;
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
//* Major formats. *//
|
||||
SF_FORMAT_WAV = $010000; // Microsoft WAV format (little endian default).
|
||||
SF_FORMAT_AIFF = $020000; // Apple/SGI AIFF format (big endian).
|
||||
SF_FORMAT_AU = $030000; // Sun/NeXT AU format (big endian).
|
||||
SF_FORMAT_RAW = $040000; // RAW PCM data.
|
||||
SF_FORMAT_PAF = $050000; // Ensoniq PARIS file format.
|
||||
SF_FORMAT_SVX = $060000; // Amiga IFF / SVX8 / SV16 format.
|
||||
SF_FORMAT_NIST = $070000; // Sphere NIST format.
|
||||
SF_FORMAT_VOC = $080000; // VOC files.
|
||||
SF_FORMAT_IRCAM = $0A0000; // Berkeley/IRCAM/CARL
|
||||
SF_FORMAT_W64 = $0B0000; // Sonic Foundry's 64 bit RIFF/WAV
|
||||
SF_FORMAT_MAT4 = $0C0000; // Matlab (tm) V4.2 / GNU Octave 2.0
|
||||
SF_FORMAT_MAT5 = $0D0000; // Matlab (tm) V5.0 / GNU Octave 2.1
|
||||
SF_FORMAT_PVF = $0E0000; // Portable Voice Format
|
||||
SF_FORMAT_XI = $0F0000; // Fasttracker 2 Extended Instrument
|
||||
SF_FORMAT_HTK = $100000; // HMM Tool Kit format
|
||||
SF_FORMAT_SDS = $110000; // Midi Sample Dump Standard
|
||||
SF_FORMAT_AVR = $120000; // Audio Visual Research
|
||||
SF_FORMAT_WAVEX = $130000; // MS WAVE with WAVEFORMATEX
|
||||
SF_FORMAT_SD2 = $160000; // Sound Designer 2
|
||||
SF_FORMAT_FLAC = $170000; // FLAC lossless file format
|
||||
SF_FORMAT_CAF = $180000; // Core Audio File format
|
||||
SF_FORMAT_OGG = $200000; // Xiph OGG container
|
||||
|
||||
|
||||
const
|
||||
//Subtypes from here on.
|
||||
SF_FORMAT_PCM_S8 = $0001; // Signed 8 bit data
|
||||
SF_FORMAT_PCM_16 = $0002; // Signed 16 bit data
|
||||
SF_FORMAT_PCM_24 = $0003; // Signed 24 bit data
|
||||
SF_FORMAT_PCM_32 = $0004; // Signed 32 bit data
|
||||
|
||||
SF_FORMAT_PCM_U8 = $0005; // Unsigned 8 bit data (WAV and RAW only)
|
||||
|
||||
SF_FORMAT_FLOAT = $0006; // 32 bit float data
|
||||
SF_FORMAT_DOUBLE = $0007; // 64 bit float data
|
||||
|
||||
SF_FORMAT_ULAW = $0010; // U-Law encoded.
|
||||
SF_FORMAT_ALAW = $0011; // A-Law encoded.
|
||||
SF_FORMAT_IMA_ADPCM = $0012; // IMA ADPCM.
|
||||
SF_FORMAT_MS_ADPCM = $0013; // Microsoft ADPCM.
|
||||
|
||||
SF_FORMAT_GSM610 = $0020; // GSM 6.10 encoding.
|
||||
SF_FORMAT_VOX_ADPCM = $0021; // OKI / Dialogix ADPCM
|
||||
|
||||
SF_FORMAT_G721_32 = $0030; // 32kbs G721 ADPCM encoding.
|
||||
SF_FORMAT_G723_24 = $0031; // 24kbs G723 ADPCM encoding.
|
||||
SF_FORMAT_G723_40 = $0032; // 40kbs G723 ADPCM encoding.
|
||||
|
||||
SF_FORMAT_DWVW_12 = $0040; // 12 bit Delta Width Variable Word encoding.
|
||||
SF_FORMAT_DWVW_16 = $0041; // 16 bit Delta Width Variable Word encoding.
|
||||
SF_FORMAT_DWVW_24 = $0042; // 24 bit Delta Width Variable Word encoding.
|
||||
SF_FORMAT_DWVW_N = $0043; // N bit Delta Width Variable Word encoding.
|
||||
|
||||
SF_FORMAT_DPCM_8 = $0050; // 8 bit differential PCM (XI only)
|
||||
SF_FORMAT_DPCM_16 = $0051; // 16 bit differential PCM (XI only)
|
||||
|
||||
SF_FORMAT_VORBIS = $0060; // Xiph Vorbis encoding.
|
||||
|
||||
|
||||
const
|
||||
//* Endian-ness options. *//
|
||||
SF_ENDIAN_FILE = $00000000; // Default file endian-ness.
|
||||
SF_ENDIAN_LITTLE = $10000000; // Force little endian-ness.
|
||||
SF_ENDIAN_BIG = $20000000; // Force big endian-ness.
|
||||
SF_ENDIAN_CPU = $30000000; // Force CPU endian-ness.
|
||||
|
||||
SF_FORMAT_SUBMASK = $0000FFFF;
|
||||
SF_FORMAT_TYPEMASK = $0FFF0000;
|
||||
SF_FORMAT_ENDMASK = $30000000;
|
||||
|
||||
{
|
||||
** The following are the valid command numbers for the sf_command()
|
||||
** interface. The use of these commands is documented in the file
|
||||
** command.html in the doc directory of the source code distribution.
|
||||
}
|
||||
const
|
||||
SFC_GET_LIB_VERSION = $1000;
|
||||
SFC_GET_LOG_INFO = $1001;
|
||||
|
||||
SFC_GET_NORM_DOUBLE = $1010;
|
||||
SFC_GET_NORM_FLOAT = $1011;
|
||||
SFC_SET_NORM_DOUBLE = $1012;
|
||||
SFC_SET_NORM_FLOAT = $1013;
|
||||
SFC_SET_SCALE_FLOAT_INT_READ = $1014;
|
||||
|
||||
SFC_GET_SIMPLE_FORMAT_COUNT = $1020;
|
||||
SFC_GET_SIMPLE_FORMAT = $1021;
|
||||
|
||||
SFC_GET_FORMAT_INFO = $1028;
|
||||
|
||||
SFC_GET_FORMAT_MAJOR_COUNT = $1030;
|
||||
SFC_GET_FORMAT_MAJOR = $1031;
|
||||
SFC_GET_FORMAT_SUBTYPE_COUNT = $1032;
|
||||
SFC_GET_FORMAT_SUBTYPE = $1033;
|
||||
|
||||
SFC_CALC_SIGNAL_MAX = $1040;
|
||||
SFC_CALC_NORM_SIGNAL_MAX = $1041;
|
||||
SFC_CALC_MAX_ALL_CHANNELS = $1042;
|
||||
SFC_CALC_NORM_MAX_ALL_CHANNELS = $1043;
|
||||
SFC_GET_SIGNAL_MAX = $1044;
|
||||
SFC_GET_MAX_ALL_CHANNELS = $1045;
|
||||
|
||||
SFC_SET_ADD_PEAK_CHUNK = $1050;
|
||||
|
||||
SFC_UPDATE_HEADER_NOW = $1060;
|
||||
SFC_SET_UPDATE_HEADER_AUTO = $1061;
|
||||
|
||||
SFC_FILE_TRUNCATE = $1080;
|
||||
|
||||
SFC_SET_RAW_START_OFFSET = $1090;
|
||||
|
||||
SFC_SET_DITHER_ON_WRITE = $10A0;
|
||||
SFC_SET_DITHER_ON_READ = $10A1;
|
||||
|
||||
SFC_GET_DITHER_INFO_COUNT = $10A2;
|
||||
SFC_GET_DITHER_INFO = $10A3;
|
||||
|
||||
SFC_GET_EMBED_FILE_INFO = $10B0;
|
||||
|
||||
SFC_SET_CLIPPING = $10C0;
|
||||
SFC_GET_CLIPPING = $10C1;
|
||||
|
||||
SFC_GET_INSTRUMENT = $10D0;
|
||||
SFC_SET_INSTRUMENT = $10D1;
|
||||
|
||||
SFC_GET_LOOP_INFO = $10E0;
|
||||
|
||||
SFC_GET_BROADCAST_INFO = $10F0;
|
||||
SFC_SET_BROADCAST_INFO = $10F1;
|
||||
|
||||
// Following commands for testing only.
|
||||
SFC_TEST_IEEE_FLOAT_REPLACE = $6001;
|
||||
|
||||
{
|
||||
** SFC_SET_ADD_* values are deprecated and will disappear at some
|
||||
** time in the future. They are guaranteed to be here up to and
|
||||
** including version 1.0.8 to avoid breakage of existing software.
|
||||
** They currently do nothing and will continue to do nothing.
|
||||
}
|
||||
SFC_SET_ADD_DITHER_ON_WRITE = $1070;
|
||||
SFC_SET_ADD_DITHER_ON_READ = $1071;
|
||||
|
||||
{
|
||||
** String types that can be set and read from files. Not all file types
|
||||
** support this and even the file types which support one, may not support
|
||||
** all string types.
|
||||
}
|
||||
const
|
||||
SF_STR_TITLE = $01;
|
||||
SF_STR_COPYRIGHT = $02;
|
||||
SF_STR_SOFTWARE = $03;
|
||||
SF_STR_ARTIST = $04;
|
||||
SF_STR_COMMENT = $05;
|
||||
SF_STR_DATE = $06;
|
||||
SF_STR_ALBUM = $07;
|
||||
SF_STR_LICENSE = $08;
|
||||
SF_STR_TRACKNUMBER = $09;
|
||||
SF_STR_GENRE = $10;
|
||||
|
||||
{
|
||||
** Use the following as the start and end index when doing metadata
|
||||
** transcoding.
|
||||
}
|
||||
SF_STR_FIRST = SF_STR_TITLE;
|
||||
SF_STR_LAST = SF_STR_GENRE;
|
||||
|
||||
const
|
||||
// True and false
|
||||
SF_FALSE = 0;
|
||||
SF_TRUE = 1;
|
||||
|
||||
const
|
||||
// Modes for opening files.
|
||||
SFM_READ = $10;
|
||||
SFM_WRITE = $20;
|
||||
SFM_RDWR = $30;
|
||||
|
||||
{
|
||||
** Public error values. These are guaranteed to remain unchanged
|
||||
** for the duration of the library major version number.
|
||||
** There are also a large number of private error numbers which are
|
||||
** internal to the library which can change at any time.
|
||||
}
|
||||
const
|
||||
SF_ERR_NO_ERROR = 0;
|
||||
SF_ERR_UNRECOGNISED_FORMAT = 1;
|
||||
SF_ERR_SYSTEM = 2;
|
||||
SF_ERR_MALFORMED_FILE = 3;
|
||||
SF_ERR_UNSUPPORTED_ENCODING = 4;
|
||||
|
||||
//A SNDFILE* pointer can be passed around much like stdio.h's FILE* pointer.
|
||||
|
||||
type
|
||||
TSNDFILE_HANDLE = pointer; // this is not a usual pointer, more like a THandle ..
|
||||
// so NOT called "PSndFile_handle"
|
||||
// => we never access members of the internal
|
||||
// structure where the pointer points to !
|
||||
// Everything is managed by the DLL internally !!!
|
||||
//PSNDFILE_tag = PSNDFILE;
|
||||
|
||||
{
|
||||
** The following typedef is system specific and is defined when libsndfile is.
|
||||
** compiled. uos_count_t can be one of loff_t (Linux), off_t (*BSD),
|
||||
** off64_t (Solaris), __int64_t (Win32) etc.
|
||||
}
|
||||
type
|
||||
Puos_count_t = ^Tuos_count_t;
|
||||
Tuos_count_t = off_t;
|
||||
|
||||
const
|
||||
SF_COUNT_MAX = ctypes.clonglong($7FFFFFFFFFFFFFFF);
|
||||
|
||||
{
|
||||
** A pointer to a SF_INFO structure is passed to sf_open_read () and filled in.
|
||||
** On write, the SF_INFO structure is filled in by the user and passed into
|
||||
** sf_open_write ().
|
||||
}
|
||||
|
||||
type
|
||||
PSF_INFO = ^TSF_INFO;
|
||||
|
||||
TSF_INFO = record
|
||||
frames: Tuos_count_t;
|
||||
// Used to be called samples. Changed to avoid confusion.
|
||||
samplerate: ctypes.cint;
|
||||
channels: ctypes.cint;
|
||||
format: ctypes.cint;
|
||||
sections: ctypes.cint;
|
||||
seekable: ctypes.cint;
|
||||
end;
|
||||
|
||||
{
|
||||
** The SF_FORMAT_INFO struct is used to retrieve information about the sound
|
||||
** file formats libsndfile supports using the sf_command () interface.
|
||||
**
|
||||
** Using this interface will allow applications to support new file formats
|
||||
** and encoding types when libsndfile is upgraded, without requiring
|
||||
** re-compilation of the application.
|
||||
**
|
||||
** Please consult the libsndfile documentation (particularly the information
|
||||
** on the sf_command () interface) for examples of its use.
|
||||
}
|
||||
|
||||
type
|
||||
PSF_FORMAT_INFO = ^TSF_FORMAT_INFO;
|
||||
|
||||
TSF_FORMAT_INFO = record
|
||||
format: ctypes.cint;
|
||||
Name: ctypes.pcchar;
|
||||
extention: ctypes.pcchar;
|
||||
end;
|
||||
|
||||
{
|
||||
** Enums and typedefs for adding dither on read and write.
|
||||
** See the html documentation for sf_command(), SFC_SET_DITHER_ON_WRITE
|
||||
** and SFC_SET_DITHER_ON_READ.
|
||||
}
|
||||
const
|
||||
SFD_DEFAULT_LEVEL = 0;
|
||||
SFD_CUSTOM_LEVEL = $40000000;
|
||||
|
||||
SFD_NO_DITHER = 500;
|
||||
SFD_WHITE = 501;
|
||||
SFD_TRIANGULAR_PDF = 502;
|
||||
|
||||
type
|
||||
PSF_DITHER_INFO = ^TSF_DITHER_INFO;
|
||||
|
||||
TSF_DITHER_INFO = record
|
||||
type_: ctypes.cint;
|
||||
level: ctypes.cdouble;
|
||||
Name: ctypes.pcchar;
|
||||
end;
|
||||
|
||||
{
|
||||
** Struct used to retrieve information about a file embedded within a
|
||||
** larger file. See SFC_GET_EMBED_FILE_INFO.
|
||||
}
|
||||
type
|
||||
PSF_EMBED_FILE_INFO = ^TSF_EMBED_FILE_INFO;
|
||||
|
||||
TSF_EMBED_FILE_INFO = record
|
||||
offset: Tuos_count_t;
|
||||
length: Tuos_count_t;
|
||||
end;
|
||||
|
||||
// Structs used to retrieve music sample information from a file.
|
||||
|
||||
const
|
||||
// The loop mode field in SF_INSTRUMENT will be one of the following.
|
||||
SF_LOOP_NONE = 800;
|
||||
SF_LOOP_FORWARD = 801;
|
||||
SF_LOOP_BACKWARD = 802;
|
||||
SF_LOOP_ALTERNATING = 803;
|
||||
|
||||
type
|
||||
PSF_INSTRUMENT = ^TSF_INSTRUMENT;
|
||||
|
||||
TSF_INSTRUMENT = record
|
||||
gain: ctypes.cint;
|
||||
basenote,
|
||||
detune: ctypes.cchar;
|
||||
velocity_lo,
|
||||
velocity_hi: ctypes.cchar;
|
||||
loop_count: ctypes.cint;
|
||||
loops: array[0..15] of record
|
||||
mode: ctypes.cint;
|
||||
start: ctypes.cuint;
|
||||
end_: ctypes.cuint;
|
||||
Count: ctypes.cuint;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Struct used to retrieve loop information from a file.
|
||||
type
|
||||
PSF_LOOP_INFO = ^TSF_LOOP_INFO;
|
||||
|
||||
TSF_LOOP_INFO = record
|
||||
time_sig_num: ctypes.cushort;
|
||||
// any positive integer > 0
|
||||
time_sig_den: ctypes.cushort;
|
||||
// any positive power of 2 > 0
|
||||
loop_mode: ctypes.cint; // see SF_LOOP enum
|
||||
|
||||
num_beats: ctypes.cint;
|
||||
// this is NOT the amount of quarter notes !!!
|
||||
// a full bar of 4/4 is 4 beats
|
||||
// a full bar of 7/8 is 7 beats
|
||||
|
||||
bpm: ctypes.cfloat;
|
||||
// suggestion, as it can be calculated using other fields:
|
||||
// file's lenght, file's sampleRate and our time_sig_den
|
||||
// -> bpms are always the amount of _quarter notes_ per minute
|
||||
|
||||
root_key: ctypes.cint;
|
||||
// MIDI note, or -1 for None
|
||||
future: array[0..5] of ctypes.cint;
|
||||
end;
|
||||
|
||||
|
||||
{
|
||||
** Struct used to retrieve broadcast (EBU) information from a file.
|
||||
** Strongly (!) based on EBU "bext" chunk format used in Broadcast WAVE.
|
||||
}
|
||||
type
|
||||
PSF_BROADCAST_INFO = ^TSF_BROADCAST_INFO;
|
||||
|
||||
TSF_BROADCAST_INFO = record
|
||||
description: array[0..255] of char;//ctypes.cchar;
|
||||
originator: array[0..31] of char;//ctypes.cchar;
|
||||
originator_reference: array[0..31] of char;//ctypes.cchar;
|
||||
origination_date: array[0..9] of char;//ctypes.cchar;
|
||||
origination_time: array[0..7] of char;//ctypes.cchar;
|
||||
time_reference_low: ctypes.cuint;//ctypes.cint;
|
||||
time_reference_high: ctypes.cuint;//ctypes.cint;
|
||||
version: ctypes.cshort;
|
||||
umid: array[0..63] of char;//ctypes.cchar;
|
||||
reserved: array[0..189] of char;//ctypes.cchar;
|
||||
coding_history_size: ctypes.cuint;
|
||||
coding_history: array[0..255] of char;//ctypes.cchar;
|
||||
end;
|
||||
|
||||
// Thanks to Phoenix
|
||||
type
|
||||
//pm_get_filelen = ^tm_get_filelen;
|
||||
tm_get_filelen =
|
||||
function (pms: PMemoryStream): Tuos_count_t; cdecl;
|
||||
//pm_seek = ^tm_seek;
|
||||
tm_seek =
|
||||
function (offset: Tuos_count_t; whence: cint32; pms: PMemoryStream): Tuos_count_t; cdecl;
|
||||
//pm_read = ^tm_read;
|
||||
tm_read =
|
||||
function (const buf: Pointer; count: Tuos_count_t; pms: PMemoryStream): Tuos_count_t; cdecl;
|
||||
//pm_write = ^tm_write;
|
||||
tm_write =
|
||||
function (const buf: Pointer; count: Tuos_count_t; pms: PMemoryStream): Tuos_count_t; cdecl;
|
||||
//pm_tell = ^tm_tell;
|
||||
tm_tell =
|
||||
function (pms: PMemoryStream): Tuos_count_t; cdecl;
|
||||
|
||||
TSF_VIRTUAL = packed record
|
||||
sf_vio_get_filelen : tm_get_filelen;
|
||||
seek : tm_seek;
|
||||
read : tm_read;
|
||||
write : tm_write;
|
||||
tell : tm_tell;
|
||||
end;
|
||||
|
||||
PSF_VIRTUAL = ^TSF_VIRTUAL;
|
||||
|
||||
{
|
||||
** Open the specified file for read, write or both. On error, this will
|
||||
** return a NULL pointer. To find the error number, pass a NULL SNDFILE
|
||||
** to sf_perror () or sf_error_str ().
|
||||
** All calls to sf_open() should be matched with a call to sf_close().
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function sf_open(path: string; mode: ctypes.cint;
|
||||
var sfinfo: TSF_INFO): TSNDFILE_HANDLE;
|
||||
|
||||
////// Dynamic load : Vars that will hold our dynamically loaded functions..
|
||||
var
|
||||
sf_open_native: function(path: PChar;
|
||||
mode: ctypes.cint; sfinfo: PSF_INFO): TSNDFILE_HANDLE; cdecl;
|
||||
|
||||
var
|
||||
sf_version_string: function(): PChar; cdecl;
|
||||
|
||||
var
|
||||
sf_open_fd: function(fd: ctypes.cint; mode: ctypes.cint; sfinfo: PSF_INFO;
|
||||
close_desc: ctypes.cint): TSNDFILE_HANDLE; cdecl;
|
||||
|
||||
var
|
||||
sf_open_virtual: function(sfvirtual: PSF_VIRTUAL; mode: ctypes.cint;
|
||||
sfinfo: PSF_INFO; user_data: Pointer): TSNDFILE_HANDLE; cdecl;
|
||||
|
||||
var
|
||||
sf_error: function(sndfile: TSNDFILE_HANDLE): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_strerror: function(sndfile: TSNDFILE_HANDLE): PChar; cdecl;
|
||||
|
||||
var
|
||||
sf_error_number: function(errnum: ctypes.cint): PChar; cdecl;
|
||||
|
||||
var
|
||||
sf_perror: function(sndfile: TSNDFILE_HANDLE): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_error_str: function(sndfile: TSNDFILE_HANDLE;
|
||||
str: ctypes.pcchar; len: size_t): ctypes.cint; cdecl;
|
||||
|
||||
{
|
||||
In libsndfile there are 4 functions with the same name (sf_command), 3 of them use the parameter "overload".
|
||||
In dynamic loading (because of var) we use 4 different names for the 4 functions sf_command :
|
||||
sf_command_pointer, sf_command_double, sf_command_array, sf_command_tsf. All that 4 functions gonna point
|
||||
to sf_command in libsndfile library.
|
||||
}
|
||||
|
||||
var
|
||||
sf_command_pointer: function(sndfile: TSNDFILE_HANDLE; command: ctypes.cint;
|
||||
Data: Pointer; datasize: ctypes.cint): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_command_double: function(sndfile: TSNDFILE_HANDLE; command: ctypes.cint;
|
||||
var Data: double; datasize: ctypes.cint): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_command_array: function(sndfile: TSNDFILE_HANDLE; command: ctypes.cint;
|
||||
var Data: array of char; datasize: ctypes.cint): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_command_tsf: function(sndfile: TSNDFILE_HANDLE; command: ctypes.cint;
|
||||
var Data: TSF_BROADCAST_INFO; datasize: ctypes.cint): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_format_check: function(var info: TSF_INFO): ctypes.cint; cdecl;
|
||||
|
||||
{
|
||||
** Seek within the waveform data chunk of the SNDFILE. sf_seek () uses
|
||||
** the same values for whence (SEEK_SET, SEEK_CUR and SEEK_END) as
|
||||
** stdio.h function fseek ().
|
||||
** An offset of zero with whence set to SEEK_SET will position the
|
||||
** read / write pointer to the first data sample.
|
||||
** On success sf_seek returns the current position in (multi-channel)
|
||||
** samples from the start of the file.
|
||||
** Please see the libsndfile documentation for moving the read pointer
|
||||
** separately from the write pointer on files open in mode SFM_RDWR.
|
||||
** On error all of these functions return -1.
|
||||
}
|
||||
|
||||
//the following CONST values originally are NOT in libsndfile.pas:
|
||||
const
|
||||
SEEK_SET = 0; //* seek relative to beginning of file */
|
||||
|
||||
const
|
||||
SEEK_CUR = 1; //* seek relative to current file position */
|
||||
|
||||
const
|
||||
SEEK_END = 2; //* seek relative to end of file */
|
||||
|
||||
const
|
||||
SEEK_DATA = 3; //* seek to the next data */
|
||||
|
||||
const
|
||||
SEEK_HOLE = 4; //* seek to the next hole */
|
||||
|
||||
const
|
||||
SEEK_MAX = SEEK_HOLE;
|
||||
|
||||
var
|
||||
sf_seek: function(sndfile: TSNDFILE_HANDLE; frame: Tuos_count_t;
|
||||
whence: ctypes.cint): Tuos_count_t; cdecl;
|
||||
|
||||
{
|
||||
** Functions for retrieving and setting string data within sound files.
|
||||
** Not all file types support this features; AIFF and WAV do. For both
|
||||
** functions, the str_type parameter must be one of the SF_STR_* values
|
||||
** defined above.
|
||||
** On error, sf_set_string() returns non-zero while sf_get_string()
|
||||
** returns NULL.
|
||||
}
|
||||
var
|
||||
sf_set_string: function(sndfile: TSNDFILE_HANDLE; str_type: ctypes.cint;
|
||||
str: ctypes.pcchar): ctypes.cint; cdecl;
|
||||
|
||||
var
|
||||
sf_get_string: function(sndfile: TSNDFILE_HANDLE;
|
||||
str_type: ctypes.cint): PChar; cdecl;
|
||||
|
||||
var
|
||||
sf_read_raw: function(sndfile: TSNDFILE_HANDLE; ptr: Pointer;
|
||||
bytes: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_write_raw: function(sndfile: TSNDFILE_HANDLE; ptr: Pointer;
|
||||
bytes: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
{
|
||||
** Functions for reading and writing the data chunk in terms of frames.
|
||||
** The number of items actually read/written = frames * number of channels.
|
||||
** sf_xxxx_raw read/writes the raw data bytes from/to the file
|
||||
** sf_xxxx_short passes data in the native short format
|
||||
** sf_xxxx_int passes data in the native int format
|
||||
** sf_xxxx_float passes data in the native float format
|
||||
** sf_xxxx_double passes data in the native double format
|
||||
** All of these read/write function return number of frames read/written.
|
||||
}
|
||||
var
|
||||
sf_readf_short: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcshort;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_writef_short: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcshort;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_readf_int: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcint;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_writef_int: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcint;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_readf_float: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcfloat;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_writef_float: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcfloat;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_readf_double: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcdouble;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_writef_double: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcdouble;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
{
|
||||
** Functions for reading and writing the data chunk in terms of items.
|
||||
** Otherwise similar to above.
|
||||
** All of these read/write function return number of items read/written.
|
||||
}
|
||||
var
|
||||
sf_read_short: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcshort;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_write_short: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcshort;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_read_int: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcint;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_write_int: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcint;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_read_float: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcfloat;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_write_float: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcfloat;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_read_double: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcdouble;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
var
|
||||
sf_write_double: function(sndfile: TSNDFILE_HANDLE; ptr: ctypes.pcdouble;
|
||||
frames: Tuos_count_t): Tuos_count_t; cdecl;
|
||||
|
||||
{
|
||||
** Close the SNDFILE and clean up all memory allocations associated
|
||||
** with this file.
|
||||
** Returns 0 on success, or an error number.
|
||||
}
|
||||
var
|
||||
sf_close: function(sndfile: TSNDFILE_HANDLE): ctypes.cint; cdecl;
|
||||
|
||||
{
|
||||
** If the file is opened SFM_WRITE or SFM_RDWR, call fsync() on the file
|
||||
** to force the writing of data to disk. If the file is opened SFM_READ
|
||||
** no action is taken.
|
||||
}
|
||||
var
|
||||
sf_write_sync: function(sndfile: TSNDFILE_HANDLE): ctypes.cint; cdecl;
|
||||
|
||||
{Special function for dynamic loading of lib ...}
|
||||
|
||||
var
|
||||
sf_Handle: TLibHandle;
|
||||
// this will hold our handle for the lib; it functions nicely as a mutli-lib prevention unit as well...
|
||||
|
||||
function sf_Load(const libfilename: string): boolean; // load the lib
|
||||
|
||||
procedure sf_Unload();
|
||||
// unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
function sf_IsLoaded: boolean;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
ReferenceCounter: cardinal = 0; // Reference counter
|
||||
|
||||
function sf_Load(const libfilename: string): boolean;
|
||||
var
|
||||
thelib: string;
|
||||
begin
|
||||
Result := False;
|
||||
if sf_Handle <> 0 then
|
||||
begin
|
||||
Result := True {is it already there ?};
|
||||
//Reference counting
|
||||
Inc(ReferenceCounter);
|
||||
end
|
||||
else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then thelib := libsf else thelib := libfilename;
|
||||
sf_Handle := DynLibs.SafeLoadLibrary(thelib); // obtain the handle we want
|
||||
if sf_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
|
||||
Pointer(sf_version_string) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_version_string'));
|
||||
Pointer(sf_open_native) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_open'));
|
||||
Pointer(sf_open_fd) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_open_fd'));
|
||||
Pointer(sf_open_virtual) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_open_virtual'));
|
||||
Pointer(sf_error) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_error'));
|
||||
Pointer(sf_strerror) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_strerror'));
|
||||
Pointer(sf_error_number) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_error_number'));
|
||||
Pointer(sf_perror) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_perror'));
|
||||
Pointer(sf_error_str) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_error_str'));
|
||||
Pointer(sf_command_pointer) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_command'));
|
||||
Pointer(sf_command_array) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_command'));
|
||||
Pointer(sf_command_double) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_command'));
|
||||
Pointer(sf_command_tsf) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_command'));
|
||||
Pointer(sf_format_check) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_format_check'));
|
||||
Pointer(sf_seek) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_seek'));
|
||||
Pointer(sf_set_string) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_set_string'));
|
||||
Pointer(sf_get_string) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_get_string'));
|
||||
Pointer(sf_read_raw) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_read_raw'));
|
||||
Pointer(sf_write_raw) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_write_raw'));
|
||||
Pointer(sf_readf_short) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_readf_short'));
|
||||
Pointer(sf_writef_short) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_writef_short'));
|
||||
Pointer(sf_readf_int) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_readf_int'));
|
||||
Pointer(sf_writef_int) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_writef_int'));
|
||||
Pointer(sf_readf_float) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_readf_float'));
|
||||
Pointer(sf_writef_float) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_writef_float'));
|
||||
Pointer(sf_readf_double) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_readf_double'));
|
||||
Pointer(sf_writef_double) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_writef_double'));
|
||||
Pointer(sf_read_short) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_read_short'));
|
||||
Pointer(sf_write_short) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_write_short'));
|
||||
Pointer(sf_read_int) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_read_int'));
|
||||
Pointer(sf_write_int) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_write_int'));
|
||||
Pointer(sf_read_float) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_read_float'));
|
||||
Pointer(sf_write_float) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_write_float'));
|
||||
Pointer(sf_read_double) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_read_double'));
|
||||
Pointer(sf_write_double) := DynLibs.GetProcedureAddress(
|
||||
sf_Handle, PChar('sf_write_double'));
|
||||
Pointer(sf_close) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_close'));
|
||||
Pointer(sf_write_sync) := DynLibs.GetProcedureAddress(sf_Handle, PChar('sf_write_sync'));
|
||||
|
||||
end;
|
||||
Result := sf_IsLoaded;
|
||||
ReferenceCounter := 1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure sf_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
Dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if sf_IsLoaded then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(sf_Handle);
|
||||
sf_Handle := DynLibs.NilHandle;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function sf_open(path: string; mode: ctypes.cint;
|
||||
var sfinfo: TSF_INFO): TSNDFILE_HANDLE;
|
||||
begin
|
||||
Result := sf_open_native(PChar(path), mode, @sfinfo);
|
||||
end;
|
||||
|
||||
function sf_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (sf_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
end.
|
||||
428
UOS/src/uos_libxmp.pas
Normal file
428
UOS/src/uos_libxmp.pas
Normal file
@@ -0,0 +1,428 @@
|
||||
unit uos_libxmp;
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Pascal Wrapper + Dynamic loading of libxmp library.
|
||||
Load library with xmp_load() and release with xmp_unload().
|
||||
License : modified LGPL.
|
||||
by Fred vS | fiens@hotmail.com | 2024}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs,
|
||||
sysutils,
|
||||
CTypes;
|
||||
|
||||
const
|
||||
XMP_VERSION = '4.6.0';
|
||||
XMP_VERCODE = $040600;
|
||||
XMP_VER_MAJOR = 4;
|
||||
XMP_VER_MINOR = 6;
|
||||
XMP_VER_RELEASE = 0;
|
||||
|
||||
const
|
||||
{$IFDEF windows}
|
||||
XMP_LIB_NAME = 'libxmp.dll';
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF unix}
|
||||
{$IFDEF darwin}
|
||||
XMP_LIB_NAME = 'libxmp.dylib';
|
||||
{$ELSE}
|
||||
XMP_LIB_NAME = 'libxmp.so.4.6.0';
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
XMP_NAME_SIZE = 64;
|
||||
|
||||
// Note event constants
|
||||
XMP_KEY_OFF = $81;
|
||||
XMP_KEY_CUT = $82;
|
||||
XMP_KEY_FADE = $83;
|
||||
|
||||
// Sample format flags
|
||||
XMP_FORMAT_8BIT = 1 shl 0;
|
||||
XMP_FORMAT_UNSIGNED = 1 shl 1;
|
||||
XMP_FORMAT_MONO = 1 shl 2;
|
||||
|
||||
// Player parameters
|
||||
XMP_PLAYER_AMP = 0;
|
||||
XMP_PLAYER_MIX = 1;
|
||||
XMP_PLAYER_INTERP = 2;
|
||||
XMP_PLAYER_DSP = 3;
|
||||
XMP_PLAYER_FLAGS = 4;
|
||||
XMP_PLAYER_CFLAGS = 5;
|
||||
XMP_PLAYER_SMPCTL = 6;
|
||||
XMP_PLAYER_VOLUME = 7;
|
||||
XMP_PLAYER_STATE = 8;
|
||||
XMP_PLAYER_SMIX_VOLUME = 9;
|
||||
XMP_PLAYER_DEFPAN = 10;
|
||||
XMP_PLAYER_MODE = 11;
|
||||
XMP_PLAYER_MIXER_TYPE = 12;
|
||||
XMP_PLAYER_VOICES = 13;
|
||||
|
||||
// Interpolation types
|
||||
XMP_INTERP_NEAREST = 0;
|
||||
XMP_INTERP_LINEAR = 1;
|
||||
XMP_INTERP_SPLINE = 2;
|
||||
|
||||
// DSP effect types
|
||||
XMP_DSP_LOWPASS = 1 shl 0;
|
||||
XMP_DSP_ALL = XMP_DSP_LOWPASS;
|
||||
|
||||
// Player state
|
||||
XMP_STATE_UNLOADED = 0;
|
||||
XMP_STATE_LOADED = 1;
|
||||
XMP_STATE_PLAYING = 2;
|
||||
|
||||
// Player flags
|
||||
XMP_FLAGS_VBLANK = 1 shl 0;
|
||||
XMP_FLAGS_FX9BUG = 1 shl 1;
|
||||
XMP_FLAGS_FIXLOOP = 1 shl 2;
|
||||
XMP_FLAGS_A500 = 1 shl 3;
|
||||
|
||||
// Player modes
|
||||
XMP_MODE_AUTO = 0;
|
||||
XMP_MODE_MOD = 1;
|
||||
XMP_MODE_NOISETRACKER = 2;
|
||||
XMP_MODE_PROTRACKER = 3;
|
||||
XMP_MODE_S3M = 4;
|
||||
XMP_MODE_ST3 = 5;
|
||||
XMP_MODE_ST3GUS = 6;
|
||||
XMP_MODE_XM = 7;
|
||||
XMP_MODE_FT2 = 8;
|
||||
XMP_MODE_IT = 9;
|
||||
XMP_MODE_ITSMP = 10;
|
||||
|
||||
// Mixer types
|
||||
XMP_MIXER_STANDARD = 0;
|
||||
XMP_MIXER_A500 = 1;
|
||||
XMP_MIXER_A500F = 2;
|
||||
|
||||
// Sample flags
|
||||
XMP_SMPCTL_SKIP = 1 shl 0;
|
||||
|
||||
// Limits
|
||||
XMP_MAX_KEYS = 121;
|
||||
XMP_MAX_ENV_POINTS = 32;
|
||||
XMP_MAX_MOD_LENGTH = 256;
|
||||
XMP_MAX_CHANNELS = 64;
|
||||
XMP_MAX_SRATE = 49170;
|
||||
XMP_MIN_SRATE = 4000;
|
||||
XMP_MIN_BPM = 20;
|
||||
XMP_MAX_FRAMESIZE = 5 * XMP_MAX_SRATE * 2 div XMP_MIN_BPM;
|
||||
|
||||
// Error codes
|
||||
XMP_END = 1;
|
||||
XMP_ERROR_INTERNAL = 2;
|
||||
XMP_ERROR_FORMAT = 3;
|
||||
XMP_ERROR_LOAD = 4;
|
||||
XMP_ERROR_DEPACK = 5;
|
||||
XMP_ERROR_SYSTEM = 6;
|
||||
XMP_ERROR_INVALID = 7;
|
||||
XMP_ERROR_STATE = 8;
|
||||
|
||||
type
|
||||
xmp_context = PChar;
|
||||
|
||||
type
|
||||
xmp_channel = record
|
||||
pan: integer; // Pan de canal (0x80 centrum)
|
||||
vol: integer; // Volume of canal
|
||||
flg: integer; // Flags of canal
|
||||
end;
|
||||
|
||||
xmp_pattern = record
|
||||
rows: integer;
|
||||
index: array[1..1] of integer;
|
||||
end;
|
||||
|
||||
xmp_event = record
|
||||
note: byte;
|
||||
ins: byte;
|
||||
vol: byte;
|
||||
fxt: byte;
|
||||
fxp: byte;
|
||||
f2t: byte;
|
||||
f2p: byte;
|
||||
_flag: byte;
|
||||
end;
|
||||
|
||||
xmp_track = record
|
||||
rows: integer;
|
||||
event: array[1..1] of xmp_event;
|
||||
end;
|
||||
|
||||
xmp_envelope = record
|
||||
flg: integer;
|
||||
npt: integer;
|
||||
scl: integer;
|
||||
sus: integer;
|
||||
sue: integer;
|
||||
lps: integer;
|
||||
lpe: integer;
|
||||
Data: array[1..XMP_MAX_ENV_POINTS * 2] of smallint;
|
||||
end;
|
||||
|
||||
xmp_subinstrument = record
|
||||
vol: integer;
|
||||
gvl: integer;
|
||||
pan: integer;
|
||||
xpo: integer;
|
||||
fin: integer;
|
||||
vwf: integer;
|
||||
vde: integer;
|
||||
vra: integer;
|
||||
vsw: integer;
|
||||
rvv: integer;
|
||||
sid: integer;
|
||||
nna: integer;
|
||||
dct: integer;
|
||||
dca: integer;
|
||||
ifc: integer;
|
||||
ifr: integer;
|
||||
end;
|
||||
|
||||
xmp_instrument = record
|
||||
Name: array[0..31] of char;
|
||||
vol: integer;
|
||||
nsm: integer;
|
||||
rls: integer;
|
||||
aei: xmp_envelope;
|
||||
pei: xmp_envelope;
|
||||
fei: xmp_envelope;
|
||||
map: array[0..XMP_MAX_KEYS] of record
|
||||
ins: byte;
|
||||
xpo: shortint;
|
||||
end;
|
||||
sub: ^xmp_subinstrument;
|
||||
extra: Pointer;
|
||||
end;
|
||||
|
||||
xmp_sample = record
|
||||
Name: array[0..31] of char;
|
||||
len: integer;
|
||||
lps: integer;
|
||||
lpe: integer;
|
||||
flg: integer;
|
||||
Data: PByte;
|
||||
end;
|
||||
|
||||
xmp_sequence = record
|
||||
entry_point: integer;
|
||||
duration: integer;
|
||||
end;
|
||||
|
||||
xmp_module = record
|
||||
Name: array[0..XMP_NAME_SIZE - 1] of char;
|
||||
typ: array[0..XMP_NAME_SIZE - 1] of char;
|
||||
pat: integer;
|
||||
trk: integer;
|
||||
chn: integer;
|
||||
ins: integer;
|
||||
smp: integer;
|
||||
spd: integer;
|
||||
bpm: integer;
|
||||
len: integer;
|
||||
rst: integer;
|
||||
gvl: integer;
|
||||
xxp: ^xmp_pattern;
|
||||
xxt: ^xmp_track;
|
||||
xxi: ^xmp_instrument;
|
||||
xxs: ^xmp_sample;
|
||||
xxc: array[0..XMP_MAX_CHANNELS - 1] of xmp_channel;
|
||||
xxo: array[0..XMP_MAX_MOD_LENGTH] of byte;
|
||||
end;
|
||||
|
||||
xmp_test_info = record
|
||||
Name: array[0..XMP_NAME_SIZE - 1] of char;
|
||||
type_: array[0..XMP_NAME_SIZE - 1] of char;
|
||||
end;
|
||||
|
||||
xmp_module_info = record
|
||||
md5: array[0..15] of byte;
|
||||
vol_base: integer;
|
||||
module: ^xmp_module;
|
||||
comment: PChar;
|
||||
num_sequences: integer;
|
||||
seq_data: ^xmp_sequence;
|
||||
end;
|
||||
|
||||
xmp_channel_info = record
|
||||
period: longword;
|
||||
position: longword;
|
||||
pitchbend: smallint;
|
||||
note: byte;
|
||||
instrument: byte;
|
||||
sample: byte;
|
||||
volume: byte;
|
||||
pan: byte;
|
||||
reserved: byte;
|
||||
event: xmp_event;
|
||||
end;
|
||||
|
||||
xmp_frame_info = record
|
||||
pos: integer;
|
||||
pattern: integer;
|
||||
row: integer;
|
||||
num_rows: integer;
|
||||
frame: integer;
|
||||
speed: integer;
|
||||
bpm: integer;
|
||||
time: integer;
|
||||
total_time: integer;
|
||||
frame_time: integer;
|
||||
buffer: Pointer;
|
||||
buffer_size: integer;
|
||||
total_size: integer;
|
||||
volume: integer;
|
||||
loop_count: integer;
|
||||
virt_channels: integer;
|
||||
virt_used: integer;
|
||||
sequence: integer;
|
||||
channel_info: array[0..XMP_MAX_CHANNELS - 1] of xmp_channel_info;
|
||||
end;
|
||||
|
||||
xmp_callbacks = record
|
||||
read_func: function(dest: Pointer; len, nmemb: longword; priv: Pointer): longword;
|
||||
seek_func: function(priv: Pointer; offset: longint; whence: integer): integer;
|
||||
tell_func: function(priv: Pointer): longint;
|
||||
close_func: function(priv: Pointer): integer;
|
||||
end;
|
||||
|
||||
{ Dynamic load : Vars that will hold our dynamically loaded functions...
|
||||
|
||||
*************************** functions ******************************* }
|
||||
|
||||
var
|
||||
xmp_create_context: function: pointer; cdecl;
|
||||
xmp_free_context: procedure(ctx: Pointer); cdecl;
|
||||
xmp_load_module: function(ctx: Pointer; const filename: PChar): Integer; cdecl;
|
||||
xmp_load_module_from_memory: function(ctx: xmp_context; const Data: Pointer; size: longint): integer; cdecl;
|
||||
xmp_load_module_from_file: function(ctx: xmp_context; file_: Pointer; size: longint): integer; cdecl;
|
||||
xmp_load_module_from_callbacks: function(ctx: xmp_context; file_: Pointer; callbacks: xmp_callbacks): integer; cdecl;
|
||||
xmp_test_module: function(const filename: PChar; info: xmp_test_info): Integer; cdecl;
|
||||
xmp_release_module: procedure(ctx: xmp_context); cdecl;
|
||||
xmp_start_player: function(ctx: xmp_context; rate: Integer; flags: Integer): Integer; cdecl;
|
||||
xmp_play_buffer: function(ctx: xmp_context; buffer: Pointer; size: Integer; loop: Integer): Integer; cdecl;
|
||||
xmp_get_frame_info: procedure(ctx: xmp_context; var info: xmp_frame_info); cdecl;
|
||||
xmp_end_player: procedure(ctx: xmp_context); cdecl;
|
||||
xmp_get_module_info: procedure(ctx: xmp_context; var info: xmp_module_info); cdecl;
|
||||
xmp_get_format_list: function(): PAnsiChar; cdecl;
|
||||
xmp_stop_module: procedure(ctx: xmp_context); cdecl;
|
||||
xmp_restart_module: procedure(ctx: xmp_context); cdecl;
|
||||
xmp_channel_vol: function(ctx: xmp_context; channel: Integer; volume: Integer): Integer; cdecl;
|
||||
xmp_set_player: function(ctx: xmp_context; param: Integer; value: Integer): Integer; cdecl;
|
||||
|
||||
// Not used yet...
|
||||
//function xmp_test_module_from_memory(const data: Pointer; size: LongInt; info: xmp_test_info): Integer; cdecl; external 'xmp';
|
||||
//function xmp_test_module_from_file(file_: Pointer; info: xmp_test_info): Integer; cdecl; external 'xmp';
|
||||
//function xmp_test_module_from_callbacks(file_: Pointer; callbacks: xmp_callbacks; info: xmp_test_info): Integer; cdecl; external 'xmp';
|
||||
//procedure xmp_scan_module(ctx: xmp_context); cdecl; external 'xmp';
|
||||
//function xmp_play_frame(ctx: xmp_context): Integer; cdecl; external 'xmp';
|
||||
//procedure xmp_inject_event(ctx: xmp_context; channel: Integer; var event: xmp_event); cdecl; external 'xmp';//function xmp_next_position(ctx: xmp_context): Integer; cdecl; external 'xmp';
|
||||
//function xmp_prev_position(ctx: xmp_context): Integer; cdecl; external 'xmp';
|
||||
//function xmp_set_position(ctx: xmp_context; pos: Integer): Integer; cdecl; external 'xmp';
|
||||
//function xmp_set_row(ctx: xmp_context; row: Integer): Integer; cdecl; external 'xmp';
|
||||
//function xmp_set_tempo_factor(ctx: xmp_context; factor: Double): Integer; cdecl; external 'xmp';//function xmp_seek_time(ctx: xmp_context; time: Integer): Integer; cdecl; external 'xmp';
|
||||
//function xmp_channel_mute(ctx: xmp_context; channel: Integer; mute: Integer): Integer; cdecl; external 'xmp';//function xmp_get_player(ctx: xmp_context; param: Integer): Integer; cdecl; external 'xmp';
|
||||
//function xmp_set_instrument_path(ctx: xmp_context; const path: PChar): Integer; cdecl; external 'xmp';
|
||||
|
||||
|
||||
{Special function for dynamic loading of lib ...}
|
||||
|
||||
var
|
||||
xmp_Handle: TLibHandle = dynlibs.NilHandle;
|
||||
{$if defined(cpu32) and defined(windows)} // try load dependency if not in /windows/system32/
|
||||
gc_Handle :TLibHandle=dynlibs.NilHandle;
|
||||
{$endif}
|
||||
var
|
||||
ReferenceCounter: cardinal = 0; // Reference counter
|
||||
|
||||
function xmp_IsLoaded: Boolean; inline;
|
||||
|
||||
function xmp_Load(const libfilename: string): Boolean; // load the lib
|
||||
|
||||
procedure xmp_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
implementation
|
||||
|
||||
function xmp_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (xmp_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Function xmp_Load(const libfilename:string) :boolean;
|
||||
var
|
||||
thelib, thelibgcc: string;
|
||||
begin
|
||||
Result := False;
|
||||
if xmp_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin
|
||||
{$if defined(cpu32) and defined(windows)}
|
||||
if Length(libfilename) = 0 then thelibgcc := 'libgcc_s_dw2-1.dll' else
|
||||
thelibgcc := IncludeTrailingBackslash(ExtractFilePath(libfilename)) + 'libgcc_s_dw2-1.dll';
|
||||
gc_Handle:= DynLibs.SafeLoadLibrary(thelibgcc);
|
||||
{$endif}
|
||||
|
||||
{go & load the library}
|
||||
if Length(libfilename) = 0 then thelib := XMP_LIB_NAME else thelib := libfilename;
|
||||
xmp_Handle:=DynLibs.LoadLibrary(thelib); // obtain the handle we want
|
||||
if xmp_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
|
||||
Pointer(xmp_create_context):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_create_context'));
|
||||
Pointer(xmp_free_context):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_free_context'));
|
||||
Pointer(xmp_load_module):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_load_module'));
|
||||
Pointer(xmp_load_module_from_memory):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_load_module_from_memory'));
|
||||
Pointer(xmp_load_module_from_file):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_load_module_from_file'));
|
||||
Pointer(xmp_load_module_from_callbacks):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_load_module_from_callbacks'));
|
||||
Pointer(xmp_test_module):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_test_module'));
|
||||
Pointer(xmp_release_module):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_release_module'));
|
||||
Pointer(xmp_start_player):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_start_player'));
|
||||
Pointer(xmp_play_buffer):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_play_buffer'));
|
||||
Pointer(xmp_get_frame_info):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_get_frame_info'));
|
||||
Pointer(xmp_end_player):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_end_player'));
|
||||
Pointer(xmp_get_module_info):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_get_module_info'));
|
||||
Pointer(xmp_get_format_list):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_get_format_list'));
|
||||
Pointer(xmp_stop_module):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_stop_module'));
|
||||
Pointer(xmp_restart_module):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_restart_module'));
|
||||
Pointer(xmp_channel_vol):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_channel_vol'));
|
||||
Pointer(xmp_set_player):=DynLibs.GetProcedureAddress(xmp_Handle,PChar('xmp_set_player'));
|
||||
end;
|
||||
Result := xmp_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
Procedure xmp_Unload;
|
||||
begin
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
if xmp_IsLoaded then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(xmp_Handle);
|
||||
xmp_Handle:=DynLibs.NilHandle;
|
||||
{$if defined(cpu32) and defined(windows)}
|
||||
if gc_Handle <> DynLibs.NilHandle then begin
|
||||
DynLibs.UnloadLibrary(gc_Handle);
|
||||
gc_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
{$endif}
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
1117
UOS/src/uos_mpg123.pas
Normal file
1117
UOS/src/uos_mpg123.pas
Normal file
File diff suppressed because it is too large
Load Diff
693
UOS/src/uos_opus.pas
Normal file
693
UOS/src/uos_opus.pas
Normal file
@@ -0,0 +1,693 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Pascal Wrapper + Dynamic loading of Opus library.
|
||||
Load library with op_load() and release with op_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com}
|
||||
|
||||
unit uos_opus;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs, CTypes, SysUtils;
|
||||
|
||||
const
|
||||
OPUS_OK = 0;
|
||||
OPUS_BAD_ARG = -1;
|
||||
OPUS_BUFFER_TOO_SMALL = -2;
|
||||
OPUS_INTERNAL_ERROR = -3;
|
||||
OPUS_INVALID_PACKET = -4;
|
||||
OPUS_UNIMPLEMENTED = -5;
|
||||
OPUS_INVALID_STATE = -6;
|
||||
OPUS_ALLOC_FAIL = -7;
|
||||
|
||||
OPUS_APPLICATION_VOIP = 2048;
|
||||
OPUS_APPLICATION_AUDIO = 2049;
|
||||
OPUS_APPLICATION_RESTRICTED_LOWDELAY = 2051;
|
||||
|
||||
OPUS_SIGNAL_VOICE = 3001; // Signal being encoded is voice
|
||||
OPUS_SIGNAL_MUSIC = 3002; // Signal being encoded is music
|
||||
|
||||
OPUS_BANDWIDTH_NARROWBAND = 1101; // 4 kHz bandpass @hideinitializer
|
||||
OPUS_BANDWIDTH_MEDIUMBAND = 1102; // 6 kHz bandpass @hideinitializer
|
||||
OPUS_BANDWIDTH_WIDEBAND = 1103; // 8 kHz bandpass @hideinitializer
|
||||
OPUS_BANDWIDTH_SUPERWIDEBAND = 1104; // 12 kHz bandpass @hideinitializer
|
||||
OPUS_BANDWIDTH_FULLBAND = 1105; // 20 kHz bandpass @hideinitializer
|
||||
|
||||
OPUS_FRAMESIZE_ARG = 5000; // Select frame size from the argument (default)
|
||||
OPUS_FRAMESIZE_2_5_MS = 5001; // Use 2.5 ms frames
|
||||
OPUS_FRAMESIZE_5_MS = 5002; // Use 5 ms frames
|
||||
OPUS_FRAMESIZE_10_MS = 5003; // Use 10 ms frames
|
||||
OPUS_FRAMESIZE_20_MS = 5004; // Use 20 ms frames
|
||||
OPUS_FRAMESIZE_40_MS = 5005; // Use 40 ms frames
|
||||
OPUS_FRAMESIZE_60_MS = 5006; // Use 60 ms frames
|
||||
|
||||
const
|
||||
OPUS_SET_APPLICATION_REQUEST = 4000;
|
||||
OPUS_GET_APPLICATION_REQUEST = 4001;
|
||||
OPUS_SET_BITRATE_REQUEST = 4002;
|
||||
OPUS_GET_BITRATE_REQUEST = 4003;
|
||||
OPUS_SET_MAX_BANDWIDTH_REQUEST = 4004;
|
||||
OPUS_GET_MAX_BANDWIDTH_REQUEST = 4005;
|
||||
OPUS_SET_VBR_REQUEST = 4006;
|
||||
OPUS_GET_VBR_REQUEST = 4007;
|
||||
OPUS_SET_BANDWIDTH_REQUEST = 4008;
|
||||
OPUS_GET_BANDWIDTH_REQUEST = 4009;
|
||||
OPUS_SET_COMPLEXITY_REQUEST = 4010;
|
||||
OPUS_GET_COMPLEXITY_REQUEST = 4011;
|
||||
OPUS_SET_INBAND_FEC_REQUEST = 4012;
|
||||
OPUS_GET_INBAND_FEC_REQUEST = 4013;
|
||||
OPUS_SET_PACKET_LOSS_PERC_REQUEST = 4014;
|
||||
OPUS_GET_PACKET_LOSS_PERC_REQUEST = 4015;
|
||||
OPUS_SET_DTX_REQUEST = 4016;
|
||||
OPUS_GET_DTX_REQUEST = 4017;
|
||||
OPUS_SET_VBR_CONSTRAINT_REQUEST = 4020;
|
||||
OPUS_GET_VBR_CONSTRAINT_REQUEST = 4021;
|
||||
OPUS_SET_FORCE_CHANNELS_REQUEST = 4022;
|
||||
OPUS_GET_FORCE_CHANNELS_REQUEST = 4023;
|
||||
OPUS_SET_SIGNAL_REQUEST = 4024;
|
||||
OPUS_GET_SIGNAL_REQUEST = 4025;
|
||||
OPUS_GET_LOOKAHEAD_REQUEST = 4027;
|
||||
OPUS_RESET_STATE_REQUEST = 4028;
|
||||
OPUS_GET_SAMPLE_RATE_REQUEST = 4029;
|
||||
OPUS_GET_FINAL_RANGE_REQUEST = 4031;
|
||||
OPUS_GET_PITCH_REQUEST = 4033;
|
||||
OPUS_SET_GAIN_REQUEST = 4034;
|
||||
OPUS_GET_GAIN_REQUEST = 4045;
|
||||
OPUS_SET_LSB_DEPTH_REQUEST = 4036;
|
||||
OPUS_GET_LSB_DEPTH_REQUEST = 4037;
|
||||
OPUS_GET_LAST_PACKET_DURATION_REQUEST = 4039;
|
||||
OPUS_SET_EXPERT_FRAME_DURATION_REQUEST = 4040;
|
||||
OPUS_GET_EXPERT_FRAME_DURATION_REQUEST = 4041;
|
||||
OPUS_SET_PREDICTION_DISABLED_REQUEST = 4042;
|
||||
OPUS_GET_PREDICTION_DISABLED_REQUEST = 4043;
|
||||
OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST = 5120;
|
||||
OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST = 5122;
|
||||
|
||||
type
|
||||
TOpusEncoder = Pointer;
|
||||
TOpusDecoder = Pointer;
|
||||
TOpusRepacketizer = Pointer;
|
||||
TOpusMSDecoder = pointer;
|
||||
TOpusMSEncoder = pointer;
|
||||
|
||||
TOpusFrames = array [0..47] of Pointer;
|
||||
TOpusFrameSizes = array [0..47] of cint;
|
||||
|
||||
type
|
||||
TRequestValueType = (orPointer, orInteger, orXY, orNoValue);
|
||||
TOpusCTLRequestRecord = record
|
||||
Request: Word;
|
||||
case ReqType: TRequestValueType of
|
||||
orPointer: (PtrValue: Pointer);
|
||||
orInteger: (IntValue: cint);
|
||||
orXY: (XValue: cint; YValue: pointer);
|
||||
end;
|
||||
|
||||
var
|
||||
opus_get_version_string: function(): PAnsiChar; cdecl; opus_strerror: function(error: cint): PAnsiChar; cdecl;
|
||||
opus_encode: function(st: TOpusEncoder; pcm : pcfloat; frame_size: cint;
|
||||
var data; max_data_bytes: cint): cint; cdecl;
|
||||
opus_encode_float: function(st: TOpusEncoder; pcm : pcfloat; frame_size: cint; var data; max_data_bytes: cint): cint; cdecl;
|
||||
opus_encoder_create: function(Fs: cint; channels, application: cint; out error: cint): TOpusEncoder; cdecl;
|
||||
|
||||
opus_encoder_ctli: function(st: TOpusEncoder; const reqrequest: word ; reqval : cint ): cint; cdecl;
|
||||
opus_encoder_ctlp: function(st: TOpusEncoder; const reqrequest: word ; reqval : pointer ): cint; cdecl;
|
||||
opus_encoder_ctlxy: function(st: TOpusEncoder; const reqrequest: word ; reqx : cint ; reqy : pointer ): cint; cdecl;
|
||||
opus_encoder_ctln: function(st: TOpusEncoder; const reqrequest: word): cint; cdecl;
|
||||
|
||||
opus_encoder_destroy: procedure(st: TOpusEncoder); cdecl;
|
||||
opus_encoder_get_size: function(channels: cint): cint; cdecl;
|
||||
opus_encoder_init: function(st: TOpusEncoder; Fs: cint; channels, application: cint): cint; cdecl;
|
||||
|
||||
opus_decode: function(st: TOpusDecoder; const data; len: cint; pcm : pcfloat; frame_size, decode_fec: cint): cint; cdecl;
|
||||
opus_decode_float: function(st: TOpusDecoder; const data; len: cint; pcm : pcfloat; frame_size, decode_fec: cint): cint; cdecl;
|
||||
opus_decoder_create: function(fs: cint; channels: cint; out error: cint): TOpusDecoder; cdecl;
|
||||
|
||||
opus_decoder_ctli: function(st: TOpusDecoder; const reqrequest: word ; reqval : cint ): cint; cdecl;
|
||||
opus_decoder_ctlp: function(st: TOpusDecoder; const reqrequest: word ; reqval : pointer ): cint; cdecl;
|
||||
opus_decoder_ctlxy: function(st: TOpusDecoder; const reqrequest: word ; reqx : cint ; reqy : pointer ): cint; cdecl;
|
||||
opus_decoder_ctln: function(st: TOpusDecoder; const reqrequest: word): cint; cdecl;
|
||||
|
||||
opus_decoder_destroy: procedure(st: TOpusDecoder); cdecl;
|
||||
opus_decoder_get_nb_samples: function(st: TOpusDecoder; const packet; len: cint): cint; cdecl;
|
||||
opus_decoder_get_size: function(channels: cint): cint; cdecl;
|
||||
opus_decoder_init: function(st: TOpusDecoder; Fs: cint; channels: cint): cint; cdecl;
|
||||
opus_packet_get_bandwidth: function(const packet): cint; cdecl;
|
||||
opus_packet_get_nb_channels: function(const packet): cint; cdecl;
|
||||
opus_packet_get_nb_frames: function(const packet; len: cint): cint; cdecl;
|
||||
opus_packet_get_nb_samples: function(const packet; len, fs: cint): cint; cdecl;
|
||||
opus_packet_get_samples_per_frame: function(const packet; fs: cint): cint; cdecl;
|
||||
opus_packet_parse: function(const packet; var out_toc: Pointer; var frames: TOpusFrames; var size: TOpusFrameSizes; var payload_offset: cint): cint; cdecl;
|
||||
opus_pcm_soft_clip: procedure(pcm : pcfloat; frame_size, channels: cint; var softclip_mem: Double); cdecl;
|
||||
|
||||
opus_multistream_packet_pad: function(var data; len, new_len, nb_streams: cint): cint; cdecl;
|
||||
opus_multistream_packet_unpad: function(var data; len, nb_streams: cint): cint; cdecl;
|
||||
opus_packet_pad: function(var data; len, new_len: cint): cint; cdecl;
|
||||
opus_packet_unpad: function(var data; len: cint): cint; cdecl;
|
||||
opus_repacketizer_cat: function(rp: TOpusRepacketizer; const data; len: cint): cint; cdecl;
|
||||
opus_repacketizer_create: function: TOpusRepacketizer; cdecl;
|
||||
opus_repacketizer_destroy: procedure(rp: TOpusRepacketizer); cdecl;
|
||||
opus_repacketizer_get_nb_frames: function(rp: TOpusRepacketizer): cint; cdecl;
|
||||
opus_repacketizer_get_size: function: cint; cdecl;
|
||||
opus_repacketizer_init: function(rp: TOpusRepacketizer): TOpusRepacketizer; cdecl;
|
||||
opus_repacketizer_out: function(rp: TOpusRepacketizer; var data; maxlen: cint): cint; cdecl;
|
||||
opus_repacketizer_out_range: function(rp: TOpusRepacketizer; var data; maxlen: cint): cint; cdecl;
|
||||
|
||||
opus_multistream_decode: function(st: TOpusMSDecoder; const data; len: cint; pcm : pcfloat; frame_size, decode_fec: cint): cint; cdecl;
|
||||
opus_multistream_decode_float: function(st: TOpusMSDecoder; const data; len: cint; pcm : pcfloat; frame_size, decode_fec: cint): cint; cdecl;
|
||||
opus_multistream_decoder_create: function(fs: cint; channels, streams, coupled_streams: cint; const mapping: array of Byte; out error: cint): TOpusMSDecoder; cdecl;
|
||||
|
||||
opus_multistream_decoder_ctli: function(st: TOpusMSDecoder; const reqrequest: word ; reqval : cint ): cint; cdecl;
|
||||
opus_multistream_decoder_ctlp: function(st: TOpusMSDecoder; const reqrequest: word ; reqval : pointer ): cint; cdecl;
|
||||
opus_multistream_decoder_ctlxy: function(st: TOpusMSDecoder; const reqrequest: word ; reqx : cint ; reqy : pointer ): cint; cdecl;
|
||||
opus_multistream_decoder_ctln: function(st: TOpusMSDecoder; const reqrequest: word): cint; cdecl;
|
||||
|
||||
opus_multistream_decoder_destroy: procedure(st: TOpusMSDecoder); cdecl;
|
||||
opus_multistream_decoder_get_size: function(streams, coupled_streams: cint): cint; cdecl;
|
||||
opus_multistream_decoder_init: function(st: TOpusMSDecoder; fs: cint; channels, streams, coupled_streams: cint; const mapping: array of Byte): cint; cdecl;
|
||||
|
||||
opus_multistream_encode: function(st: TOpusMSEncoder; pcm : pcfloat; frame_size: cint; var data; max_data_bytes: cint): cint; cdecl;
|
||||
opus_multistream_encode_float: function(st: TOpusMSEncoder; pcm : pcfloat; frame_size: cint; var data; max_data_bytes: cint): cint; cdecl;
|
||||
opus_multistream_encoder_create: function(Fs: cint; channels, streams, coupled_streams: cint; const mapping: array of Byte; application: cint; out error: cint): TOpusMSEncoder; cdecl;
|
||||
|
||||
opus_multistream_encoder_ctli: function(st: TOpusMSEncoder; const reqrequest: word ; reqval : cint ): cint; cdecl;
|
||||
opus_multistream_encoder_ctlp: function(st: TOpusMSEncoder; const reqrequest: word ; reqval : pointer ): cint; cdecl;
|
||||
opus_multistream_encoder_ctlxy: function(st: TOpusMSEncoder; const reqrequest: word ; reqx : cint ; reqy : pointer ): cint; cdecl;
|
||||
opus_multistream_encoder_ctln: function(st: TOpusMSEncoder; const reqrequest: word ): cint; cdecl;
|
||||
|
||||
opus_multistream_encoder_destroy: procedure(st: TOpusMSEncoder); cdecl;
|
||||
opus_multistream_encoder_get_size: function(streams, coupled_streams: cint): cint; cdecl;
|
||||
opus_multistream_encoder_init: function(st: TOpusMSEncoder; fs: cint; channels, streams, coupled_streams: cint; const mapping: array of Byte; application: cint): cint; cdecl;
|
||||
|
||||
opus_multistream_surround_encoder_create: function(Fs: cint; channels, mapping_family, streams, coupled_streams: cint; const mapping: array of Byte; application: cint; out error: cint): TOpusMSEncoder; cdecl;
|
||||
opus_multistream_surround_encoder_get_size: function(channels, mapping_family: cint): cint; cdecl;
|
||||
opus_multistream_surround_encoder_init: function(st: TOpusMSEncoder; fs: cint; channels, mapping_family, streams, coupled_streams: cint; const mapping: array of Byte; application: cint): cint; cdecl;
|
||||
|
||||
function opus_encoder_ctl(st: TOpusEncoder; const req: TOpusCTLRequestRecord): Integer; inline;
|
||||
function opus_decoder_ctl(st: TOpusdecoder; const req: TOpusCTLRequestRecord): Integer; inline;
|
||||
|
||||
function opus_multistream_encoder_ctl(st: TOpusMSEncoder; const req: TOpusCTLRequestRecord): cint; inline;
|
||||
function opus_multistream_decoder_ctl(st: TOpusMSdecoder; const req: TOpusCTLRequestRecord): cint; inline;
|
||||
|
||||
// Macros for opus_encode_ctl.
|
||||
function OPUS_GET_APPLICATION(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_BITRATE(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_COMPLEXITY(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_DTX(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_EXPERT_FRAME_DURATION(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_FORCE_CHANNELS(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_LOOKAHEAD(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_LSB_DEPTH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_MAX_BANDWIDTH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_PACKET_LOSS_PERC(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_PREDICTION_DISABLED(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_SIGNAL(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_VBR(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_VBR_CONSTRAINT(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
|
||||
function OPUS_SET_APPLICATION(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_BANDWIDTH(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_BITRATE(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_COMPLEXITY(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_DTX(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_EXPERT_FRAME_DURATION(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_FORCE_CHANNELS(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_INBAND_FEC(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_LSB_DEPTH(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_MAX_BANDWIDTH(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_PACKET_LOSS_PERC(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_PREDICTION_DISABLED(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_SIGNAL(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_VBR(x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_VBR_CONSTRAINT(x: cint): TOpusCTLRequestRecord; inline;
|
||||
|
||||
// For opus_decoder_ctl and opus_encoder_ctl.
|
||||
function OPUS_GET_BANDWIDTH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_FINAL_RANGE(var x: Cardinal): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_SAMPLE_RATE(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_RESET_STATE: TOpusCTLRequestRecord; inline;
|
||||
|
||||
// For the opus_decode_ctl.
|
||||
function OPUS_GET_GAIN(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_LAST_PACKET_DURATION(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_GET_PITCH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_SET_GAIN(x: cint): TOpusCTLRequestRecord; inline;
|
||||
|
||||
function OPUS_MULTISTREAM_GET_DECODER_STATE(x: cint; var y: cint): TOpusCTLRequestRecord; inline;
|
||||
function OPUS_MULTISTREAM_GET_ENCODER_STATE(x: cint; var y: cint): TOpusCTLRequestRecord; inline;
|
||||
|
||||
var op_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
|
||||
var ReferenceCounter : cardinal = 0;
|
||||
|
||||
function op_IsLoaded : boolean; inline;
|
||||
|
||||
Function op_Load(const libfilename:string) :boolean;
|
||||
|
||||
Procedure op_Unload;
|
||||
|
||||
implementation
|
||||
|
||||
function op_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (op_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Procedure op_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if op_IsLoaded then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(op_Handle);
|
||||
op_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function op_Load (const libfilename:string) :boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if op_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then exit;
|
||||
op_Handle:=DynLibs.SafeLoadLibrary(libfilename); // obtain the handle we want
|
||||
if op_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
Pointer(opus_get_version_string):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_get_version_string'));
|
||||
Pointer(opus_strerror):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_strerror'));
|
||||
Pointer(opus_encode):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encode'));
|
||||
Pointer(opus_encode_float):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encode_float'));
|
||||
Pointer(opus_encoder_create):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_create'));
|
||||
|
||||
Pointer(opus_encoder_ctli):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_ctl'));
|
||||
Pointer(opus_encoder_ctlp):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_ctl'));
|
||||
Pointer(opus_encoder_ctlxy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_ctl'));
|
||||
Pointer(opus_encoder_ctln):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_ctl'));
|
||||
|
||||
Pointer(opus_encoder_destroy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_destroy'));
|
||||
Pointer(opus_encoder_get_size):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_get_size'));
|
||||
Pointer(opus_encoder_init):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_encoder_init'));
|
||||
Pointer(opus_decode):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decode'));
|
||||
Pointer(opus_decode_float):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decode_float'));
|
||||
Pointer(opus_decoder_create):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_create'));
|
||||
|
||||
Pointer(opus_decoder_ctli):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_ctl'));
|
||||
Pointer(opus_decoder_ctlp):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_ctl'));
|
||||
Pointer(opus_decoder_ctlxy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_ctl'));
|
||||
Pointer(opus_decoder_ctln):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_ctl'));
|
||||
|
||||
Pointer(opus_decoder_destroy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_destroy'));
|
||||
Pointer(opus_decoder_get_nb_samples):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_get_nb_samples'));
|
||||
Pointer(opus_decoder_get_size):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_get_size'));
|
||||
Pointer(opus_decoder_init):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_decoder_init'));
|
||||
Pointer(opus_packet_get_bandwidth):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_get_bandwidth'));
|
||||
Pointer(opus_packet_get_nb_channels):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_get_nb_channels'));
|
||||
Pointer(opus_packet_get_nb_frames):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_get_nb_frames'));
|
||||
Pointer(opus_packet_get_nb_samples):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_get_nb_samples'));
|
||||
Pointer(opus_packet_get_samples_per_frame):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_get_samples_per_frame'));
|
||||
Pointer( opus_packet_parse):=DynLibs.GetProcedureAddress(OP_Handle,PChar(' opus_packet_parse'));
|
||||
Pointer(opus_pcm_soft_clip):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_pcm_soft_clip'));
|
||||
Pointer(opus_multistream_packet_pad):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_packet_pad'));
|
||||
Pointer(opus_multistream_packet_unpad):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_packet_unpad'));
|
||||
Pointer(opus_packet_pad):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_pad'));
|
||||
Pointer(opus_packet_unpad):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_packet_unpad'));
|
||||
Pointer(opus_repacketizer_cat):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_cat'));
|
||||
Pointer(opus_repacketizer_create):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_create'));
|
||||
Pointer(opus_repacketizer_destroy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('oopus_repacketizer_destroy'));
|
||||
Pointer(opus_repacketizer_get_nb_frames):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_get_nb_frames'));
|
||||
Pointer(opus_repacketizer_get_size):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_get_size'));
|
||||
Pointer(opus_repacketizer_init):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_init'));
|
||||
Pointer(opus_repacketizer_out):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_out'));
|
||||
Pointer(opus_repacketizer_out_range):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_repacketizer_out_range'));
|
||||
Pointer(opus_multistream_decode):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decode'));
|
||||
Pointer(opus_multistream_decode_float):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decode_float'));
|
||||
Pointer(opus_multistream_decoder_create):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_create'));
|
||||
|
||||
Pointer(opus_multistream_decoder_ctli):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_ctl'));
|
||||
Pointer(opus_multistream_decoder_ctlp):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_ctl'));
|
||||
Pointer(opus_multistream_decoder_ctlxy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_ctl'));
|
||||
Pointer(opus_multistream_decoder_ctln):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_ctl'));
|
||||
|
||||
Pointer(opus_multistream_decoder_destroy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_destroy'));
|
||||
Pointer(opus_multistream_decoder_get_size):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_get_size'));
|
||||
Pointer(opus_multistream_decoder_init):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_decoder_init'));
|
||||
Pointer(opus_multistream_encode):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encode'));
|
||||
Pointer(opus_multistream_encode_float):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encode_float'));
|
||||
Pointer(opus_multistream_encoder_create):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_create'));
|
||||
|
||||
Pointer(opus_multistream_encoder_ctli):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_ctl'));
|
||||
Pointer(opus_multistream_encoder_ctlp):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_ctl'));
|
||||
Pointer(opus_multistream_encoder_ctlxy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_ctl'));
|
||||
Pointer(opus_multistream_encoder_ctln):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_ctl'));
|
||||
|
||||
Pointer(opus_multistream_encoder_destroy):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_destroy'));
|
||||
Pointer(opus_multistream_encoder_get_size):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_get_size'));
|
||||
Pointer(opus_multistream_encoder_init):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_encoder_init'));
|
||||
Pointer(opus_multistream_surround_encoder_create):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_surround_encoder_create'));
|
||||
Pointer(opus_multistream_surround_encoder_get_size):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_surround_encoder_get_size'));
|
||||
Pointer(opus_multistream_surround_encoder_init):=DynLibs.GetProcedureAddress(OP_Handle,PChar('opus_multistream_surround_encoder_init'));
|
||||
|
||||
end;
|
||||
Result := op_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
function OPUS_GET_APPLICATION(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_APPLICATION_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_BITRATE(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_BITRATE_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_COMPLEXITY(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_COMPLEXITY_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_DTX(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_DTX_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_EXPERT_FRAME_DURATION(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_EXPERT_FRAME_DURATION_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_FORCE_CHANNELS(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_FORCE_CHANNELS_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_LOOKAHEAD(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_LOOKAHEAD_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_LSB_DEPTH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_LSB_DEPTH_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_MAX_BANDWIDTH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_MAX_BANDWIDTH_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_PACKET_LOSS_PERC(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_PACKET_LOSS_PERC_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_PREDICTION_DISABLED(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_PREDICTION_DISABLED_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_SIGNAL(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_SIGNAL_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_VBR(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_VBR_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_VBR_CONSTRAINT(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_VBR_CONSTRAINT_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_APPLICATION(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_APPLICATION_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_BANDWIDTH(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_BANDWIDTH_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_BITRATE(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_BITRATE_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_COMPLEXITY(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_COMPLEXITY_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_DTX(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_DTX_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_EXPERT_FRAME_DURATION(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_EXPERT_FRAME_DURATION_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_FORCE_CHANNELS(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_FORCE_CHANNELS_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_INBAND_FEC(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_INBAND_FEC_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_LSB_DEPTH(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_LSB_DEPTH_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_MAX_BANDWIDTH(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_MAX_BANDWIDTH_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_PACKET_LOSS_PERC(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_PACKET_LOSS_PERC_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_PREDICTION_DISABLED(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_PREDICTION_DISABLED_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_SIGNAL(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_SIGNAL_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_VBR(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_VBR_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_VBR_CONSTRAINT(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_VBR_CONSTRAINT_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_BANDWIDTH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_BANDWIDTH_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_FINAL_RANGE(var x: Cardinal): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_BANDWIDTH_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_SAMPLE_RATE(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_BANDWIDTH_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_RESET_STATE: TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_RESET_STATE_REQUEST;
|
||||
Result.ReqType := orNoValue;
|
||||
end;
|
||||
|
||||
function OPUS_GET_GAIN(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_GAIN_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_LAST_PACKET_DURATION(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_LAST_PACKET_DURATION_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_GET_PITCH(var x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_GET_PITCH_REQUEST;
|
||||
Result.ReqType := orPointer;
|
||||
Result.PtrValue := @x;
|
||||
end;
|
||||
|
||||
function OPUS_SET_GAIN(x: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_SET_GAIN_REQUEST;
|
||||
Result.ReqType := orInteger;
|
||||
Result.IntValue := x;
|
||||
end;
|
||||
|
||||
function OPUS_MULTISTREAM_GET_DECODER_STATE(x: cint; var y: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST;
|
||||
Result.ReqType := orXY;
|
||||
Result.XValue := x;
|
||||
Result.YValue := @y;
|
||||
end;
|
||||
|
||||
function OPUS_MULTISTREAM_GET_ENCODER_STATE(x: cint; var y: cint): TOpusCTLRequestRecord; inline;
|
||||
begin
|
||||
Result.Request := OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST;
|
||||
Result.ReqType := orXY;
|
||||
Result.XValue := x;
|
||||
Result.YValue := @y;
|
||||
end;
|
||||
|
||||
function opus_encoder_ctl(st: TOpusEncoder; const req: TOpusCTLRequestRecord): Integer; inline;
|
||||
begin
|
||||
case req.ReqType of
|
||||
orPointer: Result := opus_encoder_ctlp(st, req.Request, req.PtrValue);
|
||||
orInteger: Result := opus_encoder_ctli(st, req.Request, req.IntValue);
|
||||
orXY: Result := opus_encoder_ctlxy(st, req.Request, req.XValue, req.YValue);
|
||||
orNoValue: Result := opus_encoder_ctln(st, req.Request);
|
||||
else
|
||||
Result := OPUS_BAD_ARG;
|
||||
end;
|
||||
end;
|
||||
|
||||
function opus_decoder_ctl(st: TOpusDecoder; const req: TOpusCTLRequestRecord): Integer; inline;
|
||||
begin
|
||||
case req.ReqType of
|
||||
orPointer: Result := opus_decoder_ctlp(st, req.Request, req.PtrValue);
|
||||
orInteger: Result := opus_decoder_ctli(st, req.Request, req.IntValue);
|
||||
orXY: Result := opus_decoder_ctlxy(st, req.Request, req.XValue, req.YValue);
|
||||
orNoValue: Result := opus_decoder_ctln(st, req.Request);
|
||||
else
|
||||
Result := OPUS_BAD_ARG;
|
||||
end;
|
||||
end;
|
||||
|
||||
function opus_multistream_encoder_ctl(st: TOpusMSEncoder; const req: TOpusCTLRequestRecord): Integer; inline;
|
||||
begin
|
||||
case req.ReqType of
|
||||
orPointer: Result := opus_multistream_encoder_ctlp(st, req.Request, req.PtrValue);
|
||||
orInteger: Result := opus_multistream_encoder_ctli(st, req.Request, req.IntValue);
|
||||
orXY: Result := opus_multistream_encoder_ctlxy(st, req.Request, req.XValue, req.YValue);
|
||||
orNoValue: Result := opus_multistream_encoder_ctln(st, req.Request);
|
||||
else
|
||||
Result := OPUS_BAD_ARG;
|
||||
end;
|
||||
end;
|
||||
|
||||
function opus_multistream_decoder_ctl(st: TOpusMSDecoder; const req: TOpusCTLRequestRecord): Integer; inline;
|
||||
begin
|
||||
case req.ReqType of
|
||||
orPointer: Result := opus_multistream_decoder_ctlp(st, req.Request, req.PtrValue);
|
||||
orInteger: Result := opus_multistream_decoder_ctli(st, req.Request, req.IntValue);
|
||||
orXY: Result := opus_multistream_decoder_ctlxy(st, req.Request, req.XValue, req.YValue);
|
||||
orNoValue: Result := opus_multistream_decoder_ctln(st, req.Request);
|
||||
else
|
||||
Result := OPUS_BAD_ARG;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
471
UOS/src/uos_opusfile.pas
Normal file
471
UOS/src/uos_opusfile.pas
Normal file
@@ -0,0 +1,471 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Pascal Wrapper + Dynamic loading of OpusFile library.
|
||||
Load library with of_load() and release with of_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com}
|
||||
|
||||
unit uos_OpusFile;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ctypes, dynlibs, classes, pipes, SysUtils;
|
||||
|
||||
type
|
||||
TOpusFile = ^OpusFile;
|
||||
OpusFile = record
|
||||
end;
|
||||
|
||||
const
|
||||
libop=
|
||||
{$IFDEF unix}
|
||||
{$IFDEF darwin}
|
||||
'libopusfile.0.dylib';
|
||||
{$ELSE}
|
||||
'libopusfile.so.0';
|
||||
{$ENDIF}
|
||||
{$ELSE}
|
||||
'opusfile.dll';
|
||||
{$ENDIF}
|
||||
|
||||
// Error Codes
|
||||
const
|
||||
OP_FALSE = -1;
|
||||
OP_HOLE = -3;
|
||||
OP_EREAD = -128;
|
||||
OP_EFAULT = -129;
|
||||
OP_EIMPL = -130;
|
||||
OP_EINVAL = -131;
|
||||
OP_ENOTVORBIS = -132;
|
||||
OP_EBADHEADER = -133;
|
||||
OP_EVERSION = -134;
|
||||
OP_ENOTAUDIO = -135;
|
||||
OP_EBADPACKET = -136;
|
||||
OP_EBADLINK = -137;
|
||||
OP_ENOSEEK = -138;
|
||||
OP_EBADTIMESTAMP = -139;
|
||||
|
||||
{
|
||||
/**A request did not succeed.*/
|
||||
#define OP_FALSE (-1)
|
||||
/*Currently not used externally.*/
|
||||
#define OP_EOF (-2)
|
||||
/**There was a hole in the page sequence numbers (e.g., a page was corrupt or
|
||||
missing).*/
|
||||
#define OP_HOLE (-3)
|
||||
/**An underlying read, seek, or tell operation failed when it should have
|
||||
succeeded.*/
|
||||
#define OP_EREAD (-128)
|
||||
/**A <code>NULL</code> pointer was passed where one was unexpected, or an
|
||||
internal memory allocation failed, or an internal library error was
|
||||
encountered.*/
|
||||
#define OP_EFAULT (-129)
|
||||
/**The stream used a feature that is not implemented, such as an unsupported
|
||||
channel family.*/
|
||||
#define OP_EIMPL (-130)
|
||||
/**One or more parameters to a function were invalid.*/
|
||||
#define OP_EINVAL (-131)
|
||||
/**A purported Ogg Opus stream did not begin with an Ogg page, a purported
|
||||
header packet did not start with one of the required strings, "OpusHead" or
|
||||
"OpusTags", or a link in a chained file was encountered that did not
|
||||
contain any logical Opus streams.*/
|
||||
#define OP_ENOTFORMAT (-132)
|
||||
/**A required header packet was not properly formatted, contained illegal
|
||||
values, or was missing altogether.*/
|
||||
#define OP_EBADHEADER (-133)
|
||||
/**The ID header contained an unrecognized version number.*/
|
||||
#define OP_EVERSION (-134)
|
||||
/*Currently not used at all.*/
|
||||
#define OP_ENOTAUDIO (-135)
|
||||
/**An audio packet failed to decode properly.
|
||||
This is usually caused by a multistream Ogg packet where the durations of
|
||||
the individual Opus packets contained in it are not all the same.*/
|
||||
#define OP_EBADPACKET (-136)
|
||||
/**We failed to find data we had seen before, or the bitstream structure was
|
||||
sufficiently malformed that seeking to the target destination was
|
||||
impossible.*/
|
||||
#define OP_EBADLINK (-137)
|
||||
/**An operation that requires seeking was requested on an unseekable stream.*/
|
||||
#define OP_ENOSEEK (-138)
|
||||
/**The first or last granule position of a link failed basic validity checks.*/
|
||||
#define OP_EBADTIMESTAMP (-139)
|
||||
}
|
||||
|
||||
type
|
||||
TOP_PIC_FORMAT = (OP_PIC_FORMAT_UNKNOWN = -1, OP_PIC_FORMAT_URL, OP_PIC_FORMAT_JPEG,
|
||||
OP_PIC_FORMAT_PNG, OP_PIC_FORMAT_GIF);
|
||||
type
|
||||
TOpusHead = THandle;
|
||||
TOpusStream = THandle;
|
||||
|
||||
op_read_func = function (stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
op_seek_func = function (stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
|
||||
op_tell_func = function (stream: Pointer): Int64; cdecl;
|
||||
op_close_func = function (stream: Pointer): cint; cdecl;
|
||||
|
||||
TOpusFileCallbacks = record
|
||||
read: op_read_func;
|
||||
seek: op_seek_func;
|
||||
tell: op_tell_func;
|
||||
close: op_close_func;
|
||||
end;
|
||||
|
||||
function OpusReadCB(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
function OpusReadCBuosURL(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
function OpusReadCBuosMS(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
function OpusSeekCB(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
|
||||
function OpusTellCB(stream: Pointer): Int64; cdecl;
|
||||
function OpusCloseCB(stream: Pointer): cint; cdecl;
|
||||
function OpusSeekCBMS(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
|
||||
function OpusTellCBMS(stream: Pointer): Int64; cdecl;
|
||||
|
||||
const
|
||||
op_callbacks: TOpusFileCallbacks = (read: @OpusReadCB;
|
||||
seek: @OpusSeekCB;
|
||||
tell: @OpusTellCB;
|
||||
close: nil);
|
||||
|
||||
uos_callbacks: TOpusFileCallbacks = (read: @OpusReadCBuosURL;
|
||||
seek: @OpusSeekCB;
|
||||
tell: @OpusTellCB;
|
||||
close: nil);
|
||||
|
||||
uos_callbacksms: TOpusFileCallbacks = (read: @OpusReadCBuosms;
|
||||
seek: @OpusSeekCBms;
|
||||
tell: @OpusTellCBms;
|
||||
close: nil);
|
||||
|
||||
|
||||
type
|
||||
TOpusMSDecoder = Pointer;
|
||||
op_decode_cb_func = function(ctx: Pointer; decoder: TOpusMSDecoder; pcm : pcfloat; op: Pointer;
|
||||
nsamples, nchannels, format, li: pcint): cint; cdecl;
|
||||
TOpusTags = record
|
||||
user_comments: PPAnsiChar; // The array of comment string vectors
|
||||
comment_lengths: Pcint; // An array of the corresponding length of each vector, in bytes
|
||||
comments: cint; // The total number of comment streams
|
||||
vendor: PAnsiChar; // The null-terminated vendor string. This identifies the software used to encode the stream.
|
||||
end;
|
||||
POpusTags = ^TOpusTags;
|
||||
|
||||
TOpusPictureTag = record
|
||||
Pic_Type: cint; { The picture type according to the ID3v2 APIC frame:
|
||||
<ol start="0">
|
||||
<li>Other</li>
|
||||
<li>32x32 pixels 'file icon' (PNG only)</li>
|
||||
<li>Other file icon</li>
|
||||
<li>Cover (front)</li>
|
||||
<li>Cover (back)</li>
|
||||
<li>Leaflet page</li>
|
||||
<li>Media (e.g. label side of CD)</li>
|
||||
<li>Lead artist/lead performer/soloist</li>
|
||||
<li>Artist/performer</li>
|
||||
<li>Conductor</li>
|
||||
<li>Band/Orchestra</li>
|
||||
<li>Composer</li>
|
||||
<li>Lyricist/text writer</li>
|
||||
<li>Recording Location</li>
|
||||
<li>During recording</li>
|
||||
<li>During performance</li>
|
||||
<li>Movie/video screen capture</li>
|
||||
<li>A bright colored fish</li>
|
||||
<li>Illustration</li>
|
||||
<li>Band/artist logotype</li>
|
||||
<li>Publisher/Studio logotype</li>
|
||||
</ol> }
|
||||
mime_type: PAnsiChar; // The MIME type of the picture, in printable ASCII characters 0x20-0x7E.
|
||||
description: PAnsiChar; // The description of the picture, in UTF-8
|
||||
width: Cardinal;
|
||||
height: Cardinal;
|
||||
depth: Cardinal; // The color depth of the picture in bits-per-pixel
|
||||
colors: Cardinal; // For indexed-color pictures (e.g., GIF), the number of colors used, or 0
|
||||
data_length: Cardinal;
|
||||
data: Pointer;
|
||||
format: TOP_PIC_FORMAT; // The format of the picture data, if known. OP_PIC_FORMAT_UNKNOWN..OP_PIC_FORMAT_GIF
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
op_fopen: function(out cb: TOpusFileCallbacks; path: PAnsiChar; mode: PAnsiChar): TOpusStream; cdecl;
|
||||
|
||||
op_freopen: function(out cb: TOpusFileCallbacks; path: PAnsiChar; mode: PAnsiChar; stream: TOpusStream): TOpusStream;cdecl;
|
||||
op_mem_stream_create: function(out cb: TOpusFileCallbacks; const data; size: cuint): TOpusStream; cdecl;
|
||||
|
||||
opus_head_parse: function(head: TOpusHead; const data; len: cuint): cint;cdecl;
|
||||
opus_granule_sample: function(head: TOpusHead; gp: Int64): Int64;cdecl;
|
||||
opus_tags_parse: function(out tags: TOpusTags; const data; len: cuint): cint;cdecl;
|
||||
opus_tags_copy: function(var dst: TOpusTags; const src: TOpusTags): cint;cdecl;
|
||||
opus_tags_init: procedure(var tags: TOpusTags);cdecl;
|
||||
opus_tags_add: function(var dst: TOpusTags; tag, value: PAnsiChar): cint;cdecl;
|
||||
opus_tags_add_comment: function(var dst: TOpusTags; comment: PAnsiChar): cint;cdecl;
|
||||
opus_tags_set_binary_suffix: function(var tags: TOpusTags; const data; len: cint): cint;cdecl;
|
||||
opus_tags_query: function(const tags: TOpusTags; tag: PAnsiChar; count: cint): cint;cdecl;
|
||||
opus_tags_query_count: function(const tags: TOpusTags; tag: PAnsiChar): cint;cdecl;
|
||||
opus_tags_get_binary_suffix: function(const tags: TOpusTags; out len: cint): cint;cdecl;
|
||||
opus_tags_get_album_gain: function(const tags: TOpusTags; out gain_q8: cint): cint;cdecl;
|
||||
opus_tags_get_track_gain: function(const tags: TOpusTags; out gain_q8: cint): cint;cdecl;
|
||||
opus_tags_clear: procedure(var tags: TOpusTags);cdecl;
|
||||
opus_tagcompare: function(tag_name, comment: PAnsiChar): cint;cdecl;
|
||||
opus_tagncompare: function(tag_name: PAnsiChar; tag_len: cint; comment: PAnsiChar): cint;cdecl;
|
||||
opus_picture_tag_parse: function(out pic: TOpusPictureTag; tag: PAnsiChar): cint;cdecl;
|
||||
opus_picture_tag_init: procedure(var pic: TOpusPictureTag);cdecl;
|
||||
opus_picture_tag_clear: procedure(var pic: TOpusPictureTag);cdecl;
|
||||
|
||||
op_test: function(head: TOpusHead; const initial_data; initial_bytes: cuint): cint;cdecl;
|
||||
op_open_file: function(path: PAnsiChar; out error: cint): TOpusFile;cdecl;
|
||||
op_open_memory: function(const data; const _size: cuint; out error: cint): TOpusFile;cdecl;
|
||||
op_open_callbacks: function(const source; const cb: TOpusFileCallbacks;
|
||||
const initial_data; initial_bytes: cuint; out error: cint): TOpusFile; {$IFDEF windows} cdecl;{$ENDIF} // with cdecl ---> crash in linux, strange ???
|
||||
op_test_file: function(path: PAnsiChar; out error: cint): TOpusFile;cdecl;
|
||||
// op_test_url: function(path: PAnsiChar; out error: cint): TOpusFile;
|
||||
op_test_memory: function(const data; const size: cuint; out error: cint): TOpusFile;cdecl;
|
||||
op_test_callbacks: function(const source; const cb: TOpusFileCallbacks; const initial_data; initial_bytes: cuint;
|
||||
out error: cint): TOpusFile; {$IFDEF windows} cdecl;{$ENDIF} // with cdecl ---> crash in linux, strange ???
|
||||
op_test_open: function(OpusFile: TOpusFile): cint; cdecl;
|
||||
op_free: function(OpusFile: TOpusFile): cint; cdecl;
|
||||
|
||||
op_seekable: function(OpusFile: TOpusFile): cint;cdecl;
|
||||
op_link_count: function(OpusFile: TOpusFile): cint;cdecl;
|
||||
op_serialno: function(OpusFile: TOpusFile; li: pcint): Cardinal;cdecl;
|
||||
op_channel_count: function(OpusFile: TOpusFile; li: pcint): cint;cdecl;
|
||||
op_raw_total: function(OpusFile: TOpusFile; li: pcint): Int64;cdecl;
|
||||
op_pcm_total: function(OpusFile: TOpusFile; li: pcint): Int64;cdecl;
|
||||
op_head: function(OpusFile: TOpusFile; li: pcint): TOpusHead;cdecl;
|
||||
op_tags: function(OpusFile: TOpusFile; li: pcint): POpusTags;cdecl;
|
||||
op_current_link: function(OpusFile: TOpusFile): cint;cdecl;
|
||||
op_bitrate: function(OpusFile: TOpusFile; li: pcint): cint;cdecl;
|
||||
op_bitrate_instant: function(OpusFile: TOpusFile): cint;cdecl;
|
||||
op_raw_tell: function(OpusFile: TOpusFile): Int64;cdecl;
|
||||
op_pcm_tell: function(OpusFile: TOpusFile): Int64;cdecl;
|
||||
|
||||
op_raw_seek: function(OpusFile: TOpusFile; byte_offset: cInt64): cint;cdecl;
|
||||
op_pcm_seek: function(OpusFile: TOpusFile; pcm_offset: cInt64): cint;cdecl;
|
||||
|
||||
op_set_gain_offset: function(OpusFile: TOpusFile; gain_type: cint; gain_offset_q8: cint): cint;cdecl;
|
||||
op_set_dither_enabled: procedure(OpusFile: TOpusFile; enabled: cint);cdecl;
|
||||
|
||||
op_read: function(OpusFile: TOpusFile; pcm : pcint; SampleCount: cint; li: pcint): cint;cdecl;
|
||||
op_read_float: function(OpusFile: TOpusFile; pcm : pcfloat; SampleCount: cint; li: pcint): cint;cdecl;
|
||||
op_read_stereo: function(OpusFile: TOpusFile; pcm : pcint; SampleCount: cint): cint;cdecl;
|
||||
op_read_float_stereo: function(OpusFile: TOpusFile; pcm : pcfloat; SampleCount: cint): cint;cdecl;
|
||||
|
||||
of_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
|
||||
op_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
|
||||
{$IFDEF windows}
|
||||
lc_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
wt_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
og_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
{$endif}
|
||||
|
||||
ReferenceCounter : cardinal = 0;
|
||||
|
||||
function of_IsLoaded : boolean; inline;
|
||||
|
||||
Function of_Load(const libfilename:string) :boolean; // load the lib
|
||||
|
||||
Procedure of_Unload;
|
||||
|
||||
implementation
|
||||
|
||||
function of_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (of_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Procedure of_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if of_IsLoaded then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(of_Handle);
|
||||
of_Handle:=DynLibs.NilHandle;
|
||||
DynLibs.UnloadLibrary(op_Handle);
|
||||
op_Handle:=DynLibs.NilHandle;
|
||||
{$IFDEF windows}
|
||||
DynLibs.UnloadLibrary(lc_Handle);
|
||||
lc_Handle:=DynLibs.NilHandle;
|
||||
DynLibs.UnloadLibrary(wt_Handle);
|
||||
wt_Handle:=DynLibs.NilHandle;
|
||||
DynLibs.UnloadLibrary(og_Handle);
|
||||
og_Handle:=DynLibs.NilHandle;
|
||||
{$endif}
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
Function of_Load (const libfilename:string) :boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if of_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then
|
||||
begin
|
||||
{$IFDEF windows}
|
||||
wt_Handle:= DynLibs.SafeLoadLibrary('libwinpthread-1.dll');
|
||||
lc_Handle:= DynLibs.SafeLoadLibrary('libgcc_s_sjlj-1.dll');
|
||||
og_Handle:= DynLibs.SafeLoadLibrary('libogg-0.dll');
|
||||
op_Handle:= DynLibs.SafeLoadLibrary('libopus-0.dll');
|
||||
{$else}
|
||||
op_Handle:= DynLibs.SafeLoadLibrary('libopus.so');
|
||||
{$endif}
|
||||
of_Handle:=DynLibs.SafeLoadLibrary(libop);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{$IFDEF windows}
|
||||
wt_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libwinpthread-1.dll');
|
||||
lc_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libgcc_s_sjlj-1.dll');
|
||||
og_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libogg-0.dll');
|
||||
op_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libopus-0.dll');
|
||||
{$else}
|
||||
op_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libopus.so');
|
||||
{$endif}
|
||||
of_Handle:=DynLibs.SafeLoadLibrary(libfilename);
|
||||
end;
|
||||
|
||||
|
||||
if of_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
Pointer(op_fopen):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_fopen'));
|
||||
Pointer(op_freopen):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_freopen'));
|
||||
Pointer(op_mem_stream_create):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_mem_stream_create'));
|
||||
Pointer(opus_head_parse):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_head_parse'));
|
||||
Pointer(opus_granule_sample):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_granule_sample'));
|
||||
Pointer(opus_tags_parse):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_parse'));
|
||||
Pointer(opus_tags_copy):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_copy'));
|
||||
Pointer(opus_tags_init):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_init'));
|
||||
Pointer(opus_tags_add):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_add'));
|
||||
Pointer(opus_tags_add_comment):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_add_comment'));
|
||||
Pointer(opus_tags_set_binary_suffix):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_set_binary_suffix'));
|
||||
Pointer(opus_tags_query):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_query'));
|
||||
Pointer(opus_tags_query_count):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_query_count'));
|
||||
Pointer(opus_tags_get_binary_suffix):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_get_binary_suffix'));
|
||||
Pointer(opus_tags_get_album_gain):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_get_album_gain'));
|
||||
Pointer(opus_tags_get_track_gain):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_get_track_gain'));
|
||||
Pointer(opus_tags_clear):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tags_clear'));
|
||||
Pointer(opus_tagcompare):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tagcompare'));
|
||||
Pointer(opus_tagncompare):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_tagncompare'));
|
||||
Pointer(opus_picture_tag_parse):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_picture_tag_parse'));
|
||||
Pointer(opus_picture_tag_init):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_picture_tag_init'));
|
||||
Pointer(opus_picture_tag_clear):=DynLibs.GetProcedureAddress(OF_Handle,PChar('opus_picture_tag_clear'));
|
||||
Pointer(op_test):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test'));
|
||||
Pointer(op_free):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_free'));
|
||||
Pointer(op_open_file):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_open_file'));
|
||||
Pointer(op_open_memory):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_open_memory'));
|
||||
Pointer(op_open_callbacks):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_open_callbacks'));
|
||||
Pointer(op_test_file):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_file'));
|
||||
//Pointer(op_test_url):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_url'));
|
||||
Pointer(op_test_memory):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_memory'));
|
||||
Pointer(op_test_callbacks):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_callbacks'));
|
||||
Pointer(op_test_open):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_test_open'));
|
||||
Pointer(op_seekable):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_seekable'));
|
||||
Pointer(op_link_count):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_link_count'));
|
||||
Pointer(op_serialno):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_serialno'));
|
||||
Pointer(op_channel_count):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_channel_count'));
|
||||
Pointer(op_raw_total):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_raw_total'));
|
||||
Pointer(op_pcm_total):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_pcm_total'));
|
||||
Pointer(op_head):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_head'));
|
||||
Pointer(op_tags):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_tags'));
|
||||
Pointer(op_current_link):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_current_link'));
|
||||
Pointer(op_bitrate):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_bitrate'));
|
||||
Pointer(op_bitrate_instant):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_bitrate_instant'));
|
||||
Pointer(op_raw_tell):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_raw_tell'));
|
||||
Pointer(op_raw_seek):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_raw_seek'));
|
||||
Pointer(op_pcm_seek):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_pcm_seek'));
|
||||
Pointer(op_set_gain_offset):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_set_gain_offset'));
|
||||
Pointer(op_set_dither_enabled):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_set_dither_enabled'));
|
||||
Pointer(op_read):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read'));
|
||||
Pointer(op_read_float):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read_float'));
|
||||
Pointer(op_read_stereo):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read_stereo'));
|
||||
Pointer(op_read_float_stereo):=DynLibs.GetProcedureAddress(OF_Handle,PChar('op_read_float_stereo'));
|
||||
|
||||
end;
|
||||
Result := of_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function OpusReadCB(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
begin
|
||||
if nbytes<>0
|
||||
then
|
||||
result := FileRead(THandle(stream^), Buffer, nbytes)
|
||||
else
|
||||
result := 0;
|
||||
end;
|
||||
|
||||
function OpusReadCBuosURL(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
begin
|
||||
if nbytes<>0
|
||||
then
|
||||
result := TInputPipeStream(stream^).read(Buffer, nbytes)
|
||||
else
|
||||
result := 0;
|
||||
end;
|
||||
|
||||
function OpusReadCBuosMS(stream: Pointer; var buffer; nbytes: cint): cint; cdecl;
|
||||
begin
|
||||
if nbytes<>0
|
||||
then
|
||||
result := TMemoryStream(stream^).read(Buffer, nbytes)
|
||||
else
|
||||
result := 0;
|
||||
end;
|
||||
|
||||
function OpusSeekCB(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
|
||||
var
|
||||
Seek_Result: Int64;
|
||||
begin
|
||||
Seek_Result := FileSeek(THandle(stream^), offset, whence);
|
||||
if Seek_Result=-1
|
||||
then
|
||||
Result := -1
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function OpusTellCB(stream: Pointer): Int64; cdecl;
|
||||
begin
|
||||
Result := FileSeek(THandle(stream^), 0, 1);
|
||||
end;
|
||||
|
||||
function OpusSeekCBms(stream: Pointer; offset: Int64; whence: cint): cint; cdecl;
|
||||
var
|
||||
Seek_Result: Int64;
|
||||
begin
|
||||
Seek_Result := TMemoryStream(stream^).seek(offset, whence);
|
||||
if Seek_Result=-1
|
||||
then
|
||||
Result := -1
|
||||
else
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function OpusTellCBms(stream: Pointer): Int64; cdecl;
|
||||
begin
|
||||
Result := TMemoryStream(stream^).seek(0, 1);
|
||||
end;
|
||||
|
||||
function OpusCloseCB(stream: Pointer): cint; cdecl;
|
||||
begin
|
||||
FileClose(THandle(stream^));
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
end.
|
||||
93
UOS/src/uos_opusurl.pas
Normal file
93
UOS/src/uos_opusurl.pas
Normal file
@@ -0,0 +1,93 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Pascal Wrapper + Dynamic loading of OpusURL library.
|
||||
Load library with ou_load() and release with ou_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com}
|
||||
|
||||
unit uos_Opusurl;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ctypes, uos_Opusfile, dynlibs, SysUtils;
|
||||
|
||||
// Error Codes
|
||||
const
|
||||
OP_FALSE = -1;
|
||||
OP_HOLE = -3;
|
||||
OP_EREAD = -128;
|
||||
OP_EFAULT = -129;
|
||||
OP_EIMPL = -130;
|
||||
OP_EINVAL = -131;
|
||||
OP_ENOTVORBIS = -132;
|
||||
OP_EBADHEADER = -133;
|
||||
OP_EVERSION = -134;
|
||||
OP_ENOTAUDIO = -135;
|
||||
OP_EBADPACKET = -136;
|
||||
OP_EBADLINK = -137;
|
||||
OP_ENOSEEK = -138;
|
||||
OP_EBADTIMESTAMP = -139;
|
||||
|
||||
var
|
||||
|
||||
op_open_url: function(path: PAnsiChar; out error: Integer): TOpusFile;
|
||||
op_test_url: function(path: PAnsiChar; out error: Integer): TOpusFile;
|
||||
|
||||
ou_Handle:TLibHandle=dynlibs.NilHandle;
|
||||
|
||||
ReferenceCounter : cardinal = 0; // Reference counter
|
||||
|
||||
function ou_IsLoaded : boolean; inline;
|
||||
|
||||
Function ou_Load(const libfilename:string) :boolean; // load the lib
|
||||
|
||||
Procedure ou_Unload;
|
||||
|
||||
implementation
|
||||
|
||||
function ou_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (ou_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Procedure ou_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if ou_IsLoaded then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(ou_Handle);
|
||||
ou_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function ou_Load (const libfilename:string) :boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if ou_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then exit;
|
||||
ou_Handle:=DynLibs.SafeLoadLibrary(libfilename); // obtain the handle we want
|
||||
if ou_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
Pointer(op_open_url):=DynLibs.GetProcedureAddress(OU_Handle,PChar('op_open_url'));
|
||||
Pointer(op_test_url):=DynLibs.GetProcedureAddress(OU_Handle,PChar('op_test_url'));
|
||||
end;
|
||||
Result := ou_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
389
UOS/src/uos_portaudio.pas
Normal file
389
UOS/src/uos_portaudio.pas
Normal file
@@ -0,0 +1,389 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading version of PortAudio Pascal Wrapper.
|
||||
Load library with pa_load() and release with pa_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com
|
||||
Reference counting added by Max Karpushin / homeplaner@yandex.ru}
|
||||
|
||||
unit uos_portaudio;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs, CTypes;
|
||||
|
||||
const
|
||||
libpa=
|
||||
{$IFDEF unix}
|
||||
{$IFDEF darwin}
|
||||
'libportaudio.2.dylib';
|
||||
{$ELSE}
|
||||
'libportaudio.so.2';
|
||||
{$ENDIF}
|
||||
{$ELSE}
|
||||
'portaudio.dll';
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
PaError = CInt32;
|
||||
PaErrorCode =(
|
||||
paNotInitialized := -10000,
|
||||
paUnanticipatedHostError,
|
||||
paInvalidChannelCount,
|
||||
paInvalidSampleRate,
|
||||
paInvalidDevice,
|
||||
paInvalidFlag,
|
||||
paSampleFormatNotSupported,
|
||||
paBadIODeviceCombination,
|
||||
paInsufficientMemory,
|
||||
paBufferTooBig,
|
||||
paBufferTooSmall,
|
||||
paNullCallback,
|
||||
paBadStreamPtr,
|
||||
paTimedOut,
|
||||
paInternalError,
|
||||
paDeviceUnavailable,
|
||||
paIncompatibleHostApiSpecificStreamInfo,
|
||||
paStreamIsStopped,
|
||||
paStreamIsNotStopped,
|
||||
paInputOverflowed,
|
||||
paOutputUnderflowed,
|
||||
paHostApiNotFound,
|
||||
paInvalidHostApi,
|
||||
paCanNotReadFromACallbackStream,
|
||||
paCanNotWriteToACallbackStream,
|
||||
paCanNotReadFromAnOutputOnlyStream,
|
||||
paCanNotWriteToAnInputOnlyStream,
|
||||
paIncompatibleStreamHostApi,
|
||||
paBadBufferPtr,
|
||||
paNoError := 0
|
||||
);
|
||||
|
||||
PaDeviceIndex = CInt32;
|
||||
|
||||
PaHostApiIndex = CInt32;
|
||||
|
||||
PaHostApiTypeId =(paInDevelopment := 0,
|
||||
paDirectSound := 1,
|
||||
paMME := 2,
|
||||
paASIO := 3,
|
||||
paSoundManager := 4,
|
||||
paCoreAudio := 5,
|
||||
paOSS := 7,
|
||||
paALSA := 8,
|
||||
paAL := 9,
|
||||
paBeOS := 10,
|
||||
paWDMKS := 11,
|
||||
paJACK := 12,
|
||||
paWASAPI := 13,
|
||||
paAudioScienceHPI := 14
|
||||
);
|
||||
|
||||
PaHostApiInfo = record
|
||||
structVersion : CInt32;
|
||||
_type : PaHostApiTypeId ;
|
||||
_name : Pchar;
|
||||
deviceCount : CInt32;
|
||||
defaultInputDevice : PaDeviceIndex;
|
||||
defaultOutputDevice : PaDeviceIndex;
|
||||
end;
|
||||
PPaHostApiInfo = ^PaHostApiInfo;
|
||||
|
||||
PaHostErrorInfo = record
|
||||
hostApiType : PaHostApiTypeId;
|
||||
errorCode : CLong;
|
||||
errorText : PChar;
|
||||
end;
|
||||
PPaHostErrorInfo = ^PaHostErrorInfo;
|
||||
|
||||
PaTime = CDouble;
|
||||
|
||||
PaSampleFormat = pCULongLong;
|
||||
|
||||
PaDeviceInfo = record
|
||||
structVersion : CInt32;
|
||||
_name : PChar;
|
||||
hostApi : PaHostApiIndex;
|
||||
maxInputChannels : CInt32;
|
||||
maxOutputChannels : CInt32;
|
||||
defaultLowInputLatency : PaTime;
|
||||
defaultLowOutputLatency : PaTime;
|
||||
defaultHighInputLatency : PaTime;
|
||||
defaultHighOutputLatency : PaTime;
|
||||
defaultSampleRate : CDouble;
|
||||
end;
|
||||
PPaDeviceInfo = ^PaDeviceInfo;
|
||||
|
||||
PaStreamParameters = record
|
||||
device : PaDeviceIndex;
|
||||
channelCount : CInt32;
|
||||
sampleFormat : PaSampleFormat;
|
||||
suggestedLatency : PaTime;
|
||||
hostApiSpecificStreamInfo : Pointer;
|
||||
end;
|
||||
PPaStreamParameters = ^PaStreamParameters;
|
||||
|
||||
// ************************* Streaming types *************************
|
||||
|
||||
PaStream = Pointer;
|
||||
PPaStream = ^PaStream;
|
||||
PPPaStream = ^PPaStream;
|
||||
|
||||
PaStreamFlags = CULong;
|
||||
|
||||
PaStreamCallbackTimeInfo = record
|
||||
inputBufferAdcTime : PaTime;
|
||||
currentTime : PaTime;
|
||||
outputBufferDacTime : PaTime;
|
||||
end;
|
||||
PPaStreamCallbackTimeInfo = ^PaStreamCallbackTimeInfo;
|
||||
|
||||
PaStreamCallbackFlags = CULong;
|
||||
|
||||
PaStreamCallbackResult =(
|
||||
paContinue := 0,
|
||||
paComplete := 1,
|
||||
paAbort := 2);
|
||||
|
||||
PaStreamCallback = function(
|
||||
input : Pointer;
|
||||
output : Pointer;
|
||||
frameCount : CULong;
|
||||
timeInfo : PPaStreamCallbackTimeInfo;
|
||||
statusFlags : PaStreamCallbackFlags;
|
||||
userData : Pointer) : CInt32;
|
||||
PPaStreamCallback = ^PaStreamCallback;
|
||||
|
||||
PaStreamFinishedCallback = procedure(userData : Pointer);
|
||||
PPaStreamFinishedCallback = ^PaStreamFinishedCallback;
|
||||
|
||||
PaStreamInfo = record
|
||||
structVersion : CInt32;
|
||||
inputLatency : PaTime;
|
||||
outputLatency : PaTime;
|
||||
sampleRate : CDouble;
|
||||
end;
|
||||
PPaStreamInfo = ^PaStreamInfo;
|
||||
|
||||
const
|
||||
paFormatIsSupported = 0;
|
||||
paFramesPerBufferUnspecified = 0;
|
||||
paNoDevice = PaDeviceIndex(-1);
|
||||
paUseHostApiSpecificDeviceSpecification = PaDeviceIndex(-2);
|
||||
paFloat32 = PaSampleFormat($00000001);
|
||||
paInt32 = PaSampleFormat($00000002);
|
||||
paInt24 = PaSampleFormat($00000004);
|
||||
paInt16 = PaSampleFormat($00000008);
|
||||
paInt8 = PaSampleFormat($00000010);
|
||||
paUInt8 = PaSampleFormat($00000020);
|
||||
paCustomFormat = PaSampleFormat($00010000);
|
||||
paNonInterleaved = PaSampleFormat($80000000);
|
||||
paNoFlag = PaStreamFlags(0);
|
||||
paClipOff = PaStreamFlags($00000001);
|
||||
paDitherOff = PaStreamFlags($00000002);
|
||||
paNeverDropInput = PaStreamFlags($00000004);
|
||||
paPrimeOutputBuffersUsingStreamCallback = PaStreamFlags($00000008);
|
||||
paPlatformSpecificFlags = PaStreamFlags($FFFF0000);
|
||||
paInputUnderflow = PaStreamCallbackFlags($00000001);
|
||||
paInputOverflow = PaStreamCallbackFlags($00000002);
|
||||
paOutputUnderflow = PaStreamCallbackFlags($00000004);
|
||||
paOutputOverflow = PaStreamCallbackFlags($00000008);
|
||||
paPrimingOutput = PaStreamCallbackFlags($00000010);
|
||||
|
||||
////// Dynamic load : Vars that will hold our dynamically loaded functions...
|
||||
|
||||
// *************************** functions *******************************
|
||||
|
||||
var Pa_GetVersion: function():CInt32 ; cdecl;
|
||||
|
||||
var Pa_GetVersionText: function():PChar ; cdecl;
|
||||
|
||||
var Pa_GetErrorText: function(errorCode : PaError):PChar ; cdecl;
|
||||
|
||||
var Pa_Initialize: function():PaError ; cdecl;
|
||||
|
||||
var Pa_Terminate: function():PaError ; cdecl;
|
||||
|
||||
var Pa_GetHostApiCount: function():PaHostApiIndex ; cdecl;
|
||||
|
||||
var Pa_GetDefaultHostApi: function():PaHostApiIndex ; cdecl;
|
||||
|
||||
var Pa_GetHostApiInfo: function(hostApi : PaHostApiIndex):PPaHostApiInfo ; cdecl;
|
||||
|
||||
var Pa_HostApiTypeIdToHostApiIndex: function(_type : PaHostApiTypeId):PaHostApiIndex ; cdecl;
|
||||
|
||||
var Pa_HostApiDeviceIndexToDeviceIndex: function(hostApi : PaHostApiIndex;hostApiDeviceIndex : CInt32):PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetLastHostErrorInfo: function():PPaHostErrorInfo ; cdecl;
|
||||
|
||||
// ************** Device enumeration and capabilities ******************
|
||||
|
||||
var Pa_GetDeviceCount: function:PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetDefaultInputDevice: function:PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetDefaultOutputDevice: function:PaDeviceIndex ; cdecl;
|
||||
|
||||
var Pa_GetDeviceInfo: function(device : PaDeviceIndex):PPaDeviceInfo ; cdecl;
|
||||
|
||||
var Pa_IsFormatSupported: function(inputParameters,outputParameters : PPaStreamParameters; sampleRate : CDouble):PaError ; cdecl;
|
||||
|
||||
// *********************** Stream function *****************************
|
||||
|
||||
var Pa_OpenStream: function(stream : PPPaStream;
|
||||
inputParameters : PPaStreamParameters;
|
||||
outputParameters : PPaStreamParameters;
|
||||
sampleRate : CDouble;
|
||||
framesPerBuffer : CULong;
|
||||
streamFlags : PaStreamFlags;
|
||||
streamCallback : PPaStreamCallback;
|
||||
userData : Pointer):PaError ; cdecl;
|
||||
|
||||
var Pa_OpenDefaultStream: function(stream : PPPaStream;
|
||||
numInputChannels : CInt32;
|
||||
numOutputChannels : CInt32;
|
||||
sampleFormat : PaSampleFormat;
|
||||
sampleRate : CDouble;
|
||||
framesPerBuffer : CULong;
|
||||
streamCallback : PPaStreamCallback;
|
||||
userData : Pointer):PaError ; cdecl;
|
||||
|
||||
var Pa_CloseStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_SetStreamFinishedCallback: function(stream : PPaStream;
|
||||
streamFinishedCallback : PPaStreamFinishedCallback):PaError ; cdecl;
|
||||
|
||||
var Pa_StartStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_StopStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_AbortStream: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_IsStreamStopped: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_IsStreamActive: function(stream : PPaStream):PaError ; cdecl;
|
||||
|
||||
var Pa_GetStreamInfo: function(stream : PPaStream):PPaStreamInfo ; cdecl;
|
||||
|
||||
var Pa_GetStreamTime: function(stream : PPaStream):Patime ; cdecl;
|
||||
|
||||
var Pa_GetStreamCpuLoad: function(stream : PPaStream):CDouble ; cdecl;
|
||||
|
||||
var Pa_ReadStream: function(stream : PPaStream; buffer : pcfloat ;frames : CULong):PaError ; cdecl;
|
||||
|
||||
var Pa_WriteStream: function(stream : PPaStream; buffer : pcfloat ;frames : CULong):PaError ; cdecl;
|
||||
|
||||
var Pa_GetStreamReadAvailable: function(stream : PPaStream):CSLong ; cdecl;
|
||||
|
||||
var Pa_GetStreamWriteAvailable: function(stream : PPaStream):CSLong ; cdecl;
|
||||
|
||||
// ****************** Miscellaneous utilities **************************
|
||||
|
||||
var Pa_GetSampleSize: function(format : PaSampleFormat):PaError ; cdecl;
|
||||
|
||||
var Pa_Sleep: function(msec : CLong) : integer; cdecl;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
{Special function for dynamic loading of lib ...}
|
||||
|
||||
var Pa_Handle:TLibHandle=dynlibs.NilHandle; // this will hold our handle for the lib; it functions nicely as a mutli-lib prevention unit as well...
|
||||
|
||||
var ReferenceCounter : cardinal = 0; // Reference counter
|
||||
|
||||
function Pa_IsLoaded : boolean; inline;
|
||||
|
||||
Function Pa_Load(const libfilename:string) :boolean; // load the lib
|
||||
|
||||
Procedure Pa_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
implementation
|
||||
|
||||
function Pa_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (Pa_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Function Pa_Load (const libfilename:string) :boolean;
|
||||
var
|
||||
thelib: string;
|
||||
begin
|
||||
Result := False;
|
||||
if Pa_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then thelib := libpa else thelib := libfilename;
|
||||
Pa_Handle:=DynLibs.SafeLoadLibrary(thelib); // obtain the handle we want
|
||||
if Pa_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
|
||||
Pointer(Pa_GetVersion):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetVersion'));
|
||||
Pointer(Pa_GetVersionText):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetVersionText'));
|
||||
Pointer(Pa_GetErrorText):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetErrorText'));
|
||||
Pointer(Pa_Initialize):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_Initialize'));
|
||||
Pointer(Pa_Terminate):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_Terminate'));
|
||||
Pointer(Pa_GetHostApiCount):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetHostApiCount'));
|
||||
Pointer(Pa_GetDefaultHostApi):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDefaultHostApi'));
|
||||
Pointer(Pa_GetHostApiInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetHostApiInfo'));
|
||||
Pointer(Pa_HostApiTypeIdToHostApiIndex):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_HostApiTypeIdToHostApiIndex'));
|
||||
Pointer(Pa_HostApiDeviceIndexToDeviceIndex):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_HostApiDeviceIndexToDeviceIndex'));
|
||||
Pointer(Pa_GetLastHostErrorInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetLastHostErrorInfo'));
|
||||
//////////////////
|
||||
Pointer(Pa_GetDeviceCount):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDeviceCount'));
|
||||
Pointer(Pa_GetDefaultInputDevice):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDefaultInputDevice'));
|
||||
Pointer(Pa_GetDefaultOutputDevice):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDefaultOutputDevice'));
|
||||
Pointer(Pa_GetDeviceInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetDeviceInfo'));
|
||||
Pointer(Pa_IsFormatSupported):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_IsFormatSupported'));
|
||||
//////////////////////
|
||||
Pointer(Pa_OpenStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_OpenStream'));
|
||||
Pointer(Pa_OpenDefaultStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_OpenDefaultStream'));
|
||||
Pointer(Pa_CloseStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_CloseStream'));
|
||||
Pointer(Pa_SetStreamFinishedCallback):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_SetStreamFinishedCallback'));
|
||||
Pointer(Pa_StartStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_StartStream'));
|
||||
Pointer(Pa_StopStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_StopStream'));
|
||||
Pointer(Pa_AbortStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_AbortStream'));
|
||||
Pointer(Pa_IsStreamStopped):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_IsStreamStopped'));
|
||||
Pointer(Pa_IsStreamActive):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_IsStreamActive'));
|
||||
Pointer(Pa_GetStreamInfo):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamInfo'));
|
||||
Pointer(Pa_GetStreamTime):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamTime'));
|
||||
Pointer(Pa_GetStreamCpuLoad):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamCpuLoad'));
|
||||
Pointer(Pa_ReadStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_ReadStream'));
|
||||
Pointer(Pa_WriteStream):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_WriteStream'));
|
||||
Pointer(Pa_GetStreamReadAvailable):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamReadAvailable'));
|
||||
Pointer(Pa_GetStreamWriteAvailable):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetStreamWriteAvailable'));
|
||||
Pointer(Pa_GetSampleSize):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_GetSampleSize'));
|
||||
Pointer(Pa_Sleep):=DynLibs.GetProcedureAddress(PA_Handle,PChar('Pa_Sleep'));
|
||||
end;
|
||||
Result := Pa_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
Procedure Pa_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if Pa_IsLoaded then
|
||||
begin
|
||||
Pa_Terminate();
|
||||
DynLibs.UnloadLibrary(Pa_Handle);
|
||||
Pa_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
264
UOS/src/uos_shout.pas
Normal file
264
UOS/src/uos_shout.pas
Normal file
@@ -0,0 +1,264 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading version of IceCast_Shout Pascal Wrapper.
|
||||
Load library with sha_load() and release with sh_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com }
|
||||
|
||||
unit uos_shout;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs, CTypes, sysutils;
|
||||
|
||||
const
|
||||
SHOUT_THREADSAFE = 1;
|
||||
SHOUT_TLS = 1;
|
||||
SHOUTERR_SUCCESS = 0;
|
||||
SHOUTERR_INSANE = -1;
|
||||
SHOUTERR_NOCONNECT = -2;
|
||||
SHOUTERR_NOLOGIN = -3;
|
||||
SHOUTERR_SOCKET = -4;
|
||||
SHOUTERR_MALLOC = -5;
|
||||
SHOUTERR_METADATA = -6;
|
||||
SHOUTERR_CONNECTED = -7;
|
||||
SHOUTERR_UNCONNECTED = -8;
|
||||
SHOUTERR_UNSUPPORTED = -9;
|
||||
SHOUTERR_BUSY = -10;
|
||||
SHOUTERR_NOTLS = -11;
|
||||
SHOUTERR_TLSBADCERT = -12;
|
||||
SHOUTERR_RETRY = -13;
|
||||
SHOUT_FORMAT_OGG = 0;
|
||||
SHOUT_FORMAT_MP3 = 1;
|
||||
SHOUT_FORMAT_WEBM = 2;
|
||||
SHOUT_FORMAT_WEBMAUDIO = 3;
|
||||
SHOUT_FORMAT_VORBIS = SHOUT_FORMAT_OGG;
|
||||
SHOUT_PROTOCOL_HTTP = 0;
|
||||
SHOUT_PROTOCOL_XAUDIOCAST = 1;
|
||||
SHOUT_PROTOCOL_ICY = 2;
|
||||
SHOUT_PROTOCOL_ROARAUDIO = 3;
|
||||
SHOUT_TLS_DISABLED = 0;
|
||||
SHOUT_TLS_AUTO = 1;
|
||||
SHOUT_TLS_AUTO_NO_PLAIN = 2;
|
||||
SHOUT_TLS_RFC2818 = 11;
|
||||
SHOUT_TLS_RFC2817 = 12;
|
||||
SHOUT_AI_BITRATE = 'bitrate';
|
||||
SHOUT_AI_SAMPLERATE = 'samplerate';
|
||||
SHOUT_AI_CHANNELS = 'channels';
|
||||
SHOUT_AI_QUALITY = 'quality';
|
||||
SHOUT_META_NAME = 'name';
|
||||
SHOUT_META_URL = 'url';
|
||||
SHOUT_META_GENRE = 'genre';
|
||||
SHOUT_META_DESCRIPTION = 'description';
|
||||
SHOUT_META_IRC = 'irc';
|
||||
SHOUT_META_AIM = 'aim';
|
||||
SHOUT_META_ICQ = 'icq';
|
||||
|
||||
type
|
||||
shout_t = pointer;
|
||||
Pshout_t = ^shout_t;
|
||||
{$if defined(cpu64)}
|
||||
cuint64 = qword;
|
||||
size_t = cuint64;
|
||||
{$else}
|
||||
cuint32 = longword;
|
||||
size_t = cuint32;
|
||||
{$endif}
|
||||
|
||||
psize_t = ^size_t;
|
||||
|
||||
shout_metadata_t = pointer;
|
||||
Pshout_metadata_t = ^shout_metadata_t;
|
||||
|
||||
// methods
|
||||
var
|
||||
|
||||
shout_init: procedure();cdecl;
|
||||
shout_shutdown: procedure();cdecl;
|
||||
shout_version: function(var major:cint; var minor:cint; var patch:cint):pchar;cdecl;
|
||||
shout_new: function(): Pshout_t;cdecl;
|
||||
shout_free: procedure(shhandle :Pshout_t);cdecl;
|
||||
shout_get_error: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_get_errno: function(shhandle :Pshout_t):cint;cdecl;
|
||||
shout_get_connected: function(shhandle :Pshout_t):cint;cdecl;
|
||||
shout_set_host: function(shhandle :Pshout_t; host: pchar):cint;cdecl;
|
||||
shout_get_host: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_port: function(shhandle :Pshout_t; port:cushort):cint;cdecl;
|
||||
shout_get_port: function(shhandle :Pshout_t):cushort;cdecl;
|
||||
shout_set_agent: function(shhandle :Pshout_t; agent:pchar):cint;cdecl;
|
||||
shout_get_agent: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_tls: function(shhandle :Pshout_t; mode:cint):cint;cdecl;
|
||||
shout_get_tls: function(shhandle :Pshout_t):cint;cdecl;
|
||||
shout_set_ca_directory: function(shhandle :Pshout_t; directory:pchar):cint;cdecl;
|
||||
shout_get_ca_directory: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_ca_file: function(shhandle :Pshout_t; thefile:pchar):cint;cdecl;
|
||||
shout_get_ca_file: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_allowed_ciphers: function(shhandle :Pshout_t; ciphers:pchar):cint;cdecl;
|
||||
shout_get_allowed_ciphers: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_user: function(shhandle :Pshout_t; username:pchar):cint;cdecl;
|
||||
shout_get_user: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_password: function(shhandle :Pshout_t; password:pchar):cint;cdecl;
|
||||
shout_get_password: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_client_certificate: function(shhandle :Pshout_t; certificate:pchar):cint;cdecl;
|
||||
shout_get_client_certificate: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_mount: function(shhandle :Pshout_t; mount:pchar):cint;cdecl;
|
||||
shout_get_mount: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_name: function(shhandle :Pshout_t; name:pchar):cint;cdecl;
|
||||
shout_get_name: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_url: function(shhandle :Pshout_t; url:pchar):cint;cdecl;
|
||||
shout_get_url: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_genre: function(shhandle :Pshout_t; genre:pchar):cint;cdecl;
|
||||
shout_get_genre: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_description: function(shhandle :Pshout_t; description:pchar):cint;cdecl;
|
||||
shout_get_description: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_dumpfile: function(shhandle :Pshout_t; dumpfile:pchar):cint;cdecl;
|
||||
shout_get_dumpfile: function(shhandle :Pshout_t):pchar;cdecl;
|
||||
shout_set_audio_info: function(shhandle :Pshout_t; name:pchar; value:pchar):cint;cdecl;
|
||||
shout_get_audio_info: function(shhandle :Pshout_t; name:pchar):pchar;cdecl;
|
||||
shout_set_meta: function(shhandle :Pshout_t; name:pchar; value:pchar):cint;cdecl;
|
||||
shout_get_meta: function(shhandle :Pshout_t; name:pchar):pchar;cdecl;
|
||||
shout_set_public: function(shhandle :Pshout_t; make_public:cuint):cint;cdecl;
|
||||
shout_get_public: function(shhandle :Pshout_t):cuint;cdecl;
|
||||
shout_set_format: function(shhandle :Pshout_t; format:cuint):cint;cdecl;
|
||||
shout_get_format: function(shhandle :Pshout_t):cuint;cdecl;
|
||||
shout_set_protocol: function(shhandle :Pshout_t; protocol:cuint):cint;cdecl;
|
||||
shout_get_protocol: function(shhandle :Pshout_t):cuint;cdecl;
|
||||
shout_set_nonblocking: function(shhandle :Pshout_t; nonblocking:cuint):cint;cdecl;
|
||||
shout_get_nonblocking: function(shhandle :Pshout_t):cuint;cdecl;
|
||||
shout_open: function(shhandle :Pshout_t):cint;cdecl;
|
||||
shout_close: function(shhandle :Pshout_t):cint;cdecl;
|
||||
//shout_send: function(shhandle :Pshout_t; data:pcuchar; len:size_t):cint;cdecl;
|
||||
shout_send: function(shhandle :Pshout_t; data:pbyte; len:size_t):cint;cdecl;
|
||||
shout_send_raw: function(shhandle :Pshout_t; data:pcuchar; len:size_t):size_t;cdecl;
|
||||
shout_queuelen: function(shhandle :Pshout_t):size_t;cdecl;
|
||||
shout_sync: procedure(shhandle :Pshout_t);cdecl;
|
||||
shout_delay: function(shhandle :Pshout_t):cint;cdecl;
|
||||
shout_set_metadata: function(shhandle :Pshout_t; var metadata:shout_metadata_t):cint;cdecl;
|
||||
shout_metadata_new: function():Pshout_metadata_t;cdecl;
|
||||
shout_metadata_free: procedure(var shhandle:shout_metadata_t);cdecl;
|
||||
shout_metadata_add: function(var shhandle:shout_metadata_t; name:pchar; value:pchar):cint;cdecl;
|
||||
|
||||
sh_Handle:TLibHandle=dynlibs.NilHandle; // this will hold our handle for the lib; it functions nicely as a mutli-lib prevention unit as well...
|
||||
|
||||
ReferenceCounter : cardinal = 0; // Reference counter
|
||||
|
||||
function sh_IsLoaded : boolean; inline;
|
||||
|
||||
Function sh_Load(const libfilename:string) :boolean; // load the lib
|
||||
|
||||
Procedure sh_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
function sh_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (sh_Handle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
Function sh_Load (const libfilename:string) :boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if sh_Handle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true {is it already there ?}
|
||||
end else
|
||||
begin {go & load the library}
|
||||
if Length(libfilename) = 0 then exit;
|
||||
sh_Handle:=DynLibs.SafeLoadLibrary(libfilename); // obtain the handle we want
|
||||
if sh_Handle <> DynLibs.NilHandle then
|
||||
begin {now we tie the functions to the VARs from above}
|
||||
|
||||
Pointer(shout_init):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_init'));
|
||||
Pointer(shout_shutdown):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_shutdown'));
|
||||
Pointer(shout_version):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_version'));
|
||||
Pointer(shout_new):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_new'));
|
||||
Pointer(shout_free):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_free'));
|
||||
Pointer(shout_get_error):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_error'));
|
||||
Pointer(shout_get_errno):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_errno'));
|
||||
Pointer(shout_get_connected):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_connected'));
|
||||
Pointer(shout_set_host):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_host'));
|
||||
Pointer(shout_get_host):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_host'));
|
||||
Pointer(shout_set_port):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_port'));
|
||||
Pointer(shout_get_port):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_port'));
|
||||
Pointer(shout_set_agent):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_agent'));
|
||||
Pointer(shout_get_agent):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_agent'));
|
||||
Pointer(shout_set_tls):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_tls'));
|
||||
Pointer(shout_get_tls):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_tls'));
|
||||
Pointer(shout_set_ca_directory):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_ca_directory'));
|
||||
Pointer(shout_get_ca_directory):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_ca_directory'));
|
||||
Pointer(shout_set_ca_file):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_ca_file'));
|
||||
Pointer(shout_get_ca_file):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_ca_file'));
|
||||
Pointer(shout_set_allowed_ciphers):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_allowed_ciphers'));
|
||||
Pointer(shout_get_allowed_ciphers):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_allowed_ciphers'));
|
||||
Pointer(shout_set_user):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_user'));
|
||||
Pointer(shout_get_user):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_user'));
|
||||
Pointer(shout_set_password):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_password'));
|
||||
Pointer(shout_get_password):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_password'));
|
||||
Pointer(shout_set_client_certificate):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_client_certificate'));
|
||||
Pointer(shout_get_client_certificate):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_client_certificate'));
|
||||
Pointer(shout_set_mount):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_mount'));
|
||||
Pointer(shout_get_mount):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_mount'));
|
||||
Pointer(shout_set_name):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_name'));
|
||||
Pointer(shout_get_name):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_name'));
|
||||
Pointer(shout_set_url):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_url'));
|
||||
Pointer(shout_get_url):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_url'));
|
||||
Pointer(shout_set_genre):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_genre'));
|
||||
Pointer(shout_get_genre):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_genre'));
|
||||
Pointer(shout_set_description):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_description'));
|
||||
Pointer(shout_get_description):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_description'));
|
||||
Pointer(shout_set_dumpfile):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_dumpfile'));
|
||||
Pointer(shout_get_dumpfile):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_dumpfile'));
|
||||
Pointer(shout_set_audio_info):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_audio_info'));
|
||||
Pointer(shout_get_audio_info):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_audio_info'));
|
||||
Pointer(shout_set_meta):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_meta'));
|
||||
Pointer(shout_get_meta):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_meta'));
|
||||
Pointer(shout_set_public):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_public'));
|
||||
Pointer(shout_get_public):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_public'));
|
||||
Pointer(shout_set_format):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_format'));
|
||||
Pointer(shout_get_format):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_format'));
|
||||
Pointer(shout_set_protocol):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_protocol'));
|
||||
Pointer(shout_get_protocol):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_protocol'));
|
||||
Pointer(shout_set_nonblocking):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_nonblocking'));
|
||||
Pointer(shout_get_nonblocking):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_nonblocking'));
|
||||
Pointer(shout_open):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_open'));
|
||||
Pointer(shout_close):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_close'));
|
||||
Pointer(shout_send):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_send'));
|
||||
Pointer(shout_send_raw):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_send_raw'));
|
||||
Pointer(shout_queuelen):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_queuelen'));
|
||||
Pointer(shout_sync):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_sync'));
|
||||
Pointer(shout_delay):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_delay'));
|
||||
Pointer(shout_set_metadata):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_metadata'));
|
||||
Pointer(shout_metadata_new):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_metadata_new'));
|
||||
Pointer(shout_metadata_free):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_metadata_free'));
|
||||
Pointer(shout_metadata_add):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_metadata_add'));
|
||||
|
||||
end;
|
||||
Result := sh_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
Procedure sh_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
if sh_IsLoaded then
|
||||
begin
|
||||
shout_shutdown();
|
||||
DynLibs.UnloadLibrary(sh_Handle);
|
||||
sh_Handle:=DynLibs.NilHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
216
UOS/src/uos_soundtouch.pas
Normal file
216
UOS/src/uos_soundtouch.pas
Normal file
@@ -0,0 +1,216 @@
|
||||
{This unit is part of United Openlibraries of Sound (uos)}
|
||||
|
||||
{This is the Dynamic loading + Unix compatible version of SoundTouch Pascal Wrapper
|
||||
from Sandro Cumerlato <sandro.cumerlato@gmail.com>.
|
||||
of the original C version of Olli Parviainen <oparviai@iki.fi>.
|
||||
|
||||
Added BPMdetect method too.
|
||||
Load library with St_load() and release with St_unload().
|
||||
License : modified LGPL.
|
||||
Fred van Stappen / fiens@hotmail.com}
|
||||
|
||||
unit uos_soundtouch;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
{$PACKRECORDS C}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ctypes, DynLibs;
|
||||
|
||||
const
|
||||
libst=
|
||||
|
||||
{$IFDEF darwin}
|
||||
'libSoundTouchDLL.dylib';
|
||||
{$ELSE}
|
||||
{$IFDEF unix}
|
||||
'libSoundTouch.so.1';
|
||||
{$ELSE}
|
||||
{$if defined(cpu64)}
|
||||
'SoundTouch_x64.dll';
|
||||
{$else}
|
||||
'SoundTouch.dll';
|
||||
{$endif}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
{$IF not DEFINED(windows)}
|
||||
type
|
||||
THandle = pointer;
|
||||
{$endif}
|
||||
|
||||
type
|
||||
Tt_bs2bdp = ^Tt_bs2bd;
|
||||
Tt_bs2bd = packed record
|
||||
level : CInt32;
|
||||
srate : CInt32;
|
||||
a0_lo : CDouble;
|
||||
b1_lo : CDouble;
|
||||
a0_hi : CDouble;
|
||||
a1_hi : CDouble;
|
||||
b1_hi : CDouble;
|
||||
gain : CDouble;
|
||||
lfs : packed record
|
||||
asis : array[0..1] of cdouble;
|
||||
lo : array[0..1] of cdouble;
|
||||
hi : array[0..1] of cdouble;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
bpm_createInstance: function(chan: CInt32; sampleRate : CInt32): THandle; cdecl;
|
||||
bpm_destroyInstance: procedure(h: THandle); cdecl;
|
||||
bpm_getBpm: function(h: THandle): cfloat; cdecl;
|
||||
bpm_putSamples: procedure(h: THandle; const samples: pcfloat;
|
||||
numSamples: cardinal); cdecl;
|
||||
|
||||
soundtouch_clear: procedure(h: THandle); cdecl;
|
||||
soundtouch_createInstance: function(): THandle; cdecl;
|
||||
soundtouch_flush: procedure(h: THandle); cdecl;
|
||||
soundtouch_getSetting: function(h: THandle; settingId: integer): integer; cdecl;
|
||||
soundtouch_getVersionId: function(): cardinal; cdecl;
|
||||
soundtouch_getVersionString2: procedure(VersionString: PAnsiChar;
|
||||
bufferSize: integer); cdecl;
|
||||
soundtouch_getVersionString: function(): PAnsiChar; cdecl;
|
||||
soundtouch_isEmpty: function(h: THandle): integer; cdecl;
|
||||
soundtouch_numSamples: function(h: THandle): cardinal; cdecl;
|
||||
soundtouch_numUnprocessedSamples: function(h: THandle): cardinal; cdecl;
|
||||
soundtouch_putSamples: procedure(h: THandle; const samples: pcfloat;
|
||||
numSamples: cardinal); cdecl;
|
||||
soundtouch_receiveSamples: function(h: THandle; outBuffer: pcfloat;
|
||||
maxSamples: cardinal): cardinal; cdecl;
|
||||
soundtouch_setChannels: procedure(h: THandle; numChannels: cardinal); cdecl;
|
||||
soundtouch_setPitch: procedure(h: THandle; newPitch: single); cdecl;
|
||||
soundtouch_setPitchOctaves: procedure(h: THandle; newPitch: single); cdecl;
|
||||
soundtouch_setPitchSemiTones: procedure(h: THandle; newPitch: single); cdecl;
|
||||
soundtouch_setRate: procedure(h: THandle; newRate: single); cdecl;
|
||||
soundtouch_setRateChange: procedure(h: THandle; newRate: single); cdecl;
|
||||
soundtouch_setSampleRate: procedure(h: THandle; srate: cardinal); cdecl;
|
||||
soundtouch_destroyInstance: procedure(h: THandle); cdecl;
|
||||
soundtouch_setSetting: function(h: THandle; settingId: integer; Value: integer): boolean; cdecl;
|
||||
soundtouch_setTempo: procedure(h: THandle; newTempo: single); cdecl;
|
||||
soundtouch_setTempoChange: procedure(h: THandle; newTempo: single); cdecl;
|
||||
|
||||
LibHandle:TLibHandle=dynlibs.NilHandle; // this will hold our handle for the lib
|
||||
ReferenceCounter : cardinal = 0; // Reference counter
|
||||
|
||||
function ST_IsLoaded : boolean; inline;
|
||||
function ST_Load(const libfilename: string): boolean; // load the lib
|
||||
procedure ST_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
|
||||
|
||||
implementation
|
||||
|
||||
function ST_IsLoaded: boolean;
|
||||
begin
|
||||
Result := (LibHandle <> dynlibs.NilHandle);
|
||||
end;
|
||||
|
||||
function ST_Load(const libfilename: string): boolean;
|
||||
var
|
||||
thelib: string;
|
||||
begin
|
||||
Result := False;
|
||||
if LibHandle<>0 then
|
||||
begin
|
||||
Inc(ReferenceCounter);
|
||||
result:=true
|
||||
end else begin
|
||||
if Length(libfilename) = 0 then thelib := libst else thelib := libfilename;
|
||||
LibHandle:=DynLibs.SafeLoadLibrary(thelib); // obtain the handle we want.
|
||||
if LibHandle <> DynLibs.NilHandle then
|
||||
begin
|
||||
try
|
||||
Pointer(soundtouch_createInstance) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_createInstance');
|
||||
if Pointer(soundtouch_createInstance) = nil then // not the SoundTouchDLL library.
|
||||
begin
|
||||
ST_Unload;
|
||||
result := false end
|
||||
else
|
||||
begin
|
||||
Pointer(soundtouch_clear) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_clear');
|
||||
Pointer(soundtouch_destroyInstance) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_destroyInstance');
|
||||
Pointer(soundtouch_flush) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_flush');
|
||||
Pointer(soundtouch_getSetting) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_getSetting');
|
||||
Pointer(soundtouch_getVersionId) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_getVersionId');
|
||||
Pointer(soundtouch_getVersionString2) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_getVersionString2');
|
||||
Pointer(soundtouch_getVersionString) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_getVersionString');
|
||||
Pointer(soundtouch_isEmpty) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_isEmpty');
|
||||
Pointer(soundtouch_numSamples) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_numSamples');
|
||||
Pointer(soundtouch_numUnprocessedSamples) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_numUnprocessedSamples');
|
||||
Pointer(soundtouch_putSamples) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_putSamples');
|
||||
Pointer(soundtouch_receiveSamples) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_receiveSamples');
|
||||
Pointer(soundtouch_setChannels) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setChannels');
|
||||
Pointer(soundtouch_setPitch) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setPitch');
|
||||
Pointer(soundtouch_setPitchOctaves) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setPitchOctaves');
|
||||
Pointer(soundtouch_setPitchSemiTones) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setPitchSemiTones');
|
||||
Pointer(soundtouch_setRate) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setRate');
|
||||
Pointer(soundtouch_setRateChange) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setRateChange');
|
||||
Pointer(soundtouch_setSampleRate) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setSampleRate');
|
||||
Pointer(soundtouch_setSetting) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setSetting');
|
||||
Pointer(soundtouch_setTempo) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setTempo');
|
||||
Pointer(soundtouch_setTempoChange) :=
|
||||
GetProcAddress(LibHandle, 'soundtouch_setTempoChange');
|
||||
|
||||
Pointer(bpm_createInstance) :=
|
||||
GetProcAddress(LibHandle, 'bpm_createInstance');
|
||||
Pointer(bpm_destroyInstance) :=
|
||||
GetProcAddress(LibHandle, 'bpm_destroyInstance');
|
||||
Pointer(bpm_getBpm) :=
|
||||
GetProcAddress(LibHandle, 'bpm_getBpm');
|
||||
Pointer(bpm_putSamples) :=
|
||||
GetProcAddress(LibHandle, 'bpm_putSamples');
|
||||
|
||||
Result := St_IsLoaded;
|
||||
ReferenceCounter:=1;
|
||||
|
||||
end;
|
||||
|
||||
except
|
||||
ST_Unload;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ST_Unload;
|
||||
begin
|
||||
// < Reference counting
|
||||
if ReferenceCounter > 0 then
|
||||
dec(ReferenceCounter);
|
||||
if ReferenceCounter > 0 then
|
||||
exit;
|
||||
// >
|
||||
|
||||
if LibHandle <> DynLibs.NilHandle then
|
||||
begin
|
||||
DynLibs.UnloadLibrary(LibHandle);
|
||||
LibHandle := DynLibs.NilHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user