Während ein Lied spielt, soll ein 2 Sekunden langer Sound eingeblendet werden. Während der Einblendung soll die Lautstärke des Liedes verringert, danach wieder auf 100% gesetzt werden.
Folgendes funktioniert zwar:
procedure TForm1.Button2Click(Sender: TObject);
begin
uos_CreatePlayer(1);
uos_AddFromFile(1, '/kurzer_2_sec_sound.mp3');
uos_AddIntoDevOut(1);
uos_AddDSPVolumeIn(0,0,0.6,0.6); //// player 0 ist das Lied
uos_Play(1); sleep(2000);
uos_AddDSPVolumeIn(0,0,1,1);
end;
Aber der ganze Rest des Programms pausiert dann ja auch für zwei Sekunden. Hat jemand eine Idee?
procedure TForm1.Button2Click(Sender: TObject);
begin
uos_CreatePlayer(1);
uos_AddFromFile(1, '/kurzer_2_sec_sound.mp3');
uos_AddIntoDevOut(1);
uos_AddDSPVolumeIn(0,0,0.6,0.6); //// player 0 ist das Lied
uos_Play(1);
Timer1.Enabled := true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
uos_AddDSPVolumeIn(0,0,1,1);
Timer1.Enabled:= false;
end;
So funktioniert das genau einmal. Beim 2. Button2Click wird die Musik noch leiser als beim 1. Mal. Beim 3. Button2Click noch leiser und beim 4. Button2Click nicht mehr hörbar. Nach der 2 Sek. Pause ist aber jeweils immer wieder die volle Lautstärke da.
procedure TForm1.Button2Click(Sender: TObject);
begin
if not Timer1.Enabled then begin
uos_CreatePlayer(1);
uos_AddFromFile(1, '/kurzer_2_sec_sound.mp3');
uos_AddIntoDevOut(1);
uos_AddDSPVolumeIn(0,0,0.6,0.6); //// player 0 ist das Lied
uos_Play(1);
Timer1.Enabled := true;
end;
end;
Falls du den sound bei jedem click neu starten möchtest vielleicht
procedure TForm1.Button2Click(Sender: TObject);
begin
uos_CreatePlayer(1);
uos_AddFromFile(1, '/kurzer_2_sec_sound.mp3');
uos_AddIntoDevOut(1);
if not Timer1.Enabled then begin
uos_AddDSPVolumeIn(0,0,0.6,0.6); //// player 0 ist das Lied
end
else begin
//hier timer restarten, weiss nicht wie das mit Lazarus geht,
//in MSEgui waers Timer1.restart(). Vielleicht
//timer.enabled:= false;
//timer.enabled:= true;
end;
uos_Play(1);
Timer1.Enabled := true;
end;
end;
Zu deinem ersten Listing, danke, mse. Aber das ändert nichts an dem Phänomen. Auch wenn die Änderung mich zwingt, die 2 Sek. verstreichen zu lassen, bevor ich Button2Click erneut aufrufen kann.
Eventuell liegt das Problem ja an der uos-Methode selbst?
Zum anderen, den kurzen Sound mit jedem Klick neu zu starten ging ja sowieso auch mit
mse hat geschrieben:Probiere mal uos_SetDSPVolumeIn().
Hatte ich auch schon. Mal davon abgesehen, dass ich nicht weiß was der letzte Parameter (boolean) bedeuten soll, bekomme ich dann beim Aufruf von Button2Click eine Fehlermeldung: Access violation.
mse hat geschrieben:Probiere mal uos_SetDSPVolumeIn().
Hatte ich auch schon. Mal davon abgesehen, dass ich nicht weiß was der letzte Parameter (boolean) bedeuten soll, bekomme ich dann beim Aufruf von Button2Click eine Fehlermeldung: Access violation.
Vermutlich muss man einmalig uos_AddDSPVolumeIn() aufrufen um die Skalierfunktion zu erzeugen und danach uos_SetDSPVolumeIn() um den Pegel einzustellen. Wahrscheinlich wird mit jedem uos_AddDSPVolumeIn() ein weiterer Multiplizierer eingeschlauft...
function uos_DSPVolume(Data: Tuos_Data; fft: Tuos_FFT): TDArFloat;
var
x, ratio: LongInt;
vleft, vright: double;
ps: PDArShort; //////// if input is Int16 format
pl: PDArLong; //////// if input is Int32 format
pf: PDArFloat; //////// if input is Float32 format
begin
vleft := Data.VLeft;
vright := Data.VRight;
case Data.SampleFormat of
2:
begin
ps := @Data.Buffer;
for x := 0 to (Data.OutFrames) do
if odd(x) then
ps^[x] := trunc(ps^[x] * vright)
else
ps^[x] := trunc(ps^[x] * vleft);
end;
1:
begin
pl := @Data.Buffer;
for x := 0 to (Data.OutFrames) do
if odd(x) then
pl^[x] := trunc(pl^[x] * vright)
else
pl^[x] := trunc(pl^[x] * vleft);
end;
0:
begin
case Data.LibOpen of
0: ratio := 1;
1: ratio := 2;
end;
pf := @Data.Buffer;
for x := 0 to (Data.OutFrames div ratio) do
if odd(x) then
pf^[x] := pf^[x] * vright
else
pf^[x] := pf^[x] * vleft;
end;
end;
Result := Data.Buffer;
end;
function Tuos_Player.AddDSPin(InputIndex: LongInt; BeforeProc: TFunc;
AfterProc: TFunc; LoopProc: Tproc): LongInt;
begin
SetLength(StreamIn[InputIndex].DSP, Length(StreamIn[InputIndex].DSP) + 1);
StreamIn[InputIndex].DSP[Length(StreamIn[InputIndex].DSP) - 1] := Tuos_DSP.Create();
StreamIn[InputIndex].DSP[Length(StreamIn[InputIndex].DSP) - 1].BefProc := BeforeProc;
StreamIn[InputIndex].DSP[Length(StreamIn[InputIndex].DSP) - 1].AftProc := AfterProc;
StreamIn[InputIndex].DSP[Length(StreamIn[InputIndex].DSP) - 1].LoopProc := LoopProc;
StreamIn[InputIndex].DSP[Length(StreamIn[InputIndex].DSP) - 1].Enabled := True;
StreamIn[InputIndex].DSP[Length(StreamIn[InputIndex].DSP) - 1].fftdata :=
Tuos_FFT.Create();
Result := Length(StreamIn[InputIndex].DSP) - 1;
end;
function Tuos_Player.AddDSPVolumeIn(InputIndex: LongInt; VolLeft: double;
VolRight: double): LongInt; ///// DSP Volume changer
////////// InputIndex : InputIndex of a existing Input
////////// VolLeft : Left volume
////////// VolRight : Right volume
// result : index of DSPIn in array
////////// example DSPIndex1 := AddDSPVolumeIn(InputIndex1,1,1);
begin
Result := AddDSPin(InputIndex, nil, @uos_DSPVolume, nil);
StreamIn[InputIndex].Data.VLeft := VolLeft;
StreamIn[InputIndex].Data.VRight := VolRight;
end;
procedure Tuos_Player.SetDSPVolumeIn(InputIndex: LongInt; DSPVolIndex: LongInt;
VolLeft: double; VolRight: double; Enable: boolean);
////////// InputIndex : InputIndex of a existing Input
////////// DSPIndex : DSPVolIndex of a existing DSPVolume
////////// VolLeft : Left volume ( -1 = do not change)
////////// VolRight : Right volume ( -1 = do not change)
////////// Enable : Enabled
////////// example SetDSPVolumeIn(InputIndex1,DSPVolIndex1,1,0.8,True);
begin
if VolLeft <> -1 then
StreamIn[InputIndex].Data.VLeft := VolLeft;
if VolRight <> -1 then
StreamIn[InputIndex].Data.VRight := VolRight;
StreamIn[InputIndex].DSP[DSPVolIndex].Enabled := Enable;
end;
Die Prozedur aus dem Eröffnungs-Thread funktioniert, entgegen meiner ersten Aussage, genauso wenig. Auch hier wird nach jedem Aufruf von Button2Click Player 0 immer leiser.
Habs mal eben getestet (wie mse schrieb):
- einmal uos_AddDSPVolumeIn(0, 0, 1, 1) für den in der Lautstärke zu verändernden Sound hinzufügen (am besten beim Laden des Soundfiles)
- den Sound verringern beim starten des anderen Soundfiles mit uos_SetDSPVolumeIn(0, 0, 0.1, 0.1, True)
- nach Ende des Sounds (z.B. per Timer) den Sound wieder auf normale Lautstärke stellen mit uos_SetDSPVolumeIn(0, 0, 1, 1, True)
So funktioniert das bei mir erstmal ohne Probleme.