Einzelnen Beitrag anzeigen

Benutzerbild von Gausi
Gausi
Online

Registriert seit: 17. Jul 2005
880 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: ChatGPT - Wow! (Cron-Job)

  Alt 7. Jul 2024, 10:30
Ich habe ja in letzter Zeit öfter mal über KI gemeckert, besonders über Googles Bard bzw. jetzt Gemini. Aber Holladiwaldfee ... ChatGPT ist tatsächlich um Welten besser.

Da ich grade dabei bin, bei meiner Audio-Bibliothek auch Opus-Dateien zu unterstützen, habe ich für ein (bereits implementiertes) Teilproblem mal diese KIs befragt.

Mein Input: Kannst du mir eine Funktion in der Programmiersprache Delphi schreiben, die aus einer gegebenen Ogg-Datei die maximale absolute granule position ermittelt?

Gemini hat (mal wieder) irgendwelche nicht-existenten Klassen herbei-fantasiert und somit nutzlosen Code produziert.
Delphi-Quellcode:
unit OggGranulePosition;

interface
uses
  Windows,
  Messages,
  StdCtrls,
  ExtCtrls,
  OggVorbis;

implementation

function GetMaxGranulePosition(oggFileName: string): LongWord;
  var
    oggFile: TOggVorbisFile;
    oggStream: TOggVorbisStream;
    granulePosition: LongWord;
    granuleCount: LongWord;
    i: LongWord;
  begin
    oggFile := TOggVorbisFile.Create;
    try
      oggFile.Open(oggFileName, ofRead);

      oggStream := TOggVorbisStream.Create(oggFile);
      try
        granulePosition := 0;

        granuleCount := oggStream.Info.Packets;

        for i := 0 to granuleCount - 1 do
        begin
          granulePosition := Max(granulePosition, oggStream.Packets[i].Granulepos);
        end;

      finally
        oggStream.Free;
      end;

    finally
      oggFile.Free;
    end;

    Result := granulePosition;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Maximal absolute granule position: ' +
             IntToStr(GetMaxGranulePosition('C:\path\to\oggFile.ogg')));
end;

end.
ChatGPT liefert hingegen eine Struktur für den Ogg-Seitenheader, ermittelt nach einer Gültigkeits-Überprüfung daraus den gesuchten Wert. Dann wird korrekt die Größe der Seite berechnet, um sich seitenweise durch die Datei zu hangeln, um dann schließlich auf der letzten Seite den gesuchten Wert zu ermitteln.
Delphi-Quellcode:
program MaxGranulePosition;

uses
  Classes, SysUtils;

type
  TOggPageHeader = packed record
    CapturePattern: array[0..3] of AnsiChar;
    Version: Byte;
    HeaderType: Byte;
    GranulePosition: Int64;
    BitstreamSerialNumber: Cardinal;
    PageSequenceNumber: Cardinal;
    Checksum: Cardinal;
    PageSegments: Byte;
  end;

function ReadOggPageHeader(Stream: TStream; out Header: TOggPageHeader): Boolean;
begin
  Result := Stream.Read(Header, SizeOf(TOggPageHeader)) = SizeOf(TOggPageHeader);
end;

function GetMaxGranulePosition(const FileName: string): Int64;
var
  FileStream: TFileStream;
  OggPageHeader: TOggPageHeader;
  MaxGranulePosition: Int64;
  PageSegments: array of Byte;
  SegmentSize: Integer;
  I: Integer;
begin
  MaxGranulePosition := 0;
  FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    while FileStream.Position < FileStream.Size do
    begin
      if not ReadOggPageHeader(FileStream, OggPageHeader) then
        Break;

      if (OggPageHeader.CapturePattern <> 'OggS') then
        Break; // Invalid Ogg page

      if OggPageHeader.GranulePosition > MaxGranulePosition then
        MaxGranulePosition := OggPageHeader.GranulePosition;

      SetLength(PageSegments, OggPageHeader.PageSegments);
      FileStream.Read(PageSegments[0], OggPageHeader.PageSegments);

      SegmentSize := 0;
      for I := 0 to OggPageHeader.PageSegments - 1 do
        Inc(SegmentSize, PageSegments[I]);

      FileStream.Seek(SegmentSize, soFromCurrent);
    end;
  finally
    FileStream.Free;
  end;
  Result := MaxGranulePosition;
end;

var
  FileName: string;
  MaxGranule: Int64;
begin
  Write('Enter the Ogg file path: ');
  ReadLn(FileName);
  try
    MaxGranule := GetMaxGranulePosition(FileName);
    WriteLn('Max Granule Position: ', MaxGranule);
  except
    on E: Exception do
      WriteLn('Error: ', E.Message);
  end;
  ReadLn;
end.
Meine bisherigen Methode, vom Ende der Datei aus den letzten Ogg-Header zu suchen, ist zwar schneller, wenn die Seitengröße klein ist. Aber wenn die fehlschlägt (warum auch immer) ist das, was ChatGPT vorschlägt, die korrekte und sichere Variante.

Hat mich tatsächlich beeindruckt. Vor allem, weil das ja kein "Standard-Problem" ist, was ständig diskutiert wird.
The angels have the phone box.
  Mit Zitat antworten Zitat