Einzelnen Beitrag anzeigen

Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#1

frage zu threads und timer

  Alt 9. Dez 2013, 01:11
hi

ich arbeite mal wieder an meinen Bass(.dll) komponenten, die komponenten sind mittlerweile so kompliziert geworden
dass es immer schwieriger wird die zu managen! zum beispiel die Sound-Recorder komponente, die hat vier haupt threads(feeder)
und wenn einer der threads zu schnell oder zu langsam ist bricht das ganze zusammen.

und hier komme ich auch gleich zu meiner frage. was ist die eleganteste lösung um threads oder das innenleben perfect zu takten?

zur zeit benutze ich zwei verschieden methoden Sleep(x) und TSimpleEvent. vielleicht hat einer von euch noch einen dritten vorschlag
für den unteren code, das timing muss 100% präzise sein damit der buffer nicht lehr läuft.


Delphi-Quellcode:
procedure TBassRecorder.RecThreadWorkerCallback(Thread: TMultiThreadThread;
 Parameters : TObject; var Data, Results : TObject);
var
  FBuff : array [0..50000] of Byte;
  FData : DWORD;
  WorkMessage: TWorkMessage;
  WorkResult: TWorkResult;
begin
  WorkMessage := TWorkMessage.Create;
  WorkMessage.ID := TWork(Data).ID;
  WorkMessage.Text := 'Starting';
  WorkMessage.Status:= thStarting;
  Thread.SendMessage(WorkMessage, nil);

 repeat
   Sleep(TWork(Data).TimeToWait); //TimeToWait = 1
  if not ThreadPause[THREAD_REC] then
   begin
     FData:= BASS_ChannelGetData(Channel[CHANN_REC_MIXER], @FBuff, SizeOf(FBuff));
    if FData = DW_ERROR then
     begin
      Break;
      // Error
     end;
   end;
 until
  Thread.Terminated or (Channel[CHANN_REC_MIXER] = 0);


 if Thread.Terminated then
  begin
   WorkMessage := TWorkMessage.Create;
   WorkMessage.ID := TWork(Data).ID;
   WorkMessage.Text := 'Terminated';
   WorkMessage.Status:= thTerminated;
   Thread.SendMessage(WorkMessage, nil);
  end;

  WorkResult := TWorkResult.Create;
  WorkResult.ID := TWork(Data).ID;
  WorkResult.Text := 'Finished'; //finished successfuly.
  WorkResult.Status:= thFinished;
  Results := WorkResult;
end;


Delphi-Quellcode:
procedure TBassRecorder.VasThreadWorkerCallback(Thread: TMultiThreadThread; Parameters: TObject; var Data, Results: TObject);
var
  Time : QWORD;
  Level : DWORD;
  Active : Boolean;
  Timer: TWaitResult;

  WorkMessage : TWorkMessage;
  WorkResult : TWorkResult;
begin
  WorkMessage := TWorkMessage.Create;
  WorkMessage.ID := TWork(Data).ID;
  WorkMessage.Text := 'Starting';
  WorkMessage.Status:= thStarting;
  Thread.SendMessage(WorkMessage, nil);

 repeat
  if not ThreadPause[THREAD_VAS] then
   begin

     Level:= BASS_Mixer_ChannelGetLevel(Channel[CHANN_VIS_SPLIT]);
     Active:= (LOWORD(Level) >= FVAS_Threshold) or
              (HIWORD(Level) >= FVAS_Threshold);

    (* sound is coming through *)
    if Active then
     begin

      (* continue recording when the sound starts up again. *)
       ...
      (* start a new recording ehen the sound starts up again. *)
       ...
     end;
                                  

     Timer:= TWork(Data).TimeEvent.WaitFor(TWork(Data).TimeToWait); // 1000 = 1 Sec.
    if Timer = wrTimeout then
     begin
      (* sound is not coming through *)
      if not Active then
       begin

        (* Pause Recording after X Sec. of silence *)
         ...

        (* Pause Recording after X Sec. of silence *)
         ...

        (* Stop Recording after X Sec. of silence *)
         ...

       end;
     end;

   end;
 until
  (FVAS_ForceStop) or
  (Timer <> wrTimeout) or
  (Thread.Terminated) or
  (Application.Terminated);

 if Thread.Terminated then
  begin
   WorkMessage := TWorkMessage.Create;
   WorkMessage.ID := TWork(Data).ID;
   WorkMessage.Text := 'Terminated';
   WorkMessage.Status:= thTerminated;
   if Assigned(TWork(Data).TimeEvent) then
    TWork(Data).TimeEvent.SetEvent;
   Thread.SendMessage(WorkMessage, nil);
  end;

  WorkResult := TWorkResult.Create;
  WorkResult.ID := TWork(Data).ID;
  WorkResult.Text := 'Finished'; //finished successfuly.
  WorkResult.Status:= thFinished;
  if Assigned(TWork(Data).TimeEvent) then
   TWork(Data).TimeEvent.SetEvent;
  Results := WorkResult;
end;
  Mit Zitat antworten Zitat