Recent

Author Topic: [SOLVED] Thread.Start problem with Windows.  (Read 6959 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 3785
    • StrumPract is the musicians best friend
[SOLVED] Thread.Start problem with Windows.
« on: November 14, 2012, 12:41:44 pm »
Hello everybody.

Have problems with Windows...

I want to do working many threads together and independently.
With Linux and OSX Thread.Start works great but with Windows it does not work.

In the code that follow at line 473 :
Code: [Select]
UOSSTREAM[x].Thread.Start;
Does not work with Windows, it only works with :

Code: [Select]
UOSSTREAM[x].Thread.Execute;
But then i cannot do Threads working together.

Here the full code.

Whats wrong ?

Code: [Select]
unit U_OS;

{*******************************************************************************
*                  United Openlibraries of Sound ( U_OS )                      *
*                  --------------------------------------                      *
*                                                                              *
*           United procedures to access Open Sound libraries                   *
*                                                                              *
*                                                                              *
*     Lazarus Forum     /   Fred van Stappen   /  Fiens@hotmail.com            *
*                                                                              *
********************************************************************************
*        second realease     first changes:  2012-07-20                        *
*                            second changes: 2012-07-31                        *
*                            3 th changes: 2012-11-13                          *                        *
*******************************************************************************}

interface

uses

  Classes, Forms, SysUtils, dialogs ,LazDyn_PortAudio, LazDyn_LibSndFile, LazDyn_Mpg123;


const
  ///// error
  noError            = 0;
  FilePAError        = 10;
  LoadPAError        = 11;
  FileSFError        = 20;
  LoadSFError        = 21;
  FileMPError        = 30;
  LoadMPError        = 31;

  //////// UOS_load() flag
  LoadAll            = 0;   // load all PortAudio + SndFile + MPG123
  LoadPA             = 1;   // load only PortAudio
  LoadSF             = 2;   // load only SndFile
  LoadMP             = 3;   // load only MPG123
  LoadPA_SF          = 4;   // load only PortAudio + SndFile
  LoadPA_MP          = 5;   // load only PortAudio + MPG123
  LoadSF_MP          = 6;   // load only SndFile + MPG123

  Samplerate_root    = 0;

type

  TUOSThread = class(TThread)
  private

  protected
    procedure Execute; override;
  public
   constructor Create(CreateSuspended: boolean);

  end;


type
   TLoadResult = record
    PAloadERROR          : shortint;
    SFloadERROR          : shortint;
    MPloadERROR          : shortint;
    PAinitError          : integer;
    MPinitError          : integer;
   end;



type
    TStreaminfo= record
    streamname        : string;
    Stream               : PPaStream;
    thread               : TUOSThread;
    StreamisOpen         : boolean ;
    DEVICE               : integer ;
    LATENCY              : integer ;
    OutputParameters     : PaStreamParameters;
    handle            : pointer;
    SFopenError       : shortint;
    MPopenError       : shortint;
    SFoutbuf          : array [0..2047]  of byte  ;
    MPoutbuf          : array [0..2047]  of byte  ;
    {$IFDEF Win32}   //// Only Windows 32 bits
    BufFrames         : cardinal;
    OutFrames         : cardinal;
     {$else}
    BufFrames       : Tsf_count_t;
    OutFrames       : Tsf_count_t;

     {$endif}
    Filename          : string;
    Status            : shortint;  //// stop = 0, play = 1, pause = 2
    channels          : integer;
    format            : integer;
    frames            : integer;
    samplerateroot    : integer;
    samplerate        : integer;
    sections          : integer;
    seekable          : integer;
    encoding          : integer;
    title             : string;
    copyright         : string;
    software          : string;
    artist            : string;
    comment           : string;
    date              : string;
    tag               : array[0..2] of Char;   (**< Always the string "TAG", the classic intro. *)
    album             : string;  (**< Album string. *)
    genre             : byte;    (**< Genre index. *)

     end;


  var
   UOSLoadFlag         : shortint ;
   UOSLoadResult       : TLoadResult;
   UOSDefOut           : PaDeviceIndex;
   UOSDEVinfo          : PPaDeviceInfo;
   UOSAPIinfo          : PPaHostApiInfo;
   UOSSTREAM            : array   of  Tstreaminfo;
   UOSSTREAMNUM       : integer;
procedure UOS_Load(PA_FileName,SF_FileName,MP_FileName : AnsiString ; flag : shortint );  /////////// dynamic load libraries

procedure UOS_UnLoad() ;

procedure UOS_Init()  ; ////// init libraries

procedure UOS_CreateStream(Soundfile:ansistring;UOS_STREAMNAME:string; SAMPLERATE:integer ; DEVICE:integer ; CHANNELS :integer; LATENCY:integer; SAMPLEFORMAT : string) ;
       ////////////// at Samplerate ( -1 is samplerate of Soundfile) ,
       /////////////   with device ( -1 is default device )
       //////////////// with number of channels (-1 = channels of soundfile, 2 = stereo, -)
        /////////////   at latency  ( -1 is latency suggested ) )
        ///////////// with sampleformat : int8 or int16 or int24 or int32 or float32
        //////////// example : UOS_CreateStream('/home/user/test.mp3','testStream',-1,-1,-1,-1,'int16');

procedure UOS_Play(UOS_STREAMNAME:string) ;   ////// or resume if song was paused

procedure UOS_Stop(UOS_STREAMNAME:string) ;

procedure UOS_Pause(UOS_STREAMNAME:string) ;

//procedure UOS_Position() ;                  //   to do ....


implementation

procedure UOS_Stop(UOS_STREAMNAME:string) ;
var
 x : integer ;
begin
 x := 0 ;
   while (x < ( Length(UOSSTREAM)) )  do begin
 if (UOSSTREAM[x].streamname =  UOS_STREAMNAME)    then
  begin
   UOSSTREAM[x].status := 0 ;
  exit;
  end;
   x := x + 1   ;
  end;

end;

procedure UOS_Pause(UOS_STREAMNAME:string) ;
var
 x : integer ;
begin
 x := 0 ;
   while (x < ( Length(UOSSTREAM)) )  do begin
 if (UOSSTREAM[x].streamname =  UOS_STREAMNAME)    then
  begin
    UOSSTREAM[x].Status := 2 ;
  exit;
  end;
   x := x + 1   ;
  end;

end;



procedure UOS_CreateStream(Soundfile:ansistring;UOS_STREAMNAME:string; SAMPLERATE:integer ; DEVICE:integer ; CHANNELS :integer; LATENCY:integer; SAMPLEFORMAT : string) ;   /// sampleformat : int8 or int16 or int24 or int32 or float32
var
 x, x2, err : integer ;
  sfInfo      : TSF_INFO;
begin
    if not fileexists(Soundfile) then  MessageDlg (Soundfile + ' do not exists...', mtWarning,[mbYes],0)  else
  begin

 x2 := 0 ;
err := -1 ;
   while (x2 < ( Length(UOSSTREAM)) ) and (err <> 1) do begin
     application.ProcessMessages;

 if  UOSSTREAM[x2].streamname =  UOS_STREAMNAME   then
  begin


   if  UOSSTREAM[x2].StreamisOpen = true then
    begin
    UOSSTREAM[x2].status := 0 ;
    application.ProcessMessages;
    sleep(150) ; /////// < buffers need time to release (on some systems) !!!!
     application.ProcessMessages;
    end;

  err := 1  ;
  x := x2;
  end;
   x2 := x2 + 1
  end;

   x2 := 0 ;

 if err = -1 then
  while ( x2 < Length(UOSSTREAM)) and (err <> 2) do begin

 if  (UOSSTREAM[x2].streamname = '')  then
 begin
 UOSSTREAM[x2].streamname:= UOS_STREAMNAME  ;
  UOSSTREAM[x2].status := 0 ;
   UOSSTREAM[x2].StreamisOpen := false ;
 x := x2 ;
  err := 2 ;
  end;
 x2 := x2+1 ;
end;

 if err = -1 then

 begin
 SetLength(UOSSTREAM,  Length(UOSSTREAM) + 1)  ;
 UOSSTREAM[Length(UOSSTREAM)-1].streamname:= UOS_STREAMNAME  ;
  err := 0 ;
 x :=  Length(UOSSTREAM)-1 ;
  UOSSTREAM[x].StreamisOpen := false ;
   UOSSTREAM[x].status := 0 ;
end;


 if err <> -1 then begin
   if  UOSSTREAM[x].StreamisOpen = false then begin

     if device = -1 then
    UOSSTREAM[x].OutputParameters.Device := UOSDefOut else
     UOSSTREAM[x].OutputParameters.Device :=  DEVICE;


if SAMPLEFORMAT = 'int8' then

 UOSSTREAM[x].OutputParameters.SampleFormat :=  paint8 else
 if SAMPLEFORMAT = 'int16' then

 UOSSTREAM[x].OutputParameters.SampleFormat :=  paint16 else
 if SAMPLEFORMAT = 'int32' then

 UOSSTREAM[x].OutputParameters.SampleFormat :=  paint32 else
 if SAMPLEFORMAT = 'float32' then

 UOSSTREAM[x].OutputParameters.SampleFormat :=  pafloat32 else
  UOSSTREAM[x].OutputParameters.SampleFormat :=  paint16  ;


     if LATENCY = -1 then
    UOSSTREAM[x].OutputParameters.SuggestedLatency :=
      (Pa_GetDeviceInfo(  UOSSTREAM[x].OutputParameters.device)^.defaultHighOutputLatency) * 1
      else UOSSTREAM[x].OutputParameters.SuggestedLatency := Latency;


     UOSSTREAM[x].OutputParameters.HostApiSpecificStreamInfo := nil;

     UOSSTREAM[x].StreamisOpen := false ;

     end;
 end;

 ////////////////////////////

         err := -1;

  UOSSTREAM[x].MPopenError := - 1;
  UOSSTREAM[x].SFOpenError := - 1;
    if (UOSloadresult.SFloadERROR = 0) and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadSF)  or (UOSloadflag = LoadPA_SF) or
    (UOSloadflag = LoadSF_MP)) then begin

   UOSSTREAM[x].handle := sf_open(pchar(Soundfile),SFM_READ,sfInfo) ; (* try to open the file *)

   If UOSSTREAM[x].handle  = NIL then
       begin
       UOSSTREAM[x].SFOpenError := 1 ;
       end
       else
        begin
            UOSSTREAM[x].SFOpenError := 0;
            UOSSTREAM[x].filename := Soundfile ;
            UOSSTREAM[x].channels := SFinfo.channels;
            UOSSTREAM[x].format := SFinfo.format;
            UOSSTREAM[x].frames := SFinfo.frames;
            UOSSTREAM[x].samplerate := SFinfo.samplerate;
            UOSSTREAM[x].samplerateroot := SFinfo.samplerate;
            UOSSTREAM[x].sections := SFinfo.sections;
            UOSSTREAM[x].seekable := SFinfo.seekable;
            UOSSTREAM[x].copyright:= sf_get_string(UOSSTREAM[x].handle,SF_STR_COPYRIGHT);
            UOSSTREAM[x].software:= sf_get_string(UOSSTREAM[x].handle,SF_STR_SOFTWARE);
            UOSSTREAM[x].comment:= sf_get_string(UOSSTREAM[x].handle,SF_STR_COMMENT);
            UOSSTREAM[x].date   := sf_get_string(UOSSTREAM[x].handle,SF_STR_DATE);
            UOSSTREAM[x].BufFrames:= length(UOSSTREAM[x].SFoutbuf)   ;
            err := 0;
       end;

    end;


 if ((UOSSTREAM[x].SFOpenError  = 1) or (UOSSTREAM[x].SFOpenError  = -1)) and (UOSLoadresult.MPloadERROR = 0)
 and  ((UOSloadflag = LoadAll) or (UOSloadflag = LoadMP)  or (UOSloadflag = LoadPA_MP) or
    (UOSloadflag = LoadSF_MP)) then begin

       Err := -1;
 UOSSTREAM[x].handle := mpg123_new( NIL, Err);

  if Err = 0 then mpg123_open(UOSSTREAM[x].handle,pchar(Soundfile))

  else UOSSTREAM[x].MPOpenError := 1 ;
  if Err = 0 then Err := mpg123_getformat( UOSSTREAM[x].handle, UOSSTREAM[x].samplerate , UOSSTREAM[x].channels, UOSSTREAM[x].encoding) ;
  if Err = 0 then  begin

    UOSSTREAM[x].MPOpenError := 0;
    UOSSTREAM[x].filename := Soundfile ;
    UOSSTREAM[x].samplerateroot := UOSSTREAM[x].samplerate;
    UOSSTREAM[x].BufFrames:= length(UOSSTREAM[x].MPoutbuf)   ;

  end else UOSSTREAM[x].MPOpenError := 2 ;

    end;
   if err <> 0 then begin

   MessageDlg ('Cannot Open ' + Soundfile + '...', mtWarning,[mbYes],0)  ;
   exit;
   end
   else  begin

    UOSSTREAM[x].streamname   := UOS_STREAMNAME ;
    UOSSTREAM[x].status := 0;
    UOSSTREAM[x].StreamisOpen := false;

    UOSSTREAM[x].OutFrames := 0;
      if CHANNELS = -1 then UOSSTREAM[x].OutputParameters.channelCount:= UOSSTREAM[x].channels
  else  UOSSTREAM[x].OutputParameters.channelCount:= CHANNELS;

    if SAMPLERATE = -1 then
    Pa_OpenStream(@UOSSTREAM[x].Stream, nil, @UOSSTREAM[x].OutputParameters, UOSSTREAM[x].samplerate ,
      64, paClipOff, nil,nil)
      else  Pa_OpenStream(@UOSSTREAM[x].Stream, nil, @UOSSTREAM[x].OutputParameters,SAMPLERATE ,
      64, paClipOff, nil,nil)  ;

    ////////////////
     application.ProcessMessages;
       UOSSTREAM[x].Thread := TUOSThread.Create(True); // With the True parameter it doesn't start automatically
       UOSSTREAM[x].thread.FreeOnTerminate:=true;

        if Assigned(UOSSTREAM[x].Thread.FatalException) then
  raise UOSSTREAM[x].Thread.FatalException;
    application.ProcessMessages
  end;

   end;

 end;



/////////////////////


 procedure TUOSThread.Execute;

  VAR
  x ,   err  : integer  ;

  begin
    x := UOSSTREAMNUM ;

 if  (UOSSTREAM[x].status = 1) and (UOSSTREAM[x].StreamisOpen = false) then
 begin
  UOSSTREAM[x].StreamisOpen := true;
 Pa_StartStream(UOSSTREAM[X].stream) ;
   application.ProcessMessages;
 ////////////////////////////////////////////////////
  repeat
         application.ProcessMessages;
  if (UOSSTREAM[x].Status = 1) and (UOSSTREAM[x].handle <> nil)  then
 begin

   if UOSSTREAM[x].SFOpenError = 0 then
   begin
 UOSSTREAM[x].OutFrames:= sf_read_short(UOSSTREAM[x].handle, @UOSSTREAM[x].SFoutbuf[0], UOSSTREAM[x].BufFrames  ) ;
   if  (UOSSTREAM[x].OutFrames < UOSSTREAM[x].BufFrames) then UOSSTREAM[x].status := 0;
    end
   else if UOSSTREAM[x].MPOpenError = 0 then
   begin
  mpg123_read( UOSSTREAM[x].handle, @UOSSTREAM[x].MPoutbuf[0], UOSSTREAM[x].BufFrames, UOSSTREAM[x].OutFrames ) ;
   if  (UOSSTREAM[x].OutFrames < UOSSTREAM[x].BufFrames) then UOSSTREAM[x].status := 0;
     end;

   application.ProcessMessages;

    if (UOSSTREAM[x].Status = 1) and (UOSSTREAM[x].handle <> nil)  then
 begin
    if UOSSTREAM[x].SFOpenError = 0 then
   begin
   Pa_WriteStream( UOSSTREAM[x].Stream,@UOSSTREAM[x].SFoutbuf[0],Length(UOSstream[x].SFoutbuf) div 2) ;
   end
     else if UOSSTREAM[x].MPOpenError = 0 then
   begin
   Pa_WriteStream( UOSSTREAM[x].Stream,@UOSSTREAM[x].MPoutbuf[0],Length(UOSstream[x].MPoutbuf) div 4) ;
   end;

   end ;
   end;


   if UOSSTREAM[x].Status = 2 then
   begin
   sleep(100);
   end;

    err := 0;

application.ProcessMessages;     //////////// important if we want to do something else in the program !
   if UOSSTREAM[x].Status = 0 then err := 1   ;
 until  (err = 1);

     end;

if(err = 1) then

 begin

   Pa_StopStream(UOSSTREAM[x].Stream);
    Pa_CloseStream(UOSSTREAM[x].Stream);
    UOSSTREAM[x].StreamisOpen := false  ;
     if UOSSTREAM[x].SFOpenError = 0 then sf_close(UOSSTREAM[x].handle);
   if UOSSTREAM[x].MPOpenError = 0 then mpg123_close(UOSSTREAM[x].handle);
   UOSSTREAM[x].thread.Terminate;
 application.ProcessMessages;

  end;

  end;


 ////////////////////////////////////////////////////////////////////////////////////



procedure UOS_Play(UOS_STREAMNAME:string) ;
var
 x : integer ;

begin
 x := 0 ;
    application.ProcessMessages;

   while (x < ( Length(UOSSTREAM)) )  do begin


 if(UOSSTREAM[x].streamname =  UOS_STREAMNAME)    then
  begin

   UOSSTREAM[x].Status := 1 ;
   UOSSTREAMNUM := x ;
   application.ProcessMessages;
  UOSSTREAM[x].Thread.Start;  //////// < here line 473 : Working with Linux and OSX, not Windows.
    exit ;
  end;
   x := x + 1   ;
  end;

end;

////////////////////////////////////////////////////////////////////
procedure UOS_Unload() ;

 begin

  Sf_Unload();
  Mp_Unload();
  Pa_Unload();

 end;
///////////////////////////////////////////////////////////////////////////////
 procedure UOS_Init() ;

 begin

    if (UOSLoadResult.MPloadERROR = 0) and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadMP)  or (UOSloadflag = LoadPA_MP) or
    (UOSloadflag = LoadSF_MP)) then if mpg123_init()=MPG123_OK  then  UOSLoadResult.MPinitError := 0 else UOSLoadResult.MPinitError := 1;


  IF (UOSLoadResult.PAloadERROR = 0) and ((UOSloadflag = LoadAll) or (UOSloadflag = LoadPA) or
  (UOSloadflag = LoadPA_SF) or (UOSloadflag = LoadPA_MP)) Then begin
    UOSLoadResult.PAinitError := Pa_Initialize();

      if UOSLoadResult.PAinitError = 0 then begin
    UOSDefOut := Pa_GetDefaultOutputDevice();
    UOSDEVinfo:= Pa_GetDeviceInfo(UOSDefOut);
    UOSAPIinfo:= Pa_GetHostApiInfo(UOSDEVinfo^.hostApi);
     end;

  end;

   end;

procedure UOS_Load( PA_FileName,SF_FileName,MP_FileName : AnsiString ; flag : shortint ) ;

begin

 UOSloadflag := flag ;

   case flag of

    LoadAll : begin

   if not fileexists(PA_FileName) then UOSLoadResult.PAloadERROR:= 1   else
     if  Pa_Load (PA_FileName) then UOSLoadResult.PAloadERROR:= 0 else UOSLoadResult.PAloadERROR:= 2 ;

  if not fileexists(SF_FileName) then UOSLoadResult.SFloadERROR:= 1 else
    if  Sf_Load (SF_FileName)  then UOSLoadResult.SFloadERROR:= 0 else UOSLoadResult.SFloadERROR:= 2 ;

   if not fileexists(MP_FileName) then UOSLoadResult.MPloadERROR := 1 else
    if  mp_Load (Mp_FileName)  then UOSLoadResult.MPloadERROR := 0 else UOSLoadResult.MPloadERROR := 2 ;

    end;

     LoadPA : begin

    if not fileexists(PA_FileName) then  UOSLoadResult.PAloadERROR:= 1   else
     if  Pa_Load (PA_FileName) then  UOSLoadResult.PAloadERROR:= 0  else UOSLoadResult.PAloadERROR:= 2 ;

    end;

    LoadSF : begin

  if not fileexists(SF_FileName) then UOSLoadResult.SFloadERROR:= 1 else
  if  Sf_Load (SF_FileName)  then UOSLoadResult.SFloadERROR:= 0 else UOSLoadResult.SFloadERROR:= 2 ;

    end;

     LoadMP : begin

    if not fileexists(MP_FileName) then UOSLoadResult.MPloadERROR := 1 else
    if  mp_Load (Mp_FileName)  then UOSLoadResult.MPloadERROR := 0 else UOSLoadResult.MPloadERROR := 2 ;

    end;

   LoadPA_SF : begin

    if not fileexists(PA_FileName) then  UOSLoadResult.PAloadERROR:= 1   else
     if  Pa_Load (PA_FileName) then  UOSLoadResult.PAloadERROR:= 0  else UOSLoadResult.PAloadERROR:= 2 ;

  if not fileexists(SF_FileName) then UOSLoadResult.SFloadERROR:= 1 else
    if  Sf_Load (SF_FileName)  then UOSLoadResult.SFloadERROR:= 0 else UOSLoadResult.SFloadERROR:= 2 ;

     end;

   LoadPA_MP : begin
     if not fileexists(MP_FileName) then UOSLoadResult.MPloadERROR := 1 else
    if  MP_Load (Mp_FileName)  then UOSLoadResult.MPloadERROR := 0 else UOSLoadResult.MPloadERROR := 2 ;


    if not fileexists(PA_FileName) then  UOSLoadResult.PAloadERROR:= 1   else
     if  Pa_Load (PA_FileName) then  UOSLoadResult.PAloadERROR:= 0  else UOSLoadResult.PAloadERROR:= 2 ;


    end;

    LoadSF_MP : begin

   if not fileexists(SF_FileName) then UOSLoadResult.SFloadERROR:= 1 else
    if  SF_Load (SF_FileName)  then UOSLoadResult.SFloadERROR:= 0 else UOSLoadResult.SFloadERROR:= 2 ;

   if not fileexists(MP_FileName) then UOSLoadResult.MPloadERROR := 1 else
    if  mp_Load (Mp_FileName)  then UOSLoadResult.MPloadERROR := 0 else UOSLoadResult.MPloadERROR := 2 ;

    end;
    end;
    end;

  constructor TUOSThread.Create(CreateSuspended: boolean);
begin
  FreeOnTerminate := True;
  inherited Create(CreateSuspended);
end;

 initialization

  SetLength(UOSSTREAM, 1) ;
 UOSLoadResult.PAloadERROR := -1 ;
 UOSLoadResult.SFloadERROR := -1 ;
 UOSLoadResult.MPloadERROR := -1 ;
 UOSLoadResult.PAinitError := -1 ;
 UOSLoadResult.MPinitError := -1 ;

end.


« Last Edit: November 14, 2012, 06:31:03 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3785
    • StrumPract is the musicians best friend
Re: Thread.Start problem with Windows.
« Reply #1 on: November 14, 2012, 01:02:34 pm »
Hello.

Here the isolated code of problem (see earlier post for full code).
( Or here full code with lpi and libraries : https://sites.google.com/site/fiensprototyping/U_OS_Test.tar.gz )

Code: [Select]

/////// here code of variable and class
type

  TUOSThread = class(TThread)
  private

  protected
 
    procedure Execute; override;
  public
 constructor Create(CreateSuspended: boolean);

  end;   

type
    TStreaminfo= record     
      thread    : TUOSThread;
       end;   

var
     UOSSTREAM            : array   of  Tstreaminfo;       
           
//////// here code of creation of thread

     UOSSTREAM[x].Thread := TUOSThread.Create(True); // With the True parameter it doesn't start automatically
          if Assigned(UOSSTREAM[x].Thread.FatalException) then
  raise UOSSTREAM[x].Thread.FatalException;

////// here code to do it start

  UOSSTREAM[x].Thread.Start; //< not working with Windows, see earlier post   

/// here code before initialization

 constructor TUOSThread.Create(CreateSuspended: boolean);
begin
  FreeOnTerminate := True;
  inherited Create(CreateSuspended);
end; 
   


Many thanks for help.
« Last Edit: November 14, 2012, 01:11:51 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

proxy3d

  • Jr. Member
  • **
  • Posts: 76
Re: Thread.Start problem with Windows.
« Reply #2 on: November 14, 2012, 01:33:12 pm »
Thread.Resume works in WIndows. Thread.Start to replace Thread.Resume.
Or use IFDEF code for Windows and Linux. In Delphi 2010 is solved using IFDEF. In Delphi 2010 not Thread.Resume.

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Thread.Start problem with Windows.
« Reply #3 on: November 14, 2012, 02:07:38 pm »
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Thread.Start problem with Windows.
« Reply #4 on: November 14, 2012, 02:22:26 pm »
Thread.Start, works as expected for me in Windows.
eg.

Code: [Select]
program Project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes,
  { you can add units after this }
  sysutils
  ;

type

  { TTestThread }

  TTestThread = class(TThread)
    procedure Execute; override;
  end;

{ TTestThread }

procedure TTestThread.Execute;
begin
  writeln('Thread Start');
  Sleep(1000);
  writeln('Thread Stop');
end;

procedure Test;
var
  t:TTestThread;
begin
  t := TTestThread.create(true);
  t.FreeOnTerminate:=true;
  t.Start;
  writeln('Thread started');
  readln;
end;


begin
  Test;
end.

Fred vS

  • Hero Member
  • *****
  • Posts: 3785
    • StrumPract is the musicians best friend
Re: Thread.Start problem with Windows.
« Reply #5 on: November 14, 2012, 03:17:05 pm »
@ KpjComp and Blaazen.
 
Have you try the complete project ?
https://sites.google.com/site/fiensprototyping/U_OS_Test.tar.gz )
All the libraries and sound examples are included. Only have to load the lpi.


With Linux or OSX, if i click on [Play all together] it works.

On my Windows 7 system 32 bits it does not work. (i do not have the 64 bits compiled audio libraries to test, but audio 32 bits are working, im sure).

Many thanks for respond.


I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Thread.Start problem with Windows.
« Reply #6 on: November 14, 2012, 04:05:11 pm »
Well I'm not getting any sound from my machine just clicking the "Play the file" let alone the "Play All Together"..

A few pointers on your code though!!.
Your mixing LCL and Threads, and your not meant to do that.

eg. In your threads you have things like->
Code: [Select]
application.ProcessMessages

That's a big no no..


edit: Taking out all the Application.ProcessMessage out of your Execute method, it now works..
« Last Edit: November 14, 2012, 04:12:27 pm by KpjComp »

Fred vS

  • Hero Member
  • *****
  • Posts: 3785
    • StrumPract is the musicians best friend
Re: Thread.Start problem with Windows.
« Reply #7 on: November 14, 2012, 05:54:20 pm »
@ KpjComp :
Quote
A few pointers on your code though!!.
: it is just what i prefer... :-[

Your are totally right about my too much "application.processmessage" (i use it for debug and forget to release it).
By the way, i still let one inside the loop, is it to much to acces lcl ?

Sadly, it does not solve the problem with Windows (with Linux it is working like charm, i have try with 36 tracks, perfect, on a little Acer One  :'( ) ).

I have try to use the libraries without using threads in Windows and it works perfectly.  :-X

So the fault must be in my code about the threads but debugger dont help me and usually everything works easy with Windows and with hard work on Linux.
Here, for me it is the opposite... :'(

« Last Edit: November 14, 2012, 06:01:02 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Thread.Start problem with Windows.
« Reply #8 on: November 14, 2012, 06:08:34 pm »
Are you sure you got rid of ALL Application.ProcessMessages, I believe there is 3 of them in the Execute.

Also if there is an error inside a Thread, you have no means of knowing.  I would suggest adding some sort of logging to your thread.

Fred vS

  • Hero Member
  • *****
  • Posts: 3785
    • StrumPract is the musicians best friend
Re: Thread.Start problem with Windows.
« Reply #9 on: November 14, 2012, 06:14:08 pm »
Quote
edit: Taking out all the Application.ProcessMessage out of your Execute method, it now works..

Ooops do not see that. Gonna quick reboot into Windows and try without the only one Application.ProcessMessage .

Before to go, if you are still there, how do you access LCL inside the loop if you do not use Application.ProcessMessage ?
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Thread.Start problem with Windows.
« Reply #10 on: November 14, 2012, 06:18:09 pm »
Well Application.ProcessMessage doesn't make sense inside a thread.

Application.ProcessMessage is just used to let the main thread process it's message que, while the main thread is blocking.  If your using Threads, the main thread won't be blocked anyway.

edit: And if you really do need to access LCL, the TThread.Synchronize.  But saying this, if your making a Sound library there should be no need for you to access anything GUI based.
« Last Edit: November 14, 2012, 06:20:04 pm by KpjComp »

Fred vS

  • Hero Member
  • *****
  • Posts: 3785
    • StrumPract is the musicians best friend
Re: Thread.Start problem with Windows.
« Reply #11 on: November 14, 2012, 06:30:16 pm »
@ KpjComp you are my Hero.  :P
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018