@@ -82,7 +82,7 @@ interface
82
82
Classes, DynLibs, ctypes, Math, sysutils;
83
83
84
84
const
85
- uos_version : cint32 = 2250102 ;
85
+ uos_version : cint32 = 2250216 ;
86
86
87
87
{ $IF DEFINED (bs2b)}
88
88
BS2B_HIGH_CLEVEL = (CInt32 (700 )) or ( (CInt32 (30 )) shl 16 );
@@ -1290,7 +1290,23 @@ Tuos_Player = class (tobject)
1290
1290
// example :DSPoutIndex1 := OutputAddDSP (OutputIndex1,@volumeproc,nil,nil);
1291
1291
function OutputAddDSP (OutputIndex: cint32; BeforeFunc: TFunc;
1292
1292
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;
1293
1308
1309
+
1294
1310
// OutputIndex : OutputIndex of an existing Output
1295
1311
// DSPoutIndex : DSPoutIndex of existing DSPout
1296
1312
// Enable : DSP enabled
@@ -1383,6 +1399,9 @@ Tuos_Player = class (tobject)
1383
1399
function DSPLevel (Data: Tuos_Data): Tuos_Data;
1384
1400
inline;
1385
1401
1402
+ function DSPLevelOut (Data: Tuos_Data): Tuos_Data;
1403
+ inline;
1404
+
1386
1405
// Convert mono 1 channel input to stereo 2 channels input.
1387
1406
// Works only if the input is mono 1 channel othewise stereo 2 chan is keeped.
1388
1407
// InputIndex : InputIndex of an existing Input
@@ -2663,6 +2682,7 @@ function Tuos_Player.InputGetLevelLeft (InputIndex: cint32): double;
2663
2682
if (isAssigned = True) then Result := StreamIn[InputIndex].Data.LevelLeft;
2664
2683
end ;
2665
2684
2685
+
2666
2686
function Tuos_Player.InputGetLevelRight (InputIndex: cint32): double;
2667
2687
// InputIndex : InputIndex of existing input
2668
2688
// result : right level (volume) from 0 to 1
@@ -2671,6 +2691,33 @@ function Tuos_Player.InputGetLevelRight (InputIndex: cint32): double;
2671
2691
if (isAssigned = True) then Result := StreamIn[InputIndex].Data.LevelRight;
2672
2692
end ;
2673
2693
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
+
2674
2721
function Tuos_Player.InputFiltersGetLevelString (InputIndex: cint32): string;
2675
2722
// InputIndex : InputIndex of existing input
2676
2723
// result : list of left|right levels separed by $ character
@@ -4908,6 +4955,140 @@ function Tuos_Player.DSPLevel (Data: Tuos_Data): Tuos_Data;
4908
4955
Result := Data;
4909
4956
end ;
4910
4957
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
+
4911
5092
function DSPLevelString (Buffer: TDArFloat; SampleFormat, Ratio : cint32; Var resfloatleft : cfloat;
4912
5093
Var resfloatright : cfloat): string;
4913
5094
var
@@ -6508,6 +6689,8 @@ function Tuos_Player.AddIntoDevOut (Device: cint32; Latency: CDouble;
6508
6689
x := Length (StreamOut) - 1 ;
6509
6690
6510
6691
StreamOut[x].Data.Enabled := false;
6692
+ StreamOut[x].Data.levelEnable := 0 ;
6693
+ StreamOut[x].Data.levelArrayEnable := 0 ;
6511
6694
6512
6695
{ $IF DEFINED (portaudio)}
6513
6696
StreamOut[x].PAParam.hostApiSpecificStreamInfo := Nil ;
@@ -9991,12 +10174,12 @@ procedure Tuos_Player.DoTerminatePlayer;
9991
10174
begin
9992
10175
{ $IF DEFINED (portaudio)}
9993
10176
if (StreamOut[x].Data.HandleSt <> nil ) and
9994
- (StreamOut[x].Data.TypePut = 1 ) then
10177
+ (StreamOut[x].Data.TypePut = 1 ) then
9995
10178
begin
9996
10179
Pa_StopStream (StreamOut[x].Data.HandleSt);
9997
10180
Pa_CloseStream (StreamOut[x].Data.HandleSt);
9998
10181
end ;
9999
- { $ENDIF}
10182
+ { $ENDIF}
10000
10183
10001
10184
{ $IF DEFINED (shout)}
10002
10185
if (StreamOut[x].Data.TypePut = 2 ) then
@@ -11071,12 +11254,15 @@ procedure Tuos_Player.ReadFile (x : integer);
11071
11254
Move (StreamIn[x].AACI.pData^,
11072
11255
StreamIn[x].Data.Buffer[0 ],
11073
11256
outBytes);
11074
- StreamIn[x].AACI.lwDataLen := outBytes;
11257
+ StreamIn[x].AACI.lwDataLen :=
11258
+
11259
+ outBytes
11260
+ ;
11075
11261
end ;
11076
11262
end ;
11077
11263
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 ))
11080
11266
else
11081
11267
StreamIn[x].Data.outframes := 0 ;
11082
11268
@@ -11407,7 +11593,7 @@ procedure TuosThread.Execute;
11407
11593
{ $endif}
11408
11594
11409
11595
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);
11411
11597
11412
11598
// Adding level in array-level// ideal for pre-wave form
11413
11599
if (StreamIn[x].Data.levelArrayEnable = 1 ) then
@@ -11559,10 +11745,13 @@ procedure TuosThread.Execute;
11559
11745
{ $IF DEFINED (uos_debug) and DEFINED (unix)}
11560
11746
writeln (' copy buffer-in into buffer-out' );
11561
11747
{ $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
11564
11754
if (length (StreamOut[x].DSP) > 0 ) and uosIsActif then
11565
-
11566
11755
DoDSPOutAfterBufProc (x);
11567
11756
11568
11757
// apply plugin (ex: SoundTouch Library)
@@ -11578,7 +11767,11 @@ procedure TuosThread.Execute;
11578
11767
if Plugin[x3].Enabled = True then
11579
11768
plugenabled := True;
11580
11769
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
+
11582
11775
11583
11776
if uosIsActif then
11584
11777
begin
0 commit comments