Volume mit uos steuern

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Volume mit uos steuern

Beitrag von Stefan67 »

Erreichen möchte ich folgendes:

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:

Code: Alles auswählen

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?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »

Mache das "uos_AddDSPVolumeIn(0,0,1,1);" in einem TTimer.OnTimer handler.

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Volume mit uos steuern

Beitrag von Stefan67 »

So?

Code: Alles auswählen

 
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.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »

Code: Alles auswählen

 
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

Code: Alles auswählen

 
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;           
 

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Volume mit uos steuern

Beitrag von Stefan67 »

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

Code: Alles auswählen

 
    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;         
 

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »

Wo ist uos_AddDSPVolumeIn() dokumentiert?

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Volume mit uos steuern

Beitrag von Stefan67 »

mse hat geschrieben:Wo ist uos_AddDSPVolumeIn() dokumentiert?
in der uos_flat.pas

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »


Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Volume mit uos steuern

Beitrag von Stefan67 »

mse hat geschrieben:Von hier https://github.com/fredvs/uos/ ?
Ja, unter src

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »

Probiere mal uos_SetDSPVolumeIn().

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Volume mit uos steuern

Beitrag von Stefan67 »

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
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »

Dann halt trotzdem die Lied-Lautstärke nur verkleinern wenn sie nicht schon verkleinert ist.

Code: Alles auswählen

 
        if not Timer1.Enabled then begin
         uos_AddDSPVolumeIn(0,0,0.6,0.6); //// player 0 ist das Lied
        end
 

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Volume mit uos steuern

Beitrag von mse »

Stefan67 hat geschrieben:
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...

Code: Alles auswählen

 
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;
 

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Volume mit uos steuern

Beitrag von Stefan67 »

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.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Volume mit uos steuern

Beitrag von Michl »

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.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten