AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Audio CD Rippen

Ein Thema von igel457 · begonnen am 2. Jan 2010
Antwort Antwort
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#1

Audio CD Rippen

  Alt 2. Jan 2010, 23:41
Audio CD Rippen

Windows bietet keine Möglichkeit um über ReadFile Daten von einem als Volume geöffneten optischen Laufwerk zu lesen. Folgender Code demonstriert das Auslesen von Audio CDs über die entsprechende Schnittstelle der DeviceIOControl Funktion (IOCTL_CDROM_RAW_READ).

Die Daten werden in eine RAW-Datei geschrieben, könnten aber z.B. direkt wiedergegeben werden, andersweitig codiert oder mit entsprechendem WAVE-Header versehen direkt als WAVE-Datei gespeichert werden. RAW-Audio Dateien können mit den gängigen Audiobearbeitungsprogrammen geöffnet werden, es muss entsprechend Bittiefe (16-Bit), Abtastrate (44100Hz) und Kanalanzahl (2, Stereo) angegeben werden.

Folgendes Tutorial hat mir beim Erstellen des Codes sehr geholfen: http://www.codeproject.com/KB/audio-...px?msg=1686942

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils, Classes;

type
  TTrackDataAddressArray = array[0..3] of Byte;

  TTrackData = packed record
    Reserved: Byte;
    ControlAdr: Byte;
    TrackNumber: Byte;
    Reserved1: Byte;
    Address: TTrackDataAddressArray;
  end;

  TCDROMTOC = packed record
    Length: Word;
    FirstTrack: Byte;
    LastTrack: Byte;
    TrackData: array[0..99] of TTrackData;
  end;


  TRAWReadInfo = packed record
    DiskOffset: Int64;
    SectorCount: Cardinal;
    TrackMode: Cardinal;
  end;

const
  IOCTL_CDROM_READ_TOC = $00024000;
  IOCTL_CDROM_RAW_READ = $0002403e;

  YellowMode2 = 0;
  XAForm2 = 1;
  CDDA = 2;

const
  sector_size = 2352;
  sector_count = 20;

function AddressToSectors(addr: TTrackDataAddressArray): int64;
begin
  result := addr[1] * 75 * 60 + addr[2] * 75 + addr[3] - 150;
end;

procedure ReadTrackData(AStream: TStream; AID: integer; const AToc: TCDROMTOC;
  ADev: HFILE);
var
  buf: PByte;
  s: integer;
  c, rc: integer;
  offs: Int64;
  read: Cardinal;
  info: TRAWReadInfo;
  addr: int64;
  length: int64;
begin
  Writeln;
  Writeln('Reading track ', AID);

  //Calculate address and length of the track
  addr := AddressToSectors(AToc.TrackData[AID - AToc.FirstTrack].Address);
  length := AddressToSectors(AToc.TrackData[AID - AToc.FirstTrack + 1].Address) - addr;

  info.TrackMode := CDDA;

  s := sector_size * sector_count;
  GetMem(buf, s);
  try
    c := length;
    offs := addr * 2048;

    while c > 0 do
    begin
      //Set the read offset
      info.DiskOffset := offs;

      if c > sector_count then
        rc := sector_count
      else
        rc := c;

      info.SectorCount := rc;

      //Read the data
      if not DeviceIoControl(ADev, IOCTL_CDROM_RAW_READ, @info, SizeOf(info), buf,
        rc * 2352, read, nil) then
        RaiseLastOSError;

      //Write it to the memory stream
      AStream.Write(buf^, read);

      //Calculate the next read address
      c := c - sector_count;
      offs := offs + sector_count * 2048;

      Write('Sectors remaining ', c, ' ', #13);
    end;
  finally
    FreeMem(buf, s);
  end;
  Writeln;
end;

var
  i: integer;
  fs: TStream;
  hndl: HFILE;
  dummy: Cardinal;
  toc: TCDROMTOC;

begin
  //Open the CD-Audio (F: is the drive letter of the cd drive)
  hndl := CreateFile('\\.\F:', GENERIC_READ,
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

  if hndl <> INVALID_HANDLE_VALUE then
  begin
    try
      //Read the cd audio table of content
      if not DeviceIoControl(hndl, IOCTL_CDROM_READ_TOC, nil, 0, @toc, SizeOf(toc), dummy,
        nil) then
        RaiseLastOSError;

      //Read every track
      for i := toc.FirstTrack to toc.LastTrack do
      begin
        fs := TFileStream.Create('track'+FormatFloat('00', i)+'.raw', fmCreate);
        try
          ReadTrackData(fs, i, toc, hndl);
        finally
          fs.Free;
        end;
      end;
    finally
      //Close the device
      CloseHandle(hndl);
    end;
  end;
end.
Eine in Klassen gekapselte Version des Codes kann hier gefunden werden: http://audorra.svn.sourceforge.net/v...iew=markup#l_1

Ich hoffe, der Eine oder Andere kann den Code gebrauchen,
Andreas

Stichworte: cdrom, audio, rip, rippen, lesen, volume, direktzugriff, daten, cda, cdda, cdaudio, cd-audio
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  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 18:54 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