AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Eventrecorder
Thema durchsuchen
Ansicht
Themen-Optionen

Eventrecorder

Ein Thema von hadschi92 · begonnen am 8. Apr 2013 · letzter Beitrag vom 8. Apr 2013
Antwort Antwort
hadschi92
Registriert seit: 25. Okt 2006
Eventrecorder ist ein Programm um die Aufzeichnung von Veranstaltungen möglichst benutzerfreundlich zu gestalten. Das besondere an Eventrecorder ist, dass während der Aufnahme Tracks angelegt und trackspezifische Informationen gleich beigefügt werden können. Die Aufnahme wird anschließend nach vorgegebenen Kriterien und den trackspezifischen Informationen benannt und kann so geordnet abgespeichert werden.

Eine alte Version des Programmes ist bereits vorhanden, jedoch ist diese Version nicht objektorientiert geschrieben und der Quellcode ist auch sehr undurchdacht und unstrukturiert. Um dies zu ändern bin ich dabei das Programm neu zu schreiben und würde mich über eure Mithilfe freuen.

Die alte Version 0.9.6 ist im Anhang vorhanden
Miniaturansicht angehängter Grafiken
screenshot-eventrecorder-0.9.6.jpg  
Angehängte Dateien
Dateityp: zip Eventrecorder v.0.9.6.zip (1,59 MB, 22x aufgerufen)

Geändert von hadschi92 ( 8. Apr 2013 um 16:08 Uhr)
 
hadschi92

 
Delphi XE3 Professional
 
#2
  Alt 8. Apr 2013, 15:37
Mein Stand der Neuprogrammierung ist folgender:
In der Unit AudioControl sollen alle Aufnahmefunktionen gesammelt werden.
Die Aufnahme wird mit den New Audio Components realisiert.
Delphi-Quellcode:
unit AudioControl;

interface

uses
  ACS_Streams, ACS_DXAudio, ACS_LAME, ACS_Wave, NewACIndicators,
  SysUtils, Windows, Classes, Contnrs;

type
  TAudioControlState = (Initialised, Recording, Paused, Stopped);

  TAudioSaveFormat = class
  private
    FFormat: String;
    FBitrate: Integer;
  public
     procedure SetToMP3(Bitrate: Integer);
     procedure SetToWave;
     function GetFormat: String;
     function GetBitrate: Integer;
  end;

  TTrack = class
  strict private
    FAlbum: String;
    FTitle: String;
    FInterpret: String;
    FComposer: String;
    FGenre: String;
    FCategory: String;
    FDescription: String;
    FStartTime: Cardinal;
    FLengthInMilliseconds: Cardinal;
    FStreamPath: String;
    FStream: TFileStream;
    class var FNumberOfRecordedStreams: Integer;
  private
    class property NumberOfRecordedStreams: Integer read FNumberOfRecordedStreams write FNumberOfRecordedStreams;
  public
    constructor Create(Directory: String);
    destructor Destroy; override;
    property Album: String read FAlbum write FAlbum;
    property Title: String read FTitle write FTitle;
    property Interpret: String read FInterpret write FInterpret;
    property Composer: String read FComposer write FComposer;
    property Genre: String read FGenre write FGenre;
    property Category: String read FCategory write FCategory;
    property Description: String read FDescription write FDescription;
    property StartTime: Cardinal read FStartTime write FStartTime;
    property LengthInMilliseconds: Cardinal read FLengthInMilliseconds write FLengthInMilliseconds;
    function GetLengthAsString: String;
    property Stream: TFileStream read FStream write FStream;
    property StreamPath: String read FStreamPath write FStreamPath;
  end;

  TTrackList = class
  private
    FTrackList: TObjectList;
    FTemporaryDirectory: String;
    FNumberOfChannels: Cardinal;
    FBitsPerSample: Cardinal;
    FSampleRate: Cardinal;
    function GetTrack(TrackNumber: Integer): TTrack;
  public
    constructor Create(TemporaryDirectory: String);
    destructor Destroy; override;
    procedure AddTrack;
    procedure MoveTrack(StartTrackNumber, EndTrackNumber: Integer);
    procedure DeleteTrack(TrackNumber: Integer);
    procedure DeleteAllTracks;
    property NumberOfChannels: Cardinal read FNumberOfChannels;
    property BitsPerSample: Cardinal read FBitsPerSample;
    property SampleRate: Cardinal read FSampleRate;
    property Track[TrackNumber: Integer]: TTrack read GetTrack; default;
    function Count: Integer;
    function High: Integer;
    function GetLengthOfAllTracksInMilliseconds: Cardinal;
  end;

  TAudioControl = class(TComponent)
  private
    FAudioSource: TDXAudioIn;
    FAudioGain: TGainIndicator;
    FAudioStream: TStreamOut;
    FTrackList: TTrackList;
    FWaveOut: TWaveOut;
    FMP3Out: TMP3Out;
    FState: TAudioControlState;
    procedure ProcessSavingThreadAsWave(AOwner: TComponent; SaveDirectory: String; TrackNumber: Integer);
    procedure RunStream;
    procedure PauseStream;
    procedure ResumeStream;
    procedure StopStream;
  public
    constructor Create(AOwner: TComponent;
      DeviceNumber, Channels, BitsPerSample, SampleRate: Integer; Directory: String);
    destructor Destroy; override;
    procedure CreateTrackList(Directory: String);
    procedure StartRecording;
    procedure StartRecordingWithNewTrack;
    procedure PauseRecording;
    procedure StopRecording;
    property TrackList: TTrackList read FTrackList;
    property AudioGain: TGainIndicator read FAudioGain;
    property State: TAudioControlState read FState;
    procedure StartSavingThreadAsWave(AOwner: TComponent; SaveDirectory: String);
  end;

implementation

//------------------------------ TAudioControl -------------------------------//

constructor TAudioControl.Create(AOwner: TComponent;
  DeviceNumber, Channels, BitsPerSample, SampleRate: Integer; Directory: String);
begin
  Inherited Create(AOwner);
  FAudioSource := TDXAudioIn.Create(AOwner);
  FAudioSource.DeviceNumber := DeviceNumber;
  FAudioSource.InChannels := Channels;
  FAudioSource.InBitsPerSample := BitsPerSample;
  FAudioSource.InSampleRate := SampleRate;
  FAudioGain := TGainIndicator.Create(AOwner);
  FAudioGain.Input := FAudioSource;
  FAudioStream := TStreamOut.Create(AOwner);
  FAudioStream.Input := FAudioGain;
  FTrackList := TTrackList.Create(Directory);
  FState := Initialised;
end;

destructor TAudioControl.Destroy;
begin
  StopRecording;
  FTrackList.Free;
  FTrackList := nil;
  FAudioSource.Free;
  FAudioSource := nil;
  FAudioGain.Free;
  FAudioGain := nil;
  FAudioStream.Free;
  FAudioStream := nil;
  Inherited Destroy;
end;

procedure TAudioControl.CreateTrackList(Directory: String);
begin
  FTrackList := TTrackList.Create(Directory);
  FState := Initialised;
end;

procedure TAudioControl.StartRecording;
begin
  if FState = Initialised then begin
    RunStream;
  end else if FState = Recording then begin
    //
  end else if FState = Paused then begin
    ResumeStream;
  end else if FState = Stopped then begin
    RunStream;
  end else begin
    // Fehlerrückgabe
  end;
end;

procedure TAudioControl.StartRecordingWithNewTrack;
begin
  if FState = Initialised then begin
    RunStream;
  end else if FState = Recording then begin
    StopStream;
    RunStream;
  end else if FState = Paused then begin
    StopStream;
    RunStream;
  end else if FState = Stopped then begin
    RunStream;
  end else begin
    // Fehlerrückgabe
  end;
end;

procedure TAudioControl.PauseRecording;
begin
  if FState = Initialised then begin
    //
  end else if FState = Recording then begin
    PauseStream;
  end else if FState = Paused then begin
    //
  end else if FState = Stopped then begin
    //
  end else begin
    // Fehlerrückgabe
  end;
end;

procedure TAudioControl.StopRecording;
begin
  if FState = Initialised then begin
    //
  end else if FState = Recording then begin
    StopStream;
  end else if FState = Paused then begin
    StopStream;
  end else if FState = Stopped then begin
    //
  end else begin
    // Fehlerrückgabe
  end;
end;

procedure TAudioControl.StartSavingThreadAsWave(AOwner: TComponent; SaveDirectory: String);
var
  InputStream: TStreamIn;
begin
  if 1 <= (TrackList.High + 1) then begin
    FWaveOut := TWaveOut.Create(AOwner);
    InputStream := TStreamIn.Create(AOwner);
    FWaveOut.Input := InputStream;

    InputStream.InChannels := TrackList.FNumberOfChannels;
    InputStream.InBitsPerSample := TrackList.FBitsPerSample;
    InputStream.InSampleRate := TrackList.SampleRate;
    InputStream.Stream := TFileStream.Create(TrackList[0].StreamPath, fmOpenRead);

    FWaveOut.FileName := SaveDirectory + '1.wav';
    //FWaveOut.OnDone := ProcessSavingThreadAsWave(SaveDirectory, 2);
    FWaveOut.Run;
  end else begin
    FWaveOut.Free;
  end;
end;

procedure TAudioControl.ProcessSavingThreadAsWave(AOwner: TComponent; SaveDirectory: String; TrackNumber: Integer);
begin
if TrackNumber <= (TrackList.High + 1) then begin
    FWaveOut.FileName := SaveDirectory + '/' + IntToStr(TrackNumber) + '.wav';
    Inc(TrackNumber);
    //FWaveOut.OnDone := ProcessSavingThreadAsWave(self, SaveDirectory, TrackNumber);
    FWaveOut.Run;
  end else begin
    FWaveOut.Free;
  end;
end;

procedure TAudioControl.RunStream;
begin
  FTrackList.AddTrack();
  FAudioStream.Stream := (FTrackList[FTrackList.High] as TTrack).Stream;
  FAudioStream.Run;
  (FTrackList[FTrackList.High] as TTrack).StartTime := GetTickCount;
  FState := Recording;
end;

procedure TAudioControl.PauseStream;
begin
  with (FTrackList[FTrackList.High] as TTrack) do begin
    LengthInMilliseconds := LengthInMilliseconds + (GetTickCount - StartTime);
  end;
  FAudioStream.Pause;
  FState := Paused;
end;

procedure TAudioControl.ResumeStream;
begin
  FAudioStream.Resume;
  (FTrackList[FTrackList.High] as TTrack).StartTime := GetTickCount;
  FState := Recording;
end;

procedure TAudioControl.StopStream;
begin
  with (FTrackList[FTrackList.High] as TTrack) do begin
    LengthInMilliseconds := LengthInMilliseconds + (GetTickCount - StartTime);
  end;
  FAudioStream.Stop(false);

{  SavingStream := TFileStream.Create(FTrackList[FTrackList.High].StreamPath, fmCreate);
  SavingStream.CopyFrom()
  ms := TMemoryStream.Create;
  ms.LoadFromFile('C:\Download\Source.txt');
  fs := TFileStream.Create('C:\Download\Dest.txt', fmOpenReadWrite);
  fs.CopyFrom(ms, ms.Size);
  fs.Free;
   ms.Free;  }

  FTrackList[FTrackList.High].Stream.Free;
  FState := Stopped;
end;

//---------------------------------- TTrack ----------------------------------//

constructor TTrack.Create(Directory: String);
var test: TFileStream;
begin
  FAlbum := '';
  FTitle := '';
  FInterpret := '';
  FComposer := '';
  FGenre := '';
  FCategory := '';
  FDescription := '';
  FLengthInMilliseconds := 0;
  FStreamPath := Directory + IntToStr(NumberOfRecordedStreams) + '.dat';
  FStream := TFileStream.Create(FStreamPath, fmCreate);
end;

destructor TTrack.Destroy;
begin
  SysUtils.DeleteFile(FStreamPath);
  Inherited;
end;

function TTrack.GetLengthAsString: String;
begin
  Result := FormatDateTime( 'hh:mm:ss.zzz',
          (LengthInMilliseconds / (24*60*60*1000)));
end;

//------------------------------ TTrackList ----------------------------------//

constructor TTrackList.Create(TemporaryDirectory: String);
begin
  FTrackList := TObjectList.Create;
  TTrack.NumberOfRecordedStreams := 0;
  FTemporaryDirectory := TemporaryDirectory;
  FNumberOfChannels := 2;
  FBitsPerSample := 16;
  FSampleRate := 44000;
end;

destructor TTrackList.Destroy;
var
  i: Integer;
begin
  for i := 0 to High do begin
    (FTrackList[i] as TTrack).Free;
  end;
  Inherited;
end;

function TTrackList.GetTrack(TrackNumber: Integer): TTrack;
begin
  Result := (FTrackList[TrackNumber] as TTrack);
end;

procedure TTrackList.AddTrack;
begin
  FTrackList.Add(TTrack.Create(FTemporaryDirectory));
  TTrack.NumberOfRecordedStreams := TTrack.NumberOfRecordedStreams + 1;
end;

procedure TTrackList.MoveTrack(StartTrackNumber, EndTrackNumber: Integer);
begin
  FTrackList.Move(StartTrackNumber, EndTrackNumber);
end;

procedure TTrackList.DeleteTrack(TrackNumber: Integer);
begin
  FTrackList.Delete(TrackNumber);
end;

procedure TTrackList.DeleteAllTracks;
var
  i: Integer;
begin
  for i := 0 to FTrackList.Count - 1 do begin
    FTrackList.Delete(i);
  end;
end;

function TTrackList.Count: Integer;
begin
  Result := FTrackList.Count;
end;

function TTrackList.High: Integer;
begin
  Result := FTrackList.Count - 1;
end;

function TTrackList.GetLengthOfAllTracksInMilliseconds: Cardinal;
var
  i: Integer;
  LengthOfAllTracksInMilliseconds: Cardinal;
begin
  LengthOfAllTracksInMilliseconds := 0;
  for i := 0 to FTrackList.Count - 1 do begin
    LengthOfAllTracksInMilliseconds :=
      LengthOfAllTracksInMilliseconds + (FTrackList[i] as TTrack).LengthInMilliseconds;
  end;
  Result := LengthOfAllTracksInMilliseconds;
end;

//------------------------------ TAudioSaveFormat ----------------------------//

procedure TAudioSaveFormat.SetToMP3(Bitrate: Integer);
begin
  FFormat := 'mp3';
  FBitrate := Bitrate;
end;

procedure TAudioSaveFormat.SetToWave;
begin
  FFormat := 'wav';
  FBitrate := 0;
end;

function TAudioSaveFormat.GetFormat: String;
begin
  Result := FFormat;
end;

function TAudioSaveFormat.GetBitrate: Integer;
begin
  Result := FBitrate;
end;

end.
Die AudioControl Unit funktioniert bereits ganz gut. Ein paar Probleme sind noch vorhanden:
  • Mein ThinkPad parkt bei Erschütterungen die Festplatte. Bei der Verwendung von FileStream kann während der Erschütterung nicht auf die Festplatte geschrieben werden, deshalb gehen Audiodaten verloren. Ein MemoryStream ist auch nicht die perfekte Lösung, da eine Aufnahme sehr groß werden kann und der Arbeitsspeicher damit sehr gefüllt würde. Optimal wäre ein gepufferter FileStream, muss ich diesen selbst programmieren oder gibt es da schon Komponenten?
  • Die New Audio Components haben Events auf die ich reagieren kann. Jedoch weiß ich nicht, wie ich darauf reagieren kann und wie ich sie als neues Ereignis in meiner selbst erstellten Komponente weitergeben kann.
  • Außerdem soll mein Programmcode möglichst sauber und wartungsfreundlich sein, da benötige ich Anregungen von euch.

Vielen Dank für eure Mithilfe!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz