337 lines
8.7 KiB
PHP

{
$Log: acs_cdrom.inc,v $
Revision 1.12 2006/08/31 20:10:56 z0m3ie
*** empty log message ***
Revision 1.11 2006/07/04 17:12:45 z0m3ie
ACS 2.4 alt wiederhergestellt (unterschiedliche Sampleformate ...)
Revision 1.3 2006/01/03 15:37:51 z0m3ie
*** empty log message ***
Revision 1.2 2005/12/26 17:31:39 z0m3ie
fixed some problems in acs_dsfiles
fixed some problems in acs_vorbis
reworked all buffers
Revision 1.1 2005/12/19 18:35:16 z0m3ie
*** empty log message ***
Revision 1.4 2005/12/04 16:54:34 z0m3ie
All classes are renamed, Style TACS... than T... to avoid conflicts with other components (eg TMixer is TACSMixer now)
Revision 1.3 2005/10/02 16:51:46 z0m3ie
*** empty log message ***
Revision 1.2 2005/09/13 21:54:11 z0m3ie
acs is localizeable now (ACS_Strings)
Revision 1.1 2005/09/12 22:04:52 z0m3ie
modified structure again, fileformats are now in an sperat folder.
all File In/Out classes are capsulated from TFileIn and TFileOut
Revision 1.5 2005/09/09 21:33:43 z0m3ie
linux corrections
Revision 1.4 2005/09/08 22:19:00 z0m3ie
completed akrip based CDIn
Revision 1.3 2005/09/07 20:53:22 z0m3ie
begon to add MPEG and WMA support using DirectX
Revision 1.2 2005/09/04 17:59:38 z0m3ie
moving CDIn support to AKRip mostly
begon to add mpegin support for Win with mpg123
Revision 1.1 2005/08/25 20:18:00 z0m3ie
Version 2.4 restructure
TCDPlayer removed (fits not in component structure)
TMP3ToWavConverter removed (fits not in component structure)
}
type
MSFAddr = array[0..3] of Byte;
function Toc2MSF(t : MSFAddr) : TACSCDMSF;
begin
Result.Minute := t[1];
Result.Second := t[2];
Result.Frame := t[3];
end;
procedure TACSCDIn.OpenCD;
var
GetCD: GETCDHAND;
begin
with GetCD do
begin
Size := SizeOf(GETCDHAND);
Ver := 1;
ha := 0;
tgt := FCurrentDrive;
lun := 0;
readType := CDR_ANY;
jitterCorr := false;
numJitter := 0;
numOverlap := 0;
end;
FCDHandle := GetCDHandle(GetCD);
end;
procedure TACSCDIn.CloseCD;
begin
if FCDHandle <> 0 then
CloseCDHandle(FCDHandle);
FCDHandle := 0;
end;
function TACSCDIn.GetInfo : TACSCDInfo;
var
i : Integer;
begin
OpenCD;
Result := cdiUnknown;
ModifyCDParms(FCDHandle, CDP_MSF, DWORD(true));
FillChar(FToc, SizeOf(FToc),0);
if ReadTOC(FCDHandle, FTOC) <> 1 then
begin
Result := cdiNoDisc;
Exit;
end;
for i := 0 to FToc.lastTrack-1 do
begin
if (FToc.Tracks[i].adr and $04) = 0 then
begin
case Result of
cdiUnknown : Result := cdiDiscAudio;
cdiDiscData : Result := cdiDiscMixed;
end;
end else
begin
case Result of
cdiUnknown : Result := cdiDiscData;
cdiDiscAudio : Result := cdiDiscMixed;
end;
end;
end;
CloseCD;
end;
function TACSCDIn.GetStatus : TACSCDStatus;
var
ms : Integer;
AP : LongBool;
begin
if FPlaying then
Result := cdsPlaying
else if (GetInfo <> cdiNoDisc) and (GetInfo <> cdiUnknown) then
Result := cdsReady
else
Result := cdsNotReady;
end;
function TACSCDIn.GetNumTracks : Integer;
begin
OpenCD;
if FToc.lastTrack = 0 then
begin
ModifyCDParms(FCDHandle, CDP_MSF, DWORD(true));
if ReadTOC(FCDHandle, FTOC) <> 1 then
begin
Result := -1;
Exit;
end;
end;
Result := FToc.lastTrack;
CloseCD;
end;
FUNCTION TACSCDIn.GetTrackInfo(const vIndex : Integer) : TACSCDTrackInfo;
VAR
Frames: Integer;
tmpmsf : TACSCDMSF;
BEGIN
IF Busy THEN
RAISE EACSException.Create(strBusy);
IF (vIndex IN [0..GetNumTracks-1]) = False THEN
RAISE EACSException.Create(strTrackoutofrange);
IF (FToc.Tracks[vIndex].adr and $04) = 0 THEN
Result.TrackType := ttAudio
ELSE
Result.TrackType := ttData;
Result.TrackStart.Minute := FToc.Tracks[vIndex].addr[1];
Result.TrackStart.Second := FToc.Tracks[vIndex].addr[2];
Result.TrackStart.Frame := FToc.Tracks[vIndex].addr[3];
Frames := MSF2Frames(Toc2MSF(MSFAddr(FToc.Tracks[vIndex+1].addr)))-MSF2Frames(Toc2MSF(MSFAddr(FToc.Tracks[vIndex].addr)));
Frames2MSF(Frames, Result.TrackLength);
end;
procedure TACSCDIn.SetST;
begin
if Self.Busy then raise EACSException.Create(strBusy);
FStartTrack := Track;
FStartPos.Track := FStartTrack;
FillChar(FStartPos.MSF, SizeOf(FStartPos.MSF), 0);
end;
procedure TACSCDIn.SetET;
begin
if Self.Busy then raise EACSException.Create(strBusy);
FEndTrack := Track;
FEndPos.Track := FEndTrack+1;
FillChar(FEndPos.MSF, SizeOf(FEndPos.MSF), 0);
end;
procedure TACSCDIn.SetSP;
begin
if Self.Busy then raise EACSException.Create(strBusy);
FStartPos := Pos;
end;
procedure TACSCDIn.SetEP;
begin
if Self.Busy then raise EACSException.Create(strBusy);
FEndPos := Pos;
if Pos.Track = EndOfDisc.Track then FEndPos.Track := TracksCount + 1;
end;
function TACSCDIn.GetSize : Integer;
var
Sect1, Sect2 : Integer;
begin
if Busy then
begin
Result := FRipEnd-FRipStart*CD_FRAMESIZE_RAW;
Exit;
end;
Sect1 := MSF2Frames(Toc2MSF(MSFAddr(FToc.tracks[FStartPos.Track].addr)));
Sect1 := Sect1 + MSF2Frames(FStartPos.MSF);
Sect2 := MSF2Frames(Toc2MSF(MSFAddr(FToc.tracks[FEndPos.Track].addr)));
Sect2 := Sect2 + MSF2Frames(FEndPos.MSF);
Result := (Sect2 - Sect1)*CD_FRAMESIZE_RAW;
end;
procedure TACSCDIn.Init;
var
Sect1, Sect2 : Integer;
begin
if Busy then raise EACSException.Create(strBusy);
if Status = cdsNotReady then
raise EACSException.Create(strDrivenotready);
if (FStartPos.Track in [0..GetNumTracks-1]) = False then
raise EACSException.Create(strTrackoutofRange);
if Tracks[FStartPos.Track].TrackType = ttData then
raise EACSException.Create(strnoAudioTreck);
OpenCD;
FSize := GetSize;
FBusy := True;
BufStart := 1;
BufEnd := 0;
FPosition := 0;
Sect1 := MSF2Frames(Toc2MSF(MSFAddr(FToc.tracks[FStartPos.Track].addr)));
Sect1 := Sect1 + MSF2Frames(FStartPos.MSF);
Sect2 := MSF2Frames(Toc2MSF(MSFAddr(FToc.tracks[FEndPos.Track].addr)));
Sect2 := Sect2 + MSF2Frames(FEndPos.MSF);
FRipEnd := Sect2;
FRipStart := Sect1;
SetLength(FBuffer,(BUF_SIZE * CD_FRAMESIZE_RAW)+TRACKBUFEXTRA);
end;
procedure TACSCDIn.Flush;
begin
CloseCD;
FBusy := False;
Setlength(FBuffer,0);
FBuffer := nil;
FSize := 0;
end;
function TACSCDIn.GetData(Buffer : Pointer; BufferSize : Integer): Integer;
var
Abort : LongBool;
fnum : Integer;
begin
if not Busy then raise EACSException.Create(strStreamnotOpen);
if BufStart > BufEnd then //Buffer clear try to fill it
begin
BufStart := 1;
Abort := False;
if FRipEnd-FRipStart > BUF_SIZE then
fNum := BUF_SIZE
else
fNum := FRipEnd-FRipStart;
FiBuffer^.startFrame := FRipStart;
FiBuffer^.numFrames := fNum;
FiBuffer^.maxLen := FiBuffer^.numFrames * CD_FRAMESIZE_RAW;
FiBuffer^.len := 0;
FiBuffer^.status := 0;
FiBuffer^.startOffset := 0;
if ReadCDAudioLBA(FCDHandle,FiBuffer) = 1 then
begin
Inc(FRipStart,FiBuffer^.numFrames);
BufEnd := FiBuffer^.len;
end;
end;
if BufferSize < (BufEnd - BufStart + 1) then
Result := BufferSize
else
Result := BufEnd - BufStart + 1;
Move(FiBuffer^.buf[BufStart-1],Buffer^, Result);
Inc(BufStart, Result);
Inc(FPosition, Result);
end;
procedure TACSCDIn.SetCurrentDrive;
begin
if Value in [0..FCDList.num-1] then
FCurrentDrive := Value;
OpenCD;
FillChar(FToc, SizeOf(FToc),0);
ModifyCDParms(FCDHandle, CDP_MSF, DWORD(true));
ReadTOC(FCDHandle, FTOC);
CloseCD;
end;
function TACSCDIn.GetDrivesCount : Integer;
begin
Result := FCDList.num;
end;
function TACSCDIn.GetDriveName : string;
begin
Result := FCDList.Cd[FCurrentDrive].id;
end;
procedure TACSCDIn.Eject;
begin
if Busy then raise EACSException.Create(strBusy);
end;
procedure TACSCDIn.CloseTray;
begin
end;
constructor TACSCDIn.Create;
begin
inherited Create(AOwner);
AppPath := ExtractFilePath(ParamStr(0));
if AppPath[length(AppPath)] <> '\' then AppPath := AppPath + '\';
CDRIPInit(AppPath);
if not (csDesigning in ComponentState) then
if not CDRipLoaded then
raise EACSException.Create(akriplib + ' could not be loaded.');
FillChar(FCDList, SizeOf(FCDList),0);
FCDList.max := MAXCDLIST;
GetCDList(FCDList);
end;
destructor TACSCDIn.Destroy;
begin
if Busy then
Flush;
CloseCD;
inherited Destroy;
end;