mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Drive offset support
This commit is contained in:
@@ -55,6 +55,7 @@ namespace CUETools.ConsoleRipper
|
||||
{
|
||||
CDDriveReader audioSource = new CDDriveReader();
|
||||
audioSource.Open('D');
|
||||
audioSource.DriveOffset = 48;
|
||||
|
||||
StreamWriter logWriter = new StreamWriter(Path.ChangeExtension(destFile, ".log"));
|
||||
logWriter.WriteLine("{0}", programVersion);
|
||||
|
||||
@@ -37,10 +37,11 @@ namespace CUETools.Ripper.SCSI
|
||||
{
|
||||
byte[] cdtext = null;
|
||||
private Device m_device;
|
||||
uint _sampleOffset = 0;
|
||||
int _sampleOffset = 0;
|
||||
uint _samplesInBuffer = 0;
|
||||
uint _samplesBufferOffset = 0;
|
||||
uint _samplesBufferSector = 0;
|
||||
int _driveOffset = 0;
|
||||
const int CB_AUDIO = 588 * 4 + 16;
|
||||
const int NSECTORS = 32;
|
||||
int _currentTrack = -1, _currentIndex = -1, _currentTrackActualStart = -1;
|
||||
@@ -141,48 +142,9 @@ namespace CUETools.Ripper.SCSI
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe uint Read(int[,] buff, uint sampleCount)
|
||||
private void ProcessSubchannel(int sector, int Sectors2Read)
|
||||
{
|
||||
if (_toc == null)
|
||||
throw new Exception("invalid TOC");
|
||||
if (_sampleOffset >= (uint)Length)
|
||||
return 0;
|
||||
if (_sampleOffset + sampleCount > Length)
|
||||
sampleCount = (uint)Length - _sampleOffset;
|
||||
uint pos = 0;
|
||||
if (_samplesInBuffer > 0)
|
||||
{
|
||||
uint samplesRead = Math.Min(_samplesInBuffer, sampleCount);
|
||||
AudioSamples.BytesToFLACSamples_16(_sectorBuffer, (int)(_samplesBufferSector * (588 * 4 + 16) + _samplesBufferOffset * 4), buff, (int)pos, samplesRead, 2);
|
||||
pos += samplesRead;
|
||||
sampleCount -= samplesRead;
|
||||
_sampleOffset += samplesRead;
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
_samplesInBuffer -= samplesRead;
|
||||
_samplesBufferOffset += samplesRead;
|
||||
return pos;
|
||||
}
|
||||
_samplesInBuffer = 0;
|
||||
_samplesBufferOffset = 0;
|
||||
_samplesBufferSector = 0;
|
||||
}
|
||||
// if (_sampleOffset < PreGapLength && !_overreadIntoPreGap ... ?
|
||||
int firstSector = (int)_sampleOffset / 588;
|
||||
int lastSector = (int)(_sampleOffset + sampleCount + 577) / 588;
|
||||
for (int sector = firstSector; sector < lastSector; sector += NSECTORS)
|
||||
{
|
||||
int Sectors2Read = ((sector + NSECTORS) < lastSector) ? NSECTORS : (lastSector - sector);
|
||||
fixed (byte* data = _sectorBuffer)
|
||||
{
|
||||
Device.CommandStatus st = m_device.ReadCDAndSubChannel(2, 1, true, (uint)sector, (uint)Sectors2Read, (IntPtr)((void*)data), Sectors2Read * (2352 + 16));
|
||||
if (st != Device.CommandStatus.Success)
|
||||
throw new Exception("SCSI error");
|
||||
}
|
||||
for (int iSector = 0; iSector < Sectors2Read; iSector++)
|
||||
{
|
||||
uint samplesRead = Math.Min(sampleCount, 588U) - (_sampleOffset % 588);
|
||||
AudioSamples.BytesToFLACSamples_16(_sectorBuffer, iSector * (588 * 4 + 16) + ((int)_sampleOffset % 588) * 4, buff, (int)pos, samplesRead, 2);
|
||||
{
|
||||
int q_pos = (iSector + 1) * (588 * 4 + 16) - 16;
|
||||
int ctl = _sectorBuffer[q_pos + 0] >> 4;
|
||||
@@ -234,18 +196,122 @@ namespace CUETools.Ripper.SCSI
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void FetchSectors(int sector, int Sectors2Read)
|
||||
{
|
||||
fixed (byte* data = _sectorBuffer)
|
||||
{
|
||||
Device.CommandStatus st = m_device.ReadCDAndSubChannel(2, 1, true, (uint)sector, (uint)Sectors2Read, (IntPtr)((void*)data), Sectors2Read * (2352 + 16));
|
||||
if (st != Device.CommandStatus.Success)
|
||||
throw new Exception("SCSI error");
|
||||
}
|
||||
ProcessSubchannel(sector, Sectors2Read);
|
||||
}
|
||||
|
||||
public unsafe uint Read(int[,] buff, uint sampleCount)
|
||||
{
|
||||
if (_toc == null)
|
||||
throw new Exception("invalid TOC");
|
||||
if (_sampleOffset - _driveOffset >= (uint)Length)
|
||||
return 0;
|
||||
if (_sampleOffset > (uint)Length)
|
||||
{
|
||||
int samplesRead = _sampleOffset - (int)Length;
|
||||
for (int i = 0; i < samplesRead; i++)
|
||||
for (int c = 0; c < ChannelCount; c++)
|
||||
buff[i, c] = 0;
|
||||
_sampleOffset += samplesRead;
|
||||
return 0;
|
||||
}
|
||||
if ((uint)(_sampleOffset - _driveOffset + sampleCount) > Length)
|
||||
sampleCount = (uint)((int)Length + _driveOffset - _sampleOffset);
|
||||
int silenceCount = 0;
|
||||
if ((uint)(_sampleOffset + sampleCount) > Length)
|
||||
{
|
||||
silenceCount = _sampleOffset + (int)sampleCount - (int)Length;
|
||||
sampleCount -= (uint) silenceCount;
|
||||
}
|
||||
uint pos = 0;
|
||||
if (_sampleOffset < 0)
|
||||
{
|
||||
uint nullSamplesRead = Math.Min((uint)-_sampleOffset, sampleCount);
|
||||
for (int i = 0; i < nullSamplesRead; i++)
|
||||
for (int c = 0; c < ChannelCount; c++)
|
||||
buff[i, c] = 0;
|
||||
pos += nullSamplesRead;
|
||||
sampleCount -= nullSamplesRead;
|
||||
_sampleOffset += (int)nullSamplesRead;
|
||||
if (sampleCount == 0)
|
||||
return pos;
|
||||
}
|
||||
if (_samplesInBuffer > 0)
|
||||
{
|
||||
uint samplesRead = Math.Min(_samplesInBuffer, sampleCount);
|
||||
AudioSamples.BytesToFLACSamples_16(_sectorBuffer, (int)(_samplesBufferSector * (588 * 4 + 16) + _samplesBufferOffset * 4), buff, (int)pos, samplesRead, 2);
|
||||
pos += samplesRead;
|
||||
sampleCount -= samplesRead;
|
||||
_sampleOffset += samplesRead;
|
||||
_sampleOffset += (int) samplesRead;
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
_samplesInBuffer -= samplesRead;
|
||||
_samplesBufferOffset += samplesRead;
|
||||
if (silenceCount > 0)
|
||||
{
|
||||
uint nullSamplesRead = (uint) silenceCount;
|
||||
for (int i = 0; i < nullSamplesRead; i++)
|
||||
for (int c = 0; c < ChannelCount; c++)
|
||||
buff[pos + i, c] = 0;
|
||||
pos += nullSamplesRead;
|
||||
_sampleOffset += (int)nullSamplesRead;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
_samplesInBuffer = 0;
|
||||
_samplesBufferOffset = 0;
|
||||
_samplesBufferSector = 0;
|
||||
}
|
||||
// if (_sampleOffset < PreGapLength && !_overreadIntoPreGap ... ?
|
||||
int firstSector = (int)_sampleOffset / 588;
|
||||
int lastSector = (int)(_sampleOffset + sampleCount + 577) / 588;
|
||||
for (int sector = firstSector; sector < lastSector; sector += NSECTORS)
|
||||
{
|
||||
int Sectors2Read = ((sector + NSECTORS) < lastSector) ? NSECTORS : (lastSector - sector);
|
||||
FetchSectors(sector, Sectors2Read);
|
||||
for (int iSector = 0; iSector < Sectors2Read; iSector++)
|
||||
{
|
||||
uint samplesRead = (uint) (Math.Min((int)sampleCount, 588) - (_sampleOffset % 588));
|
||||
AudioSamples.BytesToFLACSamples_16(_sectorBuffer, iSector * (588 * 4 + 16) + ((int)_sampleOffset % 588) * 4, buff, (int)pos, samplesRead, 2);
|
||||
pos += samplesRead;
|
||||
sampleCount -= samplesRead;
|
||||
_sampleOffset += (int) samplesRead;
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
_samplesBufferSector = (uint)iSector;
|
||||
_samplesBufferOffset = samplesRead;
|
||||
_samplesInBuffer = 588U - samplesRead;
|
||||
if (silenceCount > 0)
|
||||
{
|
||||
uint nullSamplesRead = (uint)silenceCount;
|
||||
for (int i = 0; i < nullSamplesRead; i++)
|
||||
for (int c = 0; c < ChannelCount; c++)
|
||||
buff[pos + i, c] = 0;
|
||||
pos += nullSamplesRead;
|
||||
_sampleOffset += (int)nullSamplesRead;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (silenceCount > 0)
|
||||
{
|
||||
uint nullSamplesRead = (uint)silenceCount;
|
||||
for (int i = 0; i < nullSamplesRead; i++)
|
||||
for (int c = 0; c < ChannelCount; c++)
|
||||
buff[pos + i, c] = 0;
|
||||
pos += nullSamplesRead;
|
||||
_sampleOffset += (int)nullSamplesRead;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -306,11 +372,11 @@ namespace CUETools.Ripper.SCSI
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sampleOffset;
|
||||
return (ulong)(_sampleOffset - _driveOffset);
|
||||
}
|
||||
set
|
||||
{
|
||||
_sampleOffset = (uint)value;
|
||||
_sampleOffset = (int) value + _driveOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +388,19 @@ namespace CUETools.Ripper.SCSI
|
||||
}
|
||||
}
|
||||
|
||||
public int DriveOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return _driveOffset;
|
||||
}
|
||||
set
|
||||
{
|
||||
_driveOffset = value;
|
||||
_sampleOffset = value;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] _sectorBuffer = new byte[CB_AUDIO * NSECTORS];
|
||||
|
||||
private int fromBCD(byte hex)
|
||||
|
||||
Reference in New Issue
Block a user