diff --git a/Bwg.Hardware/app.config b/Bwg.Hardware/app.config
new file mode 100644
index 0000000..b7db281
--- /dev/null
+++ b/Bwg.Hardware/app.config
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Bwg.Logging/app.config b/Bwg.Logging/app.config
new file mode 100644
index 0000000..b7db281
--- /dev/null
+++ b/Bwg.Logging/app.config
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Bwg.Scsi/Device.cs b/Bwg.Scsi/Device.cs
index 2ee0b38..9b79def 100644
--- a/Bwg.Scsi/Device.cs
+++ b/Bwg.Scsi/Device.cs
@@ -2369,6 +2369,47 @@ namespace Bwg.Scsi
return CommandStatus.Success ;
}
+ ///
+ /// Read the subchannel data from a series of sectors
+ ///
+ /// subchannel mode
+ /// track number
+ /// output buffer
+ /// output buffer offset
+ /// timeout (in seconds)
+ ///
+ public CommandStatus ReadSubChannel42(byte mode, int track, ref byte[] data, int offs, int timeout)
+ {
+ if (m_logger != null)
+ {
+ m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadSubChannel42()"));
+ }
+
+ if (mode != 1 && mode != 2 && mode != 3)
+ throw new Exception("invalid read mode for ReadSubchannel42() call");
+
+ int size = mode == 1 ? 16 : 24;
+ if (offs + data.GetLength(0) < size)
+ throw new Exception("data buffer is not large enough to hold the data requested");
+
+ using (Command cmd = new Command(ScsiCommandCode.ReadSubChannel, 10, size, Command.CmdDirection.In, timeout))
+ {
+ // 42 00 40 01 00 00 00 00 10 00
+ //cmd.SetCDB8(1, 2); // MSF
+ cmd.SetCDB8(2, 64); // SUBQ
+ cmd.SetCDB8(3, mode);
+ cmd.SetCDB8(6, (byte)track);
+ cmd.SetCDB16(7, (ushort)size);
+
+ CommandStatus st = SendCommand(cmd);
+ if (st != CommandStatus.Success)
+ return st;
+
+ Marshal.Copy(cmd.GetBuffer(), data, offs, size);
+ }
+ return CommandStatus.Success;
+ }
+
///
/// Read the CD text information from the leadin using the ReadTocPmaAtip command form
///
@@ -3069,10 +3110,11 @@ namespace Bwg.Scsi
string args = "info";
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadFullToc(" + args + ")"));
}
- using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 32, Command.CmdDirection.In, 5 * 60))
+ using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 320, Command.CmdDirection.In, 5 * 60))
{
+ cmd.SetCDB8(1, 2);
cmd.SetCDB8(2, 3);
- cmd.SetCDB16(7, 32);
+ cmd.SetCDB16(7, 320);
CommandStatus st = SendCommand(cmd);
if (st != CommandStatus.Success)
@@ -3081,7 +3123,7 @@ namespace Bwg.Scsi
len = cmd.GetBuffer16(0);
len += 2;
- if (len <= 32)
+ if (len <= 320)
{
data = new byte[len];
Marshal.Copy(cmd.GetBuffer(), data, 0, len);
@@ -3380,7 +3422,7 @@ namespace Bwg.Scsi
string args = ctrl.ToString() + ", " + read.ToString() + ", " + write.ToString();
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetCdSpeed(" + args + ")"));
}
- using (Command cmd = new Command(ScsiCommandCode.SetCdSpeed, 12, 0, Command.CmdDirection.None, 2))
+ using (Command cmd = new Command(ScsiCommandCode.SetCdSpeed, 12, 0, Command.CmdDirection.Out, 30))
{
cmd.SetCDB8(1, (byte)ctrl);
cmd.SetCDB16(2, read);
@@ -3393,6 +3435,30 @@ namespace Bwg.Scsi
return CommandStatus.Success;
}
+ ///
+ ///
+ ///
+ ///
+ public CommandStatus SetCdSpeedDA(RotationalControl ctrl, ushort read, ushort write)
+ {
+ if (m_logger != null)
+ {
+ string args = ctrl.ToString() + ", " + read.ToString() + ", " + write.ToString();
+ m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetCdSpeed(" + args + ")"));
+ }
+ using (Command cmd = new Command((ScsiCommandCode)0xDA, 12, 0, Command.CmdDirection.None, 2))
+ {
+ cmd.SetCDB8(1, (byte)ctrl);
+ cmd.SetCDB16(2, read);
+ cmd.SetCDB16(4, write);
+
+ CommandStatus st = SendCommand(cmd);
+ if (st != CommandStatus.Success)
+ return st;
+ }
+ return CommandStatus.Success;
+ }
+
///
///
///
diff --git a/Bwg.Scsi/app.config b/Bwg.Scsi/app.config
new file mode 100644
index 0000000..b7db281
--- /dev/null
+++ b/Bwg.Scsi/app.config
@@ -0,0 +1,3 @@
+
+
+
diff --git a/CUEControls/Properties/AssemblyInfo.cs b/CUEControls/Properties/AssemblyInfo.cs
index 03ec260..02ba2cf 100644
--- a/CUEControls/Properties/AssemblyInfo.cs
+++ b/CUEControls/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUERipper/CUERipper.csproj b/CUERipper/CUERipper.csproj
index 3a3880f..5ec61d2 100644
--- a/CUERipper/CUERipper.csproj
+++ b/CUERipper/CUERipper.csproj
@@ -15,6 +15,35 @@
cue2.ico
+ F89503BB83CA42A647C506D67956D6F32C1C6E7E
+ CUERipper_TemporaryKey.pfx
+ true
+ true
+ true
+ publish\
+ true
+ Web
+ true
+ Background
+ 7
+ Days
+ false
+ false
+ true
+ http://www.cuetools.net/install/cueripper/
+ http://www.cuetools.net/
+ CUERipper
+ Gregory S. Chudov
+ true
+ index.html
+ 2
+ 2.0.7.2
+ false
+ true
+ true
+ false
+
+
true
@@ -131,21 +160,185 @@
-
+
-
-
-
-
-
-
-
-
+
+
+ False
+ .NET Framework Client Profile
+ false
+
+
+ False
+ .NET Framework 2.0 %28x86%29
+ true
+
+
+ False
+ .NET Framework 3.0 %28x86%29
+ false
+
+
+ False
+ .NET Framework 3.5
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Visual C++ Runtime Libraries %28x64%29
+ true
+
+
+ False
+ Visual C++ Runtime Libraries %28x86%29
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ Plugins %28win32%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28win32%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28win32%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28win32%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28win32%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28win32%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28x64%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28x64%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28x64%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28x64%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28x64%29
+
+
+ Auto
+ True
+ File
+
+
+ False
+ Plugins %28x64%29
+
+
+ Auto
+ True
+ File
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ Top, Left, Right
+
+
+
+ 48, 12
+
+
+ 375, 20
+
+
+
+ 0
+
+
+ textArtist
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 15
+
+
+ True
+
+
+ 12, 15
+
+
+ 30, 13
+
+
+ 1
+
+
+ Artist
+
+
+ label1
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 14
+
+
+ True
+
+
+ NoControl
+
+
+ 12, 41
+
+
+ 27, 13
+
+
+ 3
+
+
+ Title
+
+
+ label2
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 12
+
+
+ Top, Left, Right
+
+
+ 48, 38
+
+
+ 375, 20
+
+
+ 2
+
+
+ textTitle
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 13
+
+
+ 347, 90
+
+
+ 75, 23
+
+
+ 14
+
+
+ Ok
+
+
+ button1
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 11
+
+
+ 266, 90
+
+
+ 75, 23
+
+
+ 15
+
+
+ Cancel
+
+
+ button2
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 10
+
+
+ True
+
+
+ 12, 67
+
+
+ 29, 13
+
+
+ 6
+
+
+ Year
+
+
+ label3
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 9
+
+
+ 48, 64
+
+
+ 67, 20
+
+
+ 7
+
+
+ textYear
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 8
+
+
+ 163, 64
+
+
+ 100, 20
+
+
+ 8
+
+
+ textGenre
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 7
+
+
+ 318, 64
+
+
+ 104, 20
+
+
+ 9
+
+
+ textCatalog
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 6
+
+
+ True
+
+
+ 121, 67
+
+
+ 36, 13
+
+
+ 10
+
+
+ Genre
+
+
+ label4
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 5
+
+
+ True
+
+
+ 269, 67
+
+
+ 43, 13
+
+
+ 11
+
+
+ Catalog
+
+
+ label5
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 4
+
+
+ True
+
+
+ 12, 95
+
+
+ 22, 13
+
+
+ 16
+
+
+ CD
+
+
+ labelCD
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 3
+
+
+ 48, 92
+
+
+ 50, 20
+
+
+ 17
+
+
+ textBoxDiscNumber
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ 125, 92
+
+
+ 50, 20
+
+
+ 18
+
+
+ textBoxTotalDiscs
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ True
+
+
+ 107, 95
+
+
+ 12, 13
+
+
+ 19
+
+
+ /
+
+
+ labelSlash
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ True
+
+
+ 6, 13
+
+
+ 435, 127
+
+
+ CenterParent
+
+
+ Release information
+
+
+ frmProperties
+
+
+ System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/CUETools.ALACEnc/Program.cs b/CUETools.ALACEnc/Program.cs
index 59d5da1..d30913d 100644
--- a/CUETools.ALACEnc/Program.cs
+++ b/CUETools.ALACEnc/Program.cs
@@ -162,7 +162,7 @@ namespace CUETools.ALACEnc
return 2;
}
if (buffered)
- audioSource = new AudioPipe(audioSource, 0x10000, true);
+ audioSource = new AudioPipe(audioSource, 0x10000);
if (output_file == null)
output_file = Path.ChangeExtension(input_file, "m4a");
ALACWriter alac = new ALACWriter((output_file == "-" || output_file == "nul") ? "" : output_file,
diff --git a/CUETools.ARCUE/Properties/AssemblyInfo.cs b/CUETools.ARCUE/Properties/AssemblyInfo.cs
index 8e30727..7685f60 100644
--- a/CUETools.ARCUE/Properties/AssemblyInfo.cs
+++ b/CUETools.ARCUE/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.AccurateRip/AccurateRip.cs b/CUETools.AccurateRip/AccurateRip.cs
index 75b9b58..83dabea 100644
--- a/CUETools.AccurateRip/AccurateRip.cs
+++ b/CUETools.AccurateRip/AccurateRip.cs
@@ -30,8 +30,9 @@ namespace CUETools.AccurateRip
return 0U;
uint conf = 0;
for (int di = 0; di < (int)AccDisks.Count; di++)
- if (CRC(iTrack) == AccDisks[di].tracks[iTrack].CRC)
- conf += AccDisks[di].tracks[iTrack].count;
+ if (iTrack + _toc.FirstAudio - 1 < AccDisks[di].tracks.Count
+ && CRC(iTrack) == AccDisks[di].tracks[iTrack + _toc.FirstAudio - 1].CRC)
+ conf += AccDisks[di].tracks[iTrack + _toc.FirstAudio - 1].count;
return conf;
}
@@ -66,8 +67,9 @@ namespace CUETools.AccurateRip
uint conf = 0;
for (int iDisk = 0; iDisk < AccDisks.Count; iDisk++)
for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++)
- if (CRC(iTrack, oi) == AccDisks[iDisk].tracks[iTrack].CRC)
- conf += AccDisks[iDisk].tracks[iTrack].count;
+ if (iTrack + _toc.FirstAudio - 1 < AccDisks[iDisk].tracks.Count
+ && CRC(iTrack, oi) == AccDisks[iDisk].tracks[iTrack + _toc.FirstAudio - 1].CRC)
+ conf += AccDisks[iDisk].tracks[iTrack + _toc.FirstAudio - 1].count;
return conf;
}
@@ -77,8 +79,9 @@ namespace CUETools.AccurateRip
return 0U;
uint conf = 0;
for (int di = 0; di < (int)AccDisks.Count; di++)
- if (CRC(iTrack, oi) == AccDisks[di].tracks[iTrack].CRC)
- conf += AccDisks[di].tracks[iTrack].count;
+ if (iTrack +_toc.FirstAudio - 1 < AccDisks[di].tracks.Count
+ && CRC(iTrack, oi) == AccDisks[di].tracks[iTrack + _toc.FirstAudio - 1].CRC)
+ conf += AccDisks[di].tracks[iTrack + _toc.FirstAudio - 1].count;
return conf;
}
@@ -88,13 +91,15 @@ namespace CUETools.AccurateRip
return 0U;
uint total = 0;
for (int di = 0; di < (int)AccDisks.Count; di++)
- total += AccDisks[di].tracks[iTrack].count;
+ if (iTrack + _toc.FirstAudio - 1 < AccDisks[di].tracks.Count)
+ total += AccDisks[di].tracks[iTrack + _toc.FirstAudio - 1].count;
return total;
}
public uint DBCRC(int iTrack)
{
- return ARStatus == null ? AccDisks[0].tracks[iTrack].CRC : 0U;
+ return ARStatus == null && iTrack +_toc.FirstAudio - 1 < AccDisks[0].tracks.Count
+ ? AccDisks[0].tracks[iTrack + _toc.FirstAudio - 1].CRC : 0U;
}
public uint CRC(int iTrack)
@@ -136,6 +141,20 @@ namespace CUETools.AccurateRip
return crcb - crca - offs * (sumb - suma);
}
+ public int PeakLevel()
+ {
+ int peak = 0;
+ for (int track = 0; track <= _toc.AudioTracks; track++)
+ if (peak < _Peak[track])
+ peak = _Peak[track];
+ return peak;
+ }
+
+ public int PeakLevel(int iTrack)
+ {
+ return _Peak[iTrack];
+ }
+
public uint CRC32(int iTrack)
{
return CRC32(iTrack, 0);
@@ -310,6 +329,7 @@ namespace CUETools.AccurateRip
uint crc32 = _CRC32[_currentTrack, 0];
uint crcwn = _CRCWN[_currentTrack, 0];
int crcnl = _CRCNL[_currentTrack, 0];
+ int peak = _Peak[_currentTrack];
fixed (uint* t = _crc32.table)
{
for (int i = 0; i < count; i++)
@@ -337,6 +357,9 @@ namespace CUETools.AccurateRip
}
else crcnl++;
+ int pk = ((int)(lo << 16)) >> 16;
+ peak = Math.Max(peak, (pk << 1) ^ (pk >> 31));
+
uint hi = sample >> 16;
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ hi)];
crc32 = (crc32 >> 8) ^ t[(byte)(crc32 ^ (hi >> 8))];
@@ -346,6 +369,9 @@ namespace CUETools.AccurateRip
crcwn = (crcwn >> 8) ^ t[(byte)(crcwn ^ (hi >> 8))];
}
else crcnl++;
+
+ pk = ((int)(hi << 16)) >> 16;
+ peak = Math.Max(peak, (pk << 1) ^ (pk >> 31));
}
}
@@ -354,6 +380,7 @@ namespace CUETools.AccurateRip
_CRC32[_currentTrack, 0] = crc32;
_CRCWN[_currentTrack, 0] = crcwn;
_CRCNL[_currentTrack, 0] = crcnl;
+ _Peak[_currentTrack] = peak;
}
public void Write(AudioBuffer sampleBuffer)
@@ -401,6 +428,7 @@ namespace CUETools.AccurateRip
_CRCWN = new uint[_toc.AudioTracks + 1, 31 * 588];
_CacheCRCWN = new uint[_toc.AudioTracks + 1, 31 * 588];
_CRCNL = new int[_toc.AudioTracks + 1, 31 * 588];
+ _Peak = new int[_toc.AudioTracks + 1];
_currentTrack = 0;
_sampleCount = _toc[_toc.FirstAudio][0].Start * 588;
_samplesRemTrack = _toc[_toc.FirstAudio].Pregap * 588;
@@ -572,11 +600,16 @@ namespace CUETools.AccurateRip
uint conf = 0;
for (int di = 0; di < (int)AccDisks.Count; di++)
{
- count += AccDisks[di].tracks[iTrack].count;
- if (CRC(iTrack, oi) == AccDisks[di].tracks[iTrack].CRC)
- conf += AccDisks[di].tracks[iTrack].count;
- if (CRC450(iTrack, oi) == AccDisks[di].tracks[iTrack].Frame450CRC)
- partials += AccDisks[di].tracks[iTrack].count;
+ int trno = iTrack + _toc.FirstAudio - 1;
+ if (trno >= AccDisks[di].tracks.Count)
+ continue;
+ count += AccDisks[di].tracks[trno].count;
+ if (CRC(iTrack, oi) == AccDisks[di].tracks[trno].CRC
+ && 0 != AccDisks[di].tracks[trno].CRC)
+ conf += AccDisks[di].tracks[trno].count;
+ if (CRC450(iTrack, oi) == AccDisks[di].tracks[trno].Frame450CRC
+ && 0 != AccDisks[di].tracks[trno].Frame450CRC)
+ partials += AccDisks[di].tracks[trno].count;
}
if (conf > 0)
sw.WriteLine(String.Format(" {0:00}\t[{1:x8}] ({3:00}/{2:00}) Accurately ripped", iTrack + 1, CRC(iTrack, oi), count, conf));
@@ -612,12 +645,17 @@ namespace CUETools.AccurateRip
{
uint matches = 0;
for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++)
+ {
+ int trno = iTrack + _toc.FirstAudio - 1;
for (int di = 0; di < (int)AccDisks.Count; di++)
- if ((CRC(iTrack, oi) == AccDisks[di].tracks[iTrack].CRC && AccDisks[di].tracks[iTrack].CRC != 0))
+ if (trno < AccDisks[di].tracks.Count
+ && (CRC(iTrack, oi) == AccDisks[di].tracks[trno].CRC
+ && AccDisks[di].tracks[trno].CRC != 0))
{
matches++;
break;
}
+ }
if (matches == _toc.AudioTracks && oi != 0)
{
if (offsets_match++ > 16)
@@ -636,12 +674,17 @@ namespace CUETools.AccurateRip
for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++)
for (int di = 0; di < (int)AccDisks.Count; di++)
{
- if ((CRC(iTrack, oi) == AccDisks[di].tracks[iTrack].CRC && AccDisks[di].tracks[iTrack].CRC != 0))
+ int trno = iTrack + _toc.FirstAudio - 1;
+ if (trno < AccDisks[di].tracks.Count
+ && (CRC(iTrack, oi) == AccDisks[di].tracks[trno].CRC
+ && AccDisks[di].tracks[trno].CRC != 0))
{
matches++;
break;
}
- if ((CRC450(iTrack, oi) == AccDisks[di].tracks[iTrack].Frame450CRC && AccDisks[di].tracks[iTrack].Frame450CRC != 0))
+ if (trno < AccDisks[di].tracks.Count
+ && (CRC450(iTrack, oi) == AccDisks[di].tracks[trno].Frame450CRC
+ && AccDisks[di].tracks[trno].Frame450CRC != 0))
partials++;
}
if (matches != _toc.AudioTracks && oi != 0 && matches + partials != 0)
@@ -668,12 +711,15 @@ namespace CUETools.AccurateRip
for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++)
for (int iDisk = 0; iDisk < AccDisks.Count; iDisk++)
{
- if (CRC(iTrack, oi) == AccDisks[iDisk].tracks[iTrack].CRC && (AccDisks[iDisk].tracks[iTrack].CRC != 0 || oi == 0))
+ int trno = iTrack + _toc.FirstAudio - 1;
+ if (trno < AccDisks[iDisk].tracks.Count
+ && CRC(iTrack, oi) == AccDisks[iDisk].tracks[trno].CRC
+ && (AccDisks[iDisk].tracks[trno].CRC != 0 || oi == 0))
{
- conf += AccDisks[iDisk].tracks[iTrack].count;
+ conf += AccDisks[iDisk].tracks[trno].count;
if (oi == 0)
zeroOffset = true;
- pressings.AppendFormat("{0}{1}({2})", pressings.Length > 0 ? "," : "", oi, AccDisks[iDisk].tracks[iTrack].count);
+ pressings.AppendFormat("{0}{1}({2})", pressings.Length > 0 ? "," : "", oi, AccDisks[iDisk].tracks[trno].count);
}
}
if (conf > 0 && zeroOffset && pressings.Length == 0)
@@ -692,7 +738,7 @@ namespace CUETools.AccurateRip
if (CRC32(0) != 0 && (_hasLogCRC || verbose))
{
sw.WriteLine("");
- sw.WriteLine("Track\t[ CRC32 ]\t[W/O NULL]\t{0:10}", _hasLogCRC ? "[ LOG ]" : "");
+ sw.WriteLine("Track Peak [ CRC32 ] [W/O NULL] {0:10}", _hasLogCRC ? "[ LOG ]" : "");
for (int iTrack = 0; iTrack <= _toc.AudioTracks; iTrack++)
{
string inLog, extra = "";
@@ -740,7 +786,13 @@ namespace CUETools.AccurateRip
}
}
}
- sw.WriteLine(String.Format(" {0}\t[{1:X8}]\t[{2:X8}]\t{3:10}{4}", iTrack == 0 ? "--" : string.Format("{0:00}", iTrack), CRC32(iTrack), CRCWONULL(iTrack), inLog, extra));
+ sw.WriteLine(" {0} {5,5:F1} [{1:X8}] [{2:X8}] {3,10}{4}",
+ iTrack == 0 ? "--" : string.Format("{0:00}", iTrack),
+ CRC32(iTrack),
+ CRCWONULL(iTrack),
+ inLog,
+ extra,
+ ((iTrack == 0 ? PeakLevel() : PeakLevel(iTrack)) * 1000 / 65535) * 0.1);
}
}
}
@@ -897,6 +949,7 @@ namespace CUETools.AccurateRip
private int[,] _CRCNL;
private uint[,] _CacheCRCWN;
private uint[,] _CacheCRC32;
+ private int[] _Peak;
private uint[] _CRCLOG;
private IWebProxy proxy;
diff --git a/CUETools.AccurateRip/CUETools.AccurateRip.csproj b/CUETools.AccurateRip/CUETools.AccurateRip.csproj
index 2dac3ef..3e7f423 100644
--- a/CUETools.AccurateRip/CUETools.AccurateRip.csproj
+++ b/CUETools.AccurateRip/CUETools.AccurateRip.csproj
@@ -14,6 +14,9 @@
2.0
+ false
+
+
true
diff --git a/CUETools.AccurateRip/Properties/AssemblyInfo.cs b/CUETools.AccurateRip/Properties/AssemblyInfo.cs
index 4274380..9ba5ffe 100644
--- a/CUETools.AccurateRip/Properties/AssemblyInfo.cs
+++ b/CUETools.AccurateRip/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.CDImage/CDImage.cs b/CUETools.CDImage/CDImage.cs
index 141e31d..f0fda06 100644
--- a/CUETools.CDImage/CDImage.cs
+++ b/CUETools.CDImage/CDImage.cs
@@ -253,6 +253,26 @@ namespace CUETools.CDImage
_tracks.Add(new CDTrack(src._tracks[i]));
}
+ public CDImageLayout(int trackcount, int audiotracks, int firstaudio, string trackoffsets)
+ {
+ _audioTracks = audiotracks;
+ _firstAudio = firstaudio - 1;
+ _tracks = new List();
+ string[] n = trackoffsets.Split(' ');
+ if (n.Length != trackcount + 1)
+ throw new Exception("Invalid trackoffsets.");
+ for (int i = 0; i < trackcount; i++)
+ {
+ uint len = uint.Parse(n[i + 1]) - uint.Parse(n[i]) -
+ ((i + 1 < _firstAudio + _audioTracks || i + 1 == trackcount) ? 0U : 152U * 75U);
+ bool isaudio = i >= _firstAudio && i < _firstAudio + _audioTracks;
+ _tracks.Add(new CDTrack((uint)i + 1, uint.Parse(n[i]), len, isaudio, false));
+ }
+ _tracks[0][0].Start = 0;
+ if (TrackOffsets != trackoffsets)
+ throw new Exception("TrackOffsets != trackoffsets");
+ }
+
public object Clone()
{
return new CDImageLayout(this);
@@ -306,6 +326,14 @@ namespace CUETools.CDImage
}
}
+ public uint Leadout
+ {
+ get
+ {
+ return _tracks[_firstAudio][0].Start + AudioLength;
+ }
+ }
+
public uint AudioLength
{
get
@@ -326,20 +354,69 @@ namespace CUETools.CDImage
}
}
+ public string MusicBrainzTOC
+ {
+ get
+ {
+ StringBuilder mbSB = new StringBuilder();
+ mbSB.AppendFormat("{0} {1}", 1 + _firstAudio, AudioTracks + _firstAudio);
+ mbSB.AppendFormat(" {0}", _tracks[_firstAudio + (int)AudioTracks - 1].End + 1 + 150);
+ for (int iTrack = 0; iTrack < AudioTracks; iTrack++)
+ mbSB.AppendFormat(" {0}", _tracks[_firstAudio + iTrack].Start + 150);
+ return mbSB.ToString();
+ }
+ }
+
public string MusicBrainzId
{
get
{
StringBuilder mbSB = new StringBuilder();
- mbSB.AppendFormat("{0:X2}{1:X2}{2:X8}", 1, AudioTracks, _tracks[(int)AudioTracks-1].End + 1 + 150);
+ mbSB.AppendFormat("{0:X2}{1:X2}", 1 + _firstAudio, AudioTracks + _firstAudio);
+ mbSB.AppendFormat("{0:X8}", _tracks[_firstAudio + (int)AudioTracks - 1].End + 1 + 150);
for (int iTrack = 0; iTrack < AudioTracks; iTrack++)
- mbSB.AppendFormat("{0:X8}", _tracks[iTrack].Start + 150);
+ mbSB.AppendFormat("{0:X8}", _tracks[_firstAudio + iTrack].Start + 150);
mbSB.Append(new string('0', (99 - (int)AudioTracks) * 8));
byte[] hashBytes = (new SHA1CryptoServiceProvider()).ComputeHash(Encoding.ASCII.GetBytes(mbSB.ToString()));
return Convert.ToBase64String(hashBytes).Replace('+', '.').Replace('/', '_').Replace('=', '-');
}
}
+ public string TrackOffsets
+ {
+ get
+ {
+ StringBuilder mbSB = new StringBuilder();
+ for (int iTrack = 0; iTrack < TrackCount; iTrack++)
+ mbSB.AppendFormat("{0} ", _tracks[iTrack].Start);
+ mbSB.AppendFormat("{0}", Length);
+ return mbSB.ToString();
+ }
+ }
+
+ public string TOCID
+ {
+ get
+ {
+ StringBuilder mbSB = new StringBuilder();
+ for (int iTrack = 1; iTrack < AudioTracks; iTrack++)
+ mbSB.AppendFormat("{0:X8}", _tracks[_firstAudio + iTrack].Start - _tracks[_firstAudio].Start);
+ mbSB.AppendFormat("{0:X8}", _tracks[_firstAudio + (int)AudioTracks - 1].End + 1 - _tracks[_firstAudio].Start);
+ mbSB.Append(new string('0', (100 - (int)AudioTracks) * 8));
+ byte[] hashBytes = (new SHA1CryptoServiceProvider()).ComputeHash(Encoding.ASCII.GetBytes(mbSB.ToString()));
+ return Convert.ToBase64String(hashBytes).Replace('+', '.').Replace('/', '_').Replace('=', '-');
+ }
+ }
+
+ public void InsertTrack(CDTrack track)
+ {
+ _tracks.Insert((int)track.Number - 1, track);
+ if (track.IsAudio)
+ _audioTracks++;
+ if (!track.IsAudio && track.Number <= FirstAudio)
+ _firstAudio++;
+ }
+
public void AddTrack(CDTrack track)
{
_tracks.Add(track);
diff --git a/CUETools.CDImage/CUETools.CDImage.csproj b/CUETools.CDImage/CUETools.CDImage.csproj
index 684d025..68bb0f3 100644
--- a/CUETools.CDImage/CUETools.CDImage.csproj
+++ b/CUETools.CDImage/CUETools.CDImage.csproj
@@ -14,6 +14,9 @@
2.0
+ false
+
+
true
diff --git a/CUETools.CDImage/Properties/AssemblyInfo.cs b/CUETools.CDImage/Properties/AssemblyInfo.cs
index 07c6c27..b6d33e0 100644
--- a/CUETools.CDImage/Properties/AssemblyInfo.cs
+++ b/CUETools.CDImage/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.CDRepair/CDRepair.cs b/CUETools.CDRepair/CDRepair.cs
index 3759897..ed9300a 100644
--- a/CUETools.CDRepair/CDRepair.cs
+++ b/CUETools.CDRepair/CDRepair.cs
@@ -325,10 +325,13 @@ namespace CUETools.CDRepair
new public unsafe void Write(AudioBuffer sampleBuffer)
{
+ if (!verify && !encode)
+ return;
+
sampleBuffer.Prepare(this);
- if ((sampleBuffer.ByteLength & 1) != 0)
- throw new Exception("never happens");
+ if ((sampleBuffer.ByteLength & 1) != 0 || sampleCount + sampleBuffer.Length > finalSampleCount)
+ throw new Exception("sampleCount > finalSampleCount");
fixed (byte* bytes = sampleBuffer.Bytes)
{
diff --git a/CUETools.CTDB/CUEToolsDB.cs b/CUETools.CTDB/CUEToolsDB.cs
index ccbb0fb..c1fb2f7 100644
--- a/CUETools.CTDB/CUEToolsDB.cs
+++ b/CUETools.CTDB/CUEToolsDB.cs
@@ -5,6 +5,7 @@ using System.Globalization;
using System.IO;
using System.Management;
using System.Net;
+using System.Xml;
using System.Text;
using CUETools.CDImage;
using CUETools.CDRepair;
@@ -20,11 +21,7 @@ namespace CUETools.CTDB
private CDRepairEncode verify;
private CDImageLayout toc;
private HttpStatusCode accResult;
- private string id;
- private string urlfolder;
- private string fullid;
private string subResult;
- private byte[] contents;
private int length;
private int total;
List entries = new List();
@@ -40,27 +37,86 @@ namespace CUETools.CTDB
this.uploadHelper = new HttpUploadHelper();
}
- public void ContactDB(string id, string userAgent)
+ public void ContactDB(string userAgent)
{
this.userAgent = userAgent;
- this.id = id;
+ this.total = 0;
- // Calculate the three disc ids used by AR
- uint discId1 = 0;
- uint discId2 = 0;
- uint cddbDiscId = 0;
+ HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlbase + "/lookup.php?tocid=" + toc.TOCID);
+ req.Method = "GET";
+ req.Proxy = proxy;
+ req.UserAgent = userAgent;
- string[] n = id.Split('-');
- if (n.Length != 3)
- throw new Exception("Invalid accurateRipId.");
- discId1 = UInt32.Parse(n[0], NumberStyles.HexNumber);
- discId2 = UInt32.Parse(n[1], NumberStyles.HexNumber);
- cddbDiscId = UInt32.Parse(n[2], NumberStyles.HexNumber);
+ if (uploadHelper.onProgress != null)
+ uploadHelper.onProgress(this, new UploadProgressEventArgs(req.RequestUri.AbsoluteUri, 0));
- fullid = string.Format("{0:d3}-{1:x8}-{2:x8}-{3:x8}", toc.AudioTracks, discId1, discId2, cddbDiscId);
- urlfolder = string.Format("{0}/parity/{1:x}/{2:x}/{3:x}/{4}", urlbase, discId1 & 0xF, discId1 >> 4 & 0xF, discId1 >> 8 & 0xF, fullid);
-
- FetchDB(string.Format("{0}/ctdb.bin", urlfolder), out accResult, out contents, out total, entries);
+ try
+ {
+ HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
+ accResult = resp.StatusCode;
+
+ if (accResult == HttpStatusCode.OK)
+ {
+ total = 0;
+ using (Stream responseStream = resp.GetResponseStream())
+ {
+ using (XmlTextReader reader = new XmlTextReader(responseStream))
+ {
+ reader.ReadToFollowing("ctdb");
+ if (reader.ReadToDescendant("entry"))
+ do
+ {
+ XmlReader entry = reader.ReadSubtree();
+ string crc32 = reader["crc32"];
+ string confidence = reader["confidence"];
+ string npar = reader["npar"];
+ string stride = reader["stride"];
+ string id = reader["id"];
+ byte[] parity = null;
+ CDImageLayout entry_toc = null;
+
+ entry.Read();
+ while (entry.Read() && entry.NodeType != XmlNodeType.EndElement)
+ {
+ if (entry.Name == "parity")
+ {
+ entry.Read(); // entry.NodeType == XmlNodeType.Text
+ parity = Convert.FromBase64String(entry.Value);
+ entry.Read();
+ }
+ else if (entry.Name == "toc")
+ {
+ string trackcount = entry["trackcount"];
+ string audiotracks = entry["audiotracks"];
+ string firstaudio = entry["firstaudio"];
+ entry.Read();
+ string trackoffsets = entry.Value;
+ entry.Read();
+ entry_toc = new CDImageLayout(int.Parse(trackcount), int.Parse(audiotracks), int.Parse(firstaudio), trackoffsets);
+ }
+ else
+ {
+ reader.Skip();
+ }
+ }
+ entry.Close();
+ total += int.Parse(confidence);
+ entries.Add(new DBEntry(parity, 0, parity.Length, int.Parse(confidence), int.Parse(npar), uint.Parse(crc32, NumberStyles.HexNumber), id, entry_toc));
+ } while (reader.ReadToNextSibling("entry"));
+ reader.Close();
+ }
+ }
+ if (entries.Count == 0)
+ accResult = HttpStatusCode.NotFound;
+ }
+ }
+ catch (WebException ex)
+ {
+ if (ex.Status == WebExceptionStatus.ProtocolError)
+ accResult = ((HttpWebResponse)ex.Response).StatusCode;
+ else
+ accResult = HttpStatusCode.BadRequest;
+ }
}
public void FetchDB(string url, out HttpStatusCode accResult, out byte[] contents, out int total, List entries)
@@ -110,45 +166,52 @@ namespace CUETools.CTDB
}
}
- static string cpuInfo = null;
+ static string uuidInfo = null;
- public static string GetCPUID()
+ public static string GetUUID()
{
- if (cpuInfo == null)
+ if (uuidInfo == null)
{
- ManagementClass mc = new ManagementClass("win32_processor");
+ ManagementClass mc = new ManagementClass("Win32_ComputerSystemProduct");
foreach (ManagementObject mo in mc.GetInstances())
{
- //Get only the first CPU's ID
- cpuInfo = mo.Properties["processorID"].Value.ToString();
+ uuidInfo = mo.Properties["UUID"].Value.ToString();
break;
}
}
- return cpuInfo ?? "unknown";
+ return uuidInfo ?? "unknown";
}
public string Confirm(DBEntry entry)
{
- if (fullid == null)
- throw new Exception("no id");
- HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlbase + "/confirm.php");
+ HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlbase + "/confirm.php?tocid=" + toc.TOCID + "&id=" + entry.id);
+ req.Method = "GET";
req.Proxy = proxy;
req.UserAgent = userAgent;
- NameValueCollection form = new NameValueCollection();
- form.Add("id", fullid);
- form.Add("ctdbid", string.Format("{0:x8}", entry.crc));
- HttpWebResponse resp = uploadHelper.Upload(req, new UploadFile[0], form);
- using (Stream s = resp.GetResponseStream())
- using (StreamReader sr = new StreamReader(s))
- subResult = sr.ReadToEnd();
+ try
+ {
+ HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
+ if (resp.StatusCode != HttpStatusCode.OK)
+ subResult = resp.StatusCode.ToString();
+ else
+ {
+ using (Stream s = resp.GetResponseStream())
+ using (StreamReader sr = new StreamReader(s))
+ subResult = sr.ReadToEnd();
+ }
+ }
+ catch (WebException ex)
+ {
+ if (ex.Status == WebExceptionStatus.ProtocolError)
+ subResult = ((HttpWebResponse)ex.Response).StatusCode.ToString();
+ else
+ subResult = "unknown error";
+ }
return subResult;
}
public string Submit(int confidence, int total, string artist, string title)
{
- if (fullid == null)
- throw new Exception("no id");
-
UploadFile[] files = new UploadFile[1];
MemoryStream newcontents = new MemoryStream();
using (DBHDR FTYP = new DBHDR(newcontents, "ftyp"))
@@ -179,7 +242,7 @@ namespace CUETools.CTDB
}
if (artist != null && artist != "") using (DBHDR TAG = DISC.HDR("ART ")) TAG.Write(artist);
if (title != null && title != "") using (DBHDR TAG = DISC.HDR("nam ")) TAG.Write(title);
- using (DBHDR USER = DISC.HDR("USER")) USER.Write(GetCPUID());
+ using (DBHDR USER = DISC.HDR("USER")) USER.Write(GetUUID());
using (DBHDR TOOL = DISC.HDR("TOOL")) TOOL.Write(userAgent);
using (DBHDR TOOL = DISC.HDR("MBID")) TOOL.Write(toc.MusicBrainzId);
using (DBHDR DATE = DISC.HDR("DATE")) DATE.Write(DateTime.Now);
@@ -195,7 +258,18 @@ namespace CUETools.CTDB
req.Proxy = proxy;
req.UserAgent = userAgent;
NameValueCollection form = new NameValueCollection();
- form.Add("id", fullid);
+ form.Add("tocid", toc.TOCID);
+ form.Add("crc32", string.Format("%08X", verify.CRC));
+ form.Add("parity", Convert.ToBase64String(verify.Parity, 0, 16));
+ form.Add("confidence", confidence.ToString());
+ form.Add("trackcount", toc.TrackCount.ToString());
+ form.Add("firstaudio", toc.FirstAudio.ToString());
+ form.Add("audiotracks", toc.AudioTracks.ToString());
+ form.Add("trackoffsets", toc.TrackOffsets);
+ form.Add("userid", GetUUID());
+ form.Add("agent", userAgent);
+ if (artist != null && artist != "") form.Add("artist", artist);
+ if (title != null && title != "") form.Add("title", title);
HttpWebResponse resp = uploadHelper.Upload(req, files, form);
using (Stream s = resp.GetResponseStream())
using (StreamReader sr = new StreamReader(s))
@@ -257,7 +331,7 @@ namespace CUETools.CTDB
}
if (parPos != 0 && npar >= 2 && npar <= 16 && conf >= 0)
//if (parPos != 0 && npar >= 2 && npar <= 16 && conf != 0)
- entries.Add(new DBEntry(parPos, parLen, conf, npar, crc));
+ entries.Add(new DBEntry(contents, parPos, parLen, conf, npar, crc, null, null));
}
}
@@ -265,14 +339,20 @@ namespace CUETools.CTDB
{
foreach (DBEntry entry in entries)
{
- if (!verify.FindOffset(entry.npar, contents, entry.pos, entry.crc, out entry.offset, out entry.hasErrors))
+ if (entry.toc.Pregap != toc.Pregap || entry.toc.AudioLength != toc.AudioLength)
+ {
+ entry.hasErrors = false;
+ entry.canRecover = false;
+ continue;
+ }
+ if (!verify.FindOffset(entry.npar, entry.parity, entry.pos, entry.crc, out entry.offset, out entry.hasErrors))
entry.canRecover = false;
else if (entry.hasErrors)
{
byte[] contents2;
int total2;
List entries2 = new List();
- FetchDB(string.Format("{0}/{1:x8}.bin", urlfolder, entry.crc), out entry.httpStatus, out contents2, out total2, entries2);
+ FetchDB(string.Format("{0}/repair.php?tocid={1}&id={2}", urlbase, toc.TOCID, entry.id), out entry.httpStatus, out contents2, out total2, entries2);
if (entry.httpStatus != HttpStatusCode.OK)
entry.canRecover = false;
else
@@ -358,13 +438,13 @@ namespace CUETools.CTDB
{
DBEntry popular = null;
foreach (DBEntry entry in entries)
- if (!entry.hasErrors || entry.canRecover)
+ if (entry.toc.Pregap == toc.Pregap && (!entry.hasErrors || entry.canRecover))
if (popular == null || entry.conf > popular.conf)
popular = entry;
if (popular != null)
res = popular.Status;
foreach (DBEntry entry in entries)
- if (entry != popular && (!entry.hasErrors || entry.canRecover))
+ if (entry != popular && entry.toc.Pregap == toc.Pregap && (!entry.hasErrors || entry.canRecover))
res += ", or " + entry.Status;
if (res == null)
res = "could not be verified";
@@ -394,6 +474,7 @@ namespace CUETools.CTDB
public class DBEntry
{
+ public byte[] parity;
public int pos;
public int len;
public int conf;
@@ -404,14 +485,19 @@ namespace CUETools.CTDB
public bool canRecover;
public CDRepairFix repair;
public HttpStatusCode httpStatus;
+ public string id;
+ public CDImageLayout toc;
- public DBEntry(int pos, int len, int conf, int npar, uint crc)
+ public DBEntry(byte[] parity, int pos, int len, int conf, int npar, uint crc, string id, CDImageLayout toc)
{
+ this.parity = parity;
+ this.id = id;
this.pos = pos;
this.len = len;
this.conf = conf;
this.crc = crc;
this.npar = npar;
+ this.toc = toc;
}
public string Status
diff --git a/CUETools.Codecs.ALAC/Properties/AssemblyInfo.cs b/CUETools.Codecs.ALAC/Properties/AssemblyInfo.cs
index 2a267ef..8bddce4 100644
--- a/CUETools.Codecs.ALAC/Properties/AssemblyInfo.cs
+++ b/CUETools.Codecs.ALAC/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp b/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp
index 729fe67..98bca0b 100644
--- a/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp
+++ b/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp
@@ -95,12 +95,12 @@ namespace CUETools { namespace Codecs { namespace FLAC {
_decoder = FLAC__stream_decoder_new();
if (!FLAC__stream_decoder_set_metadata_respond (_decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
- throw gcnew Exception("Unable to setup the decoder.");
+ throw gcnew Exception("unable to setup the decoder");
//if (!FLAC__stream_decoder_set_disable_asm(_decoder, disableAsm))
- // throw gcnew Exception("Unable to setup the decoder.");
+ // throw gcnew Exception("unable to setup the decoder");
- if (FLAC__stream_decoder_init_stream(_decoder,
+ FLAC__StreamDecoderInitStatus st = FLAC__stream_decoder_init_stream(_decoder,
(FLAC__StreamDecoderReadCallback)Marshal::GetFunctionPointerForDelegate(_readDel).ToPointer(),
_IO->CanSeek?(FLAC__StreamDecoderSeekCallback)Marshal::GetFunctionPointerForDelegate(_seekDel).ToPointer():NULL,
_IO->CanSeek?(FLAC__StreamDecoderTellCallback)Marshal::GetFunctionPointerForDelegate(_tellDel).ToPointer():NULL,
@@ -109,17 +109,15 @@ namespace CUETools { namespace Codecs { namespace FLAC {
(FLAC__StreamDecoderWriteCallback)Marshal::GetFunctionPointerForDelegate(_writeDel).ToPointer(),
(FLAC__StreamDecoderMetadataCallback)Marshal::GetFunctionPointerForDelegate(_metadataDel).ToPointer(),
(FLAC__StreamDecoderErrorCallback)Marshal::GetFunctionPointerForDelegate(_errorDel).ToPointer(),
- NULL) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
- {
- throw gcnew Exception("Unable to initialize the decoder.");
- }
+ NULL);
+
+ if (st != FLAC__STREAM_DECODER_INIT_STATUS_OK)
+ throw gcnew Exception(String::Format("unable to initialize the decoder: {0}", gcnew String(FLAC__StreamDecoderInitStatusString[st])));
_decoderActive = true;
- if (!FLAC__stream_decoder_process_until_end_of_metadata(_decoder)) {
- throw gcnew Exception("Unable to retrieve metadata.");
- }
-
+ if (!FLAC__stream_decoder_process_until_end_of_metadata(_decoder))
+ throw gcnew Exception("unable to retrieve metadata");
}
~FLACReader ()
@@ -149,9 +147,8 @@ namespace CUETools { namespace Codecs { namespace FLAC {
_sampleOffset = offset;
_bufferOffset = 0;
_bufferLength = 0;
- if (!FLAC__stream_decoder_seek_absolute(_decoder, offset)) {
- throw gcnew Exception("Unable to seek.");
- }
+ if (!FLAC__stream_decoder_seek_absolute(_decoder, offset))
+ throw gcnew Exception("unable to seek");
}
}
@@ -263,7 +260,10 @@ namespace CUETools { namespace Codecs { namespace FLAC {
if (FLAC__stream_decoder_get_state(_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
return buff->Length - samplesNeeded;
if (!FLAC__stream_decoder_process_single(_decoder))
- throw gcnew Exception("An error occurred while decoding.");
+ {
+ String^ state = gcnew String(FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(_decoder)]);
+ throw gcnew Exception(String::Format("an error occurred while decoding: {0}", state));
+ }
} while (_bufferLength == 0);
_sampleOffset += _bufferLength;
}
@@ -307,19 +307,16 @@ namespace CUETools { namespace Codecs { namespace FLAC {
{
Int32 sampleCount = frame->header.blocksize;
- if (_bufferLength > 0) {
- throw gcnew Exception("Received unrequested samples.");
- }
+ if (_bufferLength > 0)
+ throw gcnew Exception("received unrequested samples");
if ((frame->header.bits_per_sample != pcm->BitsPerSample) ||
(frame->header.channels != pcm->ChannelCount) ||
(frame->header.sample_rate != pcm->SampleRate))
- {
- throw gcnew Exception("Format changes within a file are not allowed.");
- }
+ throw gcnew Exception("format changes within a file are not allowed");
if (_bufferOffset != 0)
- throw gcnew Exception("Internal buffer error.");
+ throw gcnew Exception("internal buffer error");
if (_sampleBuffer == nullptr || _sampleBuffer->Size < sampleCount)
_sampleBuffer = gcnew AudioBuffer(pcm, sampleCount);
@@ -382,13 +379,13 @@ namespace CUETools { namespace Codecs { namespace FLAC {
{
switch (status) {
case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
- throw gcnew Exception("Synchronization was lost.");
+ throw gcnew Exception("synchronization was lost");
case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
- throw gcnew Exception("Encountered a corrupted frame header.");
+ throw gcnew Exception("encountered a corrupted frame header");
case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
- throw gcnew Exception("Frame CRC mismatch.");
+ throw gcnew Exception("frame CRC mismatch");
default:
- throw gcnew Exception("An unknown error has occurred.");
+ throw gcnew Exception("an unknown error has occurred");
}
}
@@ -452,7 +449,7 @@ namespace CUETools { namespace Codecs { namespace FLAC {
_pcm = pcm;
if (_pcm->BitsPerSample < 16 || _pcm->BitsPerSample > 24)
- throw gcnew Exception("Bits per sample must be 16..24.");
+ throw gcnew Exception("bits per sample must be 16..24");
_initialized = false;
_disableAsm = false;
@@ -484,7 +481,7 @@ namespace CUETools { namespace Codecs { namespace FLAC {
FLAC__stream_encoder_delete(_encoder);
if ((_finalSampleCount != 0) && (_samplesWritten != _finalSampleCount))
- throw gcnew Exception("Samples written differs from the expected sample count.");
+ throw gcnew Exception("samples written differs from the expected sample count");
}
virtual void Delete()
@@ -498,12 +495,10 @@ namespace CUETools { namespace Codecs { namespace FLAC {
return _finalSampleCount;
}
void set(Int64 value) {
- if (value < 0) {
- throw gcnew Exception("Invalid final sample count.");
- }
- if (_initialized) {
- throw gcnew Exception("Final sample count cannot be changed after encoding begins.");
- }
+ if (value < 0)
+ throw gcnew Exception("invalid final sample count");
+ if (_initialized)
+ throw gcnew Exception("final sample count cannot be changed after encoding begins");
_finalSampleCount = value;
}
}
@@ -549,7 +544,7 @@ namespace CUETools { namespace Codecs { namespace FLAC {
FLAC__stream_encoder_get_verify_decoder_error_stats(_encoder, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
state = state + String::Format("({0:x} instead of {1:x} @{2:x})", got, expected, absolute_sample);
}
- throw gcnew Exception("An error occurred while encoding: " + state);
+ throw gcnew Exception("an error occurred while encoding: " + state);
}
_samplesWritten += sampleBuffer->Length;
@@ -560,9 +555,8 @@ namespace CUETools { namespace Codecs { namespace FLAC {
return _compressionLevel;
}
void set(Int32 value) {
- if ((value < 0) || (value > 8)) {
- throw gcnew Exception("Invalid compression level.");
- }
+ if ((value < 0) || (value > 8))
+ throw gcnew Exception("invalid compression level");
_compressionLevel = value;
}
}
@@ -590,7 +584,7 @@ namespace CUETools { namespace Codecs { namespace FLAC {
Verify = true;
continue;
}
- throw gcnew Exception(String::Format("Unsupported options: {0}", value));
+ throw gcnew Exception(String::Format("unsupported options: {0}", value));
}
}
}
@@ -618,9 +612,8 @@ namespace CUETools { namespace Codecs { namespace FLAC {
return _paddingLength;
}
void set(Int32 value) {
- if (value < 0) {
- throw gcnew Exception("Invalid padding length.");
- }
+ if (value < 0)
+ throw gcnew Exception("invalid padding length");
_paddingLength = value;
}
}
@@ -711,15 +704,19 @@ namespace CUETools { namespace Codecs { namespace FLAC {
FLAC__stream_encoder_set_blocksize(_encoder, (unsigned)_blockSize);
pathChars = Marshal::StringToHGlobalUni(_path);
- hFile = _wfopen((const wchar_t*)pathChars.ToPointer(), L"w+b");
+ errno_t err = _wfopen_s(&hFile, (const wchar_t*)pathChars.ToPointer(), L"w+b");
Marshal::FreeHGlobal(pathChars);
-
- if (FLAC__stream_encoder_init_FILE(_encoder, hFile, NULL, NULL) !=
- FLAC__STREAM_ENCODER_INIT_STATUS_OK)
+ if (err)
{
- throw gcnew Exception("Unable to initialize the encoder.");
+ wchar_t buffer[256];
+ _wcserror_s(buffer, err);
+ throw gcnew Exception(String::Format("unable to open output file {0}: {1}", _path, gcnew String(buffer)));
}
+ FLAC__StreamEncoderInitStatus st = FLAC__stream_encoder_init_FILE(_encoder, hFile, NULL, NULL);
+ if (st != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
+ throw gcnew Exception(String::Format("unable to initialize the encoder: {0}", gcnew String(FLAC__StreamEncoderInitStatusString[st])));
+
_initialized = true;
}
};
diff --git a/CUETools.Codecs.FLAKE/Properties/AssemblyInfo.cs b/CUETools.Codecs.FLAKE/Properties/AssemblyInfo.cs
index d884831..2fb0069 100644
--- a/CUETools.Codecs.FLAKE/Properties/AssemblyInfo.cs
+++ b/CUETools.Codecs.FLAKE/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Codecs.FlaCuda/Properties/AssemblyInfo.cs b/CUETools.Codecs.FlaCuda/Properties/AssemblyInfo.cs
index 1fde694..98f5901 100644
--- a/CUETools.Codecs.FlaCuda/Properties/AssemblyInfo.cs
+++ b/CUETools.Codecs.FlaCuda/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj b/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj
index 30c660c..37b7546 100644
--- a/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj
+++ b/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj
@@ -2,7 +2,7 @@
Debug
AnyCPU
- 8.0.50727
+ 9.0.30729
2.0
{8A0426FA-0BC2-4C49-A6E5-1F9A68156F19}
Library
@@ -14,6 +14,9 @@
2.0
+ false
+
+
true
diff --git a/CUETools.Codecs/CUETools.Codecs.csproj b/CUETools.Codecs/CUETools.Codecs.csproj
index 8fa1e6f..5d4b6ee 100644
--- a/CUETools.Codecs/CUETools.Codecs.csproj
+++ b/CUETools.Codecs/CUETools.Codecs.csproj
@@ -14,6 +14,9 @@
2.0
+ false
+
+
true
diff --git a/CUETools.Codecs/Codecs.cs b/CUETools.Codecs/Codecs.cs
index 00d5ee8..d849829 100644
--- a/CUETools.Codecs/Codecs.cs
+++ b/CUETools.Codecs/Codecs.cs
@@ -320,10 +320,20 @@ namespace CUETools.Codecs
length = Math.Min(size, _src.Length - _offset);
if (_length >= 0)
length = Math.Min(length, _length);
- dataInBytes = false;
- dataInSamples = true;
- fixed (int* dest = Samples, src = &_src.Samples[_offset, 0])
- AudioSamples.MemCpy(dest, src, Length * pcm.ChannelCount);
+ if (_src.dataInSamples)
+ {
+ dataInBytes = false;
+ dataInSamples = true;
+ fixed (int* dest = Samples, src = &_src.Samples[_offset, 0])
+ AudioSamples.MemCpy(dest, src, Length * pcm.ChannelCount);
+ }
+ else
+ {
+ dataInSamples = false;
+ dataInBytes = true;
+ fixed (byte* dest = Bytes, src = &_src.Bytes[_offset * pcm.BlockAlign])
+ AudioSamples.MemCpy(dest, src, length * pcm.BlockAlign);
+ }
}
public void Swap(AudioBuffer buffer)
@@ -1643,10 +1653,12 @@ namespace CUETools.Codecs
int _bufferPos = 0;
Exception _ex = null;
bool own;
+ ThreadPriority priority;
- public AudioPipe(IAudioSource source, int size, bool own)
+ public AudioPipe(IAudioSource source, int size, bool own, ThreadPriority priority)
{
this.own = own;
+ this.priority = priority;
_source = source;
_readBuffer = new AudioBuffer(source, size);
_writeBuffer = new AudioBuffer(source, size);
@@ -1655,6 +1667,11 @@ namespace CUETools.Codecs
_samplePos = _source.Position;
}
+ public AudioPipe(IAudioSource source, int size)
+ : this(source, size, true, ThreadPriority.BelowNormal)
+ {
+ }
+
private void Decompress(object o)
{
#if !DEBUG
@@ -1695,7 +1712,7 @@ namespace CUETools.Codecs
{
if (_workThread != null || _ex != null) return;
_workThread = new Thread(Decompress);
- _workThread.Priority = ThreadPriority.BelowNormal;
+ _workThread.Priority = priority;
_workThread.IsBackground = true;
_workThread.Start(null);
}
diff --git a/CUETools.Codecs/Properties/AssemblyInfo.cs b/CUETools.Codecs/Properties/AssemblyInfo.cs
index b30d89e..5f5f062 100644
--- a/CUETools.Codecs/Properties/AssemblyInfo.cs
+++ b/CUETools.Codecs/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj b/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj
index c3a0cb2..322a552 100644
--- a/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj
+++ b/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj
@@ -2,7 +2,7 @@
Debug
AnyCPU
- 8.0.50727
+ 9.0.30729
2.0
{8427CAA5-80B8-4952-9A68-5F3DFCFBDF40}
Library
@@ -27,7 +27,7 @@
pdbonly
true
- ..\bin\Release\plugins\
+ ..\bin\Release\Plugins %28Win32%29\
TRACE
prompt
4
diff --git a/CUETools.Compression.Rar/Properties/AssemblyInfo.cs b/CUETools.Compression.Rar/Properties/AssemblyInfo.cs
index a36d93a..f25653e 100644
--- a/CUETools.Compression.Rar/Properties/AssemblyInfo.cs
+++ b/CUETools.Compression.Rar/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Compression.Zip/Properties/AssemblyInfo.cs b/CUETools.Compression.Zip/Properties/AssemblyInfo.cs
index 5727ecb..d608293 100644
--- a/CUETools.Compression.Zip/Properties/AssemblyInfo.cs
+++ b/CUETools.Compression.Zip/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Compression/Properties/AssemblyInfo.cs b/CUETools.Compression/Properties/AssemblyInfo.cs
index d878c03..0daf3b3 100644
--- a/CUETools.Compression/Properties/AssemblyInfo.cs
+++ b/CUETools.Compression/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.FlaCudaExe/Program.cs b/CUETools.FlaCudaExe/Program.cs
index 9295d46..c147f27 100644
--- a/CUETools.FlaCudaExe/Program.cs
+++ b/CUETools.FlaCudaExe/Program.cs
@@ -191,7 +191,7 @@ namespace CUETools.FlaCudaExe
return 2;
}
if (buffered)
- audioSource = new AudioPipe(audioSource, FlaCudaWriter.MAX_BLOCKSIZE, true);
+ audioSource = new AudioPipe(audioSource, FlaCudaWriter.MAX_BLOCKSIZE);
if (output_file == null)
output_file = Path.ChangeExtension(input_file, "flac");
FlaCudaWriter encoder = new FlaCudaWriter((output_file == "-" || output_file == "nul") ? "" : output_file,
diff --git a/CUETools.FlaCudaExe/Properties/AssemblyInfo.cs b/CUETools.FlaCudaExe/Properties/AssemblyInfo.cs
index f8fe4e8..153ecaa 100644
--- a/CUETools.FlaCudaExe/Properties/AssemblyInfo.cs
+++ b/CUETools.FlaCudaExe/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Flake/Program.cs b/CUETools.Flake/Program.cs
index 2403ada..fba04f2 100644
--- a/CUETools.Flake/Program.cs
+++ b/CUETools.Flake/Program.cs
@@ -173,7 +173,7 @@ namespace CUETools.FlakeExe
return;
}
if (buffered)
- audioSource = new AudioPipe(audioSource, 0x10000, true);
+ audioSource = new AudioPipe(audioSource, 0x10000);
if (output_file == null)
output_file = Path.ChangeExtension(input_file, "flac");
FlakeWriter flake = new FlakeWriter((output_file == "-" || output_file == "nul") ? "" : output_file,
diff --git a/CUETools.Processor/AudioReadWrite.cs b/CUETools.Processor/AudioReadWrite.cs
index c70cf99..c7744bc 100644
--- a/CUETools.Processor/AudioReadWrite.cs
+++ b/CUETools.Processor/AudioReadWrite.cs
@@ -31,11 +31,20 @@ namespace CUETools.Processor
return new UserDefinedReader(path, IO, decoder.path, decoder.parameters);
if (decoder.type == null)
throw new Exception("Unsupported audio type: " + path);
-
- object src = Activator.CreateInstance(decoder.type, path, IO);
- if (src == null || !(src is IAudioSource))
- throw new Exception("Unsupported audio type: " + path + ": " + decoder.type.FullName);
- return src as IAudioSource;
+
+ try
+ {
+ object src = Activator.CreateInstance(decoder.type, path, IO);
+ if (src == null || !(src is IAudioSource))
+ throw new Exception("Unsupported audio type: " + path + ": " + decoder.type.FullName);
+ return src as IAudioSource;
+ }
+ catch (System.Reflection.TargetInvocationException ex)
+ {
+ if (ex.InnerException == null)
+ throw ex;
+ throw ex.InnerException;
+ }
}
public static IAudioSource GetAudioSource(string path, Stream IO, CUEConfig config)
diff --git a/CUETools.Processor/CUETools.Processor.csproj b/CUETools.Processor/CUETools.Processor.csproj
index 2982abc..5ca1040 100644
--- a/CUETools.Processor/CUETools.Processor.csproj
+++ b/CUETools.Processor/CUETools.Processor.csproj
@@ -29,6 +29,9 @@
false
false
true
+ false
+
+
true
diff --git a/CUETools.Processor/Processor.cs b/CUETools.Processor/Processor.cs
index 7e2fffa..09ee443 100644
--- a/CUETools.Processor/Processor.cs
+++ b/CUETools.Processor/Processor.cs
@@ -814,10 +814,10 @@ namespace CUETools.Processor
//ActivationContext is null most of the time :(
string arch = Marshal.SizeOf(typeof(IntPtr)) == 8 ? "x64" : "Win32";
- string plugins_path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "plugins (" + arch + ")");
+ string plugins_path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Plugins (" + arch + ")");
if (Directory.Exists(plugins_path))
AddPluginDirectory(plugins_path);
- plugins_path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "plugins");
+ plugins_path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Plugins");
if (Directory.Exists(plugins_path))
AddPluginDirectory(plugins_path);
}
@@ -1671,15 +1671,14 @@ string status = processor.Go();
_tracks.Add(new TrackInfo());
}
_arVerify = new AccurateRipVerify(_toc, proxy);
- _CUEToolsDB = new CUEToolsDB(_toc, proxy);
- _CUEToolsDB.UploadHelper.onProgress += new EventHandler(UploadProgress);
_isCD = true;
SourceInfo cdInfo;
cdInfo.Path = _ripper.ARName;
cdInfo.Offset = 0;
cdInfo.Length = _toc.AudioLength * 588;
_sources.Add(cdInfo);
- _ripper.ReadProgress += new EventHandler(CDReadProgress);
+ // Causes memory leak, so had to disable!
+ //_ripper.ReadProgress += new EventHandler(CDReadProgress);
_padding += TrackCount * 200;
_padding += _config.embedLog ? 500 + TrackCount * 200 : 0;
}
@@ -1690,7 +1689,10 @@ string status = processor.Go();
_archive.Close();
_archive = null;
if (_ripper != null)
+ {
+ //_ripper.ReadProgress -= new EventHandler(CDReadProgress);
_ripper.Close();
+ }
_ripper = null;
}
@@ -1739,7 +1741,8 @@ string status = processor.Go();
public void FillFromMusicBrainz(MusicBrainz.Release release)
{
- Year = release.GetEvents().Count > 0 ? release.GetEvents()[0].Date.Substring(0, 4) : "";
+ string date = release.GetEvents().Count > 0 ? release.GetEvents()[0].Date : null;
+ Year = date == null ? "" : date.Substring(0, 4);
Artist = release.GetArtist();
Title = release.GetTitle();
// How to get Genre: http://mm.musicbrainz.org/ws/1/release/6fe1e218-2aee-49ac-94f0-7910ba2151df.html?type=xml&inc=tags
@@ -1760,7 +1763,7 @@ string status = processor.Go();
Title = cdEntry.Title;
for (int i = 0; i < _toc.AudioTracks; i++)
{
- Tracks[i].Title = cdEntry.Tracks[i].Title;
+ Tracks[i].Title = cdEntry.Tracks[i + _toc.FirstAudio - 1].Title;
Tracks[i].Artist = cdEntry.Artist;
}
}
@@ -1778,7 +1781,7 @@ string status = processor.Go();
m_freedb.UserName = "gchudov";
m_freedb.Hostname = "gmail.com";
m_freedb.ClientName = "CUETools";
- m_freedb.Version = "1.9.5";
+ m_freedb.Version = "2.0.6";
m_freedb.SetDefaultSiteAddress("freedb.org");
QueryResult queryResult;
@@ -1790,6 +1793,7 @@ string status = processor.Go();
code = m_freedb.Query(AccurateRipVerify.CalculateCDDBQuery(_toc), out queryResult, out coll);
if (code == FreedbHelper.ResponseCodes.CODE_200)
{
+ ShowProgress("Looking up album via Freedb... " + queryResult.Discid, 0.5, 0.0, null, null);
code = m_freedb.Read(queryResult, out cdEntry);
if (code == FreedbHelper.ResponseCodes.CODE_210)
Releases.Add(cdEntry);
@@ -1801,7 +1805,7 @@ string status = processor.Go();
int i = 0;
foreach (QueryResult qr in coll)
{
- ShowProgress("Looking up album via freedb...", 0.0, (++i + 0.0) / coll.Count, null, null);
+ ShowProgress("Looking up album via freedb... " + qr.Discid, 0.0, (++i + 0.0) / coll.Count, null, null);
CheckStop();
code = m_freedb.Read(qr, out cdEntry);
if (code == FreedbHelper.ResponseCodes.CODE_210)
@@ -2575,6 +2579,23 @@ string status = processor.Go();
DataTrackLength = tocFromLog[1].Length;
}
+ // use data track length from log
+ if (tocFromLog != null
+ && _toc.TrackCount == _toc.AudioTracks
+ && tocFromLog.TrackCount == tocFromLog.AudioTracks
+ && tocFromLog.TrackCount == _toc.TrackCount + 1)
+ {
+ bool matches = true;
+ for (int iTrack = 1; iTrack <= _toc.TrackCount; iTrack++)
+ if (tocFromLog[iTrack + 1].Length != _toc[iTrack].Length)
+ matches = false;
+ if (matches)
+ {
+ _toc.InsertTrack(new CDTrack(1, 0, 0, false, false));
+ DataTrackLength = tocFromLog[1].Length;
+ }
+ }
+
// use data track length range from cddbId
if (DataTrackLength == 0 && _cddbDiscIdTag != null)
{
@@ -2589,8 +2610,6 @@ string status = processor.Go();
}
_arVerify = new AccurateRipVerify(_toc, proxy);
- _CUEToolsDB = new CUEToolsDB(_toc, proxy);
- _CUEToolsDB.UploadHelper.onProgress += new EventHandler(UploadProgress);
if (_eacLog != null)
{
@@ -2639,7 +2658,9 @@ string status = processor.Go();
{
ShowProgress((string)"Contacting CUETools database...", 0, 0, null, null);
- _CUEToolsDB.ContactDB(_accurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(_toc), userAgent);
+ _CUEToolsDB = new CUEToolsDB(_toc, proxy);
+ _CUEToolsDB.UploadHelper.onProgress += new EventHandler(UploadProgress);
+ _CUEToolsDB.ContactDB(userAgent);
ShowProgress("", 0.0, 0.0, null, null);
_useCUEToolsDB = true;
@@ -3152,21 +3173,24 @@ string status = processor.Go();
uint sec_end = Math.Min(sec_start + 74, tr_start + len - 1);
bool fError = false;
for (uint iSector = sec_start; iSector <= sec_end; iSector++)
- if (_ripper.Errors[(int)iSector])
+ if (_ripper.Errors[(int)iSector - (int)_toc[_toc.FirstAudio][0].Start])
fError = true;
if (fError)
{
- uint end = iSecond;
+ uint end = tr_end - 1;
for (uint jSecond = iSecond + 1; jSecond < tr_end; jSecond++)
{
uint jsec_start = tr_start + jSecond * 75;
uint jsec_end = Math.Min(jsec_start + 74, tr_start + len - 1);
bool jfError = false;
for (uint jSector = jsec_start; jSector <= jsec_end; jSector++)
- if (_ripper.Errors[(int)jSector])
+ if (_ripper.Errors[(int)jSector - (int)_toc[_toc.FirstAudio][0].Start])
jfError = true;
- if (jfError)
- end = jSecond;
+ if (!jfError)
+ {
+ end = jSecond - 1;
+ break;
+ }
}
if (errCount == 0)
logWriter.WriteLine();
@@ -3180,7 +3204,7 @@ string status = processor.Go();
logWriter.WriteLine(" Suspicious position {0}", s1);
else
logWriter.WriteLine(" Suspicious position {0} - {1}", s1, s2);
- iSecond = end;
+ iSecond = end + 1;
}
}
return errCount > 0;
@@ -3219,7 +3243,9 @@ string status = processor.Go();
_ripper.EACName,
_ripper.CorrectionQuality > 0 ? "Secure" : "Burst",
_ripper.DriveOffset,
- (OutputStyle != CUEStyle.SingleFile && OutputStyle != CUEStyle.SingleFileWithCUE) ? "Gap handling : Appended to previous track\r\n" : "" );
+ (OutputStyle == CUEStyle.SingleFile || OutputStyle == CUEStyle.SingleFileWithCUE) ? "" :
+ "Gap handling : " +
+ (_ripper.GapsDetected ? "Appended to previous track\r\n" : "Not detected, thus appended to previous track\r\n"));
logWriter.WriteLine();
logWriter.WriteLine("TOC of the extracted CD");
@@ -3256,7 +3282,7 @@ string status = processor.Go();
wereErrors |= PrintErrors(logWriter, _toc[track + _toc.FirstAudio].Start, _toc[track + _toc.FirstAudio].Length);
logWriter.WriteLine();
- logWriter.WriteLine(" Peak level {0:F1} %", (Tracks[track].PeakLevel * 1000 / 32768) * 0.1);
+ logWriter.WriteLine(" Peak level {0:F1} %", (_arVerify.PeakLevel(track + 1) * 1000 / 65535) * 0.1);
logWriter.WriteLine(" Track quality 100.0 %");
logWriter.WriteLine(" Test CRC {0:X8}", _arVerify.CRC32(track + 1));
logWriter.WriteLine(" Copy CRC {0:X8}", _arVerify.CRC32(track + 1));
@@ -3287,11 +3313,7 @@ string status = processor.Go();
logWriter.WriteLine(" Filename {0}", Path.ChangeExtension(Path.GetFullPath(_destPaths[0]), ".wav"));
wereErrors = PrintErrors(logWriter, _toc[_toc.FirstAudio][0].Start, _toc.AudioLength);
logWriter.WriteLine();
- int PeakLevel = 0;
- for (int track = 0; track < TrackCount; track++)
- if (PeakLevel < Tracks[track].PeakLevel)
- PeakLevel = Tracks[track].PeakLevel;
- logWriter.WriteLine(" Peak level {0:F1} %", (PeakLevel * 1000 / 32768) * 0.1);
+ logWriter.WriteLine(" Peak level {0:F1} %", (_arVerify.PeakLevel() * 1000 / 65535) * 0.1);
logWriter.WriteLine(" Range quality 100.0 %");
logWriter.WriteLine(" Test CRC {0:X8}", _arVerify.CRC32(0));
logWriter.WriteLine(" Copy CRC {0:X8}", _arVerify.CRC32(0));
@@ -3363,7 +3385,7 @@ string status = processor.Go();
CreateExactAudioCopyLOG();
return;
}
- StringWriter logWriter = new StringWriter();
+ StringWriter logWriter = new StringWriter(CultureInfo.InvariantCulture);
logWriter.WriteLine("{0}", _ripper.RipperVersion);
logWriter.WriteLine("Extraction logfile from : {0}", DateTime.Now);
logWriter.WriteLine("Used drive : {0}", _ripper.ARName);
@@ -3525,8 +3547,9 @@ string status = processor.Go();
public void GenerateCTDBLog(TextWriter sw)
{
- if (_CUEToolsDB.DBStatus != null)
- sw.WriteLine("CUETools DB: {0}.", _CUEToolsDB.DBStatus);
+ sw.WriteLine("[CTDB TOCID: {0}] {1}.", _toc.TOCID, _CUEToolsDB.DBStatus ?? "found");
+ if (!_processed)
+ return;
if (_CUEToolsDB.SubStatus != null)
sw.WriteLine("CUETools DB: {0}.", _CUEToolsDB.SubStatus);
if (_CUEToolsDB.DBStatus == null)
@@ -3536,21 +3559,24 @@ string status = processor.Go();
string confFormat = (_CUEToolsDB.Total < 10) ? "{0:0}/{1:0}" :
(_CUEToolsDB.Total < 100) ? "{0:00}/{1:00}" : "{0:000}/{1:000}";
string conf = string.Format(confFormat, entry.conf, _CUEToolsDB.Total);
+ string dataTrackInfo = !entry.toc[entry.toc.TrackCount].IsAudio ? string.Format("Is an Enhanced CD, data track length {0}", entry.toc[entry.toc.TrackCount].LengthMSF) :
+ !entry.toc[1].IsAudio ? string.Format("Playstation type data track length {0}", entry.toc[1].LengthMSF) : "";
string status =
- (!entry.hasErrors) ? "Accurately ripped" :
- entry.canRecover ? string.Format("Contains {0} correctable errors", entry.repair.CorrectableErrors) :
- (entry.httpStatus == 0 || entry.httpStatus == HttpStatusCode.OK) ? "No match" :
- entry.httpStatus.ToString();
+ entry.toc.Pregap != _toc.Pregap ? string.Format("Has pregap length {0}", CDImageLayout.TimeToString(entry.toc.Pregap)) :
+ entry.toc.AudioLength != _toc.AudioLength ? string.Format("Has audio length {0}", CDImageLayout.TimeToString(entry.toc.AudioLength)) :
+ ((entry.toc.TrackOffsets != _toc.TrackOffsets) ? dataTrackInfo + ", " : "") +
+ ((!entry.hasErrors) ? "Accurately ripped" :
+ entry.canRecover ? string.Format("Differs in {0} samples", entry.repair.CorrectableErrors) :
+ (entry.httpStatus == 0 || entry.httpStatus == HttpStatusCode.OK) ? "No match" :
+ entry.httpStatus.ToString());
sw.WriteLine(" [{0:x8}] ({1}) {2}", entry.crc, conf, status);
}
}
public void GenerateAccurateRipLog(TextWriter sw)
{
- if (!_processed)
- throw new Exception("not processed");
sw.WriteLine("[Verification date: {0}]", DateTime.Now);
- sw.WriteLine("[Disc ID: {0}]", _accurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(_toc));
+ sw.WriteLine("[AccurateRip ID: {0}] {1}.", _accurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(_toc), _arVerify.ARStatus ?? "found");
if (PreGapLength != 0)
sw.WriteLine("Pregap length {0}.", PreGapLengthMSF);
if (!_toc[1].IsAudio)
@@ -3568,6 +3594,13 @@ string status = processor.Go();
sw.WriteLine("Truncated 4608 extra samples in some input files.");
if (_paddedToFrame)
sw.WriteLine("Padded some input files to a frame boundary.");
+
+ if (!_processed)
+ {
+ if (_useCUEToolsDB) GenerateCTDBLog(sw);
+ return;
+ }
+
if (hdcdDecoder != null && string.Format("{0:s}", hdcdDecoder) != "")
sw.WriteLine("HDCD: {0:f}", hdcdDecoder);
if (0 != _writeOffset)
@@ -3685,9 +3718,9 @@ string status = processor.Go();
bool htoaToFile = ((OutputStyle == CUEStyle.GapsAppended) && _config.preserveHTOA &&
(_toc.Pregap != 0));
- if (_isCD && (OutputStyle == CUEStyle.GapsLeftOut || OutputStyle == CUEStyle.GapsPrepended))
- throw new Exception("Gaps Left Out/Gaps prepended modes cannot be used when ripping a CD");
-
+ if (_isCD)
+ DetectGaps();
+
if (_usePregapForFirstTrackInSingleFile)
throw new Exception("UsePregapForFirstTrackInSingleFile is not supported for writing audio files.");
@@ -3699,8 +3732,6 @@ string status = processor.Go();
destLengths = CalculateAudioFileLengths(OutputStyle);
- // TODO: if (_isCD) might need to recalc, might have changed after scanning the CD
-
// Lookup();
if (_action != CUEAction.Verify)
@@ -3708,7 +3739,18 @@ string status = processor.Go();
if (!Directory.Exists(OutputDir))
Directory.CreateDirectory(OutputDir);
}
-
+
+ if (_action == CUEAction.Encode)
+ {
+ string cueContents = CUESheetContents(OutputStyle);
+ if (_config.createEACLOG)
+ cueContents = CUESheet.Encoding.GetString(CUESheet.Encoding.GetBytes(cueContents));
+ if (OutputStyle == CUEStyle.SingleFileWithCUE && _config.createCUEFileWhenEmbedded)
+ WriteText(Path.ChangeExtension(_outputPath, ".cue"), cueContents);
+ else
+ WriteText(_outputPath, cueContents);
+ }
+
if (_audioEncoderType != AudioEncoderType.NoAudio || _action == CUEAction.Verify)
WriteAudioFilesPass(OutputDir, OutputStyle, destLengths, htoaToFile, _action == CUEAction.Verify);
@@ -3724,7 +3766,6 @@ string status = processor.Go();
if (_action == CUEAction.Encode)
{
- string cueContents = CUESheetContents(OutputStyle);
uint tracksMatch = 0;
int bestOffset = 0;
@@ -3733,12 +3774,8 @@ string status = processor.Go();
_arVerify.AccResult == HttpStatusCode.OK)
FindBestOffset(1, true, out tracksMatch, out bestOffset);
- if (_config.createEACLOG)
- {
- if (_ripperLog != null)
- _ripperLog = CUESheet.Encoding.GetString(CUESheet.Encoding.GetBytes(_ripperLog));
- cueContents = CUESheet.Encoding.GetString(CUESheet.Encoding.GetBytes(cueContents));
- }
+ if (_config.createEACLOG && _ripperLog != null)
+ _ripperLog = CUESheet.Encoding.GetString(CUESheet.Encoding.GetBytes(_ripperLog));
if (_ripperLog != null)
WriteText(Path.ChangeExtension(_outputPath, ".log"), _ripperLog);
@@ -3751,10 +3788,6 @@ string status = processor.Go();
if (OutputStyle == CUEStyle.SingleFileWithCUE || OutputStyle == CUEStyle.SingleFile)
{
- if (OutputStyle == CUEStyle.SingleFileWithCUE && _config.createCUEFileWhenEmbedded)
- WriteText(Path.ChangeExtension(_outputPath, ".cue"), cueContents);
- if (OutputStyle == CUEStyle.SingleFile)
- WriteText(_outputPath, cueContents);
if (_audioEncoderType != AudioEncoderType.NoAudio)
{
NameValueCollection tags = GenerateAlbumTags(bestOffset, OutputStyle == CUEStyle.SingleFileWithCUE, _ripperLog ?? _eacLog);
@@ -3813,7 +3846,6 @@ string status = processor.Go();
}
else
{
- WriteText(_outputPath, cueContents);
if (_config.createM3U)
WriteText(Path.ChangeExtension(_outputPath, ".m3u"), M3UContents(OutputStyle));
bool fNeedAlbumArtist = false;
@@ -4337,7 +4369,7 @@ string status = processor.Go();
{
// if (_isCD && audioSource != null && audioSource is CDDriveReader)
// updatedTOC = ((CDDriveReader)audioSource).TOC;
- if (audioSource != null && !_isCD) audioSource.Close();
+ if (audioSource != null) audioSource.Close();
audioSource = GetAudioSource(++iSource);
samplesRemSource = (int)_sources[iSource].Length;
}
@@ -4360,6 +4392,9 @@ string status = processor.Go();
else
_CUEToolsDB.Verify.Write(sampleBuffer);
}
+ // we use AR after CTDB, so that we can verify what we fixed
+ if (_useAccurateRip)
+ _arVerify.Write(sampleBuffer);
if (!discardOutput)
{
if (!_config.detectHDCD || !_config.decodeHDCD)
@@ -4372,7 +4407,7 @@ string status = processor.Go();
hdcdDecoder = null;
if (_config.decodeHDCD)
{
- if (!_isCD) audioSource.Close();
+ audioSource.Close();
audioDest.Delete();
throw new Exception("HDCD not detected.");
}
@@ -4385,12 +4420,6 @@ string status = processor.Go();
}
}
}
- if (_useAccurateRip)
- {
- _arVerify.Write(sampleBuffer);
- if (iTrack > 0 || iIndex > 0)
- Tracks[iTrack + (iIndex == 0 ? -1 : 0)].MeasurePeakLevel(sampleBuffer, copyCount);
- }
currentOffset += copyCount;
diskOffset += copyCount;
@@ -4408,40 +4437,51 @@ string status = processor.Go();
if (hdcdDecoder != null)
(hdcdDecoder as IAudioFilter).AudioDest = null;
hdcdDecoder = null;
- try { if (audioSource != null && !_isCD) audioSource.Close(); }
- catch { }
+ if (audioSource != null)
+ try { audioSource.Close(); } catch { }
audioSource = null;
- try { if (audioDest != null) audioDest.Delete(); }
- catch { }
+ if (audioDest != null)
+ try { audioDest.Delete(); } catch { }
audioDest = null;
throw ex;
}
#endif
- //if (_isCD && audioSource != null && audioSource is CDDriveReader)
- // updatedTOC = ((CDDriveReader)audioSource).TOC;
- if (_isCD)
- {
- _toc = (CDImageLayout)_ripper.TOC.Clone();
- if (_toc.Catalog != null)
- Catalog = _toc.Catalog;
- for (iTrack = 0; iTrack < _toc.AudioTracks; iTrack++)
- {
- if (_toc[_toc.FirstAudio + iTrack].ISRC != null)
- General.SetCUELine(_tracks[iTrack].Attributes, "ISRC", _toc[_toc.FirstAudio + iTrack].ISRC, false);
- if (_toc[_toc.FirstAudio + iTrack].DCP || _toc[_toc.FirstAudio + iTrack].PreEmphasis)
- _tracks[iTrack].Attributes.Add(new CUELine("FLAGS" + (_toc[_toc.FirstAudio + iTrack].PreEmphasis ? " PRE" : "") + (_toc[_toc.FirstAudio + iTrack].DCP ? " DCP" : "")));
- }
- }
-
if (hdcdDecoder != null)
(hdcdDecoder as IAudioFilter).AudioDest = null;
- if (audioSource != null && !_isCD)
+ if (audioSource != null)
audioSource.Close();
if (audioDest != null)
audioDest.Close();
}
+ private void DetectGaps()
+ {
+ if (!_isCD)
+ throw new Exception("not a CD");
+
+ try { _ripper.DetectGaps(); }
+ catch (Exception ex)
+ {
+ if (ex is StopException)
+ throw ex;
+ }
+
+ if (!_ripper.GapsDetected)
+ return;
+
+ _toc = (CDImageLayout)_ripper.TOC.Clone();
+ if (_toc.Catalog != null)
+ Catalog = _toc.Catalog;
+ for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++)
+ {
+ if (_toc[_toc.FirstAudio + iTrack].ISRC != null)
+ General.SetCUELine(_tracks[iTrack].Attributes, "ISRC", _toc[_toc.FirstAudio + iTrack].ISRC, false);
+ if (_toc[_toc.FirstAudio + iTrack].DCP || _toc[_toc.FirstAudio + iTrack].PreEmphasis)
+ _tracks[iTrack].Attributes.Add(new CUELine("FLAGS" + (_toc[_toc.FirstAudio + iTrack].PreEmphasis ? " PRE" : "") + (_toc[_toc.FirstAudio + iTrack].DCP ? " DCP" : "")));
+ }
+ }
+
public static string CreateDummyCUESheet(CUEConfig _config, string pathIn)
{
pathIn = Path.GetFullPath(pathIn);
@@ -4740,7 +4780,7 @@ string status = processor.Go();
{
_ripper.Position = 0;
//audioSource = _ripper;
- audioSource = new AudioPipe(_ripper, 0x100000, false);
+ audioSource = new AudioPipe(_ripper, 0x100000, false, ThreadPriority.Highest);
} else
if (_isArchive)
audioSource = AudioReadWrite.GetAudioSource(sourceInfo.Path, OpenArchive(sourceInfo.Path, false), _config);
@@ -4753,7 +4793,7 @@ string status = processor.Go();
//if (!(audioSource is AudioPipe) && !(audioSource is UserDefinedReader) && _config.separateDecodingThread)
if (!(audioSource is AudioPipe) && _config.separateDecodingThread)
- audioSource = new AudioPipe(audioSource, 0x10000, true);
+ audioSource = new AudioPipe(audioSource, 0x10000);
return audioSource;
}
@@ -5272,7 +5312,7 @@ string status = processor.Go();
string status = Go();
if (CTDB.AccResult == HttpStatusCode.OK)
foreach (DBEntry entry in CTDB.Entries)
- if (!entry.hasErrors)
+ if (entry.toc.TrackOffsets == _toc.TrackOffsets && !entry.hasErrors)
return "CUEToolsDB: " + CTDB.Status;
if (ArVerify.WorstConfidence() < 3)
return status + ": confidence too low";
@@ -5280,7 +5320,7 @@ string status = processor.Go();
}
case "repair":
{
- UseCUEToolsDB(false, "CUETools 205");
+ UseCUEToolsDB(false, "CUETools 2.0.6");
Action = CUEAction.Verify;
if (CTDB.DBStatus != null)
return CTDB.DBStatus;
@@ -5535,37 +5575,11 @@ string status = processor.Go();
public class TrackInfo {
private List _attributes;
- private int _peakLevel;
public TagLib.File _fileInfo;
public TrackInfo() {
_attributes = new List();
_fileInfo = null;
- _peakLevel = 0;
- }
-
- public unsafe void MeasurePeakLevel(AudioBuffer buff, int sampleCount)
- {
- if (!buff.PCM.IsRedBook)
- throw new Exception();
- fixed (byte* bb = buff.Bytes)
- {
- short* ss = (short*)bb;
- for (int i = 0; i < sampleCount * 2; i++)
- _peakLevel = Math.Max(_peakLevel, Math.Abs((int)ss[i]));
- }
- //for (uint i = 0; i < sampleCount; i++)
- // for (uint j = 0; j < 2; j++)
- // if (_peakLevel < Math.Abs(samplesBuffer[i, j]))
- // _peakLevel = Math.Abs(samplesBuffer[i, j]);
- }
-
- public int PeakLevel
- {
- get
- {
- return _peakLevel;
- }
}
public List Attributes {
diff --git a/CUETools.Processor/Properties/AssemblyInfo.cs b/CUETools.Processor/Properties/AssemblyInfo.cs
index abebb90..5d43b7b 100644
--- a/CUETools.Processor/Properties/AssemblyInfo.cs
+++ b/CUETools.Processor/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Ripper.Console/Program.cs b/CUETools.Ripper.Console/Program.cs
index 0194300..6a49de7 100644
--- a/CUETools.Ripper.Console/Program.cs
+++ b/CUETools.Ripper.Console/Program.cs
@@ -71,7 +71,7 @@ namespace CUETools.ConsoleRipper
static void Usage()
{
string drives = "";
- char[] drivesAvailable = CDDriveReader.DrivesAvailable();
+ char[] drivesAvailable = CDDrivesList.DrivesAvailable();
for (int i = 0; i < drivesAvailable.Length; i++)
drives += string.Format("{0}: ", drivesAvailable[i]);
Console.WriteLine("Usage : CUERipper.exe ");
@@ -89,7 +89,7 @@ namespace CUETools.ConsoleRipper
static void Main(string[] args)
{
Console.SetOut(Console.Error);
- Console.WriteLine("CUERipper v2.0.5 Copyright (C) 2008-10 Gregory S. Chudov");
+ Console.WriteLine("CUERipper v2.0.6 Copyright (C) 2008-10 Gregory S. Chudov");
Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
Console.WriteLine("the extent permitted by law. for details.");
@@ -102,7 +102,7 @@ namespace CUETools.ConsoleRipper
{
bool ok = true;
if (args[arg] == "-P" || args[arg] == "--paranoid")
- correctionQuality = 4;
+ correctionQuality = 2;
else if (args[arg] == "-S" || args[arg] == "--secure")
correctionQuality = 1;
else if (args[arg] == "-B" || args[arg] == "--burst")
@@ -131,7 +131,7 @@ namespace CUETools.ConsoleRipper
char[] drives;
if (driveLetter == null || driveLetter.Length < 1)
{
- drives = CDDriveReader.DrivesAvailable();
+ drives = CDDrivesList.DrivesAvailable();
if (drives.Length < 1)
{
Console.WriteLine("No CD drives found.");
@@ -206,13 +206,49 @@ namespace CUETools.ConsoleRipper
Console.WriteLine("AccurateRip : {0}", arVerify.ARStatus == null ? "ok" : arVerify.ARStatus);
Console.WriteLine("MusicBrainz : {0}", release == null ? "not found" : release.GetArtist() + " - " + release.GetTitle());
- //IAudioDest audioDest = new FLACWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate);
- IAudioDest audioDest = new WAVWriter(destFile, null, audioSource.PCM);
- audioDest.FinalSampleCount = audioSource.Length;
-
ProgressMeter meter = new ProgressMeter();
audioSource.ReadProgress += new EventHandler(meter.ReadProgress);
+ audioSource.DetectGaps();
+
+ StringWriter cueWriter = new StringWriter();
+ cueWriter.WriteLine("REM DISCID {0}", CDDBId);
+ cueWriter.WriteLine("REM ACCURATERIPID {0}", ArId);
+ cueWriter.WriteLine("REM COMMENT \"{0}\"", audioSource.RipperVersion);
+ if (release != null && release.GetEvents().Count > 0)
+ cueWriter.WriteLine("REM DATE {0}", release.GetEvents()[0].Date.Substring(0, 4));
+ if (audioSource.TOC.Catalog != null)
+ cueWriter.WriteLine("CATALOG {0}", audioSource.TOC.Catalog);
+ if (release != null)
+ {
+ cueWriter.WriteLine("PERFORMER \"{0}\"", release.GetArtist());
+ cueWriter.WriteLine("TITLE \"{0}\"", release.GetTitle());
+ }
+ cueWriter.WriteLine("FILE \"{0}\" WAVE", destFile);
+ for (int track = 1; track <= audioSource.TOC.TrackCount; track++)
+ if (audioSource.TOC[track].IsAudio)
+ {
+ cueWriter.WriteLine(" TRACK {0:00} AUDIO", audioSource.TOC[track].Number);
+ if (release != null && release.GetTracks().Count >= audioSource.TOC[track].Number)
+ {
+ cueWriter.WriteLine(" TITLE \"{0}\"", release.GetTracks()[(int)audioSource.TOC[track].Number - 1].GetTitle());
+ cueWriter.WriteLine(" PERFORMER \"{0}\"", release.GetTracks()[(int)audioSource.TOC[track].Number - 1].GetArtist());
+ }
+ if (audioSource.TOC[track].ISRC != null)
+ cueWriter.WriteLine(" ISRC {0}", audioSource.TOC[track].ISRC);
+ if (audioSource.TOC[track].DCP || audioSource.TOC[track].PreEmphasis)
+ cueWriter.WriteLine(" FLAGS{0}{1}", audioSource.TOC[track].PreEmphasis ? " PRE" : "", audioSource.TOC[track].DCP ? " DCP" : "");
+ for (int index = audioSource.TOC[track].Pregap > 0 ? 0 : 1; index <= audioSource.TOC[track].LastIndex; index++)
+ cueWriter.WriteLine(" INDEX {0:00} {1}", index, audioSource.TOC[track][index].MSF);
+ }
+ cueWriter.Close();
+ StreamWriter cueFile = new StreamWriter(Path.ChangeExtension(destFile, ".cue"));
+ cueFile.Write(cueWriter.ToString());
+ cueFile.Close();
+
+ //IAudioDest audioDest = new FLACWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate);
+ IAudioDest audioDest = new WAVWriter(destFile, null, audioSource.PCM);
+ audioDest.FinalSampleCount = audioSource.Length;
while (audioSource.Read(buff, -1) != 0)
{
arVerify.Write(buff);
@@ -271,41 +307,6 @@ namespace CUETools.ConsoleRipper
logFile.Write(logWriter.ToString());
logFile.Close();
- StringWriter cueWriter = new StringWriter();
- cueWriter.WriteLine("REM DISCID {0}", CDDBId);
- cueWriter.WriteLine("REM ACCURATERIPID {0}", ArId);
- cueWriter.WriteLine("REM COMMENT \"{0}\"", audioSource.RipperVersion);
- if (release != null && release.GetEvents().Count > 0)
- cueWriter.WriteLine("REM DATE {0}", release.GetEvents()[0].Date.Substring(0,4));
- if (audioSource.TOC.Catalog != null)
- cueWriter.WriteLine("CATALOG {0}", audioSource.TOC.Catalog);
- if (release != null)
- {
- cueWriter.WriteLine("PERFORMER \"{0}\"", release.GetArtist());
- cueWriter.WriteLine("TITLE \"{0}\"", release.GetTitle());
- }
- cueWriter.WriteLine("FILE \"{0}\" WAVE", destFile);
- for (int track = 1; track <= audioSource.TOC.TrackCount; track++)
- if (audioSource.TOC[track].IsAudio)
- {
- cueWriter.WriteLine(" TRACK {0:00} AUDIO", audioSource.TOC[track].Number);
- if (release != null && release.GetTracks().Count >= audioSource.TOC[track].Number)
- {
- cueWriter.WriteLine(" TITLE \"{0}\"", release.GetTracks()[(int)audioSource.TOC[track].Number - 1].GetTitle());
- cueWriter.WriteLine(" PERFORMER \"{0}\"", release.GetTracks()[(int)audioSource.TOC[track].Number - 1].GetArtist());
- }
- if (audioSource.TOC[track].ISRC != null)
- cueWriter.WriteLine(" ISRC {0}", audioSource.TOC[track].ISRC);
- if (audioSource.TOC[track].DCP || audioSource.TOC[track].PreEmphasis)
- cueWriter.WriteLine(" FLAGS{0}{1}", audioSource.TOC[track].PreEmphasis ? " PRE" : "", audioSource.TOC[track].DCP ? " DCP" : "");
- for (int index = audioSource.TOC[track].Pregap > 0 ? 0 : 1; index <= audioSource.TOC[track].LastIndex; index++)
- cueWriter.WriteLine(" INDEX {0:00} {1}", index, audioSource.TOC[track][index].MSF);
- }
- cueWriter.Close();
- StreamWriter cueFile = new StreamWriter(Path.ChangeExtension(destFile, ".cue"));
- cueFile.Write(cueWriter.ToString());
- cueFile.Close();
-
audioSource.Close();
//FLACReader tagger = new FLACReader(destFile, null);
diff --git a/CUETools.Ripper.SCSI/Properties/AssemblyInfo.cs b/CUETools.Ripper.SCSI/Properties/AssemblyInfo.cs
index 479fd26..73a3926 100644
--- a/CUETools.Ripper.SCSI/Properties/AssemblyInfo.cs
+++ b/CUETools.Ripper.SCSI/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Ripper.SCSI/SCSIDrive.cs b/CUETools.Ripper.SCSI/SCSIDrive.cs
index dc872dd..a429aaf 100644
--- a/CUETools.Ripper.SCSI/SCSIDrive.cs
+++ b/CUETools.Ripper.SCSI/SCSIDrive.cs
@@ -52,6 +52,7 @@ namespace CUETools.Ripper.SCSI
int _currentTrack = -1, _currentIndex = -1, _currentTrackActualStart = -1;
Logger m_logger;
CDImageLayout _toc;
+ CDImageLayout _toc2;
char m_device_letter;
InquiryResult m_inqury_result;
int m_max_sectors;
@@ -59,7 +60,6 @@ namespace CUETools.Ripper.SCSI
Crc16Ccitt _crc;
public long[,,] UserData;
public byte[,] C2Count;
- public byte[,] QData;
public long[] byte2long;
BitArray _errors;
int _errorsCount;
@@ -70,20 +70,20 @@ namespace CUETools.Ripper.SCSI
ReadCDCommand _readCDCommand = ReadCDCommand.Unknown;
ReadCDCommand _forceReadCommand = ReadCDCommand.Unknown;
Device.MainChannelSelection _mainChannelMode = Device.MainChannelSelection.UserData;
- Device.SubChannelMode _subChannelMode = Device.SubChannelMode.QOnly;
Device.C2ErrorMode _c2ErrorMode = Device.C2ErrorMode.Mode296;
string _autodetectResult;
byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO];
- byte[] _subchannelBuffer = new byte[NSECTORS * 16];
+ byte[] _subchannelBuffer = new byte[CB_AUDIO];
bool _qChannelInBCD = true;
+ private ReadProgressArgs progressArgs = new ReadProgressArgs();
public event EventHandler ReadProgress;
public CDImageLayout TOC
{
get
{
- return _toc;
+ return gapsDetected && _toc2 != null ? _toc2 : _toc;
}
}
@@ -131,11 +131,8 @@ namespace CUETools.Ripper.SCSI
{
get
{
- if (_autodetectResult != null || TestReadCommand())
- return _autodetectResult;
- string ret = _autodetectResult;
- _autodetectResult = null;
- return ret;
+ TestReadCommand();
+ return _autodetectResult;
}
}
@@ -173,7 +170,7 @@ namespace CUETools.Ripper.SCSI
(_readCDCommand == ReadCDCommand.ReadCdBEh ? "BEh" : "D8h"),
(_mainChannelMode == Device.MainChannelSelection.UserData ? 0x10 : 0xF8) +
(_c2ErrorMode == Device.C2ErrorMode.None ? 0 : _c2ErrorMode == Device.C2ErrorMode.Mode294 ? 2 : 4),
- (_subChannelMode == Device.SubChannelMode.None ? "00h" : _subChannelMode == Device.SubChannelMode.QOnly ? "02h" : "04h"),
+ (_gapDetection == GapDetectionMethod.ReadCD ? "BEh" : _gapDetection == GapDetectionMethod.ReadSubchannel ? "42h" : ""),
_qChannelInBCD ? "" : "nonBCD",
m_max_sectors);
}
@@ -183,9 +180,6 @@ namespace CUETools.Ripper.SCSI
{
m_logger = new Logger();
_crc = new Crc16Ccitt(InitialCrcValue.Zeros);
- UserData = new long[MSECTORS, 2, 4 * 588];
- C2Count = new byte[MSECTORS, 294];
- QData = new byte[MSECTORS, 16];
byte2long = new long[256];
for (long i = 0; i < 256; i++)
{
@@ -261,9 +255,15 @@ namespace CUETools.Ripper.SCSI
throw new SCSIException("ReadTOC", m_device, st);
//throw new Exception("ReadTOC: " + (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()));
+ //byte[] qdata = null;
+ //st = m_device.ReadPMA(out qdata);
+ //if (st != Device.CommandStatus.Success)
+ // throw new SCSIException("ReadPMA", m_device, st);
+
st = m_device.ReadCDText(out cdtext);
// new CDTextEncoderDecoder
+ _toc2 = null;
_toc = new CDImageLayout();
for (int iTrack = 0; iTrack < toc.Count - 1; iTrack++)
_toc.AddTrack(new CDTrack((uint)iTrack + 1,
@@ -278,15 +278,24 @@ namespace CUETools.Ripper.SCSI
_toc[1][0].Start = 0;
Position = 0;
}
+
+ UserData = new long[MSECTORS, 2, 4 * 588];
+ C2Count = new byte[MSECTORS, 294];
+
return true;
}
public void Close()
{
+ UserData = null;
+ C2Count = null;
if (m_device != null)
m_device.Close();
m_device = null;
_toc = null;
+ _toc2 = null;
+ gapsDetected = false;
+ readCommandFound = false;
_currentStart = -1;
_currentEnd = -1;
}
@@ -304,199 +313,444 @@ namespace CUETools.Ripper.SCSI
}
}
- private int ProcessSubchannel(int sector, int Sectors2Read, bool updateMap)
+ private enum GapDetectionMethod
{
- int posCount = 0;
- for (int iSector = 0; iSector < Sectors2Read; iSector++)
- {
- int q_pos = (sector - _currentStart + iSector);
- int ctl = QData[q_pos, 0] >> 4;
- int adr = QData[q_pos, 0] & 7;
- bool preemph = (ctl & 1) == 1;
- bool dcp = (ctl & 2) == 2;
+ ReadCD,
+ ReadSubchannel,
+ None
+ }
- for (int i = 0; i < 10; i++)
- _subchannelBuffer[i] = QData[ q_pos, i];
- if (!_qChannelInBCD && adr == 1)
+ private GapDetectionMethod _gapDetection = GapDetectionMethod.None;
+
+ private unsafe void LocateLastSector(int sec0, int sec1, int iTrack, int iIndex, ref int maxIndex, out int pos)
+ {
+ if (sec1 <= sec0)
+ {
+ pos = Math.Min(sec0, sec1);
+ return;
+ }
+ int msector = (sec0 + sec1) / 2;
+ int fsector = Math.Max(sec0, msector - 1);
+ int lsector = Math.Min(sec1, msector + 3);
+
+ if (lsector >= fsector && _gapDetection == GapDetectionMethod.ReadCD)
+ {
+ Device.CommandStatus st = m_device.ReadSubChannel(2, (uint)fsector, (uint)(lsector - fsector + 1), ref _subchannelBuffer, _timeout);
+ if (st != Device.CommandStatus.Success)
+ lsector = fsector - 1;
+ }
+
+ fixed (byte * data = _subchannelBuffer)
+ for (int sector = fsector; sector <= lsector; sector++)
{
- _subchannelBuffer[3] = toBCD(_subchannelBuffer[3]);
- _subchannelBuffer[4] = toBCD(_subchannelBuffer[4]);
- _subchannelBuffer[5] = toBCD(_subchannelBuffer[5]);
- _subchannelBuffer[7] = toBCD(_subchannelBuffer[7]);
- _subchannelBuffer[8] = toBCD(_subchannelBuffer[8]);
- _subchannelBuffer[9] = toBCD(_subchannelBuffer[9]);
- }
- ushort crc = _crc.ComputeChecksum(_subchannelBuffer, 0, 10);
- crc ^= 0xffff;
- if ((QData[q_pos, 10] != 0 || QData[q_pos, 11] != 0) &&
- ((byte)(crc & 0xff) != QData[q_pos, 11] || (byte)(crc >> 8) != QData[q_pos, 10])
- )
- {
- if (!updateMap)
- continue;
- _crcErrorsCount++;
- if (_debugMessages && _crcErrorsCount < 4)
+ Device.CommandStatus st = Device.CommandStatus.Success;
+ int sTrack, sIndex, sPos, ctl;
+ switch (_gapDetection)
{
- StringBuilder st = new StringBuilder();
- for (int i = 0; i < 12; i++)
- st.AppendFormat(",0x{0:X2}", QData[q_pos, i]);
- System.Console.WriteLine("\rCRC error@{0}{1};", CDImageLayout.TimeToString((uint)(sector + iSector)), st.ToString());
- }
- continue;
- }
- switch (adr)
- {
- case 1: // current position
- {
- int iTrack = fromBCD(QData[q_pos, 1]);
- int iIndex = fromBCD(QData[q_pos, 2]);
- int mm = _qChannelInBCD ? fromBCD(QData[q_pos, 7]) : QData[q_pos, 7];
- int ss = _qChannelInBCD ? fromBCD(QData[q_pos, 8]) : QData[q_pos, 8];
- int ff = _qChannelInBCD ? fromBCD(QData[q_pos, 9]) : QData[q_pos, 9];
- //if (sec != sector + iSector)
- // System.Console.WriteLine("\rLost sync: {0} vs {1} ({2:X} vs {3:X})", CDImageLayout.TimeToString((uint)(sector + iSector)), CDImageLayout.TimeToString((uint)sec), sector + iSector, sec);
- if (iTrack == 110)
+ case GapDetectionMethod.ReadSubchannel:
{
- if (sector + iSector + 75 < _toc.AudioLength)
- throw new Exception("lead out area encountred");
- // make sure that data is zero?
- return posCount;
- }
- if (iTrack == 0)
- throw new Exception("lead in area encountred");
- posCount++;
- if (!updateMap)
+ // seek to given sector
+ if (_readCDCommand == ReadCDCommand.ReadCdBEh)
+ st = m_device.ReadCDAndSubChannel(_mainChannelMode, Device.SubChannelMode.None, _c2ErrorMode, 1, false, (uint)sector, 1, (IntPtr)((void*)data), _timeout);
+ else
+ st = m_device.ReadCDDA(Device.SubChannelMode.None, (uint)sector, 1, (IntPtr)((void*)data), _timeout);
+ if (st != Device.CommandStatus.Success)
+ continue;
+ st = m_device.ReadSubChannel42(1, 0, ref _subchannelBuffer, 0, _timeout);
+ // x x x x 01 adrctl tr ind abs abs abs rel rel rel
+ if (st != Device.CommandStatus.Success)
+ continue;
+ if (_subchannelBuffer[0] != 0 || _subchannelBuffer[2] != 0 || _subchannelBuffer[3] != 12 || _subchannelBuffer[4] != 1)
+ continue;
+
+ ctl = _subchannelBuffer[5] & 0xf;
+ int adr = (_subchannelBuffer[5] >> 4) & 0xf;
+ sTrack = _subchannelBuffer[6];
+ sIndex = _subchannelBuffer[7];
+ sPos = (_subchannelBuffer[8] << 24) | (_subchannelBuffer[9] << 16) | (_subchannelBuffer[10] << 8) | (_subchannelBuffer[11]);
+ //int sRel = (_subchannelBuffer[12] << 24) | (_subchannelBuffer[13] << 16) | (_subchannelBuffer[14] << 8) | (_subchannelBuffer[15]);
+ if (adr != 1)
+ continue;
+
+ if (sTrack < _toc2.FirstAudio || sTrack >= _toc2.FirstAudio + _toc2.AudioTracks)
+ continue;
+
break;
- int sec = ff + 75 * (ss + 60 * mm) - 150; // sector + iSector;
- if (iTrack >= _toc.FirstAudio + _toc.AudioTracks)
- throw new Exception("strange track number encountred");
- if (iTrack != _currentTrack)
- {
- if (_currentTrack != -1 && iTrack != _currentTrack + 1)
- {
- if (_debugMessages)
- System.Console.WriteLine("\nNon-consequent track at {0}: {1} after {2}", CDImageLayout.TimeToString((uint)(sector + iSector)), iTrack, _currentTrack);
- //throw new Exception("invalid track");
- continue;
- }
- if (iIndex != 1 && iIndex != 0)
- {
- if (_debugMessages)
- System.Console.WriteLine("\nInvalid track start index at {0}: {1}.{2}", CDImageLayout.TimeToString((uint)(sector + iSector)), iTrack, iIndex);
- //throw new Exception("invalid index");
- continue;
- }
- _currentTrack = iTrack;
- _currentTrackActualStart = sec;
- _currentIndex = iIndex;
}
- else if (iIndex != _currentIndex)
+ case GapDetectionMethod.ReadCD:
{
- if (iIndex != _currentIndex + 1)
+ int offs = 16 * (sector - fsector);
+ ctl = _subchannelBuffer[offs + 0] >> 4;
+ int adr = _subchannelBuffer[offs + 0] & 7;
+ if (!_qChannelInBCD && adr == 1)
{
- if (_debugMessages)
- System.Console.WriteLine("\nNon-consequent index at {0}: {1} after {2}", CDImageLayout.TimeToString((uint)(sector + iSector)), iIndex, _currentIndex);
- //throw new Exception("invalid index");
- continue;
+ _subchannelBuffer[offs + 3] = toBCD(_subchannelBuffer[offs + 3]);
+ _subchannelBuffer[offs + 4] = toBCD(_subchannelBuffer[offs + 4]);
+ _subchannelBuffer[offs + 5] = toBCD(_subchannelBuffer[offs + 5]);
+ _subchannelBuffer[offs + 7] = toBCD(_subchannelBuffer[offs + 7]);
+ _subchannelBuffer[offs + 8] = toBCD(_subchannelBuffer[offs + 8]);
+ _subchannelBuffer[offs + 9] = toBCD(_subchannelBuffer[offs + 9]);
}
- _currentIndex = iIndex;
- if (_currentIndex == 1)
- {
- if (iTrack != 1)
- {
- uint pregap = (uint)(sec - _currentTrackActualStart);
- _toc[iTrack][0].Start = _toc[iTrack].Start - pregap;
- }
- _currentTrackActualStart = sec;
- } else
- _toc[iTrack].AddIndex(new CDTrackIndex((uint)iIndex, (uint)(_toc[iTrack].Start + sec - _currentTrackActualStart)));
- _currentIndex = iIndex;
+
+ ushort crc = _crc.ComputeChecksum(_subchannelBuffer, offs, 10);
+ crc ^= 0xffff;
+ ushort scrc = (ushort)((_subchannelBuffer[offs + 10] << 8) | _subchannelBuffer[offs + 11]);
+ if (scrc != 0 && scrc != crc)
+ continue;
+ if (adr != 1)
+ continue;
+
+ sTrack = fromBCD(_subchannelBuffer[offs + 1]);
+ sIndex = fromBCD(_subchannelBuffer[offs + 2]);
+
+ if (sTrack < _toc2.FirstAudio || sTrack >= _toc2.FirstAudio + _toc2.AudioTracks)
+ continue;
+
+ int mm = fromBCD(_subchannelBuffer[offs + 7]);
+ int ss = fromBCD(_subchannelBuffer[offs + 8]);
+ int ff = fromBCD(_subchannelBuffer[offs + 9]);
+ sPos = ff + 75 * (ss + 60 * mm) - 150;
+ break;
}
- if (preemph)
- _toc[iTrack].PreEmphasis = true;
- if (dcp)
- _toc[iTrack].DCP = true;
- break;
- }
- case 2: // catalog
- if (updateMap && _toc.Catalog == null)
+ default:
+ continue;
+ }
+
+ bool preemph = (ctl & 1) == 1;
+ bool dcp = (ctl & 2) == 2;
+ if (preemph)
+ _toc2[sTrack].PreEmphasis = true;
+ if (dcp)
+ _toc2[sTrack].DCP = true;
+
+ if (sPos <= sec0 || sPos > sec1)
+ continue;
+ if (sTrack > iTrack || (sTrack == iTrack && iIndex >= 0 && sIndex > iIndex))
+ {
+ LocateLastSector(sec0, sPos - 1, iTrack, iIndex, ref maxIndex, out pos);
+ return;
+ }
+ if (sTrack < iTrack || (sTrack == iTrack && (iIndex < 0 || sIndex <= iIndex)))
+ {
+ if (sTrack == iTrack && iIndex < 0)
+ maxIndex = sIndex;
+ LocateLastSector(sPos, sec1, iTrack, iIndex, ref maxIndex, out pos);
+ return;
+ }
+ }
+ if (sec1 <= sec0 + 16)
+ {
+ pos = Math.Min(sec0, sec1);
+ return;
+ }
+
+ // TODO: catch?
+ throw new Exception("gap detection failed");
+ }
+
+ private unsafe void TestGaps()
+ {
+ _gapDetection = GapDetectionMethod.None;
+
+ //st = m_device.Seek((uint)(sector + i * 33) + _toc[_toc.FirstAudio][0].Start);
+ //if (st != Device.CommandStatus.Success)
+ // break;
+ //bool ready;
+ //st = m_device.TestUnitReady(out ready);
+ //if (st != Device.CommandStatus.Success)
+ // break;
+ //if (!ready)
+ //{
+ // st = Device.CommandStatus.NotSupported;
+ // break;
+ //}
+
+ // try ReadCD:
+ Device.CommandStatus st;
+ int sector = 3;
+
+ if (_readCDCommand == ReadCDCommand.ReadCdBEh)
+ {
+ st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, ref _subchannelBuffer, _timeout);
+ if (st == Device.CommandStatus.Success)
+ {
+ int[] goodsecs = new int[2];
+ for (int bcd = 1; bcd >= 0; bcd--)
+ {
+ for (int i = 0; i < m_max_sectors; i++)
{
- StringBuilder catalog = new StringBuilder();
- for (int i = 1; i < 8; i++)
- catalog.AppendFormat("{0:x2}", QData[q_pos, i]);
- _toc.Catalog = catalog.ToString(0, 13);
+ int adr = _subchannelBuffer[i * 16 + 0] & 7;
+ if (bcd == 0 && adr == 1)
+ {
+ _subchannelBuffer[i * 16 + 3] = toBCD(_subchannelBuffer[i * 16 + 3]);
+ _subchannelBuffer[i * 16 + 4] = toBCD(_subchannelBuffer[i * 16 + 4]);
+ _subchannelBuffer[i * 16 + 5] = toBCD(_subchannelBuffer[i * 16 + 5]);
+ _subchannelBuffer[i * 16 + 7] = toBCD(_subchannelBuffer[i * 16 + 7]);
+ _subchannelBuffer[i * 16 + 8] = toBCD(_subchannelBuffer[i * 16 + 8]);
+ _subchannelBuffer[i * 16 + 9] = toBCD(_subchannelBuffer[i * 16 + 9]);
+ }
+
+ ushort crc = _crc.ComputeChecksum(_subchannelBuffer, i * 16, 10);
+ crc ^= 0xffff;
+ ushort scrc = (ushort)((_subchannelBuffer[i * 16 + 10] << 8) | _subchannelBuffer[i * 16 + 11]);
+ if (scrc != 0 && scrc != crc)
+ continue;
+ if (adr != 1)
+ continue;
+
+ int sTrack = fromBCD(_subchannelBuffer[i * 16 + 1]);
+ int sIndex = fromBCD(_subchannelBuffer[i * 16 + 2]);
+
+ if (sTrack == 0 || sTrack == 110)
+ continue;
+
+ int mm = fromBCD(_subchannelBuffer[i * 16 + 7]);
+ int ss = fromBCD(_subchannelBuffer[i * 16 + 8]);
+ int ff = fromBCD(_subchannelBuffer[i * 16 + 9]);
+ int sPos = ff + 75 * (ss + 60 * mm) - 150;
+
+ if (sPos < sector + i - 8 || sPos > sector + i + 8)
+ continue;
+
+ goodsecs[bcd]++;
}
- break;
- case 3: //isrc
- if (updateMap && _toc[_currentTrack].ISRC == null)
- {
- StringBuilder isrc = new StringBuilder();
- isrc.Append(from6bit(QData[q_pos, 1] >> 2));
- isrc.Append(from6bit(((QData[q_pos, 1] & 0x3) << 4) + (0x0f & (QData[q_pos, 2] >> 4))));
- isrc.Append(from6bit(((QData[q_pos, 2] & 0xf) << 2) + (0x03 & (QData[q_pos, 3] >> 6))));
- isrc.Append(from6bit((QData[q_pos, 3] & 0x3f)));
- isrc.Append(from6bit(QData[q_pos, 4] >> 2));
- isrc.Append(from6bit(((QData[q_pos, 4] & 0x3) << 4) + (0x0f & (QData[q_pos, 5] >> 4))));
- isrc.AppendFormat("{0:x}", QData[q_pos, 5] & 0xf);
- isrc.AppendFormat("{0:x2}", QData[q_pos, 6]);
- isrc.AppendFormat("{0:x2}", QData[q_pos, 7]);
- isrc.AppendFormat("{0:x}", QData[q_pos, 8] >> 4);
- if (!isrc.ToString().Contains("#") && isrc.ToString() != "0000000000")
- _toc[_currentTrack].ISRC = isrc.ToString();
- }
- break;
+ }
+
+ if (goodsecs[0] > 0 || goodsecs[1] > 0)
+ {
+ _qChannelInBCD = goodsecs[1] >= goodsecs[0];
+ _gapDetection = GapDetectionMethod.ReadCD;
+ }
+ }
+ }
+
+ if (_gapDetection == GapDetectionMethod.None)
+ {
+ fixed (byte* data = _subchannelBuffer)
+ {
+ // seek to given sector
+ if (_readCDCommand == ReadCDCommand.ReadCdBEh)
+ st = m_device.ReadCDAndSubChannel(_mainChannelMode, Device.SubChannelMode.None, _c2ErrorMode, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, 1, (IntPtr)((void*)data), _timeout);
+ else
+ st = m_device.ReadCDDA(Device.SubChannelMode.None, (uint)sector + _toc[_toc.FirstAudio][0].Start, 1, (IntPtr)((void*)data), _timeout);
+ }
+ if (st == Device.CommandStatus.Success)
+ {
+ st = m_device.ReadSubChannel42(1, 0, ref _subchannelBuffer, 0, _timeout);
+ if (st == Device.CommandStatus.Success)
+ {
+ if (_subchannelBuffer[0] == 0 && _subchannelBuffer[2] == 0 && _subchannelBuffer[3] == 12 && _subchannelBuffer[4] == 1)
+ {
+ int ctl = _subchannelBuffer[5] & 0xf;
+ int adr = (_subchannelBuffer[5] >> 4) & 0xf;
+ if (adr == 1)
+ {
+ _gapDetection = GapDetectionMethod.ReadSubchannel;
+ }
+ }
+ }
}
}
- return posCount;
}
+ public bool GapsDetected
+ {
+ get
+ {
+ return gapsDetected;
+ }
+ }
+
+ bool gapsDetected = false;
+
+ public unsafe bool DetectGaps()
+ {
+ if (!TestReadCommand())
+ throw new Exception("failed to autodetect read command:\n" + _autodetectResult);
+
+ if (_gapDetection == GapDetectionMethod.None)
+ {
+ gapsDetected = false;
+ return false;
+ }
+
+ if (gapsDetected)
+ return true;
+
+ _toc2 = (CDImageLayout)_toc.Clone();
+
+ if (_gapDetection == GapDetectionMethod.ReadSubchannel)
+ {
+ Device.CommandStatus st = m_device.ReadSubChannel42(2, 0, ref _subchannelBuffer, 0, _timeout);
+ if (st == Device.CommandStatus.Success)
+ if (_subchannelBuffer[0] == 0 && _subchannelBuffer[2] == 0 && _subchannelBuffer[3] == 20
+ && _subchannelBuffer[4] == 2 && _subchannelBuffer[8] == 0x80)
+ {
+ string catalog = Encoding.ASCII.GetString(_subchannelBuffer, 9, 13);
+ if (catalog.ToString() != "0000000000000")
+ _toc2.Catalog = catalog.ToString();
+ }
+ }
+
+ int sec0 = (int)_toc2[_toc2.FirstAudio][0].Start, disc1 = (int)(_toc2[_toc2.FirstAudio][0].Start + _toc2.AudioLength) - 1;
+ for (int iTrack = _toc2.FirstAudio; iTrack < _toc2.FirstAudio + _toc2.AudioTracks; iTrack++)
+ {
+ if (ReadProgress != null)
+ {
+ progressArgs.Action = "Detecting gaps";
+ progressArgs.Pass = -1;
+ progressArgs.Position = (iTrack - _toc2.FirstAudio) * 3;
+ progressArgs.PassStart = 0;
+ progressArgs.PassEnd = _toc2.TrackCount * 3 - 1;
+ progressArgs.ErrorsCount = 0;
+ progressArgs.PassTime = DateTime.Now;
+ ReadProgress(this, progressArgs);
+ }
+ int sec1, idx1 = 1;
+ LocateLastSector(sec0, Math.Min(disc1, (int)_toc[iTrack].End + 16), iTrack, -1, ref idx1, out sec1);
+ int isec0 = sec0;
+ for (int idx = 0; idx <= idx1; idx++)
+ {
+ int isec1 = sec1, iidx1 = 1;
+ if (idx < idx1)
+ {
+ if (ReadProgress != null)
+ {
+ progressArgs.Position = (iTrack - _toc2.FirstAudio) * 3 + 1;
+ progressArgs.PassTime = DateTime.Now;
+ ReadProgress(this, progressArgs);
+ }
+ LocateLastSector(isec0, sec1, iTrack, idx, ref iidx1, out isec1);
+ }
+ if (isec1 > isec0)
+ {
+ if (idx == 0 && iTrack > 1)
+ _toc2[iTrack][0].Start = _toc2[iTrack].Start - (uint)(isec1 - isec0 + 1);
+ if (idx > 1)
+ _toc2[iTrack].AddIndex(new CDTrackIndex((uint)idx, (uint)(_toc2[iTrack][0].Start + isec0 - sec0)));
+ }
+ isec0 = isec1 + 1;
+ }
+
+ if (ReadProgress != null)
+ {
+ progressArgs.Position = (iTrack - _toc2.FirstAudio) * 3 + 2;
+ progressArgs.PassTime = DateTime.Now;
+ ReadProgress(this, progressArgs);
+ }
+
+ if (_gapDetection == GapDetectionMethod.ReadSubchannel)
+ {
+ Device.CommandStatus st = m_device.ReadSubChannel42(3, iTrack, ref _subchannelBuffer, 0, _timeout);
+ if (st == Device.CommandStatus.Success)
+ if (_subchannelBuffer[0] == 0 && _subchannelBuffer[2] == 0 && _subchannelBuffer[3] == 20
+ && _subchannelBuffer[4] == 3 && _subchannelBuffer[8] == 0x80) //&& _subchannelBuffer[6] == iTrack)
+ {
+ string isrc = Encoding.ASCII.GetString(_subchannelBuffer, 9, 12);
+ if (!isrc.ToString().Contains("#") && isrc.ToString() != "000000000000")
+ _toc2[iTrack].ISRC = isrc.ToString();
+ }
+ }
+ if (_gapDetection == GapDetectionMethod.ReadCD)
+ {
+ Device.CommandStatus st = m_device.ReadSubChannel(2, _toc2[iTrack].Start + 16, 100, ref _subchannelBuffer, _timeout);
+ if (st == Device.CommandStatus.Success)
+ {
+ for (int offs = 0; offs < 100 * 16; offs += 16)
+ {
+ int ctl = _subchannelBuffer[offs + 0] >> 4;
+ int adr = _subchannelBuffer[offs + 0] & 7;
+ if (adr != 2 && adr != 3)
+ continue;
+ ushort crc = _crc.ComputeChecksum(_subchannelBuffer, offs, 10);
+ crc ^= 0xffff;
+ ushort scrc = (ushort)((_subchannelBuffer[offs + 10] << 8) | _subchannelBuffer[offs + 11]);
+ if (scrc != 0 && scrc != crc)
+ continue;
+ if (adr == 3 && _toc2[iTrack].ISRC == null)
+ {
+ StringBuilder isrc = new StringBuilder();
+ isrc.Append(from6bit(_subchannelBuffer[offs + 1] >> 2));
+ isrc.Append(from6bit(((_subchannelBuffer[offs + 1] & 0x3) << 4) + (0x0f & (_subchannelBuffer[offs + 2] >> 4))));
+ isrc.Append(from6bit(((_subchannelBuffer[offs + 2] & 0xf) << 2) + (0x03 & (_subchannelBuffer[offs + 3] >> 6))));
+ isrc.Append(from6bit((_subchannelBuffer[offs + 3] & 0x3f)));
+ isrc.Append(from6bit(_subchannelBuffer[offs + 4] >> 2));
+ isrc.Append(from6bit(((_subchannelBuffer[offs + 4] & 0x3) << 4) + (0x0f & (_subchannelBuffer[offs + 5] >> 4))));
+ isrc.AppendFormat("{0:x}", _subchannelBuffer[offs + 5] & 0xf);
+ isrc.AppendFormat("{0:x2}", _subchannelBuffer[offs + 6]);
+ isrc.AppendFormat("{0:x2}", _subchannelBuffer[offs + 7]);
+ isrc.AppendFormat("{0:x}", _subchannelBuffer[offs + 8] >> 4);
+ if (!isrc.ToString().Contains("#") && isrc.ToString() != "000000000000")
+ _toc2[iTrack].ISRC = isrc.ToString();
+ }
+ if (adr == 2 && _toc2.Catalog == null)
+ {
+ StringBuilder catalog = new StringBuilder();
+ for (int i = 1; i < 8; i++)
+ catalog.AppendFormat("{0:x2}", _subchannelBuffer[offs + i]);
+ if (catalog.ToString() != "0000000000000")
+ _toc2.Catalog = catalog.ToString(0, 13);
+ }
+ }
+ }
+ }
+ sec0 = sec1 + 1;
+ }
+
+ gapsDetected = true;
+ return true;
+ }
+
+ bool readCommandFound = false;
+
public unsafe bool TestReadCommand()
{
+ if (readCommandFound)
+ return true;
+
//ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h };
ReadCDCommand[] readmode = { ReadCDCommand.ReadCdD8h, ReadCDCommand.ReadCdBEh };
- Device.SubChannelMode[] submode = { Device.SubChannelMode.QOnly, Device.SubChannelMode.None, Device.SubChannelMode.RWMode };
- Device.C2ErrorMode[] c2mode = { Device.C2ErrorMode.Mode296, Device.C2ErrorMode.Mode294, Device.C2ErrorMode.None };
+ Device.C2ErrorMode[] c2mode = { Device.C2ErrorMode.Mode294, Device.C2ErrorMode.Mode296, Device.C2ErrorMode.None };
Device.MainChannelSelection[] mainmode = { Device.MainChannelSelection.UserData, Device.MainChannelSelection.F8h };
bool found = false;
+ _autodetectResult = "";
_currentStart = 0;
_currentTrack = -1;
_currentIndex = -1;
m_max_sectors = Math.Min(NSECTORS, m_device.MaximumTransferLength / CB_AUDIO - 1);
int sector = 3;
- for (int q = 0; q <= 1 && !found; q++)
- for (int c = 0; c <= 2 && !found; c++)
- for (int r = 0; r <= 1 && !found; r++)
- for (int m = 0; m <= 1 && !found; m++)
+ int pass = 0;
+ for (int c = 0; c <= 2 && !found; c++)
+ for (int r = 0; r <= 1 && !found; r++)
+ for (int m = 0; m <= 1 && !found; m++)
+ {
+ _readCDCommand = readmode[r];
+ _c2ErrorMode = c2mode[c];
+ _mainChannelMode = mainmode[m];
+ if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand)
+ continue;
+ if (_readCDCommand == ReadCDCommand.ReadCdD8h) // && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData))
+ continue;
+ Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead?
+ DateTime tm = DateTime.Now;
+ if (ReadProgress != null)
{
- _readCDCommand = readmode[r];
- _subChannelMode = submode[q];
- _c2ErrorMode = c2mode[c];
- _mainChannelMode = mainmode[m];
- if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand)
- continue;
- if (_readCDCommand == ReadCDCommand.ReadCdD8h) // && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData))
- continue;
- Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead?
- DateTime tm = DateTime.Now;
- Device.CommandStatus st = FetchSectors(sector, m_max_sectors, false, false);
- TimeSpan delay = DateTime.Now - tm;
- if (st == Device.CommandStatus.Success && _subChannelMode == Device.SubChannelMode.QOnly)
- {
- _qChannelInBCD = false;
- int sub1 = ProcessSubchannel(sector, m_max_sectors, false);
- _qChannelInBCD = true;
- int sub2 = ProcessSubchannel(sector, m_max_sectors, false);
- _qChannelInBCD = sub2 >= sub1;
- if (sub1 == 0 && sub2 == 0)
- {
- _autodetectResult += string.Format("{0}: {1}\n", CurrentReadCommand, "Got no subchannel information");
- continue;
- }
- }
- _autodetectResult += string.Format("{0}: {1} ({2}ms)\n", CurrentReadCommand, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), delay.TotalMilliseconds);
- found = st == Device.CommandStatus.Success && _subChannelMode != Device.SubChannelMode.RWMode;// && _subChannelMode != Device.SubChannelMode.QOnly;
- //sector += m_max_sectors;
+ progressArgs.Action = "Detecting drive features";
+ progressArgs.Pass = -1;
+ progressArgs.Position = pass++;
+ progressArgs.PassStart = 0;
+ progressArgs.PassEnd = 2 * 3 * 2 - 1;
+ progressArgs.ErrorsCount = 0;
+ progressArgs.PassTime = tm;
+ ReadProgress(this, progressArgs);
}
+ Device.CommandStatus st = FetchSectors(sector, m_max_sectors, false);
+ TimeSpan delay = DateTime.Now - tm;
+ _autodetectResult += string.Format("{0}: {1} ({2}ms)\n", CurrentReadCommand, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), delay.TotalMilliseconds);
+ found = st == Device.CommandStatus.Success;
+
+ //sector += m_max_sectors;
+ }
//if (found)
// for (int n = 1; n <= m_max_sectors; n++)
// {
@@ -508,11 +762,16 @@ namespace CUETools.Ripper.SCSI
// break;
// }
// }
+ TestGaps();
+
if (found)
_autodetectResult += "Chosen " + CurrentReadCommand + "\n";
else
_readCDCommand = ReadCDCommand.Unknown;
+
_currentStart = -1;
+ _currentEnd = -1;
+ readCommandFound = found;
return found;
}
@@ -522,8 +781,8 @@ namespace CUETools.Ripper.SCSI
private unsafe void ReorganiseSectors(int sector, int Sectors2Read)
{
int c2Size = _c2ErrorMode == Device.C2ErrorMode.None ? 0 : _c2ErrorMode == Device.C2ErrorMode.Mode294 ? 294 : 296;
- int oldSize = 4 * 588 + c2Size + (_subChannelMode == Device.SubChannelMode.None ? 0 : 16);
- fixed (byte* readBuf = _readBuffer, qBuf = _subchannelBuffer, qData = QData, c2Count = C2Count)
+ int oldSize = 4 * 588 + c2Size;
+ fixed (byte* readBuf = _readBuffer, c2Count = C2Count)
fixed (long* userData = UserData)
{
for (int iSector = 0; iSector < Sectors2Read; iSector++)
@@ -531,7 +790,6 @@ namespace CUETools.Ripper.SCSI
byte* sectorPtr = readBuf + iSector * oldSize;
long* userDataPtr = userData + (sector - _currentStart + iSector) * 8 * 588;
byte* c2CountPtr = c2Count + (sector - _currentStart + iSector) * 294;
- byte* qDataPtr = qData + (sector - _currentStart + iSector) * 16;
//if (_currentStart > 0)
//{
@@ -552,7 +810,7 @@ namespace CUETools.Ripper.SCSI
int offs = 0;
if (c2Size == 296)
{
- // sometimes sector C2 byte is placed after C2 info, not before!!
+ // TODO: sometimes sector C2 byte is placed after C2 info, not before!!
int c2 = 0;
for (int pos = 2; pos < 294; pos++)
c2 |= sectorPtr[4 * 588 + pos];
@@ -582,14 +840,8 @@ namespace CUETools.Ripper.SCSI
else
{
for (int sample = 0; sample < 4 * 588; sample++)
- userDataPtr[sample] += byte2long[sectorPtr[sample]] * 3;
+ userDataPtr[sample] += byte2long[sectorPtr[sample]];
}
- if (_subChannelMode != Device.SubChannelMode.None)
- for (int qi = 0; qi < 16; qi++)
- qDataPtr[qi] = sectorPtr[4 * 588 + c2Size + qi];
- else
- for (int qi = 0; qi < 16; qi++)
- qDataPtr[qi] = qBuf[iSector * 16 + qi];
}
}
}
@@ -604,26 +856,22 @@ namespace CUETools.Ripper.SCSI
}
}
- private unsafe Device.CommandStatus FetchSectors(int sector, int Sectors2Read, bool abort, bool subchannel)
+ private unsafe Device.CommandStatus FetchSectors(int sector, int Sectors2Read, bool abort)
{
Device.CommandStatus st;
fixed (byte* data = _readBuffer)
{
if (_debugMessages)
{
- int size = (4 * 588 +
- (_subChannelMode == Device.SubChannelMode.QOnly ? 16 : _subChannelMode == Device.SubChannelMode.RWMode ? 96 : 0) +
- (_c2ErrorMode == Device.C2ErrorMode.Mode294 ? 294 : _c2ErrorMode == Device.C2ErrorMode.Mode296 ? 296 : 0)) * (int)Sectors2Read;
+ int size = (4 * 588 + (_c2ErrorMode == Device.C2ErrorMode.Mode294 ? 294 : _c2ErrorMode == Device.C2ErrorMode.Mode296 ? 296 : 0))
+ * (int)Sectors2Read;
MemSet(data, size, 0xff);
}
if (_readCDCommand == ReadCDCommand.ReadCdBEh)
- st = m_device.ReadCDAndSubChannel(_mainChannelMode, _subChannelMode, _c2ErrorMode, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)Sectors2Read, (IntPtr)((void*)data), _timeout);
+ st = m_device.ReadCDAndSubChannel(_mainChannelMode, Device.SubChannelMode.None, _c2ErrorMode, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)Sectors2Read, (IntPtr)((void*)data), _timeout);
else
- st = m_device.ReadCDDA(_subChannelMode, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)Sectors2Read, (IntPtr)((void*)data), _timeout);
+ st = m_device.ReadCDDA(Device.SubChannelMode.None, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)Sectors2Read, (IntPtr)((void*)data), _timeout);
}
-
- if (st == Device.CommandStatus.Success && _subChannelMode == Device.SubChannelMode.None && subchannel)
- st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)Sectors2Read, ref _subchannelBuffer, _timeout);
if (st == Device.CommandStatus.Success)
{
@@ -641,13 +889,11 @@ namespace CUETools.Ripper.SCSI
int iErrors = 0;
for (int iSector = 0; iSector < Sectors2Read; iSector++)
{
- if (FetchSectors(sector + iSector, 1, false, subchannel) != Device.CommandStatus.Success)
+ if (FetchSectors(sector + iSector, 1, false) != Device.CommandStatus.Success)
{
iErrors ++;
for (int i = 0; i < 294; i++)
C2Count[sector + iSector - _currentStart, i] ++;
- for (int i = 0; i < 16; i++)
- QData[ sector + iSector - _currentStart, i] = 0;
if (_debugMessages)
System.Console.WriteLine("\nSector lost");
}
@@ -814,6 +1060,7 @@ namespace CUETools.Ripper.SCSI
fError |= (sum ^ sig) < er_limit;
bestValue += sig & (1 << i);
val >>= 8;
+ val1 >>= 8;
}
currentData.Bytes[pos * 4 * 588 + iPar] = (byte)bestValue;
}
@@ -891,10 +1138,10 @@ namespace CUETools.Ripper.SCSI
if (iSector >= _currentStart && iSector < _currentEnd)
return;
- if (_readCDCommand == ReadCDCommand.Unknown && !TestReadCommand())
- throw new Exception("failed to autodetect read command: " + _autodetectResult);
+ if (!TestReadCommand())
+ throw new Exception("failed to autodetect read command:\n" + _autodetectResult);
- _currentStart = MSECTORS * (iSector / MSECTORS);
+ _currentStart = iSector;
_currentEnd = _currentStart + MSECTORS;
if (_currentEnd > (int)_toc.AudioLength)
{
@@ -918,6 +1165,12 @@ namespace CUETools.Ripper.SCSI
for (int i = 0; i < MSECTORS; i++)
errtmp[i] = 0;
+ //Device.CommandStatus st = m_device.SetCdSpeed(Device.RotationalControl.CLVandNonPureCav, (ushort)(176 * 4), 65535);
+ //if (st != Device.CommandStatus.Success)
+ // System.Console.WriteLine("SetCdSpeed: {0}", (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()));
+
+ // TODO:
+ //int max_scans = 1 << _correctionQuality;
int max_scans = 16 << _correctionQuality;
for (int pass = 0; pass < max_scans; pass++)
{
@@ -935,10 +1188,8 @@ namespace CUETools.Ripper.SCSI
LastFetch = DateTime.Now;
if (pass == 0)
ClearSectors(sector, Sectors2Read);
- FetchSectors(sector, Sectors2Read, true, pass == 0);
+ FetchSectors(sector, Sectors2Read, true);
//TimeSpan delay1 = DateTime.Now - LastFetch;
- if (pass == 0)
- ProcessSubchannel(sector, Sectors2Read, true);
//DateTime LastFetched = DateTime.Now;
if (pass >= _correctionQuality)
{
@@ -949,7 +1200,16 @@ namespace CUETools.Ripper.SCSI
//if (sector == _currentStart)
//System.Console.WriteLine("\n{0},{1}", delay1.TotalMilliseconds, delay2.TotalMilliseconds);
if (ReadProgress != null)
- ReadProgress(this, new ReadProgressArgs(sector + Sectors2Read, pass, _currentStart, _currentEnd, _currentErrorsCount, PassTime));
+ {
+ progressArgs.Action = "Ripping";
+ progressArgs.Position = sector + Sectors2Read;
+ progressArgs.Pass = pass;
+ progressArgs.PassStart = _currentStart;
+ progressArgs.PassEnd = _currentEnd;
+ progressArgs.ErrorsCount = _currentErrorsCount;
+ progressArgs.PassTime = PassTime;
+ ReadProgress(this, progressArgs);
+ }
}
//System.Console.WriteLine();
//if (CorrectSectorsTest(start, _currentEnd, 10, realData) == 0)
@@ -970,6 +1230,7 @@ namespace CUETools.Ripper.SCSI
{
for (int i = 0; i < buff.ByteLength; i++)
buff.Bytes[i] = 0;
+ _sampleOffset += buff.Length;
return buff.Length; // == Remaining
}
if (_sampleOffset < 0)
@@ -977,9 +1238,10 @@ namespace CUETools.Ripper.SCSI
buff.Length = Math.Min(buff.Length, -_sampleOffset);
for (int i = 0; i < buff.ByteLength; i++)
buff.Bytes[i] = 0;
+ _sampleOffset += buff.Length;
return buff.Length;
}
- PrefetchSector(_sampleOffset / 588);
+ PrefetchSector(/*(int)_toc[_toc.FirstAudio][0].Start +*/ (_sampleOffset / 588));
buff.Length = Math.Min(buff.Length, (int)Length - _sampleOffset);
buff.Length = Math.Min(buff.Length, _currentEnd * 588 - _sampleOffset);
if ((_sampleOffset - _currentStart * 588) == 0 && (maxLength < 0 || (_currentEnd - _currentStart) * 588 <= buff.Length))
@@ -1101,7 +1363,7 @@ namespace CUETools.Ripper.SCSI
{
get
{
- return "CUERipper v2.0.5 Copyright (C) 2008-10 Gregory S. Chudov";
+ return "CUERipper v2.0.6 Copyright (C) 2008-10 Gregory S. Chudov";
// ripper.GetName().Name + " " + ripper.GetName().Version;
}
}
diff --git a/CUETools.Ripper/Properties/AssemblyInfo.cs b/CUETools.Ripper/Properties/AssemblyInfo.cs
index 113510b..4099b0a 100644
--- a/CUETools.Ripper/Properties/AssemblyInfo.cs
+++ b/CUETools.Ripper/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools.Ripper/Ripper.cs b/CUETools.Ripper/Ripper.cs
index 7356e13..4e60e57 100644
--- a/CUETools.Ripper/Ripper.cs
+++ b/CUETools.Ripper/Ripper.cs
@@ -11,6 +11,8 @@ namespace CUETools.Ripper
public interface ICDRipper : IAudioSource, IDisposable
{
bool Open(char Drive);
+ bool DetectGaps();
+ bool GapsDetected { get; }
CDImageLayout TOC { get; }
string ARName { get; }
string EACName { get; }
@@ -37,12 +39,17 @@ namespace CUETools.Ripper
public sealed class ReadProgressArgs : EventArgs
{
+ public string Action;
public int Position;
public int Pass;
public int PassStart, PassEnd;
public int ErrorsCount;
public DateTime PassTime;
+ public ReadProgressArgs()
+ {
+ }
+
public ReadProgressArgs(int position, int pass, int passStart, int passEnd, int errorsCount, DateTime passTime)
{
Position = position;
diff --git a/CUETools/CUETools.TestProcessor/ProcessorTest.cs b/CUETools/CUETools.TestProcessor/ProcessorTest.cs
index 37e2f35..637fb7d 100644
--- a/CUETools/CUETools.TestProcessor/ProcessorTest.cs
+++ b/CUETools/CUETools.TestProcessor/ProcessorTest.cs
@@ -71,36 +71,49 @@ namespace CUETools.TestProcessor
///
- ///A test for Open (string)
+ ///A test for CD-Extra
///
[TestMethod()]
- public void OpenTest()
+ public void OpenCDExtra()
{
- CUEConfig config = new CUEConfig();
- CUESheet target = null;
-
// test playstation-type CD-Extra
- target = new CUESheet(config);
+ CUESheet target = new CUESheet(new CUEConfig());
target.Open("Circuitry\\1.cue");
Assert.AreEqual("00078c13-001b4ab9-40086205", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
// test playstation-type CD-Extra with nonstandard pregap
- target = new CUESheet(config);
+ target = new CUESheet(new CUEConfig());
target.Open("Headcandy\\Headcandy.cue");
Assert.AreEqual("0014fc22-0052b286-62104a06", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
- // test Enhanced-CD
- target = new CUESheet(config);
- target.Open("No Man's Land\\1.cue");
- Assert.AreEqual("0015c42c-00d1e13f-ba0fe50d", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
-
- // test one-track CD
- target = new CUESheet(config);
- target.Open("Amarok\\Amarok.cue");
- Assert.AreEqual("00041f6d-00083ece-020e1201", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
+ // test playstation-type CD-Extra with no info in cuesheet
+ target = new CUESheet(new CUEConfig());
+ target.Open("Anatomy\\Anatomy.cue");
+ Assert.AreEqual("002a09da-01e82f64-f00f4811", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
}
+ ///
+ ///A test for Enhanced-CD
+ ///
+ [TestMethod()]
+ public void OpenEnhancedCD()
+ {
+ // test Enhanced-CD
+ CUESheet target = new CUESheet(new CUEConfig());
+ target.Open("No Man's Land\\1.cue");
+ Assert.AreEqual("0015c42c-00d1e13f-ba0fe50d", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
+ }
+
+ ///
+ ///A test for one-track CD
+ ///
+ [TestMethod()]
+ public void OpenOneTrackCD()
+ {
+ // test one-track CD
+ CUESheet target = new CUESheet(new CUEConfig());
+ target.Open("Amarok\\Amarok.cue");
+ Assert.AreEqual("00041f6d-00083ece-020e1201", AccurateRipVerify.CalculateAccurateRipId(target.TOC), "Wrong TOC");
+ }
}
-
-
}
diff --git a/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.cue b/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.cue
new file mode 100644
index 0000000..a43b68b
--- /dev/null
+++ b/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.cue
@@ -0,0 +1,33 @@
+FILE "Anatomy.dummy" WAVE
+ TRACK 01 AUDIO
+ INDEX 01 00:00:00
+ TRACK 02 AUDIO
+ INDEX 01 02:59:32
+ TRACK 03 AUDIO
+ INDEX 01 06:53:18
+ TRACK 04 AUDIO
+ INDEX 01 11:09:10
+ TRACK 05 AUDIO
+ INDEX 01 15:35:10
+ TRACK 06 AUDIO
+ INDEX 01 19:38:47
+ TRACK 07 AUDIO
+ INDEX 01 24:58:61
+ TRACK 08 AUDIO
+ INDEX 01 29:05:63
+ TRACK 09 AUDIO
+ INDEX 01 32:34:34
+ TRACK 10 AUDIO
+ INDEX 01 38:55:70
+ TRACK 11 AUDIO
+ INDEX 01 40:06:35
+ TRACK 12 AUDIO
+ INDEX 01 43:35:72
+ TRACK 13 AUDIO
+ INDEX 01 48:04:59
+ TRACK 14 AUDIO
+ INDEX 01 49:35:03
+ TRACK 15 AUDIO
+ INDEX 01 55:31:06
+ TRACK 16 AUDIO
+ INDEX 01 58:17:56
diff --git a/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.dummy b/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.dummy
new file mode 100644
index 0000000..728d5ad
--- /dev/null
+++ b/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.dummy
@@ -0,0 +1 @@
+160952652
\ No newline at end of file
diff --git a/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.log b/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.log
new file mode 100644
index 0000000..2a4773e
--- /dev/null
+++ b/CUETools/CUETools.TestProcessor/Test Images/Anatomy/Anatomy.log
@@ -0,0 +1,85 @@
+Exact Audio Copy V0.99 prebeta 4 from 23. January 2008
+
+EAC extraction logfile from 4. March 2010, 23:08
+
+Îëüãà Àðåôüåâà / Àíàòîìèÿ (CD1)
+
+Used drive : PIONEER DVD-RW DVR-215D Adapter: 1 ID: 0
+
+Read mode : Secure
+Utilize accurate stream : Yes
+Defeat audio cache : Yes
+Make use of C2 pointers : No
+
+Read offset correction : 48
+Overread into Lead-In and Lead-Out : No
+Fill up missing offset samples with silence : Yes
+Delete leading and trailing silent blocks : No
+Null samples used in CRC calculations : Yes
+Used interface : Native Win32 interface for Win NT & 2000
+
+Used output format : Internal WAV Routines
+Sample format : 44.100 Hz; 16 Bit; Stereo
+
+
+TOC of the extracted CD
+
+ Track | Start | Length | Start sector | End sector
+ ---------------------------------------------------------
+ 1 | 0:00.00 | 4:22.37 | 0 | 19686
+ 2 | 4:22.37 | 2:59.32 | 19687 | 33143
+ 3 | 7:21.69 | 3:53.61 | 33144 | 50679
+ 4 | 11:15.55 | 4:15.67 | 50680 | 69871
+ 5 | 15:31.47 | 4:26.00 | 69872 | 89821
+ 6 | 19:57.47 | 4:03.37 | 89822 | 108083
+ 7 | 24:01.09 | 5:20.14 | 108084 | 132097
+ 8 | 29:21.23 | 4:07.02 | 132098 | 150624
+ 9 | 33:28.25 | 3:28.46 | 150625 | 166270
+ 10 | 36:56.71 | 6:21.36 | 166271 | 194881
+ 11 | 43:18.32 | 1:10.40 | 194882 | 200171
+ 12 | 44:28.72 | 3:29.37 | 200172 | 215883
+ 13 | 47:58.34 | 4:28.62 | 215884 | 236045
+ 14 | 52:27.21 | 1:30.19 | 236046 | 242814
+ 15 | 53:57.40 | 5:56.03 | 242815 | 269517
+ 16 | 59:53.43 | 2:46.50 | 269518 | 282017
+ 17 | 62:40.18 | 2:31.73 | 282018 | 293415
+
+
+Range status and errors
+
+Selected range
+
+ Filename Z:\Music\New\Îëüãà Àðåôüåâà - 2001 - Àíàòîìèÿ (CD1) (2)\Îëüãà Àðåôüåâà - Àíàòîìèÿ (CD1).wav
+
+ Peak level 96.8 %
+ Range quality 100.0 %
+ Test_CRC 900B46C9
+ Copy_CRC 900B46C9
+ Copy OK
+
+No errors occurred
+
+
+AccurateRip summary
+
+Track 1 not present in database
+Track 2 not present in database
+Track 3 cannot be verified as accurate (confidence 2) [ABFDCBE5], AccurateRip returned [CE139C13]
+Track 4 cannot be verified as accurate (confidence 2) [FD73C536], AccurateRip returned [ABFDCBE5]
+Track 5 cannot be verified as accurate (confidence 2) [041E67B6], AccurateRip returned [FD73C536]
+Track 6 cannot be verified as accurate (confidence 2) [7F3ACA35], AccurateRip returned [041E67B6]
+Track 7 cannot be verified as accurate (confidence 2) [40F2BE73], AccurateRip returned [7F3ACA35]
+Track 8 cannot be verified as accurate (confidence 2) [19AAED4C], AccurateRip returned [40F2BE73]
+Track 9 cannot be verified as accurate (confidence 2) [7C0E0656], AccurateRip returned [19AAED4C]
+Track 10 cannot be verified as accurate (confidence 2) [ADD905EF], AccurateRip returned [7C0E0656]
+Track 11 cannot be verified as accurate (confidence 2) [A18D8581], AccurateRip returned [ADD905EF]
+Track 12 cannot be verified as accurate (confidence 2) [B4E21ED5], AccurateRip returned [A18D8581]
+Track 13 cannot be verified as accurate (confidence 2) [7D5BC78C], AccurateRip returned [B4E21ED5]
+Track 14 cannot be verified as accurate (confidence 2) [40D2728E], AccurateRip returned [7D5BC78C]
+Track 15 cannot be verified as accurate (confidence 2) [990F316E], AccurateRip returned [40D2728E]
+Track 16 cannot be verified as accurate (confidence 2) [FC5F3E48], AccurateRip returned [990F316E]
+
+No tracks could be verified as accurate
+You may have a different pressing from the one(s) in the database
+
+End of status report
diff --git a/CUETools/CUETools1.vsmdi b/CUETools/CUETools1.vsmdi
new file mode 100644
index 0000000..72f5653
--- /dev/null
+++ b/CUETools/CUETools1.vsmdi
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CUETools/Properties/AssemblyInfo.cs b/CUETools/Properties/AssemblyInfo.cs
index 2ba63af..f069d41 100644
--- a/CUETools/Properties/AssemblyInfo.cs
+++ b/CUETools/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.0.5.0")]
-[assembly: AssemblyFileVersion("2.0.5.0")]
+[assembly: AssemblyVersion("2.0.6.0")]
+[assembly: AssemblyFileVersion("2.0.6.0")]
diff --git a/CUETools/Resources/more/icons/folder.png b/CUETools/Resources/more/icons/folder.png
new file mode 100644
index 0000000..784e8fa
Binary files /dev/null and b/CUETools/Resources/more/icons/folder.png differ
diff --git a/CUETools/Resources/more/icons/folder_add.png b/CUETools/Resources/more/icons/folder_add.png
new file mode 100644
index 0000000..529fe8f
Binary files /dev/null and b/CUETools/Resources/more/icons/folder_add.png differ
diff --git a/CUETools/Resources/more/icons/folder_delete.png b/CUETools/Resources/more/icons/folder_delete.png
new file mode 100644
index 0000000..112b016
Binary files /dev/null and b/CUETools/Resources/more/icons/folder_delete.png differ
diff --git a/CUETools/Resources/more/icons/folder_feed.png b/CUETools/Resources/more/icons/folder_feed.png
new file mode 100644
index 0000000..d06ee51
Binary files /dev/null and b/CUETools/Resources/more/icons/folder_feed.png differ
diff --git a/CUETools/Resources/more/icons/folder_page.png b/CUETools/Resources/more/icons/folder_page.png
new file mode 100644
index 0000000..1ef6e11
Binary files /dev/null and b/CUETools/Resources/more/icons/folder_page.png differ
diff --git a/CUETools/frmCUETools.Designer.cs b/CUETools/frmCUETools.Designer.cs
index aca7f0d..04cc7d9 100644
--- a/CUETools/frmCUETools.Designer.cs
+++ b/CUETools/frmCUETools.Designer.cs
@@ -286,9 +286,9 @@ namespace JDP {
this.fileSystemTreeView1.DragDrop += new System.Windows.Forms.DragEventHandler(this.fileSystemTreeView1_DragDrop);
this.fileSystemTreeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.fileSystemTreeView1_AfterSelect);
this.fileSystemTreeView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.fileSystemTreeView1_MouseDown);
- this.fileSystemTreeView1.DragEnter += new System.Windows.Forms.DragEventHandler(this.fileSystemTreeView1_DragEnter);
this.fileSystemTreeView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.fileSystemTreeView1_KeyDown);
this.fileSystemTreeView1.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.fileSystemTreeView1_AfterExpand);
+ this.fileSystemTreeView1.DragOver += new System.Windows.Forms.DragEventHandler(this.fileSystemTreeView1_DragOver);
//
// tableLayoutPanel2
//
diff --git a/CUETools/frmCUETools.cs b/CUETools/frmCUETools.cs
index fcbabe6..7c78ce2 100644
--- a/CUETools/frmCUETools.cs
+++ b/CUETools/frmCUETools.cs
@@ -738,15 +738,12 @@ namespace JDP {
cueSheet.OutputStyle = cueStyle;
cueSheet.Open(pathIn);
cueSheet.PreGapLengthMSF = txtPreGapLength.Text;
- if (useAR)
- {
+ if (useAR || useCUEToolsDB)
cueSheet.DataTrackLengthMSF = txtDataTrackLength.Text;
- cueSheet.UseAccurateRip();
- }
if (useCUEToolsDB)
- {
- cueSheet.UseCUEToolsDB(false, "CUETools 205");
- }
+ cueSheet.UseCUEToolsDB(false, "CUETools 2.0.6");
+ if (useAR)
+ cueSheet.UseAccurateRip();
if (_batchPaths.Count == 0 && action == CUEAction.Encode)
{
@@ -761,10 +758,15 @@ namespace JDP {
toolStripStatusLabelAR.Text = cueSheet.ArVerify.ARStatus == null ? cueSheet.ArVerify.WorstTotal().ToString() : "";
toolStripStatusLabelAR.ToolTipText = "AccurateRip: " + (cueSheet.ArVerify.ARStatus ?? "found") + ".";
- toolStripStatusLabelCTDB.Enabled = cueSheet.CTDB.DBStatus == null;
- toolStripStatusLabelCTDB.Visible = useCUEToolsDB;
- toolStripStatusLabelCTDB.Text = cueSheet.CTDB.DBStatus == null ? cueSheet.CTDB.Total.ToString() : "";
- toolStripStatusLabelCTDB.ToolTipText = "CUETools DB: " + (cueSheet.CTDB.DBStatus ?? "found") + ".";
+ if (!useCUEToolsDB)
+ toolStripStatusLabelCTDB.Visible = false;
+ else
+ {
+ toolStripStatusLabelCTDB.Visible = true;
+ toolStripStatusLabelCTDB.Enabled = cueSheet.CTDB.DBStatus == null;
+ toolStripStatusLabelCTDB.Text = cueSheet.CTDB.DBStatus == null ? cueSheet.CTDB.Total.ToString() : "";
+ toolStripStatusLabelCTDB.ToolTipText = "CUETools DB: " + (cueSheet.CTDB.DBStatus ?? "found") + ".";
+ }
if (releases != null)
{
@@ -917,7 +919,11 @@ namespace JDP {
else
{
_batchProcessed++;
- BatchLog("{0}.", pathIn, ex.Message);
+ String msg = "";
+ for (Exception e = ex; e != null; e = e.InnerException)
+ msg += ": " + e.Message;
+ BatchLog("{0}.", pathIn, msg.Substring(2));
+
}
}
#endif
@@ -1592,13 +1598,20 @@ namespace JDP {
private void fileSystemTreeView1_KeyDown(object sender, KeyEventArgs e)
{
- if (e.KeyCode != Keys.F5) return;
- if (fileSystemTreeView1.Nodes.Count == 0) return;
- string was = fileSystemTreeView1.SelectedPath;
- fileSystemTreeView1.Nodes[0].Collapse();
- fileSystemTreeView1.Nodes[0].Expand();
- if (was != null)
- fileSystemTreeView1.SelectedPath = was;
+ switch (e.KeyCode)
+ {
+ case Keys.F5:
+ string was = fileSystemTreeView1.SelectedPath;
+ foreach (TreeNode node in fileSystemTreeView1.Nodes)
+ node.Collapse();
+ if (was != null)
+ fileSystemTreeView1.SelectedPath = was;
+ break;
+ case Keys.Delete:
+ if (FileBrowserState == FileBrowserStateEnum.DragDrop && fileSystemTreeView1.SelectedNode != null)
+ fileSystemTreeView1.Nodes.Remove(fileSystemTreeView1.SelectedNode);
+ break;
+ }
}
private void fileSystemTreeView1_NodeExpand(object sender, CUEControls.FileSystemTreeViewNodeExpandEventArgs e)
@@ -1680,11 +1693,14 @@ namespace JDP {
node.Checked = e.Node.Checked;
}
- private void fileSystemTreeView1_DragEnter(object sender, DragEventArgs e)
+ private void fileSystemTreeView1_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
- e.Effect = DragDropEffects.Copy;
+ if (((e.KeyState & 8) != 0 && FileBrowserState == FileBrowserStateEnum.DragDrop) || FileBrowserState == FileBrowserStateEnum.Checkboxes)
+ e.Effect = DragDropEffects.Copy;
+ else
+ e.Effect = DragDropEffects.Move;
}
}
@@ -1716,7 +1732,8 @@ namespace JDP {
}
break;
case FileBrowserStateEnum.DragDrop:
- fileSystemTreeView1.Nodes.Clear();
+ if (e.Effect == DragDropEffects.Move)
+ fileSystemTreeView1.Nodes.Clear();
foreach (string folder in folders)
{
TreeNode node = Directory.Exists(folder)
diff --git a/CUETools/frmCUETools.resx b/CUETools/frmCUETools.resx
index 4a4a385..00defbc 100644
--- a/CUETools/frmCUETools.resx
+++ b/CUETools/frmCUETools.resx
@@ -258,26 +258,11 @@
0
-
- Top, Bottom, Left, Right
-
-
- 19
-
-
- 3, 17
-
-
- 192, 304
-
-
- 1
-
fileSystemTreeView1
- CUEControls.FileSystemTreeView, CUEControls, Version=2.0.5.0, Culture=neutral, PublicKeyToken=null
+ CUEControls.FileSystemTreeView, CUEControls, Version=2.0.6.0, Culture=neutral, PublicKeyToken=null
grpInput
@@ -318,9 +303,1032 @@
3
+
+ 3, 17
+
+
+ tableLayoutPanelCUEStyle
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBoxMode
+
+
+ 0
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxUseAccurateRip" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="checkBoxUseFreeDb" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="rbTracks" Row="2" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbEmbedCUE" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbSingleFile" Row="1" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="checkBoxUseMusicBrainz" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,33,33332,Percent,33,33334,Percent,33,33334" /><Rows Styles="Percent,18,18229,Percent,18,18229,Percent,18,18229,Percent,22,72658,Percent,22,72658" /></TableLayoutSettings>
+
+
+ toolStripCorrectorFormat
+
+
+ System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBoxMode
+
+
+ 1
+
+
+ tableLayoutPanelVerifyMode
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBoxMode
+
+
+ 2
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxVerifyUseCDRepair" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,36,11111,Percent,63,88889" /><Rows Styles="Percent,32,72727,Percent,67,27273" /></TableLayoutSettings>
+
+
+ Fill
+
+
+ 173, 101
+
+
+ 150, 130
+
+
+ 12
+
+
+ Mode
+
+
+ groupBoxMode
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 0
+
+
+ labelEncoderMaxMode
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 0
+
+
+ labelEncoderMinMode
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 1
+
+
+ labelEncoderMode
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 2
+
+
+ trackBarEncoderMode
+
+
+ System.Windows.Forms.TrackBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 3
+
+
+ comboBoxEncoder
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 4
+
+
+ radioButtonAudioNone
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 5
+
+
+ radioButtonAudioLossy
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 6
+
+
+ radioButtonAudioHybrid
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 7
+
+
+ radioButtonAudioLossless
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 8
+
+
+ labelFormat
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 9
+
+
+ comboBoxAudioFormat
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAudioOutput
+
+
+ 10
+
+
+ Fill
+
+
+ 329, 101
+
+
+ 148, 194
+
+
+ 2
+
+
+ Audio Output
+
+
+ grpAudioOutput
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 1
+
+
+ Fill
+
+
+ NoControl
+
+
+ 3, 237
+
+
+ 164, 90
+
+
+ Zoom
+
+
+ 15
+
+
+ pictureBoxMotd
+
+
+ System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 2
+
+
+ 2
+
+
+ Fill
+
+
+ NoControl
+
+
+ 0, 48
+
+
+ 0, 0, 0, 0
+
+
+ 97, 24
+
+
+ 13
+
+
+ Template:
+
+
+ MiddleLeft
+
+
+ labelOutputTemplate
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelPaths
+
+
+ 0
+
+
+ Fill
+
+
+ 100, 51
+
+
+ 365, 21
+
+
+ 9
+
+
+ 153, 8
+
+
+ Template for output files (foobar2000 format)
+
+
+ comboBoxOutputFormat
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelPaths
+
+
+ 1
+
+
+ Fill
+
+
+ 100, 3
+
+
+ 365, 21
+
+
+ 0
+
+
+ Input file
+
+
+ txtInputPath
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelPaths
+
+
+ 2
+
+
+ Fill
+
+
+ 100, 27
+
+
+ 365, 21
+
+
+ 0
+
+
+ Output file
+
+
+ txtOutputPath
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelPaths
+
+
+ 3
+
+
+ 0, 0
+
+
+ Fill
+
+
+ 0, 0
+
+
+ 0, 0, 0, 0
+
+
+ 97, 24
+
+
+ 14
+
+
+ toolStripInput
+
+
+ toolStripInput
+
+
+ System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelPaths
+
+
+ 4
+
+
+ 0, 24
+
+
+ Fill
+
+
+ 0, 24
+
+
+ 0, 0, 0, 0
+
+
+ 97, 24
+
+
+ 15
+
+
+ toolStripOutput
+
+
+ toolStripOutput
+
+
+ System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelPaths
+
+
+ 5
+
+
+ Fill
+
+
+ 3, 17
+
+
+ 0, 0, 0, 0
+
+
+ 3
+
+
+ 468, 72
+
+
+ 14
+
+
+ tableLayoutPanelPaths
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpOutputPathGeneration
+
+
+ 0
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelOutputTemplate" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBoxOutputFormat" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtInputPath" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtOutputPath" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="toolStripInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="toolStripOutput" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,20,94017,Percent,79,05983" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings>
+
+
+ Fill
+
+
+ 3, 3
+
+
+ 474, 92
+
+
+ 1
+
+
+ CUE Paths
+
+
+ grpOutputPathGeneration
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 3
+
+
+ comboBoxScript
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAction
+
+
+ 0
+
+
+ rbActionCorrectFilenames
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAction
+
+
+ 1
+
+
+ rbActionCreateCUESheet
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAction
+
+
+ 2
+
+
+ rbActionVerify
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAction
+
+
+ 3
+
+
+ rbActionEncode
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpAction
+
+
+ 4
+
+
+ Fill
+
+
+ 3, 101
+
+
+ 164, 130
+
+
+ 4
+
+
+ Action
+
+
+ grpAction
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 4
+
+
+ tableLayoutPanel4
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpExtra
+
+
+ 0
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelPregap" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="lblWriteOffset" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="numericWriteOffset" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtPreGapLength" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelDataTrack" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="txtDataTrackLength" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,56,75676,Percent,43,24324" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings>
+
+
+ Fill
+
+
+ 173, 237
+
+
+ 150, 90
+
+
+ 6
+
+
+ Extra
+
+
+ grpExtra
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 5
+
+
+ btnConvert
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panelGo
+
+
+ 0
+
+
+ btnStop
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panelGo
+
+
+ 1
+
+
+ btnResume
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panelGo
+
+
+ 2
+
+
+ btnPause
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panelGo
+
+
+ 3
+
+
+ Fill
+
+
+ 338, 301
+
+
+ 12, 3, 12, 3
+
+
+ 130, 26
+
+
+ 14
+
+
+ panelGo
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel2
+
+
+ 6
+
+
+ Fill
+
+
+ 204, 0
+
+
+ 0, 0, 0, 0
+
+
+ 4
+
+
+ 480, 330
+
+
+ 1
+
+
+ tableLayoutPanel2
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel1
+
+
+ 2
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="groupBoxMode" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="grpAudioOutput" Row="1" RowSpan="2" Column="2" ColumnSpan="1" /><Control Name="pictureBoxMotd" Row="2" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="grpOutputPathGeneration" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="grpAction" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="grpExtra" Row="2" RowSpan="2" Column="1" ColumnSpan="1" /><Control Name="panelGo" Row="3" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="Percent,35,41667,Percent,32,70833,Percent,31,875" /><Rows Styles="Percent,29,69697,Percent,41,51515,Percent,19,39394,Percent,9,393939" /></TableLayoutSettings>
+
+
+ Fill
+
+
+ 0, 0
+
+
+ 0, 0, 0, 0
+
+
+ 2
+
+
+ 684, 451
+
+
+ 17
+
+
+ tableLayoutPanel1
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripContainer1.ContentPanel
+
+
+ 0
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="textBatchReport" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="grpInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,480" /><Rows Styles="Absolute,330,Percent,100" /></TableLayoutSettings>
+
+
+ 0, 0, 0, 0
+
+
+ 684, 451
+
+
+ toolStripContainer1.ContentPanel
+
+
+ System.Windows.Forms.ToolStripContentPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripContainer1
+
+
+ 0
+
+
+ Fill
+
+
+ toolStripContainer1.LeftToolStripPanel
+
+
+ System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripContainer1
+
+
+ 1
+
+
+ 0, 0
+
+
+ toolStripContainer1.RightToolStripPanel
+
+
+ System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripContainer1
+
+
+ 2
+
+
+ 684, 502
+
+
+ 17
+
+
+ toolStripContainer1
+
+
+ 0, 0
+
+
+ None
+
+
+ 0, 0
+
+
+ 684, 25
+
+
+ 0
+
+
+ toolStripMenu
+
+
+ System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripContainer1.TopToolStripPanel
+
+
+ 0
+
+
+ toolStripContainer1.TopToolStripPanel
+
+
+ System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripContainer1
+
+
+ 3
+
+
+ toolStripContainer1
+
+
+ System.Windows.Forms.ToolStripContainer, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ Top, Bottom, Left, Right
+
+
+ 19
+
+
+ 3, 17
+
+
+ 192, 304
+
+
+ 1
+
+
+ fileSystemTreeView1
+
+
+ CUEControls.FileSystemTreeView, CUEControls, Version=2.0.6.0, Culture=neutral, PublicKeyToken=null
+
+
+ grpInput
+
+
+ 0
+
3
+
+ checkBoxUseAccurateRip
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelCUEStyle
+
+
+ 0
+
+
+ checkBoxUseFreeDb
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelCUEStyle
+
+
+ 1
+
+
+ rbTracks
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelCUEStyle
+
+
+ 2
+
+
+ rbEmbedCUE
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelCUEStyle
+
+
+ 3
+
+
+ rbSingleFile
+
+
+ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelCUEStyle
+
+
+ 4
+
+
+ checkBoxUseMusicBrainz
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanelCUEStyle
+
+
+ 5
+
+
+ Fill
+
+
+ 3, 17
+
+
+ 0, 0, 0, 0
+
+
+ 5
+
+
+ 144, 110
+
+
+ 11
+
+
+ tableLayoutPanelCUEStyle
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBoxMode
+
+
+ 0
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxUseAccurateRip" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="checkBoxUseFreeDb" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="rbTracks" Row="2" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbEmbedCUE" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbSingleFile" Row="1" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="checkBoxUseMusicBrainz" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,33,33332,Percent,33,33334,Percent,33,33334" /><Rows Styles="Percent,18,18229,Percent,18,18229,Percent,18,18229,Percent,22,72658,Percent,22,72658" /></TableLayoutSettings>
+
+
+ 153, 8
+
True
@@ -342,9 +1350,6 @@
5
-
- 153, 8
-
Use AccurateRip
@@ -549,39 +1554,6 @@
5
-
- Fill
-
-
- 3, 17
-
-
- 0, 0, 0, 0
-
-
- 5
-
-
- 144, 110
-
-
- 11
-
-
- tableLayoutPanelCUEStyle
-
-
- System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- groupBoxMode
-
-
- 0
-
-
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxUseAccurateRip" Row="4" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="checkBoxUseFreeDb" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="rbTracks" Row="2" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbEmbedCUE" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="rbSingleFile" Row="1" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="checkBoxUseMusicBrainz" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,33,33332,Percent,33,33334,Percent,33,33334" /><Rows Styles="Percent,18,18229,Percent,18,18229,Percent,18,18229,Percent,22,72658,Percent,22,72658" /></TableLayoutSettings>
-
3, 17
@@ -591,51 +1563,6 @@
Fill
-
- Magenta
-
-
- 78, 20
-
-
- Overwrite
-
-
- 168, 22
-
-
- Locate files
-
-
- Try to locate missing files automatically
-
-
- 168, 22
-
-
- Change extension
-
-
- Replace extension for audio files with this:
-
-
- Magenta
-
-
- 79, 19
-
-
- Locate files
-
-
- Magenta
-
-
- 39, 19
-
-
- flac
-
3, 17
@@ -660,27 +1587,54 @@
1
+
+ Magenta
+
+
+ 78, 20
+
+
+ Overwrite
+
+
+ Magenta
+
+
+ 79, 19
+
+
+ Locate files
+
+
+ 168, 22
+
+
+ Locate files
+
+
+ Try to locate missing files automatically
+
+
+ 168, 22
+
+
+ Change extension
+
+
+ Replace extension for audio files with this:
+
+
+ Magenta
+
+
+ 39, 19
+
+
+ flac
+
2
-
- True
-
-
- Fill
-
-
- NoControl
-
-
- 3, 3
-
-
- 45, 29
-
-
- 0
-
checkBoxVerifyUseCDRepair
@@ -726,31 +1680,34 @@
<?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="checkBoxVerifyUseCDRepair" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,36,11111,Percent,63,88889" /><Rows Styles="Percent,32,72727,Percent,67,27273" /></TableLayoutSettings>
-
+
+ True
+
+
Fill
-
- 173, 101
+
+ NoControl
-
- 150, 130
+
+ 3, 3
-
- 12
+
+ 45, 29
-
- Mode
+
+ 0
-
- groupBoxMode
+
+ checkBoxVerifyUseCDRepair
-
- System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- tableLayoutPanel2
+
+ tableLayoutPanelVerifyMode
-
+
0
@@ -1113,195 +2070,21 @@
10
-
- Fill
-
-
- 329, 101
-
-
- 148, 194
-
-
- 2
-
-
- Audio Output
-
-
- grpAudioOutput
-
-
- System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel2
-
-
- 1
-
-
- Fill
-
-
- NoControl
-
-
- 3, 237
-
-
- 164, 90
-
-
- Zoom
-
-
- 15
-
-
- pictureBoxMotd
-
-
- System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel2
-
-
- 2
-
-
- 2
-
-
- Fill
-
-
- NoControl
-
-
- 0, 48
-
-
- 0, 0, 0, 0
-
-
- 97, 24
-
-
- 13
-
-
- Template:
-
-
- MiddleLeft
-
-
- labelOutputTemplate
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanelPaths
-
-
- 0
-
-
- Fill
-
-
- 100, 51
-
-
- 365, 21
-
-
- 9
-
-
- Template for output files (foobar2000 format)
-
-
- comboBoxOutputFormat
-
-
- System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanelPaths
-
-
- 1
-
-
- Fill
-
-
- 100, 3
-
-
- 365, 21
-
-
- 0
-
-
- Input file
-
-
- txtInputPath
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanelPaths
-
-
- 2
-
-
- Fill
-
-
- 100, 27
-
-
- 365, 21
-
-
- 0
-
-
- Output file
-
-
- txtOutputPath
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanelPaths
-
-
- 3
-
-
- 0, 0
-
-
- Fill
-
38, 21
Input:
+
+ Magenta
+
+
+ 32, 21
+
+
+ Open/close input browser
+
177, 22
@@ -1326,54 +2109,21 @@
Hide browser
-
- Magenta
-
-
- 32, 21
-
-
- Open/close input browser
-
-
- 0, 0
-
-
- 0, 0, 0, 0
-
-
- 97, 24
-
-
- 14
-
-
- toolStripInput
-
-
- toolStripInput
-
-
- System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanelPaths
-
-
- 4
-
-
- 0, 24
-
-
- Fill
-
48, 24
Output:
+
+ Magenta
+
+
+ 32, 21
+
+
+ toolStripSplitButtonOutputBrowser
+
143, 22
@@ -1392,102 +2142,6 @@
Use template
-
- Magenta
-
-
- 32, 21
-
-
- toolStripSplitButtonOutputBrowser
-
-
- 0, 24
-
-
- 0, 0, 0, 0
-
-
- 97, 24
-
-
- 15
-
-
- toolStripOutput
-
-
- toolStripOutput
-
-
- System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanelPaths
-
-
- 5
-
-
- Fill
-
-
- 3, 17
-
-
- 0, 0, 0, 0
-
-
- 3
-
-
- 468, 72
-
-
- 14
-
-
- tableLayoutPanelPaths
-
-
- System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- grpOutputPathGeneration
-
-
- 0
-
-
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelOutputTemplate" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBoxOutputFormat" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtInputPath" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtOutputPath" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="toolStripInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="toolStripOutput" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,20,94017,Percent,79,05983" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings>
-
-
- Fill
-
-
- 3, 3
-
-
- 474, 92
-
-
- 1
-
-
- CUE Paths
-
-
- grpOutputPathGeneration
-
-
- System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel2
-
-
- 3
-
Top, Left, Right
@@ -1647,36 +2301,114 @@
4
-
- Fill
-
-
- 3, 101
-
-
- 164, 130
-
-
- 4
-
-
- Action
-
-
- grpAction
-
-
- System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel2
-
-
- 4
-
2
+
+ labelPregap
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel4
+
+
+ 0
+
+
+ lblWriteOffset
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel4
+
+
+ 1
+
+
+ numericWriteOffset
+
+
+ System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel4
+
+
+ 2
+
+
+ txtPreGapLength
+
+
+ System.Windows.Forms.MaskedTextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel4
+
+
+ 3
+
+
+ labelDataTrack
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel4
+
+
+ 4
+
+
+ txtDataTrackLength
+
+
+ System.Windows.Forms.MaskedTextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tableLayoutPanel4
+
+
+ 5
+
+
+ Fill
+
+
+ 3, 17
+
+
+ 0, 0, 0, 0
+
+
+ 3
+
+
+ 144, 70
+
+
+ 6
+
+
+ tableLayoutPanel4
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ grpExtra
+
+
+ 0
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelPregap" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="lblWriteOffset" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="numericWriteOffset" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtPreGapLength" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelDataTrack" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="txtDataTrackLength" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,56,75676,Percent,43,24324" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings>
+
True
@@ -1881,66 +2613,6 @@
5
-
- Fill
-
-
- 3, 17
-
-
- 0, 0, 0, 0
-
-
- 3
-
-
- 144, 70
-
-
- 6
-
-
- tableLayoutPanel4
-
-
- System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- grpExtra
-
-
- 0
-
-
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelPregap" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="lblWriteOffset" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="numericWriteOffset" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="txtPreGapLength" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="labelDataTrack" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="txtDataTrackLength" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,56,75676,Percent,43,24324" /><Rows Styles="Percent,33,33333,Percent,33,33333,Percent,33,33333" /></TableLayoutSettings>
-
-
- Fill
-
-
- 173, 237
-
-
- 150, 90
-
-
- 6
-
-
- Extra
-
-
- grpExtra
-
-
- System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel2
-
-
- 5
-
Fill
@@ -2079,161 +2751,17 @@
3
-
- Fill
+
+ Magenta
-
- 338, 301
+
+ 73, 22
-
- 12, 3, 12, 3
+
+ default
-
- 130, 26
-
-
- 14
-
-
- panelGo
-
-
- System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel2
-
-
- 6
-
-
- Fill
-
-
- 204, 0
-
-
- 0, 0, 0, 0
-
-
- 4
-
-
- 480, 330
-
-
- 1
-
-
- tableLayoutPanel2
-
-
- System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tableLayoutPanel1
-
-
- 2
-
-
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="groupBoxMode" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="grpAudioOutput" Row="1" RowSpan="2" Column="2" ColumnSpan="1" /><Control Name="pictureBoxMotd" Row="2" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="grpOutputPathGeneration" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="grpAction" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="grpExtra" Row="2" RowSpan="2" Column="1" ColumnSpan="1" /><Control Name="panelGo" Row="3" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="Percent,35,41667,Percent,32,70833,Percent,31,875" /><Rows Styles="Percent,29,69697,Percent,41,51515,Percent,19,39394,Percent,9,393939" /></TableLayoutSettings>
-
-
- Fill
-
-
- 0, 0
-
-
- 0, 0, 0, 0
-
-
- 2
-
-
- 684, 451
-
-
- 17
-
-
- tableLayoutPanel1
-
-
- System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- toolStripContainer1.ContentPanel
-
-
- 0
-
-
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="textBatchReport" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="grpInput" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,480" /><Rows Styles="Absolute,330,Percent,100" /></TableLayoutSettings>
-
-
- 0, 0, 0, 0
-
-
- 684, 451
-
-
- toolStripContainer1.ContentPanel
-
-
- System.Windows.Forms.ToolStripContentPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- toolStripContainer1
-
-
- 0
-
-
- Fill
-
-
- toolStripContainer1.LeftToolStripPanel
-
-
- System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- toolStripContainer1
-
-
- 1
-
-
- 0, 0
-
-
- toolStripContainer1.RightToolStripPanel
-
-
- System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- toolStripContainer1
-
-
- 2
-
-
- 684, 502
-
-
- 17
-
-
- toolStripContainer1
-
-
- 0, 0
-
-
- None
+
+ Profile
100, 23
@@ -2259,18 +2787,6 @@
default
-
- Magenta
-
-
- 73, 22
-
-
- default
-
-
- Profile
-
6, 25
@@ -2313,54 +2829,18 @@
Batch log
-
- 0, 0
-
-
- 684, 25
-
-
- 0
-
-
- toolStripMenu
-
-
- System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- toolStripContainer1.TopToolStripPanel
-
-
- 0
-
-
- toolStripContainer1.TopToolStripPanel
-
-
- System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- toolStripContainer1
-
-
- 3
-
-
- toolStripContainer1
-
-
- System.Windows.Forms.ToolStripContainer, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 1
-
424, 8
+
+ 206, 76
+
+
+ contextMenuStripFileTree
+
+
+ System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
False
@@ -2385,15 +2865,6 @@
Reset to original location
-
- 206, 76
-
-
- contextMenuStripFileTree
-
-
- System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
True
@@ -2810,7 +3281,7 @@
700, 538
- CUETools 2.0.5
+ CUETools 2.0.6
toolStripStatusLabel1
diff --git a/MAC_SDK/Source/MACLib/Assembly/Assembly.obj b/MAC_SDK/Source/MACLib/Assembly/Assembly.obj
index fa72420..8e054d8 100644
Binary files a/MAC_SDK/Source/MACLib/Assembly/Assembly.obj and b/MAC_SDK/Source/MACLib/Assembly/Assembly.obj differ
diff --git a/MAC_SDK/Source/MACLib/Assembly/Assembly64.obj b/MAC_SDK/Source/MACLib/Assembly/Assembly64.obj
index 1594d7c..1cb3d66 100644
Binary files a/MAC_SDK/Source/MACLib/Assembly/Assembly64.obj and b/MAC_SDK/Source/MACLib/Assembly/Assembly64.obj differ
diff --git a/flac/src/libFLAC/ia32/bitreader_asm.obj b/flac/src/libFLAC/ia32/bitreader_asm.obj
index ab2f273..8a56e40 100644
Binary files a/flac/src/libFLAC/ia32/bitreader_asm.obj and b/flac/src/libFLAC/ia32/bitreader_asm.obj differ
diff --git a/flac/src/libFLAC/ia32/cpu_asm.obj b/flac/src/libFLAC/ia32/cpu_asm.obj
index 99d892f..27aa3ad 100644
Binary files a/flac/src/libFLAC/ia32/cpu_asm.obj and b/flac/src/libFLAC/ia32/cpu_asm.obj differ
diff --git a/flac/src/libFLAC/ia32/fixed_asm.obj b/flac/src/libFLAC/ia32/fixed_asm.obj
index d8c397c..3486f7e 100644
Binary files a/flac/src/libFLAC/ia32/fixed_asm.obj and b/flac/src/libFLAC/ia32/fixed_asm.obj differ
diff --git a/flac/src/libFLAC/ia32/lpc_asm.obj b/flac/src/libFLAC/ia32/lpc_asm.obj
index 3eee1bf..f599400 100644
Binary files a/flac/src/libFLAC/ia32/lpc_asm.obj and b/flac/src/libFLAC/ia32/lpc_asm.obj differ
diff --git a/flac/src/libFLAC/ia32/stream_encoder_asm.obj b/flac/src/libFLAC/ia32/stream_encoder_asm.obj
index 4797683..3baf650 100644
Binary files a/flac/src/libFLAC/ia32/stream_encoder_asm.obj and b/flac/src/libFLAC/ia32/stream_encoder_asm.obj differ
diff --git a/flac/src/libFLAC/ia64/lpc_asm.nasm b/flac/src/libFLAC/ia64/lpc_asm.nasm
new file mode 100644
index 0000000..250be21
--- /dev/null
+++ b/flac/src/libFLAC/ia64/lpc_asm.nasm
@@ -0,0 +1,271 @@
+; vim:filetype=nasm ts=8
+
+; libFLAC - Free Lossless Audio Codec library
+; Copyright (C) 2001,2002,2003,2004,2005,2006,2007,2008 Josh Coalson
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+;
+; - Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; - Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+;
+; - Neither the name of the Xiph.org Foundation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;/*
+; * MMX optimized FLAC DSP utils
+; * Copyright (c) 2007 Loren Merritt
+; *
+; * This file is part of FFmpeg.
+; *
+; * FFmpeg is free software; you can redistribute it and/or
+; * modify it under the terms of the GNU Lesser General Public
+; * License as published by the Free Software Foundation; either
+; * version 2.1 of the License, or (at your option) any later version.
+; *
+; * FFmpeg is distributed in the hope that it will be useful,
+; * but WITHOUT ANY WARRANTY; without even the implied warranty of
+; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+; * Lesser General Public License for more details.
+; *
+; * You should have received a copy of the GNU Lesser General Public
+; * License along with FFmpeg; if not, write to the Free Software
+; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+; */
+
+%include "nasm.h"
+
+ data_section
+
+;cglobal FLAC__lpc_compute_autocorrelation_asm_ia64
+cglobal FLAC__lpc_compute_autocorrelation_asm_ia64_sse_lag_4
+cglobal FLAC__lpc_compute_autocorrelation_asm_ia64_sse_lag_8
+cglobal FLAC__lpc_compute_autocorrelation_asm_ia64_sse_lag_12
+
+ code_section
+
+; **********************************************************************
+;
+; void FLAC__lpc_compute_autocorrelation_asm(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
+; {
+; FLAC__real d;
+; unsigned sample, coeff;
+; const unsigned limit = data_len - lag;
+;
+; FLAC__ASSERT(lag > 0);
+; FLAC__ASSERT(lag <= data_len);
+;
+; for(coeff = 0; coeff < lag; coeff++)
+; autoc[coeff] = 0.0;
+; for(sample = 0; sample <= limit; sample++) {
+; d = data[sample];
+; for(coeff = 0; coeff < lag; coeff++)
+; autoc[coeff] += d * data[sample+coeff];
+; }
+; for(; sample < data_len; sample++) {
+; d = data[sample];
+; for(coeff = 0; coeff < data_len - sample; coeff++)
+; autoc[coeff] += d * data[sample+coeff];
+; }
+; }
+;
+
+ ALIGN 16
+cident FLAC__lpc_compute_autocorrelation_asm_ia64_sse_lag_4
+ ; r9d == autoc[]
+ ; r8d == lag
+ ; rdx == data_len
+ ; rcx == data[]
+
+ ;ASSERT(lag > 0)
+ ;ASSERT(lag <= 4)
+ ;ASSERT(lag <= data_len)
+
+ ; for(coeff = 0; coeff < lag; coeff++)
+ ; autoc[coeff] = 0.0;
+ xorps xmm5, xmm5
+
+ movss xmm0, [rcx] ; xmm0 = 0,0,0,data[0]
+ add rcx, 4
+ movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0]
+ shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
+.warmup: ; xmm2 == data[sample-3],data[sample-2],data[sample-1],data[sample]
+ mulps xmm0, xmm2 ; xmm0 = xmm0 * xmm2
+ addps xmm5, xmm0 ; xmm5 += xmm0 * xmm2
+ dec rdx
+ jz .loop_end
+ ALIGN 16
+.loop_start:
+ ; start by reading the next sample
+ movss xmm0, [rcx] ; xmm0 = 0,0,0,data[sample]
+ add rcx, 4
+ shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample]
+ shufps xmm2, xmm2, 93h ; 93h=2-1-0-3 => xmm2 gets rotated left by one float
+ movss xmm2, xmm0
+ mulps xmm0, xmm2 ; xmm0 = xmm0 * xmm2
+ addps xmm5, xmm0 ; xmm5 += xmm0 * xmm2
+ dec rdx
+ jnz .loop_start
+.loop_end:
+ ; store autoc
+ movups [r9d], xmm5
+
+.end:
+ emms
+ ret
+
+ ALIGN 16
+cident FLAC__lpc_compute_autocorrelation_asm_ia64_sse_lag_8
+ ; r9d == autoc[]
+ ; r8d == lag
+ ; rdx == data_len
+ ; rcx == data[]
+
+ ;ASSERT(lag > 0)
+ ;ASSERT(lag <= 8)
+ ;ASSERT(lag <= data_len)
+
+ ; for(coeff = 0; coeff < lag; coeff++)
+ ; autoc[coeff] = 0.0;
+ xorps xmm4, xmm4
+ xorps xmm5, xmm5
+
+ movss xmm0, [rcx] ; xmm0 = 0,0,0,data[0]
+ add rcx, 4
+ movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0]
+ shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
+ movaps xmm1, xmm0 ; xmm1 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
+ xorps xmm3, xmm3 ; xmm3 = 0,0,0,0
+.warmup: ; xmm3:xmm2 == data[sample-7],data[sample-6],...,data[sample]
+ mulps xmm0, xmm2
+ mulps xmm1, xmm3 ; xmm1:xmm0 = xmm1:xmm0 * xmm3:xmm2
+ addps xmm4, xmm0
+ addps xmm5, xmm1 ; xmm5:xmm4 += xmm1:xmm0 * xmm3:xmm2
+ dec rdx
+ jz .loop_end
+ ALIGN 16
+.loop_start:
+ ; start by reading the next sample
+ movss xmm0, [rcx] ; xmm0 = 0,0,0,data[sample]
+ ; here we reorder the instructions; see the (#) indexes for a logical order
+ shufps xmm2, xmm2, 93h ; (3) 93h=2-1-0-3 => xmm2 gets rotated left by one float
+ add rcx, 4 ; (0)
+ shufps xmm3, xmm3, 93h ; (4) 93h=2-1-0-3 => xmm3 gets rotated left by one float
+ shufps xmm0, xmm0, 0 ; (1) xmm0 = data[sample],data[sample],data[sample],data[sample]
+ movss xmm3, xmm2 ; (5)
+ movaps xmm1, xmm0 ; (2) xmm1 = data[sample],data[sample],data[sample],data[sample]
+ movss xmm2, xmm0 ; (6)
+ mulps xmm1, xmm3 ; (8)
+ mulps xmm0, xmm2 ; (7) xmm1:xmm0 = xmm1:xmm0 * xmm3:xmm2
+ addps xmm5, xmm1 ; (10)
+ addps xmm4, xmm0 ; (9) xmm5:xmm4 += xmm1:xmm0 * xmm3:xmm2
+ dec rdx
+ jnz .loop_start
+.loop_end:
+ ; store autoc
+ movups [r9d], xmm4
+ movups [r9d + 16], xmm5
+
+.end:
+ emms
+ ret
+
+
+ ALIGN 16
+cident FLAC__lpc_compute_autocorrelation_asm_ia64_sse_lag_12
+ ; r9d == autoc[]
+ ; r8d == lag
+ ; rdx == data_len
+ ; rcx == data[]
+
+ ;ASSERT(lag > 0)
+ ;ASSERT(lag <= 12)
+ ;ASSERT(lag <= data_len)
+
+ movups [r9d], xmm6 ; save xmm6, which might be used by the caller
+ movups [r9d + 16], xmm7 ; save xmm7, which might be used by the caller
+
+ ; for(coeff = 0; coeff < lag; coeff++)
+ ; autoc[coeff] = 0.0;
+ xorps xmm5, xmm5
+ xorps xmm6, xmm6
+ xorps xmm7, xmm7
+
+ movss xmm0, [rcx] ; xmm0 = 0,0,0,data[0]
+ add rcx, 4
+ movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0]
+ shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
+ xorps xmm3, xmm3 ; xmm3 = 0,0,0,0
+ xorps xmm4, xmm4 ; xmm4 = 0,0,0,0
+.warmup: ; xmm3:xmm2 == data[sample-7],data[sample-6],...,data[sample]
+ movaps xmm1, xmm0
+ mulps xmm1, xmm2
+ addps xmm5, xmm1
+ movaps xmm1, xmm0
+ mulps xmm1, xmm3
+ addps xmm6, xmm1
+ mulps xmm0, xmm4
+ addps xmm7, xmm0 ; xmm7:xmm6:xmm5 += xmm0:xmm0:xmm0 * xmm4:xmm3:xmm2
+ dec rdx
+ jz .loop_end
+ ALIGN 16
+.loop_start:
+ ; start by reading the next sample
+ movss xmm0, [rcx] ; xmm0 = 0,0,0,data[sample]
+ add rcx, 4
+ shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample]
+
+ ; shift xmm4:xmm3:xmm2 left by one float
+ shufps xmm2, xmm2, 93h ; 93h=2-1-0-3 => xmm2 gets rotated left by one float
+ shufps xmm3, xmm3, 93h ; 93h=2-1-0-3 => xmm3 gets rotated left by one float
+ shufps xmm4, xmm4, 93h ; 93h=2-1-0-3 => xmm4 gets rotated left by one float
+ movss xmm4, xmm3
+ movss xmm3, xmm2
+ movss xmm2, xmm0
+
+ ; xmm7:xmm6:xmm5 += xmm0:xmm0:xmm0 * xmm3:xmm3:xmm2
+ movaps xmm1, xmm0
+ mulps xmm1, xmm2
+ addps xmm5, xmm1
+ movaps xmm1, xmm0
+ mulps xmm1, xmm3
+ addps xmm6, xmm1
+ mulps xmm0, xmm4
+ addps xmm7, xmm0
+
+ dec rdx
+ jnz .loop_start
+.loop_end:
+ ; store autoc
+ movups [r9d + 32], xmm7
+ movups xmm7, [r9d + 16] ; restore xmm7
+ movups [r9d + 16], xmm6
+ movups xmm6, [r9d] ; restore xmm6
+ movups [r9d], xmm5
+
+.end:
+ emms
+ ret
+
+
+%ifdef OBJ_FORMAT_elf
+ section .note.GNU-stack noalloc
+%endif
diff --git a/flac/src/libFLAC/ia64/lpc_asm.obj b/flac/src/libFLAC/ia64/lpc_asm.obj
new file mode 100644
index 0000000..02f43eb
Binary files /dev/null and b/flac/src/libFLAC/ia64/lpc_asm.obj differ
diff --git a/flac/src/libFLAC/ia64/nasm.h b/flac/src/libFLAC/ia64/nasm.h
new file mode 100644
index 0000000..339ee68
--- /dev/null
+++ b/flac/src/libFLAC/ia64/nasm.h
@@ -0,0 +1,81 @@
+; libFLAC - Free Lossless Audio Codec library
+; Copyright (C) 2001,2002,2003,2004,2005,2006,2007,2008 Josh Coalson
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+;
+; - Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; - Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+;
+; - Neither the name of the Xiph.org Foundation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ bits 64
+ CPU X64
+
+%ifdef OBJ_FORMAT_win32
+ %define FLAC__PUBLIC_NEEDS_UNDERSCORE
+ %idefine code_section section .text align=16 class=CODE use32
+ %idefine data_section section .data align=32 class=DATA use32
+ %idefine bss_section section .bss align=32 class=DATA use32
+%elifdef OBJ_FORMAT_win64
+; %define FLAC__PUBLIC_NEEDS_UNDERSCORE
+ %idefine code_section section .text align=16 class=CODE use32
+ %idefine data_section section .data align=32 class=DATA use32
+ %idefine bss_section section .bss align=32 class=DATA use32
+%elifdef OBJ_FORMAT_aout
+ %define FLAC__PUBLIC_NEEDS_UNDERSCORE
+ %idefine code_section section .text
+ %idefine data_section section .data
+ %idefine bss_section section .bss
+%elifdef OBJ_FORMAT_aoutb
+ %define FLAC__PUBLIC_NEEDS_UNDERSCORE
+ %idefine code_section section .text
+ %idefine data_section section .data
+ %idefine bss_section section .bss
+%elifdef OBJ_FORMAT_elf
+ %idefine code_section section .text align=16
+ %idefine data_section section .data align=32
+ %idefine bss_section section .bss align=32
+%else
+ %error unsupported object format!
+%endif
+
+%imacro cglobal 1
+ %ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE
+ global _%1
+ %else
+ global %1
+ %endif
+%endmacro
+
+%imacro cextern 1
+ %ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE
+ extern _%1
+ %else
+ extern %1
+ %endif
+%endmacro
+
+%imacro cident 1
+_%1:
+%1:
+%endmacro