diff --git a/CUETools.AccurateRip/AccurateRip.cs b/CUETools.AccurateRip/AccurateRip.cs new file mode 100644 index 0000000..a8407f2 --- /dev/null +++ b/CUETools.AccurateRip/AccurateRip.cs @@ -0,0 +1,466 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Globalization; +using System.Net; +using System.IO; +using CUETools.Codecs; +using CUETools.CDImage; + +namespace CUETools.AccurateRip +{ + public class AccurateRipVerify : IAudioDest + { + public AccurateRipVerify(CDImageLayout toc) + { + _toc = toc; + _accDisks = new List(); + Init(); + } + + unsafe private void CalculateAccurateRipCRCsSemifast(int* samples, uint count, int iTrack, uint currentOffset, uint previousOffset, uint trackLength) + { + fixed (uint* CRCsA = &_offsetedCRC[Math.Max(0, iTrack - 1), 0], + CRCsB = &_offsetedCRC[iTrack, 0], + CRCsC = &_offsetedCRC[Math.Min(_toc.AudioTracks - 1, iTrack + 1), 0]) + { + for (uint si = 0; si < count; si++) + { + uint sampleValue = (uint)((samples[2 * si] & 0xffff) + (samples[2 * si + 1] << 16)); + int i; + int iB = Math.Max(0, _arOffsetRange - (int)(currentOffset + si)); + int iC = Math.Min(2 * _arOffsetRange + 1, _arOffsetRange + (int)trackLength - (int)(currentOffset + si)); + + uint baseSumA = sampleValue * (uint)(previousOffset + 1 - iB); + for (i = 0; i < iB; i++) + { + CRCsA[i] += baseSumA; + baseSumA += sampleValue; + } + uint baseSumB = sampleValue * (uint)Math.Max(1, (int)(currentOffset + si) - _arOffsetRange + 1); + for (i = iB; i < iC; i++) + { + CRCsB[i] += baseSumB; + baseSumB += sampleValue; + } + uint baseSumC = sampleValue; + for (i = iC; i <= 2 * _arOffsetRange; i++) + { + CRCsC[i] += baseSumC; + baseSumC += sampleValue; + } + } + return; + } + } + + unsafe private void CalculateAccurateRipCRCs(int* samples, uint count, int iTrack, uint currentOffset, uint previousOffset, uint trackLength) + { + for (int si = 0; si < count; si++) + { + uint sampleValue = (uint)((samples[2 * si] & 0xffff) + (samples[2 * si + 1] << 16)); + for (int oi = -_arOffsetRange; oi <= _arOffsetRange; oi++) + { + int iTrack2 = iTrack; + int currentOffset2 = (int)currentOffset + si - oi; + + if (currentOffset2 < 5 * 588 - 1 && iTrack == 0) + // we are in the skipped area at the start of the disk + { + continue; + } + else if (currentOffset2 < 0) + // offset takes us to previous track + { + iTrack2--; + currentOffset2 += (int)previousOffset; + } + else if (currentOffset2 >= trackLength - 5 * 588 && iTrack == _toc.AudioTracks - 1) + // we are in the skipped area at the end of the disc + { + continue; + } + else if (currentOffset2 >= trackLength) + // offset takes us to the next track + { + iTrack2++; + currentOffset2 -= (int)trackLength; + } + _offsetedCRC[iTrack2, _arOffsetRange - oi] += sampleValue * (uint)(currentOffset2 + 1); + } + } + } + + unsafe private void CalculateAccurateRipCRCsFast(int* samples, uint count, int iTrack, uint currentOffset) + { + int s1 = (int)Math.Min(count, Math.Max(0, 450 * 588 - _arOffsetRange - (int)currentOffset)); + int s2 = (int)Math.Min(count, Math.Max(0, 451 * 588 + _arOffsetRange - (int)currentOffset)); + if (s1 < s2) + fixed (uint* FrameCRCs = &_offsetedFrame450CRC[iTrack, 0]) + for (int sj = s1; sj < s2; sj++) + { + int magicFrameOffset = (int)currentOffset + sj - 450 * 588 + 1; + int firstOffset = Math.Max(-_arOffsetRange, magicFrameOffset - 588); + int lastOffset = Math.Min(magicFrameOffset - 1, _arOffsetRange); + uint sampleValue = (uint)((samples[2 * sj] & 0xffff) + (samples[2 * sj + 1] << 16)); + for (int oi = firstOffset; oi <= lastOffset; oi++) + FrameCRCs[_arOffsetRange - oi] += sampleValue * (uint)(magicFrameOffset - oi); + } + fixed (uint* CRCs = &_offsetedCRC[iTrack, 0]) + { + uint baseSum = 0, stepSum = 0; + currentOffset += (uint)_arOffsetRange + 1; + for (uint si = 0; si < count; si++) + { + uint sampleValue = (uint)((samples[2 * si] & 0xffff) + (samples[2 * si + 1] << 16)); + stepSum += sampleValue; + baseSum += sampleValue * (uint)(currentOffset + si); + } + for (int i = 2 * _arOffsetRange; i >= 0; i--) + { + CRCs[i] += baseSum; + baseSum -= stepSum; + } + } + } + + public uint CRC(int iTrack) + { + return CRC(iTrack); + } + + public uint CRC(int iTrack, int oi) + { + return _offsetedCRC[iTrack, _arOffsetRange - oi]; + } + + public uint CRC450(int iTrack, int oi) + { + return _offsetedFrame450CRC[iTrack, _arOffsetRange - oi]; + } + + public void Write(int[,] sampleBuffer, uint sampleCount) + { + for (uint pos = 0; pos < sampleCount; ) + { + uint copyCount = Math.Min(sampleCount - pos, (uint)_samplesRemTrack); + if (_currentTrack != 0) + { + unsafe + { + fixed (int* pSampleBuff = &sampleBuffer[pos, 0]) + { + uint trackLength = _toc[_currentTrack].Length * 588; + uint currentOffset = (uint)_sampleCount - _toc[_currentTrack].Start * 588; + uint previousOffset = _currentTrack > 1 ? _toc[_currentTrack - 1].Length * 588 : _toc.Pregap * 588; + uint si1 = (uint)Math.Min(copyCount, Math.Max(0, 588 * (_currentTrack == 1 ? 10 : 5) - (int)currentOffset)); + uint si2 = (uint)Math.Min(copyCount, Math.Max(si1, trackLength - (int)currentOffset - 588 * (_currentTrack == _toc.AudioTracks ? 10 : 5))); + if (_currentTrack == 1) + CalculateAccurateRipCRCs(pSampleBuff, si1, _currentTrack - 1, currentOffset, previousOffset, trackLength); + else + CalculateAccurateRipCRCsSemifast(pSampleBuff, si1, _currentTrack - 1, currentOffset, previousOffset, trackLength); + if (si2 > si1) + CalculateAccurateRipCRCsFast(pSampleBuff + si1 * 2, (uint)(si2 - si1), _currentTrack - 1, currentOffset + si1); + if (_currentTrack == _toc.AudioTracks) + CalculateAccurateRipCRCs(pSampleBuff + si2 * 2, copyCount - si2, _currentTrack - 1, currentOffset + si2, previousOffset, trackLength); + else + CalculateAccurateRipCRCsSemifast(pSampleBuff + si2 * 2, copyCount - si2, _currentTrack - 1, currentOffset + si2, previousOffset, trackLength); + } + } + } + pos += copyCount; + _samplesRemTrack -= copyCount; + _sampleCount += copyCount; + CheckPosition(); + } + } + + public void Init() + { + _offsetedCRC = new uint[_toc.AudioTracks, 10 * 588]; + _offsetedFrame450CRC = new uint[_toc.AudioTracks, 10 * 588]; + _currentTrack = 0; + _sampleCount = 0; + _samplesRemTrack = _toc.Pregap * 588; + CheckPosition(); + } + + private void CheckPosition() + { + while (_samplesRemTrack <= 0) + { + if (++_currentTrack > _toc.AudioTracks) + return; + _samplesRemTrack = _toc[_currentTrack].Length * 588; + } + } + + private uint readIntLE(byte[] data, int pos) + { + return (uint)(data[pos] + (data[pos + 1] << 8) + (data[pos + 2] << 16) + (data[pos + 3] << 24)); + } + + public void ContactAccurateRip(string accurateRipId) + { + // Calculate the three disc ids used by AR + uint discId1 = 0; + uint discId2 = 0; + uint cddbDiscId = 0; + + string[] n = accurateRipId.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); + + string url = String.Format("http://www.accuraterip.com/accuraterip/{0:x}/{1:x}/{2:x}/dBAR-{3:d3}-{4:x8}-{5:x8}-{6:x8}.bin", + discId1 & 0xF, discId1 >> 4 & 0xF, discId1 >> 8 & 0xF, _toc.AudioTracks, discId1, discId2, cddbDiscId); + + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); + req.Method = "GET"; + + try + { + HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); + _accResult = resp.StatusCode; + + if (_accResult == HttpStatusCode.OK) + { + // Retrieve response stream and wrap in StreamReader + Stream respStream = resp.GetResponseStream(); + + // Allocate byte buffer to hold stream contents + byte[] urlData = new byte[13]; + int urlDataLen, bytesRead; + + _accDisks.Clear(); + while (true) + { + for (urlDataLen = 0; urlDataLen < 13; urlDataLen += bytesRead) + { + bytesRead = respStream.Read(urlData, urlDataLen, 13 - urlDataLen); + if (0 == bytesRead) + break; + } + if (urlDataLen == 0) + break; + if (urlDataLen < 13) + { + _accResult = HttpStatusCode.PartialContent; + return; + } + AccDisk dsk = new AccDisk(); + dsk.count = urlData[0]; + dsk.discId1 = readIntLE(urlData, 1); + dsk.discId2 = readIntLE(urlData, 5); + dsk.cddbDiscId = readIntLE(urlData, 9); + + for (int i = 0; i < dsk.count; i++) + { + for (urlDataLen = 0; urlDataLen < 9; urlDataLen += bytesRead) + { + bytesRead = respStream.Read(urlData, urlDataLen, 9 - urlDataLen); + if (0 == bytesRead) + { + _accResult = HttpStatusCode.PartialContent; + return; + } + } + AccTrack trk = new AccTrack(); + trk.count = urlData[0]; + trk.CRC = readIntLE(urlData, 1); + trk.Frame450CRC = readIntLE(urlData, 5); + dsk.tracks.Add(trk); + } + _accDisks.Add(dsk); + } + respStream.Close(); + } + } + catch (WebException ex) + { + if (ex.Status == WebExceptionStatus.ProtocolError) + _accResult = ((HttpWebResponse)ex.Response).StatusCode; + else + _accResult = HttpStatusCode.BadRequest; + } + } + + public bool SetTags(NameValueCollection tags) + { + throw new Exception("unsupported"); + } + + public void Close() + { + if (_sampleCount != _finalSampleCount) + throw new Exception("_sampleCount != _finalSampleCount"); + } + + public void Delete() + { + throw new Exception("unsupported"); + } + + public int BitsPerSample + { + get { return 16; } + } + + public long FinalSampleCount + { + set { _finalSampleCount = value; } + } + + public long BlockSize + { + set { throw new Exception("unsupported"); } + } + + public string Path + { + get { throw new Exception("unsupported"); } + } + + public void GenerateAccurateRipLog(TextWriter sw, int oi) + { + for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++) + { + uint count = 0; + uint partials = 0; + uint conf = 0; + string pressings = ""; + string partpressings = ""; + 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 (pressings != "") + pressings = pressings + ","; + pressings = pressings + (di + 1).ToString(); + } + if (CRC450(iTrack, oi) == AccDisks[di].tracks[iTrack].Frame450CRC) + { + partials += AccDisks[di].tracks[iTrack].count; + if (partpressings != "") + partpressings = partpressings + ","; + partpressings = partpressings + (di + 1).ToString(); + } + } + if (conf > 0) + sw.WriteLine(String.Format(" {0:00}\t[{1:x8}] ({3:00}/{2:00}) Accurately ripped as in pressing(s) #{4}", iTrack + 1, CRC(iTrack, oi), count, conf, pressings)); + else if (partials > 0) + sw.WriteLine(String.Format(" {0:00}\t[{1:x8}] ({3:00}/{2:00}) Partial match to pressing(s) #{4} ", iTrack + 1, CRC(iTrack, oi), count, partials, partpressings)); + else + sw.WriteLine(String.Format(" {0:00}\t[{1:x8}] (00/{2:00}) No matches", iTrack + 1, CRC(iTrack, oi), count)); + } + } + + //private string CalculateAccurateRipId() + //{ + // // Calculate the three disc ids used by AR + // uint discId1 = 0; + // uint discId2 = 0; + // uint cddbDiscId = 0; + + // for (int iTrack = 1; iTrack <= _toc.TrackCount; iTrack++) + // { + // discId1 += _toc[iTrack].Start; + // discId2 += (_toc[iTrack].Start == 0 ? 1 : _toc[iTrack].Start) * ((uint)iTrack); + // cddbDiscId += sumDigits(_toc[iTrack].Start / 75 + 2); + // } + // uint trackOffset = _toc.Length; + // if (_dataTrackLength.HasValue) + // { + // trackOffset += ((90 + 60) * 75) + 150; // 90 second lead-out, 60 second lead-in, 150 sector gap + // cddbDiscId += sumDigits((uint)(trackOffset / 75) + 2); + // trackOffset += _dataTrackLength.Value; + // } + // discId1 += trackOffset; + // discId2 += (trackOffset == 0 ? 1 : trackOffset) * ((uint)TrackCount + 1); + + // if (!_dataTrackLength.HasValue && _cddbDiscIdTag != null) + // { + // uint cddbDiscIdNum = UInt32.Parse(_cddbDiscIdTag, NumberStyles.HexNumber); + // if ((cddbDiscIdNum & 0xff) == TrackCount + 1) + // { + // uint lengthFromTag = ((cddbDiscIdNum >> 8) & 0xffff); + // _minDataTrackLength = ((lengthFromTag + _toc[1].Start / 75) - 152) * 75 - trackOffset; + // } + // } + + // cddbDiscId = ((cddbDiscId % 255) << 24) + + // ((trackOffset / 75 - _toc[1].Start / 75) << 8) + + // (uint)(TrackCount + (_dataTrackLength.HasValue ? 1 : 0)); + + // discId1 &= 0xFFFFFFFF; + // discId2 &= 0xFFFFFFFF; + // cddbDiscId &= 0xFFFFFFFF; + + // return String.Format("{0:x8}-{1:x8}-{2:x8}", discId1, discId2, cddbDiscId); + //} + + public List AccDisks + { + get + { + return _accDisks; + } + } + + public HttpStatusCode AccResult + { + get + { + return _accResult; + } + } + + public string ARStatus + { + get + { + return _accResult == HttpStatusCode.NotFound ? "disk not present in database" : + _accResult == HttpStatusCode.OK ? null + : _accResult.ToString(); + } + } + + CDImageLayout _toc; + long _sampleCount, _finalSampleCount, _samplesRemTrack; + int _currentTrack; + private List _accDisks; + private HttpStatusCode _accResult; + private uint[,] _offsetedCRC; + private uint[,] _offsetedFrame450CRC; + + private const int _arOffsetRange = 5 * 588 - 1; + } + + public struct AccTrack + { + public uint count; + public uint CRC; + public uint Frame450CRC; + } + + public class AccDisk + { + public uint count; + public uint discId1; + public uint discId2; + public uint cddbDiscId; + public List tracks; + + public AccDisk() + { + tracks = new List(); + } + } +} diff --git a/CUETools.AccurateRip/CUETools.AccurateRip.csproj b/CUETools.AccurateRip/CUETools.AccurateRip.csproj new file mode 100644 index 0000000..a4823c0 --- /dev/null +++ b/CUETools.AccurateRip/CUETools.AccurateRip.csproj @@ -0,0 +1,107 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {5802C7E9-157E-4124-946D-70B5AE48A5A1} + Library + Properties + CUETools.AccurateRip + CUETools.AccurateRip + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + true + ..\bin\x64\Debug\ + DEBUG;TRACE + full + x64 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + true + + + ..\bin\x64\Release\ + TRACE + true + pdbonly + x64 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + true + + + true + ..\bin\win32\Debug\ + DEBUG;TRACE + full + x86 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + true + + + ..\bin\win32\Release\ + TRACE + true + pdbonly + x86 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + true + + + + + + + + + + + + + {6458A13A-30EF-45A9-9D58-E5031B17BEE2} + CUETools.Codecs + + + {1DD41038-D885-46C5-8DDE-E0B82F066584} + CUETools.CDImage + + + + + \ No newline at end of file diff --git a/CUETools.AccurateRip/Properties/AssemblyInfo.cs b/CUETools.AccurateRip/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..76947c6 --- /dev/null +++ b/CUETools.AccurateRip/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CUETools.AccurateRip")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("CUETools.AccurateRip")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("080b79f6-6b19-417e-a1d1-afcb6e469112")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CUETools.CDImage/CDImage.cs b/CUETools.CDImage/CDImage.cs new file mode 100644 index 0000000..abc9d8b --- /dev/null +++ b/CUETools.CDImage/CDImage.cs @@ -0,0 +1,310 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CUETools.CDImage +{ + public class CDTrackIndex + { + public CDTrackIndex(uint index, uint start) + { + _start = start; + _index = index; + _length = 0; + } + + public CDTrackIndex(uint index, uint start, uint length) + { + _length = length; + _start = start; + _index = index; + } + + public uint Start + { + get + { + return _start; + } + set + { + _start = value; + } + } + + public uint Length + { + get + { + return _length; + } + set + { + _length = value; + } + } + + public uint Index + { + get + { + return _index; + } + } + + public string MSF + { + get + { + return CDImageLayout.TimeToString(_start); + } + } + + uint _start, _length, _index; + } + + public class CDTrack + { + public CDTrack(uint number, uint start, uint length, bool isAudio) + { + _number = number; + _start = start; + _length = length; + _isAudio = isAudio; + _indexes = new List(); + _indexes.Add(new CDTrackIndex(0, start, 0)); + } + + public uint Start + { + get + { + return _start; + } + set + { + _start = value; + } + } + + public string StartMSF + { + get + { + return CDImageLayout.TimeToString(_start); + } + } + + public uint Length + { + get + { + return _length; + } + set + { + _length = value; + } + } + + public string LengthMSF + { + get + { + return CDImageLayout.TimeToString(_length); + } + } + + public string ISRC + { + get + { + return _isrc; + } + set + { + _isrc = value; + } + } + + public uint End + { + get + { + return _start + _length - 1; + } + } + + public string EndMSF + { + get + { + return CDImageLayout.TimeToString(End); + } + } + + public uint Number + { + get + { + return _number; + } + } + + public uint Pregap + { + get + { + return _indexes[0].Length; + } + } + + public CDTrackIndex this[int key] + { + get + { + return _indexes[key]; + } + } + + public uint LastIndex + { + get + { + return (uint) _indexes.Count - 1; + } + } + + public bool IsAudio + { + get + { + return _isAudio; + } + } + + public void AddIndex(CDTrackIndex index) + { + if (index.Index == 0) + _indexes[0] = index; + else + _indexes.Add(index); + } + + IList _indexes; + string _isrc; + bool _isAudio; + uint _start; + uint _length; + uint _number; + } + + public class CDImageLayout + { + public CDImageLayout(uint length) + { + _tracks = new List(); + _length = length; + } + + public uint Length + { + get + { + return _length; + } + set + { + _length = value; + } + } + + public CDTrack this[int key] + { + get + { + return _tracks[key - 1]; + } + } + + public int TrackCount + { + get + { + return _tracks.Count; + } + } + + public uint Pregap + { + get + { + return _tracks[0].Pregap; + } + } + + public uint AudioTracks + { + get + { + return _audioTracks; + } + } + + public String Catalog + { + get + { + return _catalog; + } + set + { + _catalog = value; + } + } + + public void AddTrack(CDTrack track) + { + _tracks.Add(track); + if (track.IsAudio) + _audioTracks++; + } + + public static int TimeFromString(string s) + { + string[] n = s.Split(':'); + if (n.Length != 3) + { + throw new Exception("Invalid timestamp."); + } + int min, sec, frame; + + min = Int32.Parse(n[0]); + sec = Int32.Parse(n[1]); + frame = Int32.Parse(n[2]); + + return frame + (sec * 75) + (min * 60 * 75); + } + + public static string TimeToString(uint t) + { + uint min, sec, frame; + + frame = t % 75; + t /= 75; + sec = t % 60; + t /= 60; + min = t; + + return String.Format("{0:00}:{1:00}:{2:00}", min, sec, frame); + } + + public string _cddbId; + public string _ArId; + + uint _length; + string _catalog; + IList _tracks; + uint _audioTracks; + } +} diff --git a/CUETools.CDImage/CUETools.CDImage.csproj b/CUETools.CDImage/CUETools.CDImage.csproj new file mode 100644 index 0000000..dbdad51 --- /dev/null +++ b/CUETools.CDImage/CUETools.CDImage.csproj @@ -0,0 +1,91 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {1DD41038-D885-46C5-8DDE-E0B82F066584} + Library + Properties + CUETools.CDImage + CUETools.CDImage + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + ..\bin\win32\Debug\ + DEBUG;TRACE + full + x86 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + + + ..\bin\win32\Release\ + TRACE + true + pdbonly + x86 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + + + true + ..\bin\x64\Debug\ + DEBUG;TRACE + full + x64 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + + + ..\bin\x64\Release\ + TRACE + true + pdbonly + x64 + C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules + true + GlobalSuppressions.cs + prompt + + + + + + + + + + + + + \ No newline at end of file diff --git a/CUETools.CDImage/Properties/AssemblyInfo.cs b/CUETools.CDImage/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9233644 --- /dev/null +++ b/CUETools.CDImage/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CUETools.CDImage")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("CUETools.CDImage")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3db8bfa6-d3ba-4875-b02f-ef81119eab98")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")]