Skip to content

Commit ee59deb

Browse files
committed
Added OutputSetLevelEnable(), OutputGetLevelLeft(), OutputGetLevelRight, DSPLevelOut(). Needed for best monitoring.
1 parent ea035b7 commit ee59deb

File tree

4 files changed

+542
-22
lines changed

4 files changed

+542
-22
lines changed

examples/uos.pas

+204-11
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ interface
8282
Classes, DynLibs, ctypes, Math, sysutils;
8383

8484
const
85-
uos_version : cint32 = 2250102;
85+
uos_version : cint32 = 2250216;
8686

8787
{$IF DEFINED (bs2b)}
8888
BS2B_HIGH_CLEVEL = (CInt32 (700)) or ( (CInt32 (30)) shl 16);
@@ -1290,7 +1290,23 @@ Tuos_Player = class (tobject)
12901290
// example :DSPoutIndex1 := OutputAddDSP (OutputIndex1,@volumeproc,nil,nil);
12911291
function OutputAddDSP (OutputIndex: cint32; BeforeFunc: TFunc;
12921292
AfterFunc: TFunc; EndedFunc: TFunc; LoopProc: TProc): cint32;
1293+
1294+
// set level calculation (default is 0)
1295+
// 0 => no calcul
1296+
// 1 => calcul before all DSP procedures.
1297+
// 2 => calcul after all DSP procedures.
1298+
// 3 => calcul before and after all DSP procedures.
1299+
procedure OutputSetLevelEnable (OutputIndex: cint32; levelcalc : cint32);
1300+
1301+
// OutputIndex : OutputIndex of existing Output
1302+
// result : left level from 0 to 1
1303+
function OutputGetLevelLeft (OutputIndex: cint32): double; inline;
1304+
1305+
// OutputIndex : OutputIndex of existing Output
1306+
// result : right level from 0 to 1
1307+
function OutputGetLevelRight (OutputIndex: cint32): double; inline;
12931308

1309+
12941310
// OutputIndex : OutputIndex of an existing Output
12951311
// DSPoutIndex : DSPoutIndex of existing DSPout
12961312
// Enable : DSP enabled
@@ -1383,6 +1399,9 @@ Tuos_Player = class (tobject)
13831399
function DSPLevel (Data: Tuos_Data): Tuos_Data;
13841400
inline;
13851401

1402+
function DSPLevelOut (Data: Tuos_Data): Tuos_Data;
1403+
inline;
1404+
13861405
// Convert mono 1 channel input to stereo 2 channels input.
13871406
// Works only if the input is mono 1 channel othewise stereo 2 chan is keeped.
13881407
// InputIndex : InputIndex of an existing Input
@@ -2663,6 +2682,7 @@ function Tuos_Player.InputGetLevelLeft (InputIndex: cint32): double;
26632682
if (isAssigned = True) then Result := StreamIn[InputIndex].Data.LevelLeft;
26642683
end;
26652684

2685+
26662686
function Tuos_Player.InputGetLevelRight (InputIndex: cint32): double;
26672687
// InputIndex : InputIndex of existing input
26682688
// result : right level (volume) from 0 to 1
@@ -2671,6 +2691,33 @@ function Tuos_Player.InputGetLevelRight (InputIndex: cint32): double;
26712691
if (isAssigned = True) then Result := StreamIn[InputIndex].Data.LevelRight;
26722692
end;
26732693

2694+
procedure Tuos_Player.OutputSetLevelEnable (OutputIndex: cint32; levelcalc : cint32);
2695+
// set level calculation (default is 0)
2696+
// 0 => no calcul
2697+
// 1 => calcul before all DSP procedures.
2698+
// 2 => calcul after all DSP procedures.
2699+
// 3 => calcul before and after all DSP procedures.
2700+
begin
2701+
if (isAssigned = True) then
2702+
StreamOut[OutputIndex].Data.levelEnable := levelcalc;
2703+
end;
2704+
2705+
function Tuos_Player.OutputGetLevelLeft (OutputIndex: cint32): double;
2706+
// OutputIndex : OutputIndex of existing Output
2707+
// result : left level (volume) from 0 to 1
2708+
begin
2709+
Result := 0;
2710+
if (isAssigned = True) then Result := StreamOut[OutputIndex].Data.LevelLeft;
2711+
end;
2712+
2713+
function Tuos_Player.OutputGetLevelRight (OutputIndex: cint32): double;
2714+
// InputIndex : InputIndex of existing input
2715+
// result : right level (volume) from 0 to 1
2716+
begin
2717+
Result := 0;
2718+
if (isAssigned = True) then Result := StreamOut[OutputIndex].Data.LevelRight;
2719+
end;
2720+
26742721
function Tuos_Player.InputFiltersGetLevelString (InputIndex: cint32): string;
26752722
// InputIndex : InputIndex of existing input
26762723
// result : list of left|right levels separed by $ character
@@ -4908,6 +4955,140 @@ function Tuos_Player.DSPLevel (Data: Tuos_Data): Tuos_Data;
49084955
Result := Data;
49094956
end;
49104957

4958+
4959+
function Tuos_Player.DSPLevelOut (Data: Tuos_Data): Tuos_Data;
4960+
var
4961+
x, ratio: cint32;
4962+
ps: PDArShort;
4963+
// if input is Int16 format
4964+
pl: PDArLong;
4965+
// if input is Int32 format
4966+
pf: PDArFloat;
4967+
// if input is Float32 format
4968+
mins, maxs: array[0..1] of cInt16;
4969+
// if input is Int16 format
4970+
minl, maxl: array[0..1] of cInt32;
4971+
// if input is Int32 format
4972+
minf, maxf: array[0..1] of cfloat;
4973+
// if input is Float32 format
4974+
begin
4975+
4976+
case Data.SampleFormat of
4977+
2:
4978+
begin
4979+
mins[0] := 32767;
4980+
mins[1] := 32767;
4981+
maxs[0] := -32768;
4982+
maxs[1] := -32768;
4983+
ps := @Data.Buffer;
4984+
x := 0;
4985+
while x < Data.OutFrames -1 do
4986+
begin
4987+
if ps^[x] < mins[0] then
4988+
mins[0] := ps^[x];
4989+
if ps^[x] > maxs[0] then
4990+
maxs[0] := ps^[x];
4991+
4992+
Inc (x, 1);
4993+
4994+
if ps^[x] < mins[1] then
4995+
mins[1] := ps^[x];
4996+
if ps^[x] > maxs[1] then
4997+
maxs[1] := ps^[x];
4998+
4999+
Inc (x, 1);
5000+
end;
5001+
5002+
if Abs (mins[0]) > Abs (maxs[0]) then
5003+
Data.LevelLeft := Sqrt (Abs (mins[0]) / 32768)
5004+
else
5005+
Data.LevelLeft := Sqrt (Abs (maxs[0]) / 32768);
5006+
5007+
if Abs (mins[1]) > Abs (maxs[1]) then
5008+
Data.Levelright := Sqrt (Abs (mins[1]) / 32768)
5009+
else
5010+
Data.Levelright := Sqrt (Abs (maxs[1]) / 32768);
5011+
5012+
end;
5013+
5014+
1:
5015+
begin
5016+
minl[0] := 2147483647;
5017+
minl[1] := 2147483647;
5018+
maxl[0] := -2147483648;
5019+
maxl[1] := -2147483648;
5020+
pl := @Data.Buffer;
5021+
x := 0;
5022+
while x < Data.OutFrames -1 do
5023+
begin
5024+
if pl^[x] < minl[0] then
5025+
minl[0] := pl^[x];
5026+
if pl^[x] > maxl[0] then
5027+
maxl[0] := pl^[x];
5028+
5029+
Inc (x, 1);
5030+
5031+
if pl^[x] < minl[1] then
5032+
minl[1] := pl^[x];
5033+
if pl^[x] > maxl[1] then
5034+
maxl[1] := pl^[x];
5035+
5036+
Inc (x, 1);
5037+
end;
5038+
5039+
if Abs (minl[0]) > Abs (maxl[0]) then
5040+
Data.LevelLeft := Sqrt (Abs (minl[0]) / 2147483648)
5041+
else
5042+
Data.LevelLeft := Sqrt (Abs (maxl[0]) / 2147483648);
5043+
5044+
if Abs (minl[1]) > Abs (maxl[1]) then
5045+
Data.Levelright := Sqrt (Abs (minl[1]) / 2147483648)
5046+
else
5047+
Data.Levelright := Sqrt (Abs (maxl[1]) / 2147483648);
5048+
end;
5049+
5050+
0:
5051+
begin
5052+
ratio := 1;
5053+
5054+
minf[0] := 1;
5055+
minf[1] := 1;
5056+
maxf[0] := -1;
5057+
maxf[1] := -1;
5058+
pf := @Data.Buffer;
5059+
x := 0;
5060+
while x < (Data.OutFrames div ratio)-1 do
5061+
begin
5062+
if pf^[x] < minf[0] then
5063+
minf[0] := pf^[x];
5064+
if pf^[x] > maxf[0] then
5065+
maxf[0] := pf^[x];
5066+
5067+
Inc (x, 1);
5068+
5069+
if pf^[x] < minf[1] then
5070+
minf[1] := pf^[x];
5071+
if pf^[x] > maxf[1] then
5072+
maxf[1] := pf^[x];
5073+
5074+
Inc (x, 1);
5075+
end;
5076+
5077+
if Abs (minf[0]) > Abs (maxf[0]) then
5078+
Data.LevelLeft := Sqrt (Abs (minf[0]))
5079+
else
5080+
Data.LevelLeft := Sqrt (Abs (maxf[0]));
5081+
5082+
if Abs (minf[1]) > Abs (maxf[1]) then
5083+
Data.Levelright := Sqrt (Abs (minf[1]))
5084+
else
5085+
Data.Levelright := Sqrt (Abs (maxf[1]));
5086+
end;
5087+
end;
5088+
5089+
Result := Data;
5090+
end;
5091+
49115092
function DSPLevelString (Buffer: TDArFloat; SampleFormat, Ratio : cint32; Var resfloatleft : cfloat;
49125093
Var resfloatright : cfloat): string;
49135094
var
@@ -6508,6 +6689,8 @@ function Tuos_Player.AddIntoDevOut (Device: cint32; Latency: CDouble;
65086689
x := Length (StreamOut) - 1;
65096690

65106691
StreamOut[x].Data.Enabled := false;
6692+
StreamOut[x].Data.levelEnable := 0;
6693+
StreamOut[x].Data.levelArrayEnable := 0;
65116694

65126695
{$IF DEFINED (portaudio)}
65136696
StreamOut[x].PAParam.hostApiSpecificStreamInfo := Nil;
@@ -9991,12 +10174,12 @@ procedure Tuos_Player.DoTerminatePlayer;
999110174
begin
999210175
{$IF DEFINED (portaudio)}
999310176
if (StreamOut[x].Data.HandleSt <> nil) and
9994-
(StreamOut[x].Data.TypePut = 1) then
10177+
(StreamOut[x].Data.TypePut = 1) then
999510178
begin
999610179
Pa_StopStream (StreamOut[x].Data.HandleSt);
999710180
Pa_CloseStream (StreamOut[x].Data.HandleSt);
999810181
end;
9999-
{$ENDIF}
10182+
{$ENDIF}
1000010183

1000110184
{$IF DEFINED (shout)}
1000210185
if (StreamOut[x].Data.TypePut = 2) then
@@ -11071,12 +11254,15 @@ procedure Tuos_Player.ReadFile (x : integer);
1107111254
Move (StreamIn[x].AACI.pData^,
1107211255
StreamIn[x].Data.Buffer[0],
1107311256
outBytes);
11074-
StreamIn[x].AACI.lwDataLen := outBytes;
11257+
StreamIn[x].AACI.lwDataLen :=
11258+
11259+
outBytes
11260+
;
1107511261
end;
1107611262
end;
1107711263
if StreamIn[x].AACI.lwDataLen > (StreamIn[x].AACI.BitsPerSample div 8) then
11078-
StreamIn[x].Data.outframes := trunc (StreamIn[x].AACI.lwDataLen / (StreamIn[x].AACI.
11079-
BitsPerSample / 8))
11264+
StreamIn[x].Data.outframes := trunc (StreamIn[x].AACI.lwDataLen Div (StreamIn[x].AACI.
11265+
BitsPerSample Div 8))
1108011266
else
1108111267
StreamIn[x].Data.outframes := 0;
1108211268

@@ -11407,7 +11593,7 @@ procedure TuosThread.Execute;
1140711593
{$endif}
1140811594

1140911595
if (StreamIn[x].Data.levelEnable = 1) or (StreamIn[x].Data.levelEnable = 3) then
11410-
StreamIn[x].Data := DSPLevel (StreamIn[x].Data);
11596+
StreamIn[x].Data := DSPLevel(StreamIn[x].Data);
1141111597

1141211598
// Adding level in array-level// ideal for pre-wave form
1141311599
if (StreamIn[x].Data.levelArrayEnable = 1) then
@@ -11559,10 +11745,13 @@ procedure TuosThread.Execute;
1155911745
{$IF DEFINED (uos_debug) and DEFINED (unix)}
1156011746
writeln ('copy buffer-in into buffer-out');
1156111747
{$endif}
11562-
11563-
// DSPOut AfterBuffProc
11748+
11749+
// calcul level before all dsp
11750+
if (Streamout[x].Data.levelEnable = 1) then
11751+
Streamout[x].Data := DSPLevelOut(Streamout[x].Data);
11752+
11753+
// DSPOut AfterBuffProc
1156411754
if (length (StreamOut[x].DSP) > 0) and uosIsActif then
11565-
1156611755
DoDSPOutAfterBufProc (x);
1156711756

1156811757
// apply plugin (ex: SoundTouch Library)
@@ -11578,7 +11767,11 @@ procedure TuosThread.Execute;
1157811767
if Plugin[x3].Enabled = True then
1157911768
plugenabled := True;
1158011769
end;
11581-
//
11770+
11771+
// calcul level after all dsp
11772+
if (Streamout[x].Data.levelEnable = 2) then
11773+
Streamout[x].Data := DSPLevelOut(Streamout[x].Data);
11774+
1158211775

1158311776
if uosIsActif then
1158411777
begin

0 commit comments

Comments
 (0)