![]() |
Audio CD Rippen
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: ![]()
Delphi-Quellcode:
Eine in Klassen gekapselte Version des Codes kann hier gefunden werden:
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. ![]() 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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz