source: trunk/Packages/uos/uos_bs2b.pas

Last change on this file was 664, checked in by chronos, 3 days ago
  • Added: Ability to play music in background in start screen and in-game. Used uos as audio library.
File size: 15.1 KB
Line 
1{This unit is part of United Openlibraries of Sound (uos)}
2
3{This is the Dynamic loading Pascal Wrapper of
4 bs2b library of Boris Mikhaylov
5 Load library with bs_load() and release with bs_unload().
6 License : modified LGPL.
7 Fred van Stappen / fiens@hotmail.com
8}
9
10
11unit uos_bs2b;
12
13{$mode objfpc}{$H+}
14{$PACKRECORDS C}
15
16
17interface
18
19uses
20 SysUtils, dynlibs, ctypes, math;
21
22const
23libsb=
24 {$IFDEF unix}
25 'libbs2b.so.0';
26 {$ELSE}
27 'bs2b.dll';
28 {$ENDIF}
29
30{ Minimum/maximum sample rate (Hz) }
31 BS2B_MINSRATE = 2000;
32 BS2B_MAXSRATE = 384000;
33
34{ Minimum/maximum cut frequency (Hz) }
35{ bs2b_set_level_fcut() }
36 BS2B_MINFCUT = 300;
37 BS2B_MAXFCUT = 2000;
38
39{ Minimum/maximum feed level (dB * 10 @ low frequencies) }
40{ bs2b_set_level_feed() }
41{ 1 dB }
42 BS2B_MINFEED = 10;
43{ 15 dB }
44 BS2B_MAXFEED = 150;
45
46const
47
48 // for using with bs2b_set_level
49
50 BS2B_HIGH_CLEVEL = (CInt32(700)) or ((CInt32(30)) shl 16);
51 BS2B_MIDDLE_CLEVEL = (CInt32(500)) or ((CInt32(45)) shl 16);
52 BS2B_LOW_CLEVEL = (CInt32(360)) or ((CInt32(60)) shl 16);
53 { Easy crossfeed levels (Obsolete) }
54 BS2B_HIGH_ECLEVEL = (CInt32(700)) or ((CInt32(60)) shl 16);
55 BS2B_MIDDLE_ECLEVEL = (CInt32(500)) or ((CInt32(72)) shl 16);
56 BS2B_LOW_ECLEVEL = (CInt32(360)) or ((CInt32(84)) shl 16);
57
58 BS2B_DEFAULT_CLEVEL = (CInt32(700)) or ((CInt32(45)) shl 16);
59 BS2B_CMOY_CLEVEL =(CInt32(700)) or ((CInt32(60)) shl 16);
60 BS2B_JMEIER_CLEVEL = (CInt32(650)) or ((CInt32(95)) shl 16);
61
62{ Default sample rate (Hz) }
63const
64 BS2B_DEFAULT_SRATE = 44100;
65
66{ A delay at low frequency by microseconds according to cut frequency }
67function bs2b_level_delay(fcut : longint) : longint;
68
69{ Crossfeed level }
70{ Sample rate (Hz) }
71{ Lowpass IIR filter coefficients }
72{ Highboost IIR filter coefficients }
73{ Global gain against overloading }
74{ Buffer of last filtered sample: [0] 1-st channel, [1] 2-d channel }
75type
76 Tt_bs2bdp = ^Tt_bs2bd;
77 Tt_bs2bd = packed record
78 level : CInt32;
79 srate : CInt32;
80 a0_lo : CDouble;
81 b1_lo : CDouble;
82 a0_hi : CDouble;
83 a1_hi : CDouble;
84 b1_hi : CDouble;
85 gain : CDouble;
86 lfs : packed record
87 asis : array[0..1] of cdouble;
88 lo : array[0..1] of cdouble;
89 hi : array[0..1] of cdouble;
90 end;
91 end;
92
93////// Dynamic load : Vars that will hold our dynamically loaded functions...
94// *************************** functions *******************************
95
96var
97{ Open }
98bs2b_open : function():Tt_bs2bdp; cdecl;
99
100{ Close }
101bs2b_close : procedure(bs2bdp:Tt_bs2bdp); cdecl;
102
103{ Sets a new coefficients by new crossfeed value.
104 * level = ( fcut | feed << 16 ) )
105 * where 'feed' is crossfeeding level at low frequencies (dB * 10)
106 * and 'fcut' is cut frecuency (Hz)
107 }
108bs2b_set_level : procedure(bs2bdp:Tt_bs2bdp; level: CInt32); cdecl;
109
110{ Return a current crossfeed level value. }
111bs2b_get_level : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
112
113{ Sets a new coefficients by new cut frecuency value (Hz). }
114bs2b_set_level_fcut : procedure(bs2bdp:Tt_bs2bdp; fcut: CInt32); cdecl;
115
116{ Return a current cut frecuency value (Hz). }
117bs2b_get_level_fcut : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
118
119{ Sets a new coefficients by new crossfeeding level value (dB * 10). }
120bs2b_set_level_feed : procedure(bs2bdp:Tt_bs2bdp; feed: CInt32); cdecl;
121
122{ Return a current crossfeeding level value (dB * 10). }
123bs2b_get_level_feed : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
124
125{ Return a current delay value at low frequencies (micro seconds). }
126bs2b_get_level_delay : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
127
128{ Clear buffers and sets a new coefficients with new sample rate value.
129 * srate - sample rate by Hz. }
130bs2b_set_srate : procedure(bs2bdp:Tt_bs2bdp; srate: CInt32); cdecl;
131
132{ Return current sample rate value }
133bs2b_get_srate : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
134
135{ Clear buffer }
136bs2b_clear : procedure(bs2bdp:Tt_bs2bdp); cdecl;
137
138{ Return 1 if buffer is clear }
139bs2b_is_clear : function(bs2bdp:Tt_bs2bdp): CInt32; cdecl;
140
141{ Return bs2b version string }
142(* Const before declarator ignored *)
143bs2b_runtime_version : function():pchar; cdecl;
144
145{ Return bs2b version integer }
146bs2b_runtime_version_int : function(): CInt32; cdecl;
147
148{ 'bs2b_cross_feed_*' crossfeeds buffer of 'n' stereo samples
149 * pointed by 'sample'.
150 * sample[i] - first channel,
151 * sample[i+1] - second channel.
152 * Where 'i' is ( i = 0; i < n * 2; i += 2 )
153 }
154{ sample poits to double floats native endians }
155bs2b_cross_feed_d : procedure(bs2bdp:Tt_bs2bdp; var sample:Cdouble; n: CInt32); cdecl;
156
157{ sample poits to double floats big endians }
158bs2b_cross_feed_dbe : procedure(bs2bdp:Tt_bs2bdp; var sample:Cdouble; n: CInt32); cdecl;
159
160{ sample poits to double floats little endians }
161bs2b_cross_feed_dle : procedure(bs2bdp:Tt_bs2bdp; var sample:Cdouble; n: CInt32); cdecl;
162
163{ sample poits to floats native endians }
164bs2b_cross_feed_f : procedure(bs2bdp:Tt_bs2bdp; var sample:Cfloat; n:CInt32); cdecl;
165
166{ sample poits to floats big endians }
167bs2b_cross_feed_fbe : procedure(bs2bdp:Tt_bs2bdp; var sample:Cfloat; n:CInt32); cdecl;
168
169{ sample poits to floats little endians }
170bs2b_cross_feed_fle : procedure(bs2bdp:Tt_bs2bdp; var sample:cfloat; n:CInt32); cdecl;
171
172{ sample poits to 32bit signed integers native endians }
173bs2b_cross_feed_s32 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
174
175{ sample poits to 32bit unsigned integers native endians }
176bs2b_cross_feed_u32 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
177
178{ sample poits to 32bit signed integers big endians }
179bs2b_cross_feed_s32be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
180
181{ sample poits to 32bit unsigned integers big endians }
182bs2b_cross_feed_u32be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
183
184{ sample poits to 32bit signed integers little endians }
185bs2b_cross_feed_s32le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
186
187{ sample poits to 32bit unsigned integers little endians }
188bs2b_cross_feed_u32le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt32); cdecl;
189
190{ sample poits to 16bit signed integers native endians }
191bs2b_cross_feed_s16 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt16; n:CInt); cdecl;
192
193{ sample poits to 16bit unsigned integers native endians }
194bs2b_cross_feed_u16 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
195
196{ sample poits to 16bit signed integers big endians }
197bs2b_cross_feed_s16be : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
198
199{ sample poits to 16bit unsigned integers big endians }
200bs2b_cross_feed_u16be : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
201
202{ sample poits to 16bit signed integers little endians }
203bs2b_cross_feed_s16le : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
204
205{ sample poits to 16bit unsigned integers little endians }
206bs2b_cross_feed_u16le : procedure(bs2bdp:Tt_bs2bdp; var sample:cint16; n:cint); cdecl;
207
208{ sample poits to 8bit signed integers }
209bs2b_cross_feed_s8 : procedure(bs2bdp:Tt_bs2bdp; var sample:cint8; n:cint); cdecl;
210
211{ sample poits to 8bit unsigned integers }
212bs2b_cross_feed_u8 : procedure(bs2bdp:Tt_bs2bdp; var sample:cint8; n:cint); cdecl;
213
214{ sample poits to 24bit signed integers native endians }
215bs2b_cross_feed_s24 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
216
217{ sample poits to 24bit unsigned integers native endians }
218bs2b_cross_feed_u24 : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
219
220{ sample poits to 24bit signed integers be endians }
221bs2b_cross_feed_s24be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
222
223{ sample poits to 24bit unsigned integers be endians }
224bs2b_cross_feed_u24be : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
225
226{ sample poits to 24bit signed integers little endians }
227bs2b_cross_feed_s24le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
228
229{ sample poits to 24bit unsigned integers little endians }
230bs2b_cross_feed_u24le : procedure(bs2bdp:Tt_bs2bdp; var sample:CInt32; n:CInt); cdecl;
231
232 function bs_IsLoaded() : boolean; inline;
233
234 Function bs_Load(const libfilename:string) :boolean; // load the lib
235
236 Procedure bs_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
237
238implementation
239
240function bs2b_level_delay(fcut : longint) : longint;
241begin
242 result:=floor((18700/fcut)*10);
243end;
244
245 var
246 bs_Handle :TLibHandle=dynlibs.NilHandle;
247 {$IFDEF windows} // try load dependency if not in /windows/system32/
248 gc_Handle :TLibHandle=dynlibs.NilHandle;
249 {$endif}
250 ReferenceCounter : cardinal = 0; // Reference counter
251
252function bs_IsLoaded(): boolean;
253begin
254 Result := (bs_Handle <> dynlibs.NilHandle);
255end;
256
257Procedure bs_Unload();
258begin
259// < Reference counting
260 if ReferenceCounter > 0 then
261 dec(ReferenceCounter);
262 if ReferenceCounter > 0 then
263 exit;
264 // >
265 if bs_IsLoaded() then
266 begin
267 DynLibs.UnloadLibrary(bs_Handle);
268 bs_Handle:=DynLibs.NilHandle;
269 {$IFDEF windows}
270 if gc_Handle <> DynLibs.NilHandle then begin
271 DynLibs.UnloadLibrary(gc_Handle);
272 gc_Handle:=DynLibs.NilHandle;
273 end;
274 {$endif}
275 bs2b_open:=nil;
276 bs2b_close:=nil;
277 bs2b_set_level:=nil;
278 bs2b_get_level:=nil;
279 bs2b_set_level_fcut:=nil;
280 bs2b_get_level_fcut:=nil;
281 bs2b_set_level_feed:=nil;
282 bs2b_get_level_feed:=nil;
283 bs2b_get_level_delay:=nil;
284 bs2b_set_srate:=nil;
285 bs2b_get_srate:=nil;
286 bs2b_clear:=nil;
287 bs2b_is_clear:=nil;
288 bs2b_runtime_version:=nil;
289 bs2b_runtime_version_int:=nil;
290 bs2b_cross_feed_d:=nil;
291 bs2b_cross_feed_dbe:=nil;
292 bs2b_cross_feed_dle:=nil;
293 bs2b_cross_feed_f:=nil;
294 bs2b_cross_feed_fbe:=nil;
295 bs2b_cross_feed_fle:=nil;
296 bs2b_cross_feed_s32:=nil;
297 bs2b_cross_feed_u32:=nil;
298 bs2b_cross_feed_s32be:=nil;
299 bs2b_cross_feed_u32be:=nil;
300 bs2b_cross_feed_s32le:=nil;
301 bs2b_cross_feed_u32le:=nil;
302 bs2b_cross_feed_s16:=nil;
303 bs2b_cross_feed_u16:=nil;
304 bs2b_cross_feed_s16be:=nil;
305 bs2b_cross_feed_u16be:=nil;
306 bs2b_cross_feed_s16le:=nil;
307 bs2b_cross_feed_u16le:=nil;
308 bs2b_cross_feed_s8:=nil;
309 bs2b_cross_feed_u8:=nil;
310 bs2b_cross_feed_s24:=nil;
311 bs2b_cross_feed_u24:=nil;
312 bs2b_cross_feed_s24be:=nil;
313 bs2b_cross_feed_u24be:=nil;
314 bs2b_cross_feed_s24le:=nil;
315 bs2b_cross_feed_u24le:=nil;
316 end;
317end;
318
319 Function bs_Load(const libfilename:string) :boolean;
320 begin
321 Result := False;
322 if bs_Handle<>0 then
323begin
324 Inc(ReferenceCounter);
325result:=true {is it already there ?}
326end else begin {go & load the library}
327 if Length(libfilename) = 0 then
328 begin
329 {$IFDEF windows}
330 gc_Handle:= DynLibs.SafeLoadLibrary('libgcc_s_dw2-1.dll');
331 {$endif}
332 bs_Handle:=DynLibs.SafeLoadLibrary(libsb);
333 end
334 else
335 begin
336 {$IFDEF windows}
337 gc_Handle:= DynLibs.SafeLoadLibrary(ExtractFilePath(libfilename)+'libgcc_s_dw2-1.dll');
338 {$endif}
339
340 bs_Handle:=DynLibs.SafeLoadLibrary(libfilename);
341 end;
342
343 if bs_Handle <> DynLibs.NilHandle then
344 begin {now we tie the functions to the VARs from above}
345
346 pointer(bs2b_open):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_open'));
347 pointer(bs2b_close):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_close'));
348 pointer(bs2b_set_level):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_level'));
349 pointer(bs2b_get_level):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level'));
350 pointer(bs2b_set_level_fcut):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_level_fcut'));
351 pointer(bs2b_get_level_fcut):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level_fcut'));
352 pointer(bs2b_set_level_feed):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_level_feed'));
353 pointer(bs2b_get_level_feed):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level_feed'));
354 pointer(bs2b_get_level_delay):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_level_delay'));
355 pointer(bs2b_set_srate):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_set_srate'));
356 pointer(bs2b_get_srate):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_get_srate'));
357 pointer(bs2b_clear):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_clear'));
358 pointer(bs2b_is_clear):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_is_clear'));
359 pointer(bs2b_runtime_version):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_runtime_version'));
360 pointer(bs2b_runtime_version_int):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_runtime_version_int'));
361 pointer(bs2b_cross_feed_d):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_d'));
362 pointer(bs2b_cross_feed_dbe):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_dbe'));
363 pointer(bs2b_cross_feed_dle):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_dle'));
364 pointer(bs2b_cross_feed_f):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_f'));
365 pointer(bs2b_cross_feed_fbe):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_fbe'));
366 pointer(bs2b_cross_feed_fle):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_fle'));
367 pointer(bs2b_cross_feed_s32):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s32'));
368 pointer(bs2b_cross_feed_u32):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u32'));
369 pointer(bs2b_cross_feed_s32be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s32be'));
370 pointer(bs2b_cross_feed_u32be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u32be'));
371 pointer(bs2b_cross_feed_s32le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s32le'));
372 pointer(bs2b_cross_feed_u32le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u32le'));
373 pointer(bs2b_cross_feed_s16):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s16'));
374 pointer(bs2b_cross_feed_u16):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u16'));
375 pointer(bs2b_cross_feed_s16be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s16be'));
376 pointer(bs2b_cross_feed_u16be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u16be'));
377 pointer(bs2b_cross_feed_s16le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s16le'));
378 pointer(bs2b_cross_feed_u16le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u16le'));
379 pointer(bs2b_cross_feed_s8):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s8'));
380 pointer(bs2b_cross_feed_u8):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u8'));
381 pointer(bs2b_cross_feed_s24):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s24'));
382 pointer(bs2b_cross_feed_u24):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u24'));
383 pointer(bs2b_cross_feed_s24be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s24be'));
384 pointer(bs2b_cross_feed_u24be):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u24be'));
385 pointer(bs2b_cross_feed_s24le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_s24le'));
386 pointer(bs2b_cross_feed_u24le):=DynLibs.GetProcAddress(bs_handle,PChar('bs2b_cross_feed_u24le'));
387 end;
388 Result := bs_IsLoaded;
389 ReferenceCounter:=1;
390 end;
391end;
392
393end.
394
Note: See TracBrowser for help on using the repository browser.