When UOS quits, it plays the loaded sound files all over again, why?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

When UOS quits, it plays the loaded sound files all over again, why?

Little_Game_Developer
When UOS quits, it plays the loaded sound files all over again, why?

Program parts cannot unfortunately not be enclosed,
because the project is just way too big.

But both Wave and OGG files are used.
The wave files are loaded into the memory. Then at the end of the
programs they are properly released. And right here when releasing, all smaller sound files will be played one after the other without that being intended! The only thing that helps is to set the DSPVolume down to zero. The program uses only PortAudio & LibSndFile, all under Linux Ubuntu 18.04 Mate and Debian (Testing) Mate.
It seems that when releasing, the error occurs that a sound is replayed without it being supposed to.

It seems to me to be a bug in UOS.

I don't have a lot of time to get involved with this forum, just once in a while, once in a while, but it would be nice to have a solution.

- I don't speak English very well and so I have everything translated by one program.
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
Hello.

Could you give only part of your code, when you create the player when you play it.

I really want to help you but you do no give enough details.

> It seems to me to be a bug in UOS.

Maybe but without code or more detail I cannot do anything.

Fre;D

Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
Re-hello.

Did you call uos_Free() before to close the application?

Did you use PlayNoFree() ?

Fre;D

Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

Little_Game_Developer
Translation program used to translate from German to English.

Thanks for the help.

Here is a small summary as an excerpt,
from my game. I really can't contribute more, unfortunately.

As mentioned, the workaround is a DSPVolume reduction to zero a solution, but not really.

The problem is that when releasing (uos_Free() & ....) the UOS resources at the program end,
the smaller sounds played with PlayNoFree,
replayed, for whatever reason I don't understand.

Independent of everything: Thanks for UOS, this is currently the only suitable sound package for Lazarus, which is easy to use under Linux!
Please continue, thank you, and all the best.

(Little question, is PortAudio still under active development? I don't know?)

Please keep in mind that I can only visit the forum sometimes when the time allows it, unfortunately there is no other way.

Excerpt:

----

unit Main;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
    LCLType, Types, IntfGraphics, ComCtrls, fpImage,
    math, uos_flat{, LCLIntf};

type

    { TGameDlg }

    TGameDlg = class(TForm)
        GameArea: TPanel;
        Game_EventHandler: TTimer;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormChangeBounds(Sender: TObject);
        procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
        procedure GameAreaPaint(Sender: TObject);
        procedure Game_EventHandlerTimer(Sender: TObject);
    private
    public
    end;

// SOUND CATEGORYS
    cSC_None                        = -1;
    cSC_Event                       = 0;
    cSC_Atmosphere                  = 1;
    cSC_Music                       = 2;

    // SOUNDS : EVENT
    cSES_None                       = -1;
    cSES_S_NStep                    = 0;
    cSES_M_NStep                    = 1;
    cSES_M_LStep                    = 2;
    cSES_ChangeTool                 = 3;
    cSES_ChangeKeyMode              = 4;
    cSES_Shipping                   = 5;
    cSES_Woodenaxe                  = 6;
    cSES_Pickaxe                    = 7;
    cSES_Build                      = 8;
    cSES_Remove                     = 9;
    cSES_Harvest                    = 10;
    cSES_Seeding                    = 11;

    // SOUNDS : ATMOSPHERE
    cSAS_None                       = -1;
    cSAS_S_Atmosphere               = 0;
    cSAS_S_Rainfall                 = 1;

    // SOUNDS : MUSIC
    cSMC_None                       = -1;
    cSMC_Music1                     = 0;
    cSMC_Music2                     = 1;
    cSMC_Music3                     = 2;
    cSMC_Music4                     = 3;
    cSMC_Music5                     = 4;
    cSMC_Music6                     = 5;
    cSMC_Music7                     = 6;
    cSMC_Music8                     = 7;
    cSMC_Music9                     = 8;
    cSMC_Music10                    = 9;
    cSMC_Music11                    = 10;
    cSMC_Music12                    = 11;

....

TG_Game = class
    private
    public
    // AREA: SOUNDS.
    UOS_LibraryPortAudio: String;
    UOS_LibrarySndFile: String;

    UOS_Device_Usable: Boolean;
    UOS_Sounds_Usable: Boolean;

    S_ES: array of Integer;
    S_AS: array of Integer;
    S_MC: array of Integer;
    S_MCFN: array of String;
    S_MCNow: Integer;

    // AREA: SOUND.
    function LoadUOS(): Boolean;
    function LoadASound(pCategory: Integer; pFileName: String): Boolean; // Add A Sound to S_ES (Sound Event : Category)
    procedure CallOn_SMCAllEnd();
    function SetVolumeASound(pCategory: Integer; pID: Integer; pVolume: Integer): Boolean;
    function LoadAllSounds(): Boolean;
    function PlayASound(pCategory: Integer; pID: Integer): Boolean;
    function PauseASound(pCategory: Integer; pID: Integer): Boolean;
    function ResumeASound(pCategory: Integer; pID: Integer): Boolean;

    // AREA: GAME QUIT.
    function Quit(): Boolean;

    function Game_CleaningPower(): Boolean;
end;

....

procedure TGameDlg.FormCreate(Sender: TObject);
begin
     try
        // Create Game Class!!!!
        Game := TG_Game.Create;
        //....
     except
           writeln('Initialize Error!');
           GameDlg.Close();
           Application.Terminate;
           Exit;
     end;
end;

function Game_Initialize(): Boolean; // GLOBAL!
begin
     try

        ....

        Result := True;
        Exit;
     except
           Game_CleaningPower();
           Result := False;
           Exit;
     end;
end;

procedure TGameDlg.FormDestroy(Sender: TObject);
begin
     try
        Game_CleaningPower();
        Exit;
     except
           Game_CleaningPower();
           Exit;
     end;
end;

// GAME QUIT.
function TG_Game.Quit(): Boolean;
begin
     try
        // ToDo....
        Result := True;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

....

function Game_CleaningPower(): Boolean;
var
   tCnt: Integer;
begin
    // Free Sound Resources
    if (Game.UOS_Device_Usable = True) And (Game.UOS_Sounds_Usable = True) then
    begin
         Game.SetVolumeASound(cSC_Music, cSMC_Music1, 0);
         Game.SetVolumeASound(cSC_Music, cSMC_Music2, 0);
         Game.SetVolumeASound(cSC_Music, cSMC_Music3, 0);

         Game.SetVolumeASound(cSC_Atmosphere, cSAS_S_Atmosphere, 0);
         Game.SetVolumeASound(cSC_Atmosphere, cSAS_S_Rainfall, 0);

         Game.SetVolumeASound(cSC_Event, cSES_S_NStep, 0);
         Game.SetVolumeASound(cSC_Event, cSES_M_NStep, 0);
         Game.SetVolumeASound(cSC_Event, cSES_M_LStep, 0);
         Game.SetVolumeASound(cSC_Event, cSES_ChangeTool, 0);
         Game.SetVolumeASound(cSC_Event, cSES_ChangeKeyMode, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Shipping, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Woodenaxe, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Pickaxe, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Build, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Remove, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Harvest, 0);
         Game.SetVolumeASound(cSC_Event, cSES_Seeding, 0);

         for tCnt := High(Game.S_MC) downto 0 do
         begin
              uos_BeginProc(Game.S_MC[tCnt], nil);
              uos_EndProc(Game.S_MC[tCnt], nil);
              uos_LoopBeginProc(Game.S_MC[tCnt], nil);
              uos_LoopEndProc(Game.S_MC[tCnt], nil);
         end;

         for tCnt := High(Game.S_AS) downto 0 do
         begin
              uos_BeginProc(Game.S_AS[tCnt], nil);
              uos_EndProc(Game.S_AS[tCnt], nil);
              uos_LoopBeginProc(Game.S_AS[tCnt], nil);
              uos_LoopEndProc(Game.S_AS[tCnt], nil);
         end;

         for tCnt := High(Game.S_ES) downto 0 do
         begin
              uos_BeginProc(Game.S_ES[tCnt], nil);
              uos_EndProc(Game.S_ES[tCnt], nil);
              uos_LoopBeginProc(Game.S_ES[tCnt], nil);
              uos_LoopEndProc(Game.S_ES[tCnt], nil);
         end;

         Game.UOS_Device_Usable := False;
         Game.UOS_Sounds_Usable := False;

         SetLength(Game.S_MC, 0);
         SetLength(Game.S_MCFN, 0);
         SetLength(Game.S_AS, 0);
         SetLength(Game.S_ES, 0);

         uos_Free();
    end;
end;

// AREA: SOUND.

function TG_Game.LoadUOS(): Boolean;
{var
   tPath: String;}
begin
     try
        //{$IFDEF Windows} // DON'T FUNC! BUT DON'T REQUIRED
         //{$if defined(cpu64)}
          //Game.UOS_LibraryPortAudio := Application.Location + 'uos-master/lib/Windows/64bit/LibPortaudio-64.dll';
          //Game.UOS_LibrarySndFile := Application.Location + 'uos-master/lib/Windows/64bit/LibSndFile-64.dll';
         //{$else}
         //Game.UOS_LibraryPortAudio := Application.Location + 'uos-master/lib/Windows/32bit/LibPortaudio-32.dll';
          //Game.UOS_LibrarySndFile := Application.Location + 'uos-master/lib/Windows/32bit/LibSndFile-32.dll';
         //{$endif}
        //{$ENDIF}

        {$IFDEF Darwin} // DONT REQUIRED
         tPath := Application.Location;
         tPath := copy(tPath, 1, Pos('/uos', tPath) - 1);
         Game.UOS_LibraryPortAudio := tPath + 'uos-master/lib/Mac/32bit/LibPortaudio-32.dylib';
         Game.UOS_LibrarySndFile := tPath + 'uos-master/lib/Mac/32bit/LibSndFile-32.dylib';
        {$ENDIF}

        {$IFDEF linux} // Ok.
         {$if defined(cpu64)}
          Game.UOS_LibraryPortAudio := Application.Location + 'uos-master/lib/Linux/64bit/LibPortaudio-64.so';
          Game.UOS_LibrarySndFile := Application.Location + 'uos-master/lib/Linux/64bit/LibSndFile-64.so';
         {$else}
          Game.UOS_LibraryPortAudio := Application.Location + 'uos-master/lib/Linux/32bit/LibPortaudio-32.so';
          Game.UOS_LibrarySndFile := Application.Location + 'uos-master/lib/Linux/32bit/LibSndFile-32.so';
         {$endif}
        {$ENDIF}

        {$IFDEF freebsd} // DONT REQUIRED TO TIME BUT IN FUTURE....
         {$if defined(cpu64)}
          Game.UOS_LibraryPortAudio := Application.Location + 'uos-master/lib/FreeBSD/64bit/libportaudio-64.so';
          Game.UOS_LibrarySndFile := Application.Location + 'uos-master/lib/FreeBSD/64bit/libsndfile-64.so';
         {$else}
          Game.UOS_LibraryPortAudio := Application.Location + 'uos-master/lib/FreeBSD/32bit/libportaudio-32.so';
          Game.UOS_LibrarySndFile := Application.Location + 'uos-master/lib/FreeBSD/32bit/libsndfile-32.so';
         {$endif}
        {$ENDIF}

        if uos_LoadLib(PChar(Game.UOS_LibraryPortAudio), PChar(Game.UOS_LibrarySndFile), nil, nil, nil, nil) = 0 then
        begin
             Game.UOS_Device_Usable := True;
        end
        else
        begin
             Game.UOS_Device_Usable := False;
             if uosLoadResult.PAloaderror = 1 then
             begin
                  ShowMessage(Game.UOS_LibraryPortAudio + ' do not exist!');
             end;
             if uosLoadResult.PAloaderror = 2 then
             begin
                  ShowMessage(Game.UOS_LibraryPortAudio + ' do not load!');
             end;
             if uosLoadResult.SFloaderror = 1 then
             begin
                  ShowMessage(Game.UOS_LibrarySndFile + ' do not exist!');
             end;
             if uosLoadResult.SFloaderror = 2 then
             begin
                  ShowMessage(Game.UOS_LibrarySndFile + ' do not load!');
             end;
        end;

     except
           Game.UOS_Device_Usable := False;
           uos_free();
     end;
end;

function TG_Game.LoadASound(pCategory: Integer; pFileName: String): Boolean;
begin
     try
        if (pCategory >= cSC_Event) And (pCategory <= cSC_Music) then
        begin
             case pCategory of
                  cSC_Event:
                    begin
                         if (FileExists(Application.Location + cP_StdSounds + pFileName + cX_WAV) = True) Or (FileExists(Application.Location + cP_StdSounds + pFileName + cX_OGG) = True) then
                         begin
                              SetLength(Game.S_ES, (Length(Game.S_ES) + 1));
                              Game.S_ES[High(Game.S_ES)] := Game.S_Count;

                              uos_CreatePlayer(Game.S_ES[High(Game.S_ES)]);

                              if (FileExists(Application.Location + cP_StdSounds + pFileName + cX_WAV) = True) then
                              begin
                                   uos_AddFromFile(Game.S_ES[High(Game.S_ES)], PChar(Application.Location + cP_StdSounds + pFileName + cX_WAV));
                              end
                              else if (FileExists(Application.Location + cP_StdSounds + pFileName + cX_OGG) = True) then
                              begin
                                   uos_AddFromFile(Game.S_ES[High(Game.S_ES)], PChar(Application.Location + cP_StdSounds + pFileName + cX_OGG));
                              end;

                              uos_InputAddDSPVolume(Game.S_ES[High(Game.S_ES)], 0, 0, 0);
                              uos_AddIntoDevOut(Game.S_ES[High(Game.S_ES)]);

                              uos_PlayNoFree(Game.S_ES[High(Game.S_ES)], 1);
                              uos_Stop(Game.S_ES[High(Game.S_ES)]);

                              uos_InputSetDSPVolume(Game.S_ES[High(Game.S_ES)], 0, 1, 1, True);

                              //uos_flat.uos_InputSeek ;

                              Game.S_Count := (Game.S_Count + 1);

                              Result := True;
                              Exit;
                         end;
                    end;
                  cSC_Atmosphere:
                    begin
                         if (FileExists(Application.Location + cP_StdAtmosphere + pFileName + cX_WAV) = True) Or (FileExists(Application.Location + cP_StdSounds + pFileName + cX_OGG) = True) then
                         begin
                              SetLength(Game.S_AS, (Length(Game.S_AS) + 1));
                              Game.S_AS[High(Game.S_AS)] := Game.S_Count;

                              uos_CreatePlayer(Game.S_AS[High(Game.S_AS)]);

                              if (FileExists(Application.Location + cP_StdAtmosphere + pFileName + cX_WAV) = True) then
                              begin
                                   uos_AddFromFile(Game.S_AS[High(Game.S_AS)], PChar(Application.Location + cP_StdAtmosphere + pFileName + cX_WAV));
                              end
                              else if (FileExists(Application.Location + cP_StdAtmosphere + pFileName + cX_OGG) = True) then
                              begin
                                   uos_AddFromFile(Game.S_AS[High(Game.S_AS)], PChar(Application.Location + cP_StdAtmosphere + pFileName + cX_OGG));
                              end;

                              uos_InputAddDSPVolume(Game.S_AS[High(Game.S_AS)], 0, 0, 0);
                              uos_AddIntoDevOut(Game.S_AS[High(Game.S_AS)]);

                              uos_PlayNoFree(Game.S_AS[High(Game.S_AS)], 1);
                              uos_Stop(Game.S_AS[High(Game.S_AS)]);

                              uos_InputSetDSPVolume(Game.S_AS[High(Game.S_AS)], 0, 1, 1, True);

                              Game.S_Count := (Game.S_Count + 1);

                              Result := True;
                              Exit;
                         end;
                    end;
                  cSC_Music:
                    begin
                         if (FileExists(Application.Location + cP_StdMusics + pFileName + cX_WAV) = True) Or (FileExists(Application.Location + cP_StdMusics + pFileName + cX_OGG) = True) then
                         begin
                              SetLength(Game.S_MC, (Length(Game.S_MC) + 1));
                              SetLength(Game.S_MCFN, (Length(Game.S_MCFN) + 1));
                              Game.S_MC[High(Game.S_MC)] := Game.S_Count;

                              if (FileExists(Application.Location + cP_StdMusics + pFileName + cX_WAV) = True) then
                              begin
                                   Game.S_MCFN[High(Game.S_MCFN)] := Application.Location + cP_StdMusics + pFileName + cX_WAV;
                              end
                              else if (FileExists(Application.Location + cP_StdMusics + pFileName + cX_OGG) = True) then
                              begin
                                   Game.S_MCFN[High(Game.S_MCFN)] := Application.Location + cP_StdMusics + pFileName + cX_OGG;
                              end;

                              Game.S_MCNow := 0;

                              Game.S_Count := (Game.S_Count + 1);

                              Result := True;
                              Exit;
                         end;
                    end;
             end;
        end;
        Result := False;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

// This Callback is for Music Play List....
procedure TG_Game.CallOn_SMCAllEnd();
begin
     try
        if (Game.S_MCNow < 2) then
        begin
             Game.PauseASound(cSC_Music, Game.S_MCNow);
             Game.S_MCNow := (Game.S_MCNow + 1);
        end
        else
        begin
             Game.S_MCNow := 0;
        end;
        case Game.S_MCNow of
             0:
               begin
                    Game.PlayASound(cSC_Music, cSMC_Music1);
               end;
             1:
               begin
                    Game.PlayASound(cSC_Music, cSMC_Music2);
               end;
             2:
               begin
                    Game.PlayASound(cSC_Music, cSMC_Music3);
               end;
        end;
     except
     end;
end;

function TG_Game.SetVolumeASound(pCategory: Integer; pID: Integer; pVolume: Integer): Boolean;
begin
     try
        if (Game.UOS_Device_Usable = True) And (Game.UOS_Sounds_Usable = True) then
        begin
             if (pCategory >= cSC_Event) And (pCategory <= cSC_Music) then
             begin
                  case pCategory of
                       cSC_Event:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_ES)) then
                              begin
                                   if (Game.S_ES[pID] >= 0) And (Game.S_ES[pID] <= Game.S_Count) then
                                   begin
                                        uos_InputSetDSPVolume(Game.S_ES[pID], 0, pVolume, pVolume, True);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                       cSC_Atmosphere:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_AS)) then
                              begin
                                   if (Game.S_AS[pID] >= 0) And (Game.S_AS[pID] <= Game.S_Count) then
                                   begin
                                        uos_InputSetDSPVolume(Game.S_AS[pID], 0, pVolume, pVolume, True);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                       cSC_Music:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_MC)) then
                              begin
                                   if (Game.S_MC[pID] >= 0) And (Game.S_MC[pID] <= Game.S_Count) then
                                   begin
                                        uos_InputSetDSPVolume(Game.S_MC[pID], 0, pVolume, pVolume, True);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                  end;
             end;
        end;
        Result := False;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

function TG_Game.LoadAllSounds(): Boolean;
begin
     try
        Game.UOS_Device_Usable := False;
        Game.UOS_Sounds_Usable := False;

        Game.LoadUOS();

        if (Game.UOS_Device_Usable = True) then
        begin
             Game.LoadASound(cSC_Event, 'S_NStep');
             Game.LoadASound(cSC_Event, 'M_NStep');
             Game.LoadASound(cSC_Event, 'M_LStep');
             Game.LoadASound(cSC_Event, 'ChTool');
             Game.LoadASound(cSC_Event, 'ChKeyMode');
             Game.LoadASound(cSC_Event, 'Shipping');
             Game.LoadASound(cSC_Event, 'Woodenaxe');
             Game.LoadASound(cSC_Event, 'Pickaxe');
             Game.LoadASound(cSC_Event, 'Build');
             Game.LoadASound(cSC_Event, 'Remove');
             Game.LoadASound(cSC_Event, 'Harvest');
             Game.LoadASound(cSC_Event, 'Seeding');

             Game.LoadASound(cSC_Atmosphere, 'S_Atmosphere');
             Game.LoadASound(cSC_Atmosphere, 'S_Rainfall');

             Game.LoadASound(cSC_Music, 'MrBkDreaming');
             Game.LoadASound(cSC_Music, 'MrBkAsia');
             Game.LoadASound(cSC_Music, 'MrBkAdventure');

             Game.UOS_Sounds_Usable := True;

             Game.PlayASound(cSC_Atmosphere, cSAS_S_Atmosphere);

             Result := True;
             Exit;
        end;
        Result := False;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

function TG_Game.PlayASound(pCategory: Integer; pID: Integer): Boolean;
begin
     try
        if (Game.UOS_Device_Usable = True) And (Game.UOS_Sounds_Usable = True) then
        begin
             if (pCategory >= cSC_Event) And (pCategory <= cSC_Music) then
             begin
                  case pCategory of
                       cSC_Event:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_ES)) then
                              begin
                                   if (Game.S_ES[pID] >= 0) And (Game.S_ES[pID] <= Game.S_Count) then
                                   begin
                                        uos_PlayNoFree(Game.S_ES[pID], 1);

                                        // No Loops Allowed!!!!

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                              Result := True;
                              Exit;
                         end;
                       cSC_Atmosphere:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_AS)) then
                              begin
                                   if (Game.S_AS[pID] >= 0) And (Game.S_AS[pID] <= Game.S_Count) then
                                   begin
                                        uos_PlayNoFree(Game.S_AS[pID], -1);

                                        // Every Time loops!!!!

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                       cSC_Music:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_MC)) then
                              begin
                                   if (Game.S_MC[pID] >= 0) And (Game.S_MC[pID] <= Game.S_Count) then
                                   begin
                                        uos_CreatePlayer(Game.S_MC[pID]);
                                        uos_AddFromFile(Game.S_MC[pID], PChar(Game.S_MCFN[pID]));
                                        uos_InputAddDSPVolume(Game.S_MC[pID], 0, 1, 1);
                                        uos_AddIntoDevOut(Game.S_MC[pID]);
                                        uos_EndProc(Game.S_MC[pID], @Game.CallOn_SMCAllEnd);
                                        uos_Play(Game.S_MC[pID], 1);

                                        // No Loops Allowed!!!!

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                  end;
             end;
        end;
        Result := False;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

function TG_Game.PauseASound(pCategory: Integer; pID: Integer): Boolean;
begin
     try
        if (Game.UOS_Device_Usable = True) And (Game.UOS_Sounds_Usable = True) then
        begin
             if (pCategory >= cSC_Event) And (pCategory <= cSC_Music) then
             begin
                  case pCategory of
                       cSC_Event:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_ES)) then
                              begin
                                   if (Game.S_ES[pID] >= 0) And (Game.S_ES[pID] <= Game.S_Count) then
                                   begin
                                        // Pause & Resume Not Allowed!!!!
                                        Result := False;
                                        Exit;
                                   end;
                              end;
                         end;
                       cSC_Atmosphere:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_AS)) then
                              begin
                                   if (Game.S_AS[pID] >= 0) And (Game.S_AS[pID] <= Game.S_Count) then
                                   begin
                                        uos_Stop(Game.S_AS[pID]);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                         cSC_Music:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_MC)) then
                              begin
                                   if (Game.S_MC[pID] >= 0) And (Game.S_MC[pID] <= Game.S_Count) then
                                   begin
                                        uos_EndProc(Game.S_MC[Game.S_MCNow], nil);
                                        uos_Stop(Game.S_MC[Game.S_MCNow]);
                                        uos_FreePlayer(Game.S_MC[Game.S_MCNow]);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                  end;
             end;
        end;
        Result := False;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

function TG_Game.ResumeASound(pCategory: Integer; pID: Integer): Boolean;
begin
     try
        if (Game.UOS_Device_Usable = True) And (Game.UOS_Sounds_Usable = True) then
        begin
             if (pCategory >= cSC_Event) And (pCategory <= cSC_Music) then
             begin
                  case pCategory of
                       cSC_Event:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_ES)) then
                              begin
                                   if (Game.S_ES[pID] >= 0) And (Game.S_ES[pID] <= Game.S_Count) then
                                   begin
                                        // Pause & Resume Not Allowed!!!!
                                        Result := False;
                                        Exit;
                                   end;
                              end;
                         end;
                       cSC_Atmosphere:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_AS)) then
                              begin
                                   if (Game.S_AS[pID] >= 0) And (Game.S_AS[pID] <= Game.S_Count) then
                                   begin
                                        uos_PlayNoFree(Game.S_MC[pID], -1);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                         cSC_Music:
                         begin
                              if (pID >= 0) And (pID <= High(Game.S_MC)) then
                              begin
                                   if (Game.S_MC[pID] >= 0) And (Game.S_MC[pID] <= Game.S_Count) then
                                   begin
                                        Game.PlayASound(pCategory, Game.S_MCNow);

                                        Result := True;
                                        Exit;
                                   end;
                              end;
                         end;
                  end;
             end;
        end;
        Result := False;
        Exit;
     except
           Result := False;
           Exit;
     end;
end;

....

Game.S_Count := 0;
Game.S_IsIDPYMusic := False;
Game.S_IsPlayMusic := False;
Game.LoadAllSounds();

    ....
    Game.PlayASound(cSC_Event, cSES_Build); // All only Examples....

    ....

....
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
Hello.

Huh, that is more than "few part of your code"!

OK, I will check your code this week-end, write you later.

Fre;D
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
This post was updated on .
Hello.

OK, I did try part of your code using PlayNoFee().

I could not reproduce the problem (some chunk played when application close).

Anyway, in last commits 88aec9e , there are filters in uos_free() method.
https://github.com/fredvs/uos/

Maybe it solves your problems.

Could you try it with this code?

function Game_CleaningPower(): Boolean;
begin
    // To free uos resources, use only this:
 if (Game.UOS_Device_Usable = True) And (Game.UOS_Sounds_Usable = True) then uos_Free();
end;

Fre;D
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

Little_Game_Developer
Translated with DeepL translation program from German to English!

Many thanks for the extensive help.

That's exactly what I tried! But unfortunately all sound elements that were played with "uos_PlayNoFree(....);" will be played again at the end of the game/program when calling "uos_Free();".
It's only "Wave Files", but I can't rule out that it would be the same with OGGs. Amazing is, that even longer "Wave Files" are only played for the length of the shorter pieces. So it takes less than one second.
As an example, atmospheres sounds that I implemented as "Wave Files" in the length of 4 minutes are used here. These are played at the end of the program when calling "uos_Free();", at the same time with the other shorter "Wave Files", also only under one second.
Please note that some short event sounds are only played for about 0.190 seconds. I don't need longer event sounds usually.
And only for this time, at the end, all things will be played again at the same time when calling "uos_Free();". I suspect that UOS might have problems in the "uos_PlayNoFree(); / Wave" area with short sounds of less than 1 second, maybe only in combination with longer sounds or not. Or simultaneously in "uos_Free();"  Later.

Ps. The "reCaptcha" doesn't work properly, even if you select everything right, you often can't get any further.
The thing doesn't seem to understand what traffic light, bus, car, or zebra crossing means. Can you improve that somehow?

As mentioned, unfortunately I can only drop by here in the forum sometimes,
that can vary from time.
But really many thanks.
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

Little_Game_Developer
Small addition to the last post.

I also have longer event sounds than 0,190 seconds.
Some also longer than 1 second, as well as longer atmosphere sounds, all "Wave-Files" and "uos_PlayNoFree();", except for the music (which goes around the 3 minutes, each (PlayList)), and is OGG (music with "uos_Play();").
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
This post was updated on .
Hello.

Before that I investigate more, to be sure, did you try with last commits of uos ?

[EDIT] Google translation:

Vorher untersuche ich mehr, um sicherzugehen, haben Sie mit den letzten Ă„nderungen an UOS-Code versucht?
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
This post was updated on .
> Ps. The "reCaptcha" doesn't work properly, even if you select everything right, you often can't get any further.
> The thing doesn't seem to understand what traffic light, bus, car, or zebra crossing means. Can you improve that somehow?

Sorry, I do not understand. What is "reCaptcha" ?

[EDIT] Are you talking about the "robot tester" of uos-forum?
If yes, I have no power on this, it is a nabble.com feature.

Fre;D
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

Little_Game_Developer
Yeah, "reCaptcha" is the robot check, that's what I meant.
Ok, if you can't do anything about it, no problem.

So I tried a lot of things around now,
and it's still not really going any better with the new commit.
But, I managed not to play everything at the end of the program!

I have to say, that I had done it in my own "LoadASound" function, that all Event & Atmosphere sounds were started in "LoadAllSounds", once with "uos_PlayNoFree" (volume 0%) and stopped directly with "uos_Stop" (then again to volume 100%), so that they are already in RAM when starting the program.
Then an atmosphere sound was created with "uos_PlayNoFree" using the
(-1=Endless Loop Parameter), played to repeat.
And if necessary, rain sounds are also played in the same way.

As one of the tests, I took out the loading of all sounds into memory by an initial "uos_PlayNoFree & uos_Stop", and set the loop parameter of the atmosphere sound to play all at once.
And then the error almost didn't occur anymore.
But if it did, then only the step (go) sound (0.190 seconds/wave) became,
played at the end.

Very strange. I may be wrong, but if I understand it correctly, the error could be in connection with the loop parameter "-1" (atmosphere 4 minutes wave file) of "uos_PlayNoFree" and the 0.190 seconds long "step" sound.
Even with the new UOS (Commit) not everything could be solved.
I found out that the problems are strongest at the beginning,
if very shortly after the program & UOS start, several or even only one sound is played with "uos_PlayNoFree".

I know this seems crazy, but I just don't know what else to do to narrow down the error.
The short play is, always under one second at the end of the program, i.e. when unloading UOS with "uos_Free".

Short sound structure info about my game:

Surface:
-> Event Sounds (Wave Files - "uos_PlayNoFree").
    -> Action Sounds over days (as short as possible).
-> Atmospheric noises (Wave Files - "uos_PlayNoFree").
    -> Wind (Endless).
    -> Rain (Sometimes).

Mine:
-> Event Sounds (Wave Files - "uos_PlayNoFree").
    -> Action sounds underground (as short as possible).
-> Atmospheric noises (Wave Files - "uos_PlayNoFree").
    -> mine caves noises.

 In general:
-> music (playlist) ("uos_Play" - with "EndProc" function call)
(Only Ogg files Music files with a length up to 3-4 minutes)

The ID numbers of the players (sounds) of the UOS are managed in three integer arrays (event, atmosphere & music).

It can't be ruled out that the error might be in my program, but it seems to work out of my reach so far.
You don't have to do all the work to keep looking for the problem, of course I have full understanding!
But if they do, then perhaps it could be valuable for others who use UOS,
if the bug is actually in UOS and not in my game, which is not sure.

In any case, many thanks for the very frequent and extensive help so far.

For permanent health reasons I can unfortunately not be constantly occupied with the project, always only when it is possible.
This can mean that I cannot always react promptly to new suggestions.
And so far other users seem strangely not to have this problem with UOS.

I would still have a theoretical question, but this is not important!
Would it be conceivable or even sensible to develop UOS in this way?
1. that all sounds are loaded at the beginning of the program.
2. that, if necessary, the sounds will be played.
3. and that at the end of the program the sounds are unloaded again.
So a different structure.

Just a simple example:

// Program : Start
tEventSound1 := uos_LoadSound('EventSound.wav');
tEventSound2 := uos_LoadSound('EventSound.wav');
tMusic := uos_LoadSound('Music.ogg');'

// Program : Application
uos_PlaySound(tMusic, -1) // Endless loop (until program end)

for tCnt := 0 to 12 do
beginning
    uos_PlaySound(tEventSound1, 1);
    Sleep(uos_GetLength(tEventSound1));
end;

for tCnt := 0 to 12 do
beginning
    uos_PlaySound(tEventSound2, 1);
    Sleep(uos_GetLength(tEventSound2));
end;

// Program : End
uos_Free();

Ps. Thank you for pre-translating with Google Translate in German.
But I use among other things the Chromium Browser, you can set it to automatically translate every possible language into German without any addons, in the language settings.
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
Hello.

> 1. that all sounds are loaded at the beginning of the program.

Why dont you use uos_AddFromMemoryStream()?
Take a look at consoleplaymemorystream demo.

> 2. that, if necessary, the sounds will be played.

With uos_playnofree() it should work.

> 3. and that at the end of the program the sounds are unloaded again.

You may use uos_playpaused + uos_stop for this.

All what you explained, IMHO, can be done by uos.

It is sad that I do not have more of your code to understand why it does not work with your code.

Fre;D

Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
Re-hello.

Did you try with mp3 files?
It seems that you use .ogg and .wav files.

Normally mp3 and ogg files should give same result but maybe it is a problem of libsoundfile (ogg and wav use libsndfile, mp3 use libmpg123).

Of course if you could give code that reproduce your problem i would be **much** easier to fix it.

Other thing, what OS are you using?
It seems that you are using Linux.
But what Linux, 32 or 64 bit?
Did you try to compile your prog for Windows?
If yes, do you have still the problem with Windows?

[EDIT] Do you have plan to give your program on GitHUB (and so much easier to debug) ?

Fre;D

Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

Little_Game_Developer
Hello again. Unfortunately I don't have much time at the moment!

INFO:
Operating system:
2x Linux Ubuntu 18.04 (64Bit) Mate and Debian Testing (64Bit) Mate, so GTK Gnome Direction/Category.
(No Windows "to test projects", no Mac OS, and no FreeBSD yet, maybe later).
The PCs are about 11-12 years old computers, one with Intel Duo Core (8 GB Ram) and one with AMD (4 GB Ram).

With Wine I tried it a long time ago, without this project, to test it in a clean project only for UOS, under Linux, that led unfortunately to memory errors (Leaks). Do you have to use backslashes for "Wine" filenames or is it possible like with Linux with slashes, I'm not sure?

IMPORTANT!
I'm not using a GitHub, and the project is a family internal project, so guaranteed not intended for publishing, really!
But everything about UOS I showed in the post the other day.
(Info: The project uses except UOS only the normal scope of delivery of Lazarus for Linux Ubuntu)
To test everything in MP3, unfortunately I don't have time for that at the moment, and it wouldn't be so good for the project, because I want to do without codecs for MP3. Therefore I only use PortAudio & LibSndFile from UOS,
because they only know wave and OGG.

INTEREST:
Now I've found out something!
If you want to play an Atmosphere track, I use "uos_PlayNoFree" with parameter Loop=-1 (Wave, 39 seconds - a rain sound).
And so far I've used "uos_Stop" to stop it.
Now I thought that uos_Stop might not be suitable for "uos_PlayNoFree" before you're done with the whole program. So I built in "uos_Pause", and with "uos_RePlay" I tried to make the (Rain) Atmosphere piece work again, and it can't be started under any circumstances.

1ST EXAMPLE:
"uos_PlayNoFree(<RainSoundWaveID>, -1)" = Starts the track endlessly.
"uos_Pause(<RainSoundWaveID>) = Pauses the track.
"uos_RePlay(<RainSoundWaveID>) = Should let the track continue, but not!

QUESTION?
Can "uos_Stop" be used without hesitation on a "uos_PlayNoFree" track in an endless loop? And can then, again with "uos_PlayNoFree", the track be restarted, so that the duration loop (-1) remains, without memory error or other errors?

2ND EXAMPLE:
"uos_PlayNoFree(<RainSoundWaveID>, -1)" = Starts the track endlessly.
"uos_Stop(<RainSoundWaveID>) = Stops the track.
"uos_PlayNoFree(<RainSoundWaveID>, -1) = Starts the track from the beginning, with endless loop.

Or does this lead to memory errors? I always had the second EXAMPLE before, until now. The first EXAMPLE, however, would also be a conceivable variant if it would work, which unfortunately it doesn't, why?

I now think that the problem is in the Atmosphere Loop area, so a "uos_PlayNoFree" with parameter Loop=-1 is a "uos_PlayNoFree" that will cause the rest to go into problems, maybe because of the "uos_Stop" and then calling "uos_PlayNoFree" again (Loop=-1 endless).

Thanks again for the tip with "uos_AddFromMemoryStream", I think I'll try to implement it soon when there's more time.

As I said, I don't have much time, but I would be happy if you could answer the questions on occasion.

Thanks a lot!
Reply | Threaded
Open this post in threaded view
|

Re: When UOS quits, it plays the loaded sound files all over again, why?

fredvs
Administrator
> Unfortunately I don't have much time at the moment!

Same for me!

Sorry but I cannot help you more.
The only way would be that you give a simple example how to reproduce your problems.

Sorry but my crystal ball is not working good those last time.

Fre;D