mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Preliminary support for CDTOC tag
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace CUETools.CDImage
|
namespace CUETools.CDImage
|
||||||
{
|
{
|
||||||
@@ -437,6 +438,21 @@ namespace CUETools.CDImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string TAG
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
StringBuilder mbSB = new StringBuilder();
|
||||||
|
mbSB.AppendFormat(CultureInfo.InvariantCulture, "{0:X}", AudioTracks);
|
||||||
|
for (int iTrack = _firstAudio; iTrack < TrackCount; iTrack++)
|
||||||
|
mbSB.AppendFormat("+{0:X}", _tracks[iTrack].Start + 150);
|
||||||
|
mbSB.AppendFormat("+{0:X}", Length + 150);
|
||||||
|
for (int iTrack = 0; iTrack < _firstAudio; iTrack++)
|
||||||
|
mbSB.AppendFormat("+X{0:X}", _tracks[iTrack].Start + 150);
|
||||||
|
return mbSB.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static CDImageLayout FromString(string str)
|
public static CDImageLayout FromString(string str)
|
||||||
{
|
{
|
||||||
var ids = str.Split(':');
|
var ids = str.Split(':');
|
||||||
@@ -453,6 +469,44 @@ namespace CUETools.CDImage
|
|||||||
return new CDImageLayout(trackcount, audiotracks, firstaudio, string.Join(" ", ids));
|
return new CDImageLayout(trackcount, audiotracks, firstaudio, string.Join(" ", ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CDImageLayout FromTag(string str)
|
||||||
|
{
|
||||||
|
var ids = str.Split('+');
|
||||||
|
int audiotracks;
|
||||||
|
int firstaudio = 1;
|
||||||
|
int trackcount = ids.Length - 2;
|
||||||
|
int offs;
|
||||||
|
var ids2 = new List<string>();
|
||||||
|
if (!int.TryParse(ids[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out audiotracks))
|
||||||
|
return null;
|
||||||
|
if (trackcount > audiotracks && ids[ids.Length - 1][0] == 'X')
|
||||||
|
{
|
||||||
|
firstaudio = 1 + trackcount - audiotracks;
|
||||||
|
for (int i = 0; i < trackcount - audiotracks; i++)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(ids[i + 2 + audiotracks].Substring(1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out offs))
|
||||||
|
return null;
|
||||||
|
ids2.Add((offs - 150).ToString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= audiotracks; i++)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(ids[i + 1], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out offs))
|
||||||
|
return null;
|
||||||
|
ids2.Add((offs - 150).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= trackcount; i++)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(ids[i + 1], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out offs))
|
||||||
|
return null;
|
||||||
|
ids2.Add((offs - 150).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new CDImageLayout(trackcount, audiotracks, firstaudio, string.Join(" ", ids2.ToArray()));
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
StringBuilder mbSB = new StringBuilder();
|
StringBuilder mbSB = new StringBuilder();
|
||||||
|
|||||||
@@ -87,5 +87,8 @@ namespace CUETools.Processor
|
|||||||
|
|
||||||
[DefaultValue(false), Category("Tagging"), DisplayName("Use id3v2.4 instead of id3v2.3")]
|
[DefaultValue(false), Category("Tagging"), DisplayName("Use id3v2.4 instead of id3v2.3")]
|
||||||
public bool UseId3v24 { get; set; }
|
public bool UseId3v24 { get; set; }
|
||||||
|
|
||||||
|
[DefaultValue(true), Category("Tagging"), DisplayName("Write CDTOC tag")]
|
||||||
|
public bool WriteCDTOCTag { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1549,20 +1549,30 @@ namespace CUETools.Processor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tocFromLog == null)
|
||||||
|
{
|
||||||
|
var tocTag = GetCommonMiscTag("CDTOC");
|
||||||
|
if (tocTag != null)
|
||||||
|
{
|
||||||
|
tocFromLog = CDImageLayout.FromTag(tocTag);
|
||||||
|
if (tocFromLog != null && tocFromLog.TOCID != _toc.TOCID)
|
||||||
|
tocFromLog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// use pregaps from log
|
// use pregaps from log
|
||||||
if (tocFromLog != null)
|
if (tocFromLog != null)
|
||||||
{
|
{
|
||||||
//int srcNo = (int) _toc[_toc.FirstAudio].LastIndex - (PreGapLength == 0 ? 1 : 0);
|
|
||||||
if (PreGapLength < tocFromLog.Pregap)
|
|
||||||
{
|
|
||||||
PreGapLength = tocFromLog.Pregap;
|
|
||||||
//srcNo ++;
|
|
||||||
}
|
|
||||||
int trNo;
|
int trNo;
|
||||||
for (trNo = 1; trNo < tocFromLog.AudioTracks && trNo < _toc.AudioTracks; trNo++)
|
for (trNo = 0; trNo < tocFromLog.AudioTracks && trNo < _toc.AudioTracks; trNo++)
|
||||||
{
|
{
|
||||||
if (_toc[_toc.FirstAudio + trNo].Pregap < tocFromLog[tocFromLog.FirstAudio + trNo].Pregap)
|
if (_toc[_toc.FirstAudio + trNo].Pregap < tocFromLog[tocFromLog.FirstAudio + trNo].Pregap)
|
||||||
_toc[_toc.FirstAudio + trNo].Pregap = tocFromLog[tocFromLog.FirstAudio + trNo].Pregap;
|
{
|
||||||
|
if (_toc.FirstAudio + trNo == 1)
|
||||||
|
PreGapLength = tocFromLog[tocFromLog.FirstAudio + trNo].Pregap;
|
||||||
|
else
|
||||||
|
_toc[_toc.FirstAudio + trNo].Pregap = tocFromLog[tocFromLog.FirstAudio + trNo].Pregap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//if (_toc[_toc.FirstAudio].Length > tocFromLog[tocFromLog.FirstAudio].Length)
|
//if (_toc[_toc.FirstAudio].Length > tocFromLog[tocFromLog.FirstAudio].Length)
|
||||||
//{
|
//{
|
||||||
@@ -1613,26 +1623,31 @@ namespace CUETools.Processor
|
|||||||
_toc[_toc.TrackCount][0].Start = tocFromLog[_toc.TrackCount].Start;
|
_toc[_toc.TrackCount][0].Start = tocFromLog[_toc.TrackCount].Start;
|
||||||
_toc[_toc.TrackCount][1].Start = tocFromLog[_toc.TrackCount].Start;
|
_toc[_toc.TrackCount][1].Start = tocFromLog[_toc.TrackCount].Start;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_toc.TrackCount == _toc.AudioTracks
|
if (_toc.TrackCount == _toc.AudioTracks
|
||||||
&& tocFromLog.TrackCount == tocFromLog.AudioTracks
|
&& tocFromLog.TrackCount == tocFromLog.AudioTracks
|
||||||
&& tocFromLog.TrackCount > _toc.TrackCount)
|
&& tocFromLog.TrackCount > _toc.TrackCount)
|
||||||
{
|
{
|
||||||
int dtracks = tocFromLog.TrackCount - _toc.TrackCount;
|
int dtracks = tocFromLog.TrackCount - _toc.TrackCount;
|
||||||
bool matches = true;
|
var toc2 = new CDImageLayout(tocFromLog);
|
||||||
for (int iTrack = 1; iTrack <= _toc.TrackCount; iTrack++)
|
for (int iTrack = 1; iTrack <= dtracks; iTrack++)
|
||||||
if (tocFromLog[iTrack + dtracks].Length != _toc[iTrack].Length)
|
toc2[iTrack].IsAudio = false;
|
||||||
matches = false;
|
toc2.FirstAudio += dtracks;
|
||||||
if (matches)
|
toc2.AudioTracks -= (uint)dtracks;
|
||||||
{
|
if (toc2.TOCID == _toc.TOCID)
|
||||||
for (int iTrack = 1; iTrack <= dtracks; iTrack++)
|
tocFromLog = toc2;
|
||||||
{
|
|
||||||
_toc.InsertTrack(new CDTrack((uint)iTrack, 0, 0, false, false));
|
|
||||||
tocFromLog[iTrack].IsAudio = false;
|
|
||||||
}
|
|
||||||
tocFromLog.FirstAudio += dtracks;
|
|
||||||
tocFromLog.AudioTracks -= (uint)dtracks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tocFromLog.AudioTracks == _toc.AudioTracks
|
||||||
|
// && tocFromLog.TOCID == _toc.TOCID
|
||||||
|
&& _toc.TrackCount == _toc.AudioTracks
|
||||||
|
&& tocFromLog.FirstAudio > 1
|
||||||
|
&& tocFromLog.TrackCount == tocFromLog.FirstAudio + tocFromLog.AudioTracks - 1)
|
||||||
|
{
|
||||||
|
for (int iTrack = 1; iTrack < tocFromLog.FirstAudio; iTrack++)
|
||||||
|
_toc.InsertTrack(new CDTrack((uint)iTrack, 0, 0, false, false));
|
||||||
|
}
|
||||||
|
|
||||||
if (tocFromLog.AudioTracks == _toc.AudioTracks
|
if (tocFromLog.AudioTracks == _toc.AudioTracks
|
||||||
&& tocFromLog.TrackCount == _toc.TrackCount
|
&& tocFromLog.TrackCount == _toc.TrackCount
|
||||||
&& tocFromLog.FirstAudio == _toc.FirstAudio
|
&& tocFromLog.FirstAudio == _toc.FirstAudio
|
||||||
@@ -3100,6 +3115,9 @@ namespace CUETools.Processor
|
|||||||
isUsingAccurateRip &&
|
isUsingAccurateRip &&
|
||||||
_arVerify.ExceptionStatus == WebExceptionStatus.Success)
|
_arVerify.ExceptionStatus == WebExceptionStatus.Success)
|
||||||
GenerateAccurateRipTags(destTags, bestOffset, iTrack);
|
GenerateAccurateRipTags(destTags, bestOffset, iTrack);
|
||||||
|
|
||||||
|
if (_config.advanced.WriteCDTOCTag)
|
||||||
|
destTags.Add("CDTOC", _toc.TAG);
|
||||||
|
|
||||||
return destTags;
|
return destTags;
|
||||||
}
|
}
|
||||||
@@ -4096,6 +4114,7 @@ namespace CUETools.Processor
|
|||||||
uint number = 0;
|
uint number = 0;
|
||||||
string album = null;
|
string album = null;
|
||||||
string cueFound = null;
|
string cueFound = null;
|
||||||
|
CDImageLayout tocFound = null;
|
||||||
TimeSpan dur = TimeSpan.Zero;
|
TimeSpan dur = TimeSpan.Zero;
|
||||||
TagLib.UserDefined.AdditionalFileTypes.Config = _config;
|
TagLib.UserDefined.AdditionalFileTypes.Config = _config;
|
||||||
TagLib.File.IFileAbstraction fileAbsraction = new TagLib.File.LocalFileAbstraction(file.FullName);
|
TagLib.File.IFileAbstraction fileAbsraction = new TagLib.File.LocalFileAbstraction(file.FullName);
|
||||||
@@ -4106,7 +4125,10 @@ namespace CUETools.Processor
|
|||||||
album = fileInfo.Tag.Album;
|
album = fileInfo.Tag.Album;
|
||||||
number = fileInfo.Tag.Track;
|
number = fileInfo.Tag.Track;
|
||||||
dur = fileInfo.Properties.Duration;
|
dur = fileInfo.Properties.Duration;
|
||||||
cueFound = fmt.allowEmbed ? Tagging.Analyze(fileInfo).Get("CUESHEET") : null;
|
var tags = Tagging.Analyze(fileInfo);
|
||||||
|
cueFound = fmt.allowEmbed ? tags.Get("CUESHEET") : null;
|
||||||
|
var toc = tags.Get("CDTOC");
|
||||||
|
if (toc != null) tocFound = CDImageLayout.FromTag(toc);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
if (cueFound != null)
|
if (cueFound != null)
|
||||||
@@ -4117,13 +4139,14 @@ namespace CUETools.Processor
|
|||||||
fileGroups.Add(group);
|
fileGroups.Add(group);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
disc = Math.Min(5, Math.Max(1, disc));
|
disc = Math.Min(50, Math.Max(1, disc));
|
||||||
FileGroupInfo groupFound = null;
|
FileGroupInfo groupFound = null;
|
||||||
foreach (FileGroupInfo fileGroup in fileGroups)
|
foreach (FileGroupInfo fileGroup in fileGroups)
|
||||||
{
|
{
|
||||||
if (fileGroup.type == FileGroupInfoType.TrackFiles
|
if (fileGroup.type == FileGroupInfoType.TrackFiles
|
||||||
&& fileGroup.discNo == disc
|
&& fileGroup.discNo == disc
|
||||||
&& fileGroup.album == album
|
&& fileGroup.album == album
|
||||||
|
&& (fileGroup.TOC == null ? "" : fileGroup.TOC.ToString()) == (tocFound == null ? "" : tocFound.ToString())
|
||||||
&& fileGroup.main.Extension.ToLower() == ext)
|
&& fileGroup.main.Extension.ToLower() == ext)
|
||||||
{
|
{
|
||||||
groupFound = fileGroup;
|
groupFound = fileGroup;
|
||||||
@@ -4135,6 +4158,7 @@ namespace CUETools.Processor
|
|||||||
groupFound = new FileGroupInfo(file, FileGroupInfoType.TrackFiles);
|
groupFound = new FileGroupInfo(file, FileGroupInfoType.TrackFiles);
|
||||||
groupFound.discNo = disc;
|
groupFound.discNo = disc;
|
||||||
groupFound.album = album;
|
groupFound.album = album;
|
||||||
|
groupFound.TOC = tocFound;
|
||||||
groupFound.durations = new Dictionary<FileSystemInfo, TimeSpan>();
|
groupFound.durations = new Dictionary<FileSystemInfo, TimeSpan>();
|
||||||
fileGroups.Add(groupFound);
|
fileGroups.Add(groupFound);
|
||||||
}
|
}
|
||||||
@@ -4143,7 +4167,9 @@ namespace CUETools.Processor
|
|||||||
if (dur != TimeSpan.Zero) groupFound.durations.Add(file, dur);
|
if (dur != TimeSpan.Zero) groupFound.durations.Add(file, dur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileGroups.RemoveAll(group => group.type == FileGroupInfoType.TrackFiles && group.files.Count < 2);
|
fileGroups.RemoveAll(group => group.type == FileGroupInfoType.TrackFiles && (
|
||||||
|
(group.TOC == null && group.files.Count < 2) ||
|
||||||
|
(group.TOC != null && group.TOC.AudioTracks != group.files.Count)));
|
||||||
// tracks must be sorted according to tracknumer (or filename if missing)
|
// tracks must be sorted according to tracknumer (or filename if missing)
|
||||||
foreach (FileGroupInfo group in fileGroups)
|
foreach (FileGroupInfo group in fileGroups)
|
||||||
if (group.type == FileGroupInfoType.TrackFiles)
|
if (group.type == FileGroupInfoType.TrackFiles)
|
||||||
|
|||||||
Reference in New Issue
Block a user