1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
|
unit Libacarsd;
interface
// Flags for messages with errors - see ACD->flags
const
MSG_NOERROR = $00;
MSG_ERR_ALL = $01; // This message is trash
MSG_ERR_REG = $02; // Registration is not valid
MSG_ERR_LAB = $04; // Label is not valid
MSG_ERR_BLK = $08; // Blockindicator is not valid
MSG_ERR_MSG = $10; // The messagenumber is not valid
MSG_ERR_FLI = $20; // The flightnumber is not valid
MSG_ERR_EXT = $40; // The messagecontent is not valid
// Typedefinition for a single char within ACARS stream
type
PAcdCont= ^TAcdCont;
TAcdCont = record
error: byte; // Error indicated by 1. No error = 0
data : byte; // Decoded char - without error? see above
end;
// Typedefinition for the complete ACARS stream
type
PAcd = ^TAcd;
TAcd = record
len : integer; // Count of decoded chars
errors : integer; // Errorcounter
closed : integer; // Transmission correct closed
flags : integer; // Flags for this transmission - see above
squitter: integer; // This is a Squitter message
uplink : integer; // This is a Uplink message
lastpos : integer; // Last position within soundstream
crc : word; // Calcutated CRC. 0 if message is complete and validated!
c : array[0..1023] of TAcdCont; // Included typedef from above
end;
type
PAcarsd = ^_Libacarsd;
_Libacarsd = record
acarsd_codepos: integer;
acarsd_utable : array[0..9] of LongWord;
codeholder : array[0..99] of TAcd;
_private : pointer;
end;
// GET or SET values for an libacarsd option
const ACARSD_GET = $40000000;
const ACARSD_SET = $80000000;
// Posible options to get or set
const ACARSD_CODETABLES = $00000001;
const ACARSD_CRCMODE = $00000002;
const ACARSD_CODEPOS = $00000004;
const ACARSD_VOLUME = $00000008;
const ACARSD_BUFSIZE = $00000010;
const ACARSD_PASSES = $00000020;
const ACARSD_SAMPLE = $00000040;
const ACARSD_BUFFERS = $00000080;
// Get Option
function getOpt(aLib: PAcarsd; aFlags: integer): integer;
// Set Option
function setOpt(aLib: PAcarsd; aFlags: integer; aValue: integer):integer;
// Macro to test for a uplink message
function isUplink(aLib: PAcarsd; aIndex: integer): boolean;
// Macro to test for a squitter message
function isSquitter(aLib: PAcarsd; aIndex: integer): boolean;
// Type of soundstreams
// Only 3 types are supported at the moment:
// 19500 Hz
// 22050 Hz
// 44100 Hz
// all streams have to be MONO, 8bit
const STREAM19500 = 0;
const STREAM22050 = 1;
const STREAM44100 = 2;
// Flags to notify the application if there is something in the buffer
// You can build a while loop like this:
// while (ACARS_Decoder(buff)==ACD_SUCCESS) {...
const ACD_NOTHING = 0;
const ACD_SUCCESS = 1;
// Flags for the goodoffset function
const ACARSD_VALIDATED = 1; // Result is the offset to the validated message
const ACARSD_WITHCRC = 2; // Result is the offset to the message without errors but with CRC failed
const ACARSD_BEST = 3; // Result is the offset to the best possible message
const ACARSD_NONE = 4; // No usable message found
// Initialize internal structures
function acarsdInit(const aBufferSize, aSampleRate, aPass: integer): PAcarsd; stdcall;
// Destroy internal structures
// Not needed at the moment, because libacarsd uses no dynamic allocated memory!
function acarsdDestroy(aLib: PAcarsd): integer; stdcall;
// Run decoder on given buffer
function acarsdDecoder(aLib: PAcarsd; aBuffer: PByte): integer; stdcall;
// Get the offset from the codeholder structure where the message
// is validated
function acarsdGoodOffset(aLib: PAcarsd; aNum: PInteger):integer; stdcall;
// Sort the used codetables to the optimal usage
procedure acarsdSortTables(aLib: PAcarsd); stdcall;
// GET or SET options for libacarsd
// On GET functions you'll become the value of the requested option
// On SET functions you'll return 1 (TRUE) if the option could
// be changed or 0 (FALSE) on error
// This function returns -1 on unknown options
function acarsdOption(aLib: PAcarsd; aOption, aValue: integer): integer; stdcall;
// Return the volume information string
function acarsdVInfo(aLib: PAcarsd): PChar; stdcall;
// Output the ACARS transmission as string
// The caller has to free the string
function acarsdHumanReadable(aLib: PAcarsd; const aForce: integer): PChar; stdcall;
// Get all errors from the selected message as string
function acarsdErrorsOfMsg(aLib: PAcarsd; const aOffset: integer): PChar; stdcall;
type
TAcarsd = class
private
fSampleRate: integer;
fLib: PAcarsd;
fBufferSize: integer;
fPassCount: integer;public
property Lib: PAcarsd read fLib;
property BufferSize : integer read fBufferSize;
property SampleRate : integer read fSampleRate;
property PassCount : integer read fPassCount;
public
function Decoder(aBuffer: PByte): integer; stdcall;
function GoodOffset(aNum: PInteger):integer; stdcall;
procedure SortTables; stdcall;
function Option(aOption, aValue: integer): integer; stdcall;
function VInfo: string; stdcall;
function HumanReadable(const aForce: integer): string; stdcall;
function ErrorsOfMsg(const aOffset: integer): string; stdcall;
function isUplink(aIndex:integer): boolean;
function isSquitter(aIndex: integer): boolean;
public
constructor Create(const aBufferSize, aSampleRate, aPass: integer); virtual;
destructor Destroy;
end;
implementation
function getOpt(aLib: PAcarsd; aFlags: integer): integer;
begin
result := acarsdOption(aLib, ACARSD_GET or aFlags, 0);
end;
function setOpt(aLib: PAcarsd; aFlags: integer; aValue: integer):integer;
begin
result := acarsdOption(aLib, ACARSD_SET or aFlags, aValue);
end;
function isUplink(aLib: PAcarsd; aIndex: integer): boolean;
begin
result := aLib^.codeholder[aIndex].uplink > 0;
end;
function isSquitter(aLib: PAcarsd; aIndex: integer): boolean;
begin
result := aLib^.codeholder[aIndex].squitter > 0;
end;
const
LIB = 'libacarsd.dll';
function acarsdInit; external LIB name 'acarsd_init';
function acarsdDestroy; external LIB name 'acarsd_destroy';
function acarsdDecoder; external LIB name 'ACARS_Decoder';
function acarsdGoodOffset; external LIB name 'acarsd_goodoffset';
procedure acarsdSortTables; external LIB name 'acarsd_sorttables';
function acarsdOption; external LIB name 'acarsd_option';
function acarsdVInfo; external LIB name 'ACARS_VInfo';
function acarsdHumanReadable; external LIB name 'acarsd_human_readable';
function acarsdErrorsOfMsg; external LIB name 'acarsd_errors_of_msg';
{ TAcarsd }
constructor TAcarsd.Create(const aBufferSize, aSampleRate, aPass: integer);
begin
inherited Create;
fBufferSize := aBufferSize;
fSampleRate := aSampleRate;
fPassCount := aPass;
fLib := acarsdInit(fBufferSize, fSampleRate, fPassCount);
end;
destructor TAcarsd.Destroy;
begin
acarsdDestroy(fLib);
inherited Destroy;
end;
function TAcarsd.Decoder(aBuffer: PByte): integer;
begin
result := acarsdDecoder(fLib, aBuffer);
end;
function TAcarsd.ErrorsOfMsg(const aOffset: integer): string;
begin
result := acarsdErrorsOfMsg(fLib, aOffset);
end;
function TAcarsd.GoodOffset(aNum: PInteger): integer;
begin
result := acarsdGoodOffset(fLib, aNum);
end;
function TAcarsd.HumanReadable(const aForce: integer): string;
begin
result := acarsdHumanReadable(fLib, aForce);
end;
function TAcarsd.isSquitter(aIndex: integer): boolean;
begin
result := Libacarsd.isSquitter(fLib, aIndex);
end;
function TAcarsd.isUplink(aIndex: integer): boolean;
begin
result := Libacarsd.isUplink(fLib, aIndex);
end;
function TAcarsd.Option(aOption, aValue: integer): integer;
begin
result := acarsdOption(fLib, aOption, aValue);
end;
procedure TAcarsd.SortTables;
begin
acarsdSortTables(fLib);
end;
function TAcarsd.VInfo: string;
begin
result := acarsdVInfo(fLib);
end;
end. |