diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml
index 2635b13ab..658b67ed7 100644
--- a/.github/workflows/CI-windows.yml
+++ b/.github/workflows/CI-windows.yml
@@ -34,6 +34,7 @@ jobs:
git apply --directory=ThirdParty/flac ThirdParty/submodule_flac_CUETools.patch --verbose --whitespace=nowarn
powershell -c "Expand-Archive ThirdParty/MAC_SDK/MAC_1086_SDK.zip -DestinationPath ThirdParty/MAC_SDK/"
git apply --directory=ThirdParty/MAC_SDK ThirdParty/ThirdParty_MAC_SDK_CUETools.patch --verbose
+ git apply --directory=ThirdParty/openclnet ThirdParty/submodule_openclnet_CUETools.patch --verbose
git apply --directory=ThirdParty/taglib-sharp ThirdParty/submodule_taglib-sharp_CUETools.patch --verbose
git apply --directory=ThirdParty/WavPack ThirdParty/submodule_WavPack_CUETools.patch --verbose
git apply --directory=ThirdParty/WindowsMediaLib ThirdParty/submodule_WindowsMediaLib_CUETools.patch --verbose
@@ -43,6 +44,9 @@ jobs:
- name: Build Release|Any CPU
run: |
"%DEVENV_PATH%" "%SLN_PATH%" /Build "Release|Any CPU"
+ - name: Test AccurateRip Meta
+ run: |
+ dotnet test CUETools\CUETools.TestProcessor\CUETools.TestProcessor.csproj --configuration Release --filter AccurateRipMetaTest -v:minimal
- name: Build Release|x64
run: |
"%DEVENV_PATH%" "%SLN_PATH%" /Build "Release|x64"
diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml
index fd3284e87..1ac807101 100644
--- a/.github/workflows/release-windows.yml
+++ b/.github/workflows/release-windows.yml
@@ -35,6 +35,7 @@ jobs:
git apply --directory=ThirdParty/flac ThirdParty/submodule_flac_CUETools.patch --verbose --whitespace=nowarn
powershell -c "Expand-Archive ThirdParty/MAC_SDK/MAC_1086_SDK.zip -DestinationPath ThirdParty/MAC_SDK/"
git apply --directory=ThirdParty/MAC_SDK ThirdParty/ThirdParty_MAC_SDK_CUETools.patch --verbose
+ git apply --directory=ThirdParty/openclnet ThirdParty/submodule_openclnet_CUETools.patch --verbose
git apply --directory=ThirdParty/taglib-sharp ThirdParty/submodule_taglib-sharp_CUETools.patch --verbose
git apply --directory=ThirdParty/WavPack ThirdParty/submodule_WavPack_CUETools.patch --verbose
git apply --directory=ThirdParty/WindowsMediaLib ThirdParty/submodule_WindowsMediaLib_CUETools.patch --verbose
diff --git a/Bwg.Hardware/Bwg.Hardware.csproj b/Bwg.Hardware/Bwg.Hardware.csproj
index 433d3353d..af04ddaae 100644
--- a/Bwg.Hardware/Bwg.Hardware.csproj
+++ b/Bwg.Hardware/Bwg.Hardware.csproj
@@ -1,7 +1,7 @@
- net47;net20
+ netstandard2.1
0.0.7.1
Bwg.Hardware
Bwg.Hardware
@@ -16,6 +16,10 @@
https://svn.code.sf.net/p/bwgburn/code/
svn
BwgSoftware
-
-
-
+
+
+
+
+
+
+
diff --git a/Bwg.Logging/Bwg.Logging.csproj b/Bwg.Logging/Bwg.Logging.csproj
index 0527ed5f1..197f336a9 100644
--- a/Bwg.Logging/Bwg.Logging.csproj
+++ b/Bwg.Logging/Bwg.Logging.csproj
@@ -1,7 +1,7 @@
- net47;net20
+ netstandard2.1
0.0.7.1
Bwg.Logging
Bwg.Logging
diff --git a/Bwg.Scsi/Bwg.Scsi.csproj b/Bwg.Scsi/Bwg.Scsi.csproj
index 87a3b9b77..b58b90fe5 100644
--- a/Bwg.Scsi/Bwg.Scsi.csproj
+++ b/Bwg.Scsi/Bwg.Scsi.csproj
@@ -1,7 +1,7 @@
- net47;net20
+ netstandard2.1
0.0.7.1
Bwg.Scsi
Bwg.Scsi
diff --git a/CUEControls/CUEControls.csproj b/CUEControls/CUEControls.csproj
index e5cfe4453..452c8316e 100644
--- a/CUEControls/CUEControls.csproj
+++ b/CUEControls/CUEControls.csproj
@@ -1,23 +1,22 @@
- net47;net20
+ net10.0-windows
2.2.6.0
CUEControls
- CUEControls
- CUETools
+ CUEControls
+ 7.0
+ CUETools
Library containing windows GUI controls for CUETools.
Copyright (c) 2008-2025 Grigory Chudov
Grigory Chudov
- true
+ true
+ true
+ $(NoWarn);WFO1000
..\bin\$(Configuration)\
https://github.com/gchudov/cuetools.net
git
-
-
-
-
-
+
diff --git a/CUEPlayer/CUEPlayer.csproj b/CUEPlayer/CUEPlayer.csproj
index 4a6283749..af48efe6b 100644
--- a/CUEPlayer/CUEPlayer.csproj
+++ b/CUEPlayer/CUEPlayer.csproj
@@ -1,296 +1,46 @@
-
-
-
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {04E59836-0C5A-4B9B-8899-848D56911758}
- WinExe
- Properties
- CUEPlayer
- CUEPlayer
- v4.7
- 512
- false
-
-
- 3.5
-
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- true
-
-
-
- true
- full
- false
- ..\bin\Debug\net47\
- DEBUG;TRACE
- prompt
- 4
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\net47\
- TRACE
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
- Form
-
-
- Browser.cs
-
-
- DataSet1.xsd
-
-
- Form
-
-
- Deck.cs
-
-
- Form
-
-
- frmCUEPlayer.cs
-
-
- Form
-
-
- Icecast.cs
-
-
- Form
-
-
- IcecastSettings.cs
-
-
- Form
-
-
- Output.cs
-
-
- Form
-
-
- Playlist.cs
-
-
-
-
- Browser.cs
-
-
- Deck.cs
-
-
- frmCUEPlayer.cs
-
-
- Icecast.cs
-
-
- IcecastSettings.cs
-
-
- Output.cs
-
-
- Playlist.cs
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
- Designer
-
-
- True
- Resources.resx
- True
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
- True
- Settings.settings
- True
-
-
-
-
-
- {CA4D64E6-6544-4A29-8BA5-7DB08D50D072}
- CUEControls
- False
-
-
- {1DD41038-D885-46C5-8DDE-E0B82F066584}
- CUETools.CDImage
- False
-
-
- {FAD09EE2-D6B2-4A8E-9F1C-2A9FB293661A}
- CUETools.Codecs.CoreAudio
-
-
- {8FC5DA7C-F6AC-4D04-85BC-1233DDF569E7}
- CUETools.Codecs.Icecast
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
- False
-
-
- {AFF1AFF9-839D-4892-88CD-8BD09BAFC1D2}
- CUETools.DSP.Mixer
-
-
- {A6303861-CA06-4C2C-A104-BA9291538F6F}
- CUETools.DSP.Resampler
-
-
- {4911BD82-49EF-4858-8B51-5394F86739A4}
- CUETools.Processor
- False
-
-
- {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}
- ProgressODoom
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- DataSet1.xsd
-
-
- Designer
- MSDataSetGenerator
-
-
- DataSet1.xsd
-
-
-
-
-
-
- False
- .NET Framework 3.5 SP1 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
- SQL Server Compact 3.5 SP2
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+ net10.0-windows
+ WinExe
+ CUEPlayer
+ CUEPlayer
+ 7.0
+ true
+ false
+ true
+ $(NoWarn);WFO1000
+ ..\bin\$(Configuration)\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ PreserveNewest
+
+
+
+
diff --git a/CUEPlayer/DataSet1.cs b/CUEPlayer/DataSet1.cs
index cbf14c209..d10133fc8 100644
--- a/CUEPlayer/DataSet1.cs
+++ b/CUEPlayer/DataSet1.cs
@@ -1,9 +1,229 @@
-namespace CUEPlayer {
-
-
- public partial class DataSet1 {
- partial class PlaylistDataTable
- {
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+
+namespace CUEPlayer {
+
+
+ public partial class DataSet1 : DataSet {
+ private readonly PlaylistDataTable tablePlaylist;
+
+ public DataSet1()
+ {
+ DataSetName = "DataSet1";
+ tablePlaylist = new PlaylistDataTable();
+ Tables.Add(tablePlaylist);
+ }
+
+ public PlaylistDataTable Playlist
+ {
+ get { return tablePlaylist; }
+ }
+
+ public partial class PlaylistDataTable : DataTable
+ {
+ private readonly DataColumn columnId;
+ private readonly DataColumn columnPath;
+ private readonly DataColumn columnArtist;
+ private readonly DataColumn columnTitle;
+ private readonly DataColumn columnAlbum;
+ private readonly DataColumn columnLength;
+ private readonly DataColumn columnTrack;
+
+ public PlaylistDataTable()
+ : base("Playlist")
+ {
+ columnId = Columns.Add("id", typeof(int));
+ columnId.AutoIncrement = true;
+ columnId.AutoIncrementSeed = -1;
+ columnId.AutoIncrementStep = -1;
+ columnPath = Columns.Add("path", typeof(string));
+ columnArtist = Columns.Add("artist", typeof(string));
+ columnTitle = Columns.Add("title", typeof(string));
+ columnAlbum = Columns.Add("album", typeof(string));
+ columnLength = Columns.Add("length", typeof(int));
+ columnTrack = Columns.Add("track", typeof(int));
+ PrimaryKey = new[] { columnId };
+ }
+
+ public PlaylistRow this[int index]
+ {
+ get { return (PlaylistRow)Rows[index]; }
+ }
+
+ public PlaylistRow AddPlaylistRow(string path, string artist, string title, string album, int length, int track)
+ {
+ PlaylistRow row = (PlaylistRow)NewRow();
+ row.path = path;
+ row.artist = artist;
+ row.title = title;
+ row.album = album;
+ row.length = length;
+ row.track = track;
+ Rows.Add(row);
+ return row;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ foreach (DataRow row in Rows)
+ if (row.RowState != DataRowState.Deleted)
+ yield return (PlaylistRow)row;
+ }
+
+ protected override Type GetRowType()
+ {
+ return typeof(PlaylistRow);
+ }
+
+ protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
+ {
+ return new PlaylistRow(builder);
+ }
+ }
+
+ public partial class PlaylistRow : DataRow
+ {
+ internal PlaylistRow(DataRowBuilder builder)
+ : base(builder)
+ {
+ }
+
+ public int id
+ {
+ get { return FieldValue("id"); }
+ set { this["id"] = value; }
+ }
+
+ public string path
+ {
+ get { return FieldValue("path"); }
+ set { this["path"] = value ?? (object)DBNull.Value; }
+ }
+
+ public string artist
+ {
+ get { return FieldValue("artist"); }
+ set { this["artist"] = value ?? (object)DBNull.Value; }
+ }
+
+ public string title
+ {
+ get { return FieldValue("title"); }
+ set { this["title"] = value ?? (object)DBNull.Value; }
+ }
+
+ public string album
+ {
+ get { return FieldValue("album"); }
+ set { this["album"] = value ?? (object)DBNull.Value; }
+ }
+
+ public int length
+ {
+ get { return FieldValue("length"); }
+ set { this["length"] = value; }
+ }
+
+ public int track
+ {
+ get { return FieldValue("track"); }
+ set { this["track"] = value; }
+ }
+
+ private T FieldValue(string columnName)
+ {
+ object value = this[columnName];
+ if (value == DBNull.Value)
+ return default(T);
+ return (T)value;
+ }
+ }
+ }
+
+ namespace DataSet1TableAdapters
+ {
+ public class PlaylistTableAdapter
+ {
+ private static string PlaylistFile
+ {
+ get
+ {
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "CUEPlayer",
+ "playlist.xml");
+ }
+ }
+
+ public int Fill(DataSet1.PlaylistDataTable table)
+ {
+ table.Clear();
+ if (!File.Exists(PlaylistFile))
+ return 0;
+
+ DataSet dataSet = new DataSet();
+ dataSet.ReadXml(PlaylistFile);
+ if (!dataSet.Tables.Contains("Playlist"))
+ return 0;
+
+ int count = 0;
+ foreach (DataRow row in dataSet.Tables["Playlist"].Rows)
+ {
+ DataSet1.PlaylistRow playlistRow = table.AddPlaylistRow(
+ ReadString(row, "path"),
+ ReadString(row, "artist"),
+ ReadString(row, "title"),
+ ReadString(row, "album"),
+ ReadInt32(row, "length"),
+ ReadInt32(row, "track"));
+ if (dataSet.Tables["Playlist"].Columns.Contains("id"))
+ playlistRow.id = ReadInt32(row, "id");
+ count++;
+ }
+ table.AcceptChanges();
+ return count;
+ }
+
+ public int Update(DataSet1.PlaylistDataTable table)
+ {
+ string directory = Path.GetDirectoryName(PlaylistFile);
+ if (!Directory.Exists(directory))
+ Directory.CreateDirectory(directory);
+
+ DataTable copy = table.Clone();
+ foreach (DataRow row in table.Rows)
+ {
+ if (row.RowState == DataRowState.Deleted)
+ continue;
+ DataRow newRow = copy.NewRow();
+ foreach (DataColumn column in table.Columns)
+ newRow[column.ColumnName] = row[column, DataRowVersion.Current];
+ copy.Rows.Add(newRow);
+ }
+
+ DataSet dataSet = new DataSet("DataSet1");
+ dataSet.Tables.Add(copy);
+ dataSet.WriteXml(PlaylistFile, XmlWriteMode.WriteSchema);
+ int count = copy.Rows.Count;
+ table.AcceptChanges();
+ return count;
+ }
+
+ private static string ReadString(DataRow row, string columnName)
+ {
+ if (!row.Table.Columns.Contains(columnName) || row[columnName] == DBNull.Value)
+ return null;
+ return Convert.ToString(row[columnName]);
+ }
+
+ private static int ReadInt32(DataRow row, string columnName)
+ {
+ if (!row.Table.Columns.Contains(columnName) || row[columnName] == DBNull.Value)
+ return 0;
+ return Convert.ToInt32(row[columnName]);
+ }
+ }
+ }
+}
diff --git a/CUEPlayer/Deck.cs b/CUEPlayer/Deck.cs
index 1ec726218..d001a4392 100644
--- a/CUEPlayer/Deck.cs
+++ b/CUEPlayer/Deck.cs
@@ -1,11 +1,12 @@
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Text;
-using System.Threading;
-using System.Windows.Forms;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Windows.Forms;
using CUETools.Codecs;
using CUETools.Processor;
using CUETools.DSP.Mixer;
@@ -73,7 +74,7 @@ internal void UpdateDeck()
textBoxAlbum.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].album;
textBoxTitle.Text = playingRow < 0 ? "" : dataSet.Playlist[playingRow].title;
textBoxDuration.Text = "";
- pictureBox.Image = playingCue != null && playingCue.Cover != null ? playingCue.Cover : pictureBox.InitialImage;
+ pictureBox.Image = GetCoverImage(playingCue) ?? pictureBox.InitialImage;
if (nextDeck != null && nextDeck.playingSource == null && playingRow >= 0 && playingRow < dataSet.Playlist.Rows.Count - 1)
{
@@ -88,8 +89,8 @@ internal void UpdateDeck()
mediaSlider.Value = (int)(playingSource.Position - playingStart);
}
- private void mediaSliderA_ValueChanged(object sender, EventArgs e)
- {
+ private void mediaSliderA_ValueChanged(object sender, EventArgs e)
+ {
if (mediaSlider.Maximum == 1) return;
TimeSpan len1 = TimeSpan.FromSeconds(mediaSlider.Maximum / 44100.0);
TimeSpan len2 = TimeSpan.FromSeconds(mediaSlider.Value / 44100.0);
@@ -97,10 +98,24 @@ private void mediaSliderA_ValueChanged(object sender, EventArgs e)
string lenStr2 = string.Format("{0:d}.{1:d2}:{2:d2}:{3:d2}", len2.Days, len2.Hours, len2.Minutes, len2.Seconds).TrimStart('0', ':', '.');
lenStr1 = "0:00".Substring(0, Math.Max(0, 4 - lenStr1.Length)) + lenStr1;
lenStr2 = "0:00".Substring(0, Math.Max(0, 4 - lenStr2.Length)) + lenStr2;
- textBoxDuration.Text = lenStr2 + " / " + lenStr1;
- }
-
- private int seekTo = -1;
+ textBoxDuration.Text = lenStr2 + " / " + lenStr1;
+ }
+
+ private static Image GetCoverImage(CUESheet cueSheet)
+ {
+ if (cueSheet == null || cueSheet.AlbumArt == null)
+ return null;
+ var picture = cueSheet.AlbumArt.Find(x => x.Type == TagLib.PictureType.FrontCover) ??
+ cueSheet.AlbumArt.Find(x => x.Type != TagLib.PictureType.NotAPicture);
+ if (picture == null)
+ return null;
+ using (MemoryStream imageStream = new MemoryStream(picture.Data.Data, 0, picture.Data.Count))
+ try { return Image.FromStream(imageStream); }
+ catch { }
+ return null;
+ }
+
+ private int seekTo = -1;
private bool stopNow = false;
private void PlayThread()
diff --git a/CUEPlayer/Properties/Resources.Designer.cs b/CUEPlayer/Properties/Resources.Designer.cs
index 5d5c3efe9..c27069a65 100644
--- a/CUEPlayer/Properties/Resources.Designer.cs
+++ b/CUEPlayer/Properties/Resources.Designer.cs
@@ -19,7 +19,7 @@ namespace CUEPlayer.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/CUEPlayer/Properties/Settings.Designer.cs b/CUEPlayer/Properties/Settings.Designer.cs
index ab8462056..3500a56d0 100644
--- a/CUEPlayer/Properties/Settings.Designer.cs
+++ b/CUEPlayer/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace CUEPlayer.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "18.6.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/CUEPlayer/app.config b/CUEPlayer/app.config
index 26cdf92ef..b22c675f1 100644
--- a/CUEPlayer/app.config
+++ b/CUEPlayer/app.config
@@ -11,6 +11,6 @@
-
+
diff --git a/CUERipper.WPF/CUERipper.WPF.csproj b/CUERipper.WPF/CUERipper.WPF.csproj
index ffdd9999c..f51ac2d4d 100644
--- a/CUERipper.WPF/CUERipper.WPF.csproj
+++ b/CUERipper.WPF/CUERipper.WPF.csproj
@@ -1,159 +1,39 @@
-
-
+
+
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {2D8D7A03-DFFA-44EF-9299-8BB56D122245}
+ net10.0-windows
WinExe
- Properties
- CUERipper.WPF
CUERipper.WPF
- v4.7
- 512
- {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 4
-
-
-
-
-
-
- 3.5
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\net47\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- ..\bin\Release\net47\
- TRACE
- prompt
- 4
- false
+ CUERipper.WPF
+ 7.0
+ true
+ true
+ false
+ ..\bin\$(Configuration)\
+
-
- 3.0
-
-
- 3.0
-
-
-
- 3.5
-
-
-
-
- 3.5
-
-
- 3.5
-
-
-
-
+
+
+
+
-
- MSBuild:Compile
- Designer
-
-
- MSBuild:Compile
- Designer
-
-
- App.xaml
- Code
-
-
- Window1.xaml
- Code
-
+
+
+
+
+
-
- Code
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
+
ResXFileCodeGenerator
Resources.Designer.cs
-
-
+
SettingsSingleFileGenerator
Settings.Designer.cs
-
-
-
-
- {CA4D64E6-6544-4A29-8BA5-7DB08D50D072}
- CUEControls
-
-
- {1DD41038-D885-46C5-8DDE-E0B82F066584}
- CUETools.CDImage
-
-
- {4911BD82-49EF-4858-8B51-5394F86739A4}
- CUETools.Processor
-
-
-
-
-
-
-
-
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
-
-
\ No newline at end of file
+
+
diff --git a/CUERipper.WPF/Properties/Resources.Designer.cs b/CUERipper.WPF/Properties/Resources.Designer.cs
index 4fd0e16b7..6f4dfdb91 100644
--- a/CUERipper.WPF/Properties/Resources.Designer.cs
+++ b/CUERipper.WPF/Properties/Resources.Designer.cs
@@ -19,7 +19,7 @@ namespace CUERipper.WPF.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/CUERipper.WPF/Properties/Settings.Designer.cs b/CUERipper.WPF/Properties/Settings.Designer.cs
index 6269b8287..008c3faaa 100644
--- a/CUERipper.WPF/Properties/Settings.Designer.cs
+++ b/CUERipper.WPF/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace CUERipper.WPF.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "18.6.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/CUERipper.WPF/app.config b/CUERipper.WPF/app.config
index 545e8d3eb..220b02fab 100644
--- a/CUERipper.WPF/app.config
+++ b/CUERipper.WPF/app.config
@@ -1,6 +1,6 @@
-
+
diff --git a/CUERipper/CUERipper.csproj b/CUERipper/CUERipper.csproj
index 0fe5a3cfe..2109250b3 100644
--- a/CUERipper/CUERipper.csproj
+++ b/CUERipper/CUERipper.csproj
@@ -1,278 +1,44 @@
-
-
-
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {39B43BBB-BAFC-4D85-9BEA-3BCB7EFED89C}
- WinExe
- Properties
- CUERipper
- CUERipper
-
-
- 3.5
-
-
- cue2.ico
- F89503BB83CA42A647C506D67956D6F32C1C6E7E
- CUERipper_TemporaryKey.pfx
- false
- false
- true
- false
-
-
- LocalIntranet
- Properties\app.manifest
- v4.7
- 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
- 0
- 1.0.0.%2a
- false
- true
- true
-
-
-
- true
- full
- false
- ..\bin\Debug\net47\
- DEBUG;TRACE
- prompt
- 4
- true
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\net47\
- TRACE
- prompt
- 4
- AllRules.ruleset
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
- Form
-
-
- frmCUERipper.cs
-
-
- Form
-
-
- frmFreedbSubmit.cs
-
-
- Form
-
-
- Options.cs
-
-
-
-
- frmCUERipper.cs
-
-
- Designer
- frmCUERipper.cs
-
-
- frmCUERipper.cs
-
-
- frmFreedbSubmit.cs
-
-
- frmFreedbSubmit.cs
-
-
- frmFreedbSubmit.cs
-
-
- Options.cs
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
- Designer
-
-
-
- True
- Resources.resx
- True
-
-
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
- True
- Settings.settings
- True
-
-
-
-
- {CA4D64E6-6544-4A29-8BA5-7DB08D50D072}
- CUEControls
-
-
- {5802C7E9-157E-4124-946D-70B5AE48A5A1}
- CUETools.AccurateRip
-
-
- {1DD41038-D885-46C5-8DDE-E0B82F066584}
- CUETools.CDImage
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
-
-
- {c36efaa5-4f81-4a29-800d-ba866ff13bc8}
- CUETools.CTDB.Types
-
-
- {AA2A9A7E-45FB-4632-AD85-85B0E556F818}
- CUETools.CTDB
-
-
- {4911BD82-49EF-4858-8B51-5394F86739A4}
- CUETools.Processor
-
-
- {D2700165-3E77-4B28-928D-551F5FC11954}
- CUETools.Ripper
-
-
- {5ADCFD6D-BFEA-4B10-BB45-9083BBB56AF4}
- Freedb
-
-
- {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}
- ProgressODoom
-
-
- {1219a514-d3fa-40db-bbb2-92ce05e35839}
- TaglibSharp
-
-
-
-
-
-
-
-
-
-
-
-
-
- False
- .NET Framework 3.5 SP1 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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+ net10.0-windows
+ 2.2.6.0
+ WinExe
+ CUERipper
+ CUERipper
+ cue2.ico
+ Properties\app.manifest
+ 7.0
+ true
+ false
+ true
+ $(NoWarn);WFO1000
+ ..\bin\$(Configuration)\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
diff --git a/CUERipper/Options.cs b/CUERipper/Options.cs
index 77f623638..888a8922e 100644
--- a/CUERipper/Options.cs
+++ b/CUERipper/Options.cs
@@ -91,7 +91,9 @@ public CUERipperSettings(CUEConfig config)
[DefaultValue(false), Category("CTDB"), DisplayName("Detailed log")]
public bool DetailedCTDBLog { get { return config.advanced.DetailedCTDBLog; } set { config.advanced.DetailedCTDBLog = value; } }
- [DefaultValue("gnudb.gnudb.org"), Category("Various"), DisplayName("Freedb site address")]
- public string FreedbSiteAddress { get { return config.advanced.FreedbSiteAddress ; } set { config.advanced.FreedbSiteAddress = value; } }
+#if DORMANT_FREEDB
+ [DefaultValue("gnudb.gnudb.org"), Category("Various"), DisplayName("Freedb site address")]
+ public string FreedbSiteAddress { get { return config.advanced.FreedbSiteAddress ; } set { config.advanced.FreedbSiteAddress = value; } }
+#endif
}
}
diff --git a/CUERipper/Program.cs b/CUERipper/Program.cs
index 0e56cf1e5..69efe3e50 100644
--- a/CUERipper/Program.cs
+++ b/CUERipper/Program.cs
@@ -1,9 +1,8 @@
-using System;
-using System.Deployment.Application;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Windows.Forms;
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Windows.Forms;
using CUETools.Processor;
using CUETools.Processor.Settings;
@@ -31,26 +30,10 @@ static void Main()
Application.Run(new frmCUERipper());
}
- static void GetSatelliteAssemblies(string groupName)
- {
- if (ApplicationDeployment.IsNetworkDeployed)
- {
- ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
-
- if (deploy.IsFirstRun)
- {
- try
- {
- deploy.DownloadFileGroup(groupName);
- }
- catch (DeploymentException)
- {
- // Log error. Do not report this error to the user, because a satellite
- // assembly may not exist if the user's culture and the application's
- // default culture match.
- }
- }
- }
- }
- }
-}
\ No newline at end of file
+ static void GetSatelliteAssemblies(string groupName)
+ {
+ // System.Deployment.Application is not available on .NET 10.
+ // Optional plugin file groups must be included by the publish/package step.
+ }
+ }
+}
diff --git a/CUERipper/Properties/Resources.Designer.cs b/CUERipper/Properties/Resources.Designer.cs
index 18cec7edc..8b296b685 100644
--- a/CUERipper/Properties/Resources.Designer.cs
+++ b/CUERipper/Properties/Resources.Designer.cs
@@ -19,7 +19,7 @@ namespace CUERipper.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/CUERipper/Properties/Settings.Designer.cs b/CUERipper/Properties/Settings.Designer.cs
index ec1ef4e54..696701e66 100644
--- a/CUERipper/Properties/Settings.Designer.cs
+++ b/CUERipper/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace CUERipper.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "18.6.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/CUERipper/app.config b/CUERipper/app.config
index b979734e5..8f8552c04 100644
--- a/CUERipper/app.config
+++ b/CUERipper/app.config
@@ -8,6 +8,6 @@
-
+
diff --git a/CUERipper/frmCUERipper.cs b/CUERipper/frmCUERipper.cs
index 499e8d060..e3fb9bfb6 100644
--- a/CUERipper/frmCUERipper.cs
+++ b/CUERipper/frmCUERipper.cs
@@ -2,20 +2,23 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
-using System.Drawing;
-using System.IO;
-using System.Net;
-using System.Threading;
-using System.Windows.Forms;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Windows.Forms;
using System.Runtime.InteropServices;
using CUEControls;
using CUETools.AccurateRip;
using CUETools.CTDB;
-using CUETools.Processor;
-using CUETools.Processor.Settings;
-using CUETools.Ripper;
-using Freedb;
-using CUETools.Codecs;
+using CUETools.Processor;
+using CUETools.Processor.Settings;
+using CUETools.Ripper;
+#if DORMANT_FREEDB
+using Freedb;
+#endif
+using CUETools.Codecs;
using System.Xml;
using System.Xml.Serialization;
@@ -38,11 +41,13 @@ public partial class frmCUERipper : Form
public readonly static XmlSerializerNamespaces xmlEmptyNamespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { XmlQualifiedName.Empty });
public readonly static XmlWriterSettings xmlEmptySettings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true };
- public frmCUERipper()
- {
- InitializeComponent();
- _config = new CUEConfig();
- _startStop = new StartStop();
+ public frmCUERipper()
+ {
+ InitializeComponent();
+ if (!imageListMetadataSource.Images.ContainsKey(AccurateRipMeta.SourceKey))
+ imageListMetadataSource.Images.Add(AccurateRipMeta.SourceKey, Properties.Resources.accuraterip16);
+ _config = new CUEConfig();
+ _startStop = new StartStop();
cueRipperConfig = new CUERipperConfig();
m_icon_mgr = new CUEControls.ShellIconMgr();
m_icon_mgr.SetExtensionIcon(".flac", Properties.Resources.flac);
@@ -452,20 +457,21 @@ private void SetupControls()
buttonTracks.Enabled = data.selectedRelease != null && !running;
buttonMetadata.Enabled = data.selectedRelease != null && !running;
- buttonFreedbSubmit.Enabled = data.selectedRelease != null && !running;
- buttonVA.Enabled = data.selectedRelease != null && !running &&
- data.selectedRelease.ImageKey == "freedb" && !data.selectedRelease.metadata.IsVarious() && (new CUEMetadata(data.selectedRelease.metadata)).FreedbToVarious();
- buttonEncoding.Enabled = data.selectedRelease != null && !running &&
- data.selectedRelease.ImageKey == "freedb" && (new CUEMetadata(data.selectedRelease.metadata)).FreedbToEncoding();
- buttonReload.Enabled = data.selectedRelease != null && !running;
+ buttonFreedbSubmit.Visible = false;
+ buttonFreedbSubmit.Enabled = false;
+ buttonVA.Visible = false;
+ buttonVA.Enabled = false;
+ buttonEncoding.Visible = false;
+ buttonEncoding.Enabled = false;
+ buttonReload.Enabled = data.selectedRelease != null && !running;
buttonEjectDisk.Enabled = selectedDriveInfo !=null && !running;
buttonSettings.Enabled = !running;
}
- private void CheckStop()
- {
- lock (_startStop)
- {
+ private void CheckStop()
+ {
+ lock (_startStop)
+ {
if (_startStop._stop)
{
_startStop._stop = false;
@@ -480,11 +486,24 @@ private void CheckStop()
}
if (backgroundWorkerArtwork.IsBusy && backgroundWorkerArtwork.CancellationPending)
{
- throw new StopException();
- }
- }
-
- private void UploadProgress(object sender, Krystalware.UploadHelper.UploadProgressEventArgs e)
+ throw new StopException();
+ }
+ }
+
+ private void CheckStopRequested()
+ {
+ lock (_startStop)
+ {
+ if (_startStop._stop)
+ {
+ _startStop._stop = false;
+ _startStop._pause = false;
+ throw new StopException();
+ }
+ }
+ }
+
+ private void UploadProgress(object sender, Krystalware.UploadHelper.UploadProgressEventArgs e)
{
CheckStop();
this.BeginInvoke((MethodInvoker)delegate()
@@ -801,20 +820,34 @@ private void UpdateRelease()
// });
//}
- private void FreeDB_LookupProgress(object sender)
- {
- CheckStop();
- //_progress.percentDisk = (1.0 + _progress.percentDisk) / 2;
+ private void AccurateRipMetaLookupProgress(string detail)
+ {
+ CheckStop();
+ string text = Properties.Resources.LookingUpVia + " " + AccurateRipMeta.DisplayName + "..." + (string.IsNullOrEmpty(detail) ? "" : " " + detail);
+ this.BeginInvoke((MethodInvoker)delegate()
+ {
+ toolStripStatusLabel1.Text = text;
+ toolStripProgressBar1.Value = (100 + 2 * toolStripProgressBar1.Value) / 3;
+ });
+ }
+
+#if DORMANT_FREEDB
+ // FreeDB progress UI is dormant with the FreeDB provider.
+ private void FreeDB_LookupProgress(object sender)
+ {
+ CheckStop();
+ //_progress.percentDisk = (1.0 + _progress.percentDisk) / 2;
//_progress.input = e.Uri.ToString();
string text = Properties.Resources.LookingUpVia + " FreeDB..." + (sender is string ? " " + (sender as string) : "");
this.BeginInvoke((MethodInvoker)delegate()
{
toolStripStatusLabel1.Text = text;
- toolStripProgressBar1.Value = (100 + 2 * toolStripProgressBar1.Value) / 3;
- });
- }
-
- private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource, CTDBResponseMeta release)
+ toolStripProgressBar1.Value = (100 + 2 * toolStripProgressBar1.Value) / 3;
+ });
+ }
+#endif
+
+ private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource, CTDBResponseMeta release)
{
CUEMetadataEntry entry = new CUEMetadataEntry(audioSource.TOC, release.source);
entry.metadata.FillFromCtdb(release, entry.TOC.FirstAudio - 1);
@@ -828,14 +861,17 @@ private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource, CTDBResponseMeta
// return entry;
//}
- private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource, CDEntry cdEntry)
- {
- CUEMetadataEntry entry = new CUEMetadataEntry(audioSource.TOC, "freedb");
- entry.metadata.FillFromFreedb(cdEntry, entry.TOC.FirstAudio - 1);
- return entry;
- }
-
- private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource)
+#if DORMANT_FREEDB
+ // FreeDB CDEntry conversion is dormant with the FreeDB provider.
+ private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource, CDEntry cdEntry)
+ {
+ CUEMetadataEntry entry = new CUEMetadataEntry(audioSource.TOC, "freedb");
+ entry.metadata.FillFromFreedb(cdEntry, entry.TOC.FirstAudio - 1);
+ return entry;
+ }
+#endif
+
+ private CUEMetadataEntry CreateCUESheet(ICDRipper audioSource)
{
CUEMetadataEntry entry = new CUEMetadataEntry(audioSource.TOC, "blank");
entry.metadata.Artist = "Unknown Artist";
@@ -862,8 +898,12 @@ private void Lookup(object o)
cueSheet.OpenCD(audioSource);
cueSheet.Action = CUEAction.Encode;
- this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " CTDB..."; });
- cueSheet.UseCUEToolsDB("CUERipper " + CUESheet.CUEToolsVersion, selectedDriveInfo.drive.ARName, false, loadAllMetadata ? CTDBMetadataSearch.Extensive : _config.advanced.metadataSearch);
+ CTDBMetadataSearch metadataSearch = loadAllMetadata ? CTDBMetadataSearch.Extensive : _config.advanced.metadataSearch;
+ bool loadAllMetadataRequested = loadAllMetadata;
+ loadAllMetadata = false;
+
+ this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " CTDB..."; });
+ cueSheet.UseCUEToolsDB("CUERipper " + CUESheet.CUEToolsVersion, selectedDriveInfo.drive.ARName, false, metadataSearch);
cueSheet.CTDB.UploadHelper.onProgress += new EventHandler(UploadProgress);
this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " AccurateRip..."; });
cueSheet.UseAccurateRip();
@@ -886,11 +926,10 @@ private void Lookup(object o)
data.Releases.Add(CreateCUESheet(audioSource, ctdbMeta));
}
- if (data.Releases.Count == 0 || loadAllMetadata)
- {
- loadAllMetadata = false;
-
- //this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " MusicBrainz..."; });
+ bool noMetadataReleases = data.Releases.Count == 0;
+ if (noMetadataReleases || loadAllMetadataRequested)
+ {
+ //this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " MusicBrainz..."; });
//ReleaseQueryParameters p = new ReleaseQueryParameters();
//p.DiscId = audioSource.TOC.MusicBrainzId;
@@ -917,83 +956,98 @@ private void Lookup(object o)
//MusicBrainzService.Proxy = null;
//MusicBrainzService.XmlRequest -= new EventHandler(MusicBrainz_LookupProgress);
- this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " Freedb..."; });
-
- FreedbHelper m_freedb = new FreedbHelper();
- m_freedb.Proxy = _config.GetProxy();
- m_freedb.UserName = _config.advanced.FreedbUser;
- m_freedb.Hostname = _config.advanced.FreedbDomain;
- m_freedb.ClientName = "CUERipper";
- m_freedb.Version = CUESheet.CUEToolsVersion;
- try
- {
- m_freedb.SetDefaultSiteAddress(_config.advanced.FreedbSiteAddress);
- }
- catch (Exception ex)
- {
- this.Invoke((MethodInvoker)delegate()
- {
- MessageBox.Show(this, ex.Message, "FreedbHelper.SetDefaultSiteAddress", MessageBoxButtons.OK, MessageBoxIcon.Error);
- });
- }
-
- QueryResult queryResult;
- QueryResultCollection coll;
- string code = string.Empty;
- try
- {
- FreeDB_LookupProgress(this);
- code = m_freedb.Query(AccurateRipVerify.CalculateCDDBQuery(audioSource.TOC), out queryResult, out coll);
- if (code == FreedbHelper.ResponseCodes.CODE_200)
- {
- bool duplicate = false;
- foreach (var ctdbMeta in cueSheet.CTDB.Metadata)
- if (ctdbMeta.source == "freedb" && ctdbMeta.id == queryResult.Category + "/" + queryResult.Discid)
- duplicate = true;
- if (!duplicate)
- {
- FreeDB_LookupProgress(queryResult.Category + "/" + queryResult.Discid);
- CDEntry cdEntry;
- code = m_freedb.Read(queryResult, out cdEntry);
- if (code == FreedbHelper.ResponseCodes.CODE_210)
- {
- CUEMetadataEntry r = CreateCUESheet(audioSource, cdEntry);
- data.Releases.Add(r);
- }
- }
- }
- else
- if (code == FreedbHelper.ResponseCodes.CODE_210 ||
- code == FreedbHelper.ResponseCodes.CODE_211)
- {
- foreach (QueryResult qr in coll)
- {
- bool duplicate = false;
- foreach (var ctdbMeta in cueSheet.CTDB.Metadata)
- if (ctdbMeta.source == "freedb" && ctdbMeta.id == qr.Category + "/" + qr.Discid)
- duplicate = true;
- if (!duplicate)
- {
- CDEntry cdEntry;
- FreeDB_LookupProgress(qr.Category + "/" + qr.Discid);
- code = m_freedb.Read(qr, out cdEntry);
- if (code == FreedbHelper.ResponseCodes.CODE_210)
- {
- CUEMetadataEntry r = CreateCUESheet(audioSource, cdEntry);
- data.Releases.Add(r);
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Trace.WriteLine(ex.Message);
- }
- }
-
- // Add a blank Release to the metadata selection drop-down list in any case. It can be used, if the metadata retrieved is not correct or undesired.
- data.Releases.Add(CreateCUESheet(audioSource));
+#if DORMANT_FREEDB
+ // FreeDB lookup is dormant. AccurateRip Meta is the active replacement provider.
+ this.BeginInvoke((MethodInvoker)delegate() { toolStripStatusLabel1.Text = Properties.Resources.LookingUpVia + " Freedb..."; });
+
+ FreedbHelper m_freedb = new FreedbHelper();
+ m_freedb.Proxy = _config.GetProxy();
+ m_freedb.UserName = _config.advanced.FreedbUser;
+ m_freedb.Hostname = _config.advanced.FreedbDomain;
+ m_freedb.ClientName = "CUERipper";
+ m_freedb.Version = CUESheet.CUEToolsVersion;
+ try
+ {
+ m_freedb.SetDefaultSiteAddress(_config.advanced.FreedbSiteAddress);
+ }
+ catch (Exception ex)
+ {
+ this.Invoke((MethodInvoker)delegate()
+ {
+ MessageBox.Show(this, ex.Message, "FreedbHelper.SetDefaultSiteAddress", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ });
+ }
+
+ QueryResult queryResult;
+ QueryResultCollection coll;
+ string code = string.Empty;
+ try
+ {
+ FreeDB_LookupProgress(this);
+ code = m_freedb.Query(AccurateRipVerify.CalculateCDDBQuery(audioSource.TOC), out queryResult, out coll);
+ if (code == FreedbHelper.ResponseCodes.CODE_200)
+ {
+ bool duplicate = false;
+ foreach (var ctdbMeta in cueSheet.CTDB.Metadata)
+ if (ctdbMeta.source == "freedb" && ctdbMeta.id == queryResult.Category + "/" + queryResult.Discid)
+ duplicate = true;
+ if (!duplicate)
+ {
+ FreeDB_LookupProgress(queryResult.Category + "/" + queryResult.Discid);
+ CDEntry cdEntry;
+ code = m_freedb.Read(queryResult, out cdEntry);
+ if (code == FreedbHelper.ResponseCodes.CODE_210)
+ {
+ CUEMetadataEntry r = CreateCUESheet(audioSource, cdEntry);
+ data.Releases.Add(r);
+ }
+ }
+ }
+ else
+ if (code == FreedbHelper.ResponseCodes.CODE_210 ||
+ code == FreedbHelper.ResponseCodes.CODE_211)
+ {
+ foreach (QueryResult qr in coll)
+ {
+ bool duplicate = false;
+ foreach (var ctdbMeta in cueSheet.CTDB.Metadata)
+ if (ctdbMeta.source == "freedb" && ctdbMeta.id == qr.Category + "/" + qr.Discid)
+ duplicate = true;
+ if (!duplicate)
+ {
+ CDEntry cdEntry;
+ FreeDB_LookupProgress(qr.Category + "/" + qr.Discid);
+ code = m_freedb.Read(qr, out cdEntry);
+ if (code == FreedbHelper.ResponseCodes.CODE_210)
+ {
+ CUEMetadataEntry r = CreateCUESheet(audioSource, cdEntry);
+ data.Releases.Add(r);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine(ex.Message);
+ }
+#endif
+ }
+
+ // AccurateRip Meta is a peer of the CTDB metadata sources rather than a fallback for
+ // them: whenever CTDB is asked for metadata, this provider is asked too, so its release
+ // and its cover art appear on the first lookup instead of only after Reload.
+ if (metadataSearch != CTDBMetadataSearch.None)
+ {
+ AccurateRipMetaLookupProgress(null);
+ var provider = new AccurateRipMetaProvider();
+ CUEMetadataEntry accurateRipMeta = provider.Lookup(audioSource.TOC, _config.GetProxy(), CheckStopRequested);
+ if (accurateRipMeta != null)
+ data.Releases.Add(accurateRipMeta);
+ }
+
+ // Add a blank Release to the metadata selection drop-down list in any case. It can be used, if the metadata retrieved is not correct or undesired.
+ data.Releases.Add(CreateCUESheet(audioSource));
_workThread = null;
if (musicbrainzError != "")
@@ -1019,7 +1073,12 @@ private void Lookup(object o)
toolStripStatusLabelMusicBrainz.Text = mbresults_count > 0 ? mbresults_count.ToString() : "";
toolStripStatusLabelMusicBrainz.ToolTipText = "Musicbrainz: " + (mbresults_count > 0 ? mbresults_count.ToString() + " entries found." : (musicbrainzError + "click to submit."));
if (_config.advanced.coversSearch != CUEConfigAdvanced.CTDBCoversSearch.None)
- backgroundWorkerArtwork.RunWorkerAsync(new BackgroundWorkerArtworkArgs() { cueSheet = cueSheet, meta = data.selectedRelease });
+ backgroundWorkerArtwork.RunWorkerAsync(new BackgroundWorkerArtworkArgs()
+ {
+ cueSheet = cueSheet,
+ meta = data.selectedRelease,
+ releases = data.Releases.ToList()
+ });
});
}
@@ -1514,24 +1573,15 @@ private void buttonReload_Click(object sender, EventArgs e)
_workThread.Start(selectedDriveInfo.drive);
}
- private void buttonVA_Click(object sender, EventArgs e)
- {
- if (data.selectedRelease == null) return;
- data.selectedRelease.metadata.FreedbToVarious();
- UpdateRelease();
- data.Releases.ResetItem(bnComboBoxRelease.SelectedIndex);
- SetupControls();
- }
-
- private void buttonEncoding_Click(object sender, EventArgs e)
- {
- if (data.selectedRelease == null) return;
- data.selectedRelease.metadata.FreedbToEncoding();
- UpdateRelease();
- data.Releases.ResetItem(bnComboBoxRelease.SelectedIndex);
- UpdateOutputPath();
- SetupControls();
- }
+ private void buttonVA_Click(object sender, EventArgs e)
+ {
+ // FreeDB various-artist repair is dormant. AccurateRip Meta does not need this action.
+ }
+
+ private void buttonEncoding_Click(object sender, EventArgs e)
+ {
+ // FreeDB encoding repair is dormant. AccurateRip Meta responses are Unicode JSON.
+ }
private void listTracks_Click(object sender, EventArgs e)
{
@@ -1558,9 +1608,10 @@ private void listTracks_Click(object sender, EventArgs e)
}
}
- private void FreedbSubmit(object o)
- {
- StringCollection tmp = new StringCollection();
+#if DORMANT_FREEDB
+ private void FreedbSubmit(object o)
+ {
+ StringCollection tmp = new StringCollection();
tmp.Add("DTITLE=");
CDEntry entry = new CDEntry(tmp);
entry.Artist = data.selectedRelease.metadata.Artist;
@@ -1650,17 +1701,14 @@ private void FreedbSubmit(object o)
});
}
_workThread = null;
- this.BeginInvoke((MethodInvoker)delegate() { SetupControls(); });
- }
-
- private void buttonFreedbSubmit_Click(object sender, EventArgs e)
- {
- _workThread = new Thread(FreedbSubmit);
- _workThread.Priority = ThreadPriority.BelowNormal;
- _workThread.IsBackground = true;
- SetupControls();
- _workThread.Start();
- }
+ this.BeginInvoke((MethodInvoker)delegate() { SetupControls(); });
+ }
+#endif
+
+ private void buttonFreedbSubmit_Click(object sender, EventArgs e)
+ {
+ // FreeDB submission is dormant. AccurateRip Meta currently has no submission API.
+ }
List albumArt = new List();
int currentAlbumArt = 0;//, frontAlbumArt = -1;
@@ -1701,22 +1749,73 @@ private void SelectAlbumArt()
resetPictureBox(null);
}
- private void backgroundWorkerArtwork_DoWork(object sender, DoWorkEventArgs e)
- {
- var args = e.Argument as BackgroundWorkerArtworkArgs;
- var cueSheet = args.cueSheet;
- albumArt.Clear();
- currentAlbumArt = 0;
- //frontAlbumArt = -1;
- var knownUrls = new List();
- var firstUrls = new List();
-
- if (args.meta != null && args.meta.metadata.AlbumArt.Count > 0)
- foreach (var aa in args.meta.metadata.AlbumArt)
- firstUrls.Add(aa.uri);
-
- for (int i = 0; i < 2; i++)
- {
+ private void backgroundWorkerArtwork_DoWork(object sender, DoWorkEventArgs e)
+ {
+ var args = e.Argument as BackgroundWorkerArtworkArgs;
+ var cueSheet = args.cueSheet;
+ albumArt.Clear();
+ currentAlbumArt = 0;
+ var knownUrls = new List();
+ var firstUrls = new List();
+ var selectedReleaseCovers = new List();
+ var otherReleaseCovers = new List();
+
+ var releases = args.releases ?? new List();
+ if (releases.Count == 0 && args.meta != null)
+ releases.Add(args.meta);
+
+ foreach (var release in releases)
+ {
+ if (release == null || release.metadata == null || release.metadata.AlbumArt == null)
+ continue;
+
+ foreach (var releaseCover in release.metadata.AlbumArt)
+ {
+ if (releaseCover == null)
+ continue;
+ if (_config.advanced.coversSearch == CUEConfigAdvanced.CTDBCoversSearch.Primary && !releaseCover.primary)
+ continue;
+
+ // args.meta is the same CUEMetadataEntry instance captured from data.Releases for selected-release priority.
+ if (object.ReferenceEquals(release, args.meta))
+ {
+ if (!string.IsNullOrEmpty(releaseCover.uri))
+ firstUrls.Add(releaseCover.uri);
+ selectedReleaseCovers.Add(releaseCover);
+ }
+ else
+ {
+ otherReleaseCovers.Add(releaseCover);
+ }
+ }
+ }
+
+ var releaseCovers = selectedReleaseCovers.Concat(otherReleaseCovers);
+ foreach (var releaseCover in releaseCovers)
+ {
+ string fetchUrl = !string.IsNullOrEmpty(releaseCover.uri150) ? releaseCover.uri150 : releaseCover.uri;
+ if (string.IsNullOrEmpty(fetchUrl) || knownUrls.Contains(fetchUrl))
+ continue;
+
+ var ms = new MemoryStream();
+ if (!cueSheet.CTDB.FetchFile(fetchUrl, ms))
+ continue;
+
+ lock (this.albumArt)
+ {
+ if (backgroundWorkerArtwork.CancellationPending)
+ {
+ e.Cancel = true;
+ return;
+ }
+ this.albumArt.Add(new AlbumArt(releaseCover, ms.ToArray()));
+ }
+ knownUrls.Add(fetchUrl);
+ backgroundWorkerArtwork.ReportProgress(0);
+ }
+
+ for (int i = 0; i < 2; i++)
+ {
foreach (var metadata in cueSheet.CTDB.Metadata)
{
if (metadata.coverart == null)
@@ -1914,10 +2013,11 @@ private void listMetadata_PreviewKeyDown(object sender, PreviewKeyDownEventArgs
}
internal class BackgroundWorkerArtworkArgs
- {
- public CUESheet cueSheet;
- public CUEMetadataEntry meta;
- }
+ {
+ public CUESheet cueSheet;
+ public CUEMetadataEntry meta;
+ public List releases;
+ }
internal class AlbumArt
{
diff --git a/CUETools.ALACEnc/CUETools.ALACEnc.csproj b/CUETools.ALACEnc/CUETools.ALACEnc.csproj
index e6288638d..b5645b86a 100644
--- a/CUETools.ALACEnc/CUETools.ALACEnc.csproj
+++ b/CUETools.ALACEnc/CUETools.ALACEnc.csproj
@@ -1,9 +1,7 @@
- net47;net20;netcoreapp2.0
- false
- 2.0.9
+ net10.0
2.2.6.0
CUETools.ALACEnc
CUETools.ALACEnc
diff --git a/CUETools.ARCUE/CUETools.ARCUE.csproj b/CUETools.ARCUE/CUETools.ARCUE.csproj
index 1075c0667..e96771d2f 100644
--- a/CUETools.ARCUE/CUETools.ARCUE.csproj
+++ b/CUETools.ARCUE/CUETools.ARCUE.csproj
@@ -1,9 +1,7 @@
- net47;netcoreapp2.0
- false
- 2.0.9
+ net10.0
2.2.6.0
CUETools.ARCUE
CUETools.ARCUE
diff --git a/CUETools.AccurateRip/CUETools.AccurateRip.csproj b/CUETools.AccurateRip/CUETools.AccurateRip.csproj
index fc2763575..f68e72078 100644
--- a/CUETools.AccurateRip/CUETools.AccurateRip.csproj
+++ b/CUETools.AccurateRip/CUETools.AccurateRip.csproj
@@ -1,7 +1,7 @@
- net20;net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.AccurateRip
CUETools.AccurateRip
diff --git a/CUETools.CDImage/CUETools.CDImage.csproj b/CUETools.CDImage/CUETools.CDImage.csproj
index c103a5dca..1e49300c7 100644
--- a/CUETools.CDImage/CUETools.CDImage.csproj
+++ b/CUETools.CDImage/CUETools.CDImage.csproj
@@ -1,7 +1,7 @@
- net20;net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.CDImage
CUETools.CDImage
diff --git a/CUETools.CLParity/CLParity.cs b/CUETools.CLParity/CLParity.cs
index 6a56349f9..218708cf4 100644
--- a/CUETools.CLParity/CLParity.cs
+++ b/CUETools.CLParity/CLParity.cs
@@ -111,7 +111,7 @@ public class CLParityWriter : IAudioDest
bool inited = false;
OpenCLManager OCLMan;
- Program openCLProgram;
+ CLProgram openCLProgram;
CLParityTask task1;
CLParityTask task2;
@@ -123,6 +123,7 @@ public class CLParityWriter : IAudioDest
public CLParityWriter(string path, Stream IO, AudioPCMConfig pcm)
{
_pcm = pcm;
+ _encoderSettings = new CUETools.Codecs.WAV.EncoderSettings(pcm);
if (pcm.BitsPerSample != 16)
throw new Exception("Bits per sample must be 16.");
if (pcm.ChannelCount != 2)
@@ -137,6 +138,7 @@ public CLParityWriter(string path, AudioPCMConfig pcm)
}
internal CLParitySettings _settings = new CLParitySettings();
+ private readonly IAudioEncoderSettings _encoderSettings;
public object Settings
{
@@ -152,6 +154,8 @@ public object Settings
}
}
+ IAudioEncoderSettings IAudioDest.Settings => _encoderSettings;
+
//[DllImport("kernel32.dll")]
//static extern bool GetThreadTimes(IntPtr hThread, out long lpCreationTime, out long lpExitTime, out long lpKernelTime, out long lpUserTime);
//[DllImport("kernel32.dll")]
@@ -388,7 +392,7 @@ public unsafe void do_output_frames(int strideCount)
internal class CLParityTask
{
- Program openCLProgram;
+ CLProgram openCLProgram;
public CommandQueue openCLCQ;
public Kernel reedSolomonInit;
public Kernel reedSolomonInitGx;
@@ -432,7 +436,7 @@ internal class CLParityTask
public CLParityWriter writer;
public bool UseMappedMemory = false;
- unsafe public CLParityTask(Program _openCLProgram, CLParityWriter writer, int groupSize, int npar, int stride, int maxStridesCount)
+ unsafe public CLParityTask(CLProgram _openCLProgram, CLParityWriter writer, int groupSize, int npar, int stride, int maxStridesCount)
{
this.UseMappedMemory = writer._settings.MappedMemory || writer._settings.DeviceType == OpenCLDeviceType.CPU;
this.groupSize = groupSize;
@@ -629,7 +633,6 @@ internal unsafe void EnqueueKernels()
}
}
-#if LKJLKJLJK
public static class OpenCLExtensions
{
public static void SetArgs(this Kernel kernel, params object[] args)
@@ -660,5 +663,4 @@ public static void EnqueueNDRangeKernel(this CommandQueue queue, Kernel kernel,
queue.EnqueueNDRangeKernel(kernel, 2, null, new long[] { localSizeX * globalSizeX, localSizeY * globalSizeY }, new long[] { localSizeX, localSizeY });
}
}
-#endif
}
diff --git a/CUETools.CLParity/CUETools.CLParity.csproj b/CUETools.CLParity/CUETools.CLParity.csproj
index 7c131fcc9..363bc7022 100644
--- a/CUETools.CLParity/CUETools.CLParity.csproj
+++ b/CUETools.CLParity/CUETools.CLParity.csproj
@@ -1,128 +1,37 @@
-
-
+
+
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {D41FEFF9-9D43-4049-BF9B-B13D9AC7E192}
+ net10.0-windows
+ 2.2.6.0
Library
- Properties
- CUETools.CLParity
CUETools.CLParity
-
-
- 3.5
-
-
- v4.7
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\plugins\net47\
- DEBUG;TRACE
- prompt
- 4
- true
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\plugins\net47\
- TRACE
- prompt
- 4
+ CUETools.CLParity
+ 7.0
+ true
true
- AllRules.ruleset
+ false
+ $(NoWarn);WFO1000
+ ..\bin\$(Configuration)\$(TargetFramework)\plugins\
+ false
+ $(BaseIntermediateOutputPath)\$(Configuration)\$(TargetFramework)\
-
-
- False
- ..\ThirdParty\OpenCLNet.dll
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
- {082D6B9E-326E-4D15-9798-EDAE9EDE70A6}
- CUETools.Codecs.Flake
- False
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
+
+
+
False
-
+
+
-
- PreserveNewest
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
+
+
+
+
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
+
+ PreserveNewest
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/CUETools.CLParity/Properties/Resources.Designer.cs b/CUETools.CLParity/Properties/Resources.Designer.cs
index 39b66af0a..baf61d06c 100644
--- a/CUETools.CLParity/Properties/Resources.Designer.cs
+++ b/CUETools.CLParity/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18033
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -19,7 +19,7 @@ namespace CUETools.CLParity.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/CUETools.CTDB.Converter/CUETools.CTDB.Converter.csproj b/CUETools.CTDB.Converter/CUETools.CTDB.Converter.csproj
index cc91ce79d..b1f7938d5 100644
--- a/CUETools.CTDB.Converter/CUETools.CTDB.Converter.csproj
+++ b/CUETools.CTDB.Converter/CUETools.CTDB.Converter.csproj
@@ -1,9 +1,7 @@
- net47;net20;netcoreapp2.0
- false
- 2.0.9
+ net10.0
2.2.6.0
CUETools.CTDB.Converter
CUETools.CTDB.Converter
diff --git a/CUETools.CTDB.EACPlugin/CUETools.CTDB.EACPlugin.csproj b/CUETools.CTDB.EACPlugin/CUETools.CTDB.EACPlugin.csproj
index 46037b6dd..91a6644a6 100644
--- a/CUETools.CTDB.EACPlugin/CUETools.CTDB.EACPlugin.csproj
+++ b/CUETools.CTDB.EACPlugin/CUETools.CTDB.EACPlugin.csproj
@@ -1,180 +1,32 @@
-
-
-
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {816D964C-9772-46C5-AF1D-49E8C78A1E7C}
- Library
- Properties
- CUETools.CTDB.EACPlugin
- CUETools.CTDB.EACPlugin
- v2.0
- 512
-
-
- 3.5
-
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\interop\EAC\
- DEBUG;TRACE
- prompt
- 4
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\interop\EAC\
- TRACE
- prompt
- 4
- AllRules.ruleset
-
-
-
- Form
-
-
- FormSubmitParity.cs
-
-
- Form
-
-
- FormMetadata.cs
-
-
- Component
-
-
- ImagePreview.cs
-
-
-
-
-
- Form
-
-
- Options.cs
-
-
-
- True
- True
- Resources.resx
-
-
-
-
- FormSubmitParity.cs
-
-
- FormMetadata.cs
-
-
- ImagePreview.cs
-
-
- Options.cs
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
-
-
-
-
-
-
- .\Interop.HelperFunctionsLib.dll
- True
-
-
-
-
-
-
-
-
- {5802c7e9-157e-4124-946d-70b5ae48a5a1}
- CUETools.AccurateRip
-
-
- {1dd41038-d885-46c5-8dde-e0b82f066584}
- CUETools.CDImage
-
-
- {6458a13a-30ef-45a9-9d58-e5031b17bee2}
- CUETools.Codecs
-
-
- {c36efaa5-4f81-4a29-800d-ba866ff13bc8}
- CUETools.CTDB.Types
-
-
- {aa2a9a7e-45fb-4632-ad85-85b0e556f818}
- CUETools.CTDB
-
-
- {eceb839c-171b-4535-958f-9899310a0342}
- CUETools.Parity
-
-
-
-
-
+
+
+
+ net10.0-windows
+ Library
+ CUETools.CTDB.EACPlugin
+ CUETools.CTDB.EACPlugin
+ true
+ false
+ $(NoWarn);WFO1000
+ ..\bin\$(Configuration)\$(TargetFramework)\interop\EAC\
+ false
+ $(BaseIntermediateOutputPath)\$(Configuration)\$(TargetFramework)\
+
+
+
+
+ .\Interop.HelperFunctionsLib.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CUETools.CTDB.Types/CUETools.CTDB.Types.csproj b/CUETools.CTDB.Types/CUETools.CTDB.Types.csproj
index 409d6327c..e7c1ed0ce 100644
--- a/CUETools.CTDB.Types/CUETools.CTDB.Types.csproj
+++ b/CUETools.CTDB.Types/CUETools.CTDB.Types.csproj
@@ -1,7 +1,7 @@
- net20;net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.CTDB.Types
CUETools.CTDB
diff --git a/CUETools.CTDB/CUETools.CTDB.csproj b/CUETools.CTDB/CUETools.CTDB.csproj
index 59df590f6..62d6975bb 100644
--- a/CUETools.CTDB/CUETools.CTDB.csproj
+++ b/CUETools.CTDB/CUETools.CTDB.csproj
@@ -1,7 +1,7 @@
- net20;net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.CTDB
CUETools.CTDB
@@ -22,15 +22,9 @@
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/CUETools.CTDB/CUEToolsDB.cs b/CUETools.CTDB/CUEToolsDB.cs
index c8b0dc3e1..077e80a0f 100644
--- a/CUETools.CTDB/CUEToolsDB.cs
+++ b/CUETools.CTDB/CUEToolsDB.cs
@@ -7,17 +7,13 @@
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
-using CUETools.AccurateRip;
-using CUETools.CDImage;
-using CUETools.Parity;
-#if NET20
-using System.Management;
-#else
-using DeviceId;
-using DeviceId.Encoders;
-using DeviceId.Formatters;
-#endif
-using Krystalware.UploadHelper;
+using CUETools.AccurateRip;
+using CUETools.CDImage;
+using CUETools.Parity;
+using DeviceId;
+using DeviceId.Encoders;
+using DeviceId.Formatters;
+using Krystalware.UploadHelper;
namespace CUETools.CTDB
{
@@ -281,31 +277,16 @@ public bool FetchFile(string url, Stream output)
public static string GetUUID()
{
- if (uuidInfo == null)
- {
-#if NET20
- string id = "CTDB userid";
- using (ManagementClass mc = new ManagementClass("Win32_ComputerSystemProduct"))
- foreach (ManagementObject mo in mc.GetInstances())
- {
- id = id + mo.Properties["UUID"].Value.ToString();
- break;
- }
- byte[] hashBytes = (new SHA1CryptoServiceProvider()).ComputeHash(Encoding.ASCII.GetBytes(id));
- uuidInfo = Convert.ToBase64String(hashBytes).Replace('+', '.').Replace('/', '_').Replace('=', '-');
-#else
- uuidInfo = new DeviceIdBuilder()
- .AddMachineName()
-#if NET47
- .AddProcessorId()
- .AddMotherboardSerialNumber()
-#endif
- .UseFormatter(new HashDeviceIdFormatter(() => SHA256.Create(), new Base64UrlByteArrayEncoder()))
- .ToString();
-#endif
- }
- return uuidInfo;
- }
+ if (uuidInfo == null)
+ {
+ uuidInfo = new DeviceIdBuilder()
+ .AddMachineName()
+ .AddMacAddress(excludeWireless: true, excludeDockerBridge: true)
+ .UseFormatter(new HashDeviceIdFormatter(() => SHA256.Create(), new Base64UrlByteArrayEncoder()))
+ .ToString();
+ }
+ return uuidInfo;
+ }
public CTDBResponse Submit(int confidence, int quality, string artist, string title, string barcode)
{
diff --git a/CUETools.ChaptersToCue/CUETools.ChaptersToCue.csproj b/CUETools.ChaptersToCue/CUETools.ChaptersToCue.csproj
index 141d158f8..5c1f6f848 100644
--- a/CUETools.ChaptersToCue/CUETools.ChaptersToCue.csproj
+++ b/CUETools.ChaptersToCue/CUETools.ChaptersToCue.csproj
@@ -1,110 +1,20 @@
-
-
+
+
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {6ADBBF4B-AD3A-4782-A694-18662196780B}
+ net10.0
Exe
- Properties
- CUETools.ChaptersToCue
CUETools.ChaptersToCue
-
-
- 3.5
-
-
- v4.7
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\net47\
- DEBUG;TRACE
- prompt
- 4
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\net47\
- TRACE
- prompt
- 4
- AllRules.ruleset
+ CUETools.ChaptersToCue
+ false
+ ..\bin\$(Configuration)\
+
-
-
-
-
-
-
-
-
-
-
- {1DD41038-D885-46C5-8DDE-E0B82F066584}
- CUETools.CDImage
-
-
- {c36efaa5-4f81-4a29-800d-ba866ff13bc8}
- CUETools.CTDB.Types
-
-
- {AA2A9A7E-45FB-4632-AD85-85B0E556F818}
- CUETools.CTDB
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
-
-
- {1219a514-d3fa-40db-bbb2-92ce05e35839}
- TaglibSharp
-
-
-
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
+
+
+
+
+
-
-
-
\ No newline at end of file
+
+
diff --git a/CUETools.Codecs.ALAC/CUETools.Codecs.ALAC.csproj b/CUETools.Codecs.ALAC/CUETools.Codecs.ALAC.csproj
index effe2f82e..18600e1e6 100644
--- a/CUETools.Codecs.ALAC/CUETools.Codecs.ALAC.csproj
+++ b/CUETools.Codecs.ALAC/CUETools.Codecs.ALAC.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.ALAC
CUETools.Codecs
diff --git a/CUETools.Codecs.CoreAudio/CUETools.Codecs.CoreAudio.csproj b/CUETools.Codecs.CoreAudio/CUETools.Codecs.CoreAudio.csproj
index 94861db06..53edbdf33 100644
--- a/CUETools.Codecs.CoreAudio/CUETools.Codecs.CoreAudio.csproj
+++ b/CUETools.Codecs.CoreAudio/CUETools.Codecs.CoreAudio.csproj
@@ -1,7 +1,7 @@
- net47;net20
+ netstandard2.1
2.2.6.0
CUETools.Codecs.CoreAudio
CUETools.Codecs.CoreAudio
diff --git a/CUETools.Codecs.DirectSound/CUETools.Codecs.DirectSound.csproj b/CUETools.Codecs.DirectSound/CUETools.Codecs.DirectSound.csproj
index 84fd72b2d..d63d3447e 100644
--- a/CUETools.Codecs.DirectSound/CUETools.Codecs.DirectSound.csproj
+++ b/CUETools.Codecs.DirectSound/CUETools.Codecs.DirectSound.csproj
@@ -1,99 +1,29 @@
-
-
+
+
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {5A9FB016-6388-475D-AB33-6F86AD49FDAD}
+ net10.0-windows
+ 1.0.0.0
Library
- Properties
- CUETools.Codecs.DirectSound
CUETools.Codecs.DirectSound
- v4.7
- 512
-
-
-
-
- 3.5
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\net47\
- DEBUG;TRACE
- prompt
- 4
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\net47\
- TRACE
- prompt
- 4
- AllRules.ruleset
+ CUETools.Codecs.DirectSound
+ 7.0
+ true
+ false
+ $(NoWarn);WFO1000
+ ..\bin\$(Configuration)\$(TargetFramework)\plugins\
+ false
+ $(BaseIntermediateOutputPath)\$(Configuration)\$(TargetFramework)\
-
-
- False
-
-
-
-
-
-
-
-
-
-
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
+
+
+
+ False
-
+
+
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
+
+
-
-
-
\ No newline at end of file
+
+
diff --git a/CUETools.Codecs.DirectSound/DirectSoundOut.cs b/CUETools.Codecs.DirectSound/DirectSoundOut.cs
index 2ed8e3ca7..2ad9e50c2 100644
--- a/CUETools.Codecs.DirectSound/DirectSoundOut.cs
+++ b/CUETools.Codecs.DirectSound/DirectSoundOut.cs
@@ -1,297 +1,77 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-using System.Threading;
+using System;
using System.Windows.Forms;
-using Microsoft.DirectX;
-using Microsoft.DirectX.DirectSound;
+using CUETools.Codecs.CoreAudio;
+using NAudio.CoreAudioApi;
namespace CUETools.Codecs.DirectSound
{
- public class DirectSoundOut : IWavePlayer
- {
- private Device dSound;
- private WaveFormat format;// = new WaveFormat();
- private BufferDescription description = new BufferDescription();
- private SecondaryBuffer secondaryBuffer;
- private Notify notify;
- private MemoryStream pcmStream;
- private int SecBufByteSize;
- private AudioEncoderSettings m_settings;
- PlaybackState playbackState = PlaybackState.Stopped;
-
- ///
- /// Playback Stopped
- ///
- public event EventHandler PlaybackStopped;
-
- AutoResetEvent
- SecBufNotifyAtBegin = new AutoResetEvent(false),
- SecBufNotifyAtOneThird = new AutoResetEvent(false),
- SecBufNotifyAtTwoThirds = new AutoResetEvent(false);
- WaitHandle[] SecBufWaitHandles;
-
- public DirectSoundOut(Control owner, AudioPCMConfig pcm, int delay)
- {
- this.m_settings = new AudioEncoderSettings(pcm);
-
- //buffer = new CyclicBuffer(44100*4/10);
- //output = new CycilcBufferOutputStream(buffer);
- //input = new CycilcBufferInputStream(buffer);
-
- dSound = new Device();
- dSound.SetCooperativeLevel(owner, CooperativeLevel.Priority);
- format.AverageBytesPerSecond = pcm.SampleRate * pcm.BlockAlign;
- format.BitsPerSample = (short)pcm.BitsPerSample;
- format.BlockAlign = (short)pcm.BlockAlign;
- format.Channels = (short)pcm.ChannelCount;
- format.SamplesPerSecond = pcm.SampleRate;
- format.FormatTag = WaveFormatTag.Pcm;
- SecBufByteSize = delay * pcm.SampleRate * pcm.BlockAlign / 1000;
- description.Format = format;
- description.BufferBytes = SecBufByteSize;
- description.CanGetCurrentPosition = true;
- description.ControlPositionNotify = true;
- //description.ControlVolume = true;
- description.GlobalFocus = true;
- secondaryBuffer = new SecondaryBuffer(description, dSound);
- //secondaryBuffer.Volume = 100;
-
- notify = new Notify(secondaryBuffer);
- BufferPositionNotify[] bufferPositions = new BufferPositionNotify[3];
- bufferPositions[0].Offset = 0;
- bufferPositions[0].EventNotifyHandle = SecBufNotifyAtBegin.Handle;
- bufferPositions[1].Offset = SecBufByteSize / 3;
- bufferPositions[1].EventNotifyHandle = SecBufNotifyAtOneThird.Handle;
- bufferPositions[2].Offset = 2 * SecBufByteSize / 3;
- bufferPositions[2].EventNotifyHandle = SecBufNotifyAtTwoThirds.Handle;
- notify.SetNotificationPositions(bufferPositions);
- pcmStream = new MemoryStream(SecBufByteSize);
-
- SecBufWaitHandles = new WaitHandle[] { SecBufNotifyAtBegin, SecBufNotifyAtOneThird, SecBufNotifyAtTwoThirds };
-
- //wavoutput = new WAVWriter("", output, pcm);
- }
-
- ///
- /// Volume
- ///
- public float Volume
- {
- get
- {
- return 1.0f;
- }
- set
- {
- if (value != 1.0f)
- {
- throw new NotImplementedException();
- }
- }
- }
-
- //int SecBufNextWritePosition = 0;
- //bool SecBufInitialLoad = false;
-
- bool playing = false;
- public void Write(AudioBuffer src)
- {
- //wavoutput.Write(src);
-
- pcmStream.SetLength(0);
- pcmStream.Write(src.Bytes, 0, src.ByteLength);
- pcmStream.Position = 0;
- //pcmStream.Position = 0;
-
- //while (true)
- //{
- // if (SecBufInitialLoad)
- // {
- // int count = Math.Min(src.ByteLength, SecBufByteSize - SecBufNextWritePosition);
- // if (count > 0)
- // {
- // secondaryBuffer.Write(SecBufNextWritePosition, pcmStream, count, LockFlag.None);
- // SecBufNextWritePosition += count;
- // pcmStream.Position += count;
- // }
-
- // if (SecBufByteSize == SecBufNextWritePosition)
- // {
- // // Finished filling the buffer
- // SecBufInitialLoad = false;
- // SecBufNextWritePosition = 0;
-
- // // So start the playback in its own thread
- // secondaryBuffer.Play(0, BufferPlayFlags.Looping);
-
- // // Yield rest of timeslice so playback can
- // // start right away.
- // Thread.Sleep(0);
- // }
- // else
- // {
- // continue; // Get more PCM data
- // }
- // }
-
- // Exhaust the current PCM data by writing the data into secondaryBuffer
- while (pcmStream.Position < pcmStream.Length)
- {
- int PlayPosition, WritePosition;
-
- secondaryBuffer.GetCurrentPosition(out PlayPosition, out WritePosition);
-
- int WriteCount = (int)Math.Min(
- (SecBufByteSize + PlayPosition - WritePosition) % SecBufByteSize,
- pcmStream.Length - pcmStream.Position);
-
- if (WriteCount > 0)
- {
- secondaryBuffer.Write(
- WritePosition,
- pcmStream,
- WriteCount,
- LockFlag.None);
- pcmStream.Position += WriteCount;
- if (!playing)
- {
- secondaryBuffer.Play(0, 0);
- playing = true;
- }
- }
- else
- {
- WaitHandle.WaitAny(SecBufWaitHandles, new TimeSpan(0, 0, 5), true);
- }
- }
- }
-
- ///
- /// Begin Playback
- ///
- public void Play()
- {
- switch (playbackState)
- {
- case PlaybackState.Playing:
- return;
- case PlaybackState.Paused:
- playbackState = PlaybackState.Playing;
- return;
- case PlaybackState.Stopped:
- playbackState = PlaybackState.Playing;
- //playThread = new Thread(new ThreadStart(PlayThread));
- //playThread.Priority = ThreadPriority.Highest;
- //playThread.IsBackground = true;
- //playThread.Name = "Pro Audio";
- //playThread.Start();
- return;
- }
- }
-
- ///
- /// Stop playback and flush buffers
- ///
- public void Stop()
- {
- if (playbackState != PlaybackState.Stopped)
- {
- playbackState = PlaybackState.Stopped;
- //if (frameEventWaitHandle != null)
- // frameEventWaitHandle.Set();
- //playThread.Join();
- //playThread = null;
- //ReleaseBuffer(readBuffers[0], false, 0);
- //ReleaseBuffer(readBuffers[1], false, 0);
- //active = null;
- //active_offset = 0;
- }
- }
-
- ///
- /// Stop playback without flushing buffers
- ///
- public void Pause()
- {
- if (playbackState == PlaybackState.Playing)
- {
- playbackState = PlaybackState.Paused;
- }
- //if (frameEventWaitHandle != null)
- // frameEventWaitHandle.Set();
- }
-
- ///
- /// Playback State
- ///
- public PlaybackState PlaybackState
- {
- get { return playbackState; }
- }
-
- public void Close()
- {
- if (secondaryBuffer != null)
- {
- secondaryBuffer.Dispose();
- secondaryBuffer = null;
- }
- if (dSound != null)
- {
- dSound.Dispose();
- dSound = null;
- }
- //wavoutput.Close();
- }
-
- public void Delete()
- {
- Close();
- }
-
- #region IAudioDest Members
-
- public long Position
- {
- get
- {
- return 0;
- }
- }
-
- public long FinalSampleCount
- {
- set { ; }
- }
-
- public object Settings
- {
- get
- {
- return m_settings;
- }
- }
-
- public string Path { get { return null; } }
-
- #endregion
-
- #region IDisposable Members
-
- ///
- /// Dispose
- ///
- public void Dispose()
- {
- //if (audioClient != null)
- {
- Stop();
- }
-
- }
-
- #endregion
- }
+ public class DirectSoundOut : CUETools.Codecs.IWavePlayer
+ {
+ private readonly WasapiOut player;
+
+ public DirectSoundOut(Control owner, AudioPCMConfig pcm, int delay)
+ {
+ player = new WasapiOut(WasapiOut.GetDefaultAudioEndpoint(), AudioClientShareMode.Shared, true, delay, pcm);
+ }
+
+ public event EventHandler PlaybackStopped
+ {
+ add { player.PlaybackStopped += value; }
+ remove { player.PlaybackStopped -= value; }
+ }
+
+ public float Volume
+ {
+ get { return player.Volume; }
+ set { player.Volume = value; }
+ }
+
+ public CUETools.Codecs.PlaybackState PlaybackState => (CUETools.Codecs.PlaybackState)player.PlaybackState;
+
+ public long Position => player.Position;
+
+ public long FinalSampleCount
+ {
+ set { player.FinalSampleCount = value; }
+ }
+
+ public IAudioEncoderSettings Settings => player.Settings;
+
+ public string Path => player.Path;
+
+ public void Write(AudioBuffer src)
+ {
+ player.Write(src);
+ }
+
+ public void Play()
+ {
+ player.Play();
+ }
+
+ public void Stop()
+ {
+ player.Stop();
+ }
+
+ public void Pause()
+ {
+ player.Pause();
+ }
+
+ public void Close()
+ {
+ player.Close();
+ }
+
+ public void Delete()
+ {
+ player.Delete();
+ }
+
+ public void Dispose()
+ {
+ player.Dispose();
+ }
+ }
}
diff --git a/CUETools.Codecs.FLACCL/CUETools.Codecs.FLACCL.csproj b/CUETools.Codecs.FLACCL/CUETools.Codecs.FLACCL.csproj
index eef5c9144..fb605770a 100644
--- a/CUETools.Codecs.FLACCL/CUETools.Codecs.FLACCL.csproj
+++ b/CUETools.Codecs.FLACCL/CUETools.Codecs.FLACCL.csproj
@@ -1,131 +1,41 @@
-
-
-
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {DFE55765-564C-4B8F-993B-A94C4D1C212E}
- Library
- Properties
- CUETools.Codecs.FLACCL
- CUETools.Codecs.FLACCL
-
-
- 3.5
-
-
- v4.7
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\net47\plugins\
- DEBUG;TRACE
- prompt
- 4
- true
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\net47\plugins\
- TRACE
- prompt
- 4
- true
- AllRules.ruleset
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
- {082D6B9E-326E-4D15-9798-EDAE9EDE70A6}
- CUETools.Codecs.Flake
- False
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
- False
-
-
- {8373e3b2-16f0-4fd3-a13b-0b0248ffc228}
- OpenCLNet
-
-
-
-
- PreserveNewest
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+ net10.0-windows
+ 2.2.6.0
+ Library
+ CUETools.Codecs.FLACCL
+ CUETools.Codecs.FLACCL
+ 7.0
+ true
+ true
+ false
+ $(NoWarn);WFO1000
+ ..\bin\$(Configuration)\$(TargetFramework)\plugins\
+ false
+ $(BaseIntermediateOutputPath)\$(Configuration)\$(TargetFramework)\
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/CUETools.Codecs.FLACCL/Properties/Resources.Designer.cs b/CUETools.Codecs.FLACCL/Properties/Resources.Designer.cs
index b43ad8e85..6f341093c 100644
--- a/CUETools.Codecs.FLACCL/Properties/Resources.Designer.cs
+++ b/CUETools.Codecs.FLACCL/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18033
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -19,7 +19,7 @@ namespace CUETools.Codecs.FLACCL.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/CUETools.Codecs.Flake/CUETools.Codecs.Flake.csproj b/CUETools.Codecs.Flake/CUETools.Codecs.Flake.csproj
index 3f1b647db..dc45658ec 100644
--- a/CUETools.Codecs.Flake/CUETools.Codecs.Flake.csproj
+++ b/CUETools.Codecs.Flake/CUETools.Codecs.Flake.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.Flake
CUETools.Codecs.Flake
diff --git a/CUETools.Codecs.HDCD/CUETools.Codecs.HDCD.csproj b/CUETools.Codecs.HDCD/CUETools.Codecs.HDCD.csproj
index 998621d09..d7acaccba 100644
--- a/CUETools.Codecs.HDCD/CUETools.Codecs.HDCD.csproj
+++ b/CUETools.Codecs.HDCD/CUETools.Codecs.HDCD.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.HDCD
CUETools.Codecs.HDCD
diff --git a/CUETools.Codecs.HDCD/HDCDDLL.cs b/CUETools.Codecs.HDCD/HDCDDLL.cs
index c0750fb8c..cac612ae4 100644
--- a/CUETools.Codecs.HDCD/HDCDDLL.cs
+++ b/CUETools.Codecs.HDCD/HDCDDLL.cs
@@ -53,7 +53,7 @@ static HDCDDLL()
var myFolder = System.IO.Path.GetDirectoryName(myPath);
var is64 = IntPtr.Size == 8;
var subfolder = is64 ? "x64" : "win32";
-#if NET47
+#if NET48
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
#else
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
diff --git a/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj b/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj
index 00c6d013a..219bf91f6 100644
--- a/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj
+++ b/CUETools.Codecs.Icecast/CUETools.Codecs.Icecast.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.Icecast
CUETools.Codecs.Icecast
diff --git a/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj b/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj
index 43bcfaf0f..26b589703 100644
--- a/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj
+++ b/CUETools.Codecs.LossyWAV/CUETools.Codecs.LossyWAV.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.LossyWAV
CUETools.Codecs.LossyWAV
diff --git a/CUETools.Codecs.MACLib/CUETools.Codecs.MACLib.csproj b/CUETools.Codecs.MACLib/CUETools.Codecs.MACLib.csproj
index ae90a69a0..936f0d38f 100644
--- a/CUETools.Codecs.MACLib/CUETools.Codecs.MACLib.csproj
+++ b/CUETools.Codecs.MACLib/CUETools.Codecs.MACLib.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.MACLib
CUETools.Codecs.MACLib
diff --git a/CUETools.Codecs.MACLib/MACLibDll.cs b/CUETools.Codecs.MACLib/MACLibDll.cs
index 30efa25e4..d5289c99c 100644
--- a/CUETools.Codecs.MACLib/MACLibDll.cs
+++ b/CUETools.Codecs.MACLib/MACLibDll.cs
@@ -72,7 +72,7 @@ static MACLibDll()
var myFolder = System.IO.Path.GetDirectoryName(myPath);
var is64 = IntPtr.Size == 8;
var subfolder = is64 ? "x64" : "win32";
-#if NET47
+#if NET48
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
#else
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
diff --git a/CUETools.Codecs.MPEG/CUETools.Codecs.MPEG.csproj b/CUETools.Codecs.MPEG/CUETools.Codecs.MPEG.csproj
index 473bb4f92..7d043cbdf 100644
--- a/CUETools.Codecs.MPEG/CUETools.Codecs.MPEG.csproj
+++ b/CUETools.Codecs.MPEG/CUETools.Codecs.MPEG.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.MPEG
CUETools.Codecs.MPEG
diff --git a/CUETools.Codecs.WMA/CUETools.Codecs.WMA.csproj b/CUETools.Codecs.WMA/CUETools.Codecs.WMA.csproj
index 11e5be0a8..2f0e88be5 100644
--- a/CUETools.Codecs.WMA/CUETools.Codecs.WMA.csproj
+++ b/CUETools.Codecs.WMA/CUETools.Codecs.WMA.csproj
@@ -1,7 +1,7 @@
- net47;net20
+ netstandard2.1
2.2.6.0
CUETools.Codecs.WMA
CUETools.Codecs.WMA
diff --git a/CUETools.Codecs.ffmpeg/CUETools.Codecs.ffmpeg.csproj b/CUETools.Codecs.ffmpeg/CUETools.Codecs.ffmpeg.csproj
index b8bad433f..b386b79f2 100644
--- a/CUETools.Codecs.ffmpeg/CUETools.Codecs.ffmpeg.csproj
+++ b/CUETools.Codecs.ffmpeg/CUETools.Codecs.ffmpeg.csproj
@@ -1,7 +1,7 @@
- net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.ffmpegdll
CUETools.Codecs.ffmpegdll
@@ -25,7 +25,7 @@
-
+
diff --git a/CUETools.Codecs.lame_enc/CUETools.Codecs.LAME.csproj b/CUETools.Codecs.lame_enc/CUETools.Codecs.LAME.csproj
index d95f4f801..ae7e56b63 100644
--- a/CUETools.Codecs.lame_enc/CUETools.Codecs.LAME.csproj
+++ b/CUETools.Codecs.lame_enc/CUETools.Codecs.LAME.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.lame_enc
CUETools.Codecs.lame_enc
diff --git a/CUETools.Codecs.libFLAC/CUETools.Codecs.libFLAC.csproj b/CUETools.Codecs.libFLAC/CUETools.Codecs.libFLAC.csproj
index f2bef093a..368e65b79 100644
--- a/CUETools.Codecs.libFLAC/CUETools.Codecs.libFLAC.csproj
+++ b/CUETools.Codecs.libFLAC/CUETools.Codecs.libFLAC.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.libFLAC
CUETools.Codecs.libFLAC
diff --git a/CUETools.Codecs.libFLAC/FLACDLL.cs b/CUETools.Codecs.libFLAC/FLACDLL.cs
index 8555e7b3b..37f123e44 100644
--- a/CUETools.Codecs.libFLAC/FLACDLL.cs
+++ b/CUETools.Codecs.libFLAC/FLACDLL.cs
@@ -163,7 +163,7 @@ static FLACDLL()
var myFolder = System.IO.Path.GetDirectoryName(myPath);
var is64 = IntPtr.Size == 8;
var subfolder = is64 ? "x64" : "win32";
-#if NET47
+#if NET48
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
#else
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
diff --git a/CUETools.Codecs.libmp3lame/CUETools.Codecs.libmp3lame.csproj b/CUETools.Codecs.libmp3lame/CUETools.Codecs.libmp3lame.csproj
index 2e874255b..01205e4ef 100644
--- a/CUETools.Codecs.libmp3lame/CUETools.Codecs.libmp3lame.csproj
+++ b/CUETools.Codecs.libmp3lame/CUETools.Codecs.libmp3lame.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.libmp3lame
CUETools.Codecs.libmp3lame
diff --git a/CUETools.Codecs.libmp3lame/libmp3lamedll.cs b/CUETools.Codecs.libmp3lame/libmp3lamedll.cs
index 12a086658..42eae49f2 100644
--- a/CUETools.Codecs.libmp3lame/libmp3lamedll.cs
+++ b/CUETools.Codecs.libmp3lame/libmp3lamedll.cs
@@ -52,7 +52,7 @@ static libmp3lamedll()
var myFolder = System.IO.Path.GetDirectoryName(myPath);
var is64 = IntPtr.Size == 8;
var subfolder = is64 ? "x64" : "win32";
-#if NET47
+#if NET48
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
#else
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
diff --git a/CUETools.Codecs.libwavpack/CUETools.Codecs.libwavpack.csproj b/CUETools.Codecs.libwavpack/CUETools.Codecs.libwavpack.csproj
index 364267a04..f20505199 100644
--- a/CUETools.Codecs.libwavpack/CUETools.Codecs.libwavpack.csproj
+++ b/CUETools.Codecs.libwavpack/CUETools.Codecs.libwavpack.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs.libwavpack
CUETools.Codecs.libwavpack
diff --git a/CUETools.Codecs.libwavpack/wavpackdll.cs b/CUETools.Codecs.libwavpack/wavpackdll.cs
index a320d9dba..dc04b2531 100644
--- a/CUETools.Codecs.libwavpack/wavpackdll.cs
+++ b/CUETools.Codecs.libwavpack/wavpackdll.cs
@@ -71,7 +71,7 @@ static wavpackdll()
var myFolder = System.IO.Path.GetDirectoryName(myPath);
var is64 = IntPtr.Size == 8;
var subfolder = is64 ? "x64" : "win32";
-#if NET47
+#if NET48
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
#else
IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
diff --git a/CUETools.Codecs/AudioEncoderSettings.cs b/CUETools.Codecs/AudioEncoderSettings.cs
index 6d86eb32c..a0650dae5 100644
--- a/CUETools.Codecs/AudioEncoderSettings.cs
+++ b/CUETools.Codecs/AudioEncoderSettings.cs
@@ -1,20 +1,11 @@
using System;
using System.ComponentModel;
-using System.Collections.Generic;
-using System.Text;
-using Newtonsoft.Json;
-
-#if NET20
- namespace System.Runtime.CompilerServices
- {
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class
- | AttributeTargets.Method)]
- public sealed class ExtensionAttribute : Attribute { }
- }
-#endif
-
-namespace CUETools.Codecs
-{
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json;
+
+namespace CUETools.Codecs
+{
public interface IAudioEncoderSettings
{
string Name { get; }
diff --git a/CUETools.Codecs/CUETools.Codecs.csproj b/CUETools.Codecs/CUETools.Codecs.csproj
index baf595324..fb673685c 100644
--- a/CUETools.Codecs/CUETools.Codecs.csproj
+++ b/CUETools.Codecs/CUETools.Codecs.csproj
@@ -1,7 +1,7 @@
- net20;net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Codecs
CUETools.Codecs
@@ -17,7 +17,7 @@
-
+
diff --git a/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj b/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj
index 86ec0cc82..b34838b62 100644
--- a/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj
+++ b/CUETools.Compression.Rar/CUETools.Compression.Rar.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Compression.Rar
CUETools.Compression.Rar
diff --git a/CUETools.Compression.Zip/CUETools.Compression.Zip.csproj b/CUETools.Compression.Zip/CUETools.Compression.Zip.csproj
index ec4870c33..f00e9c809 100644
--- a/CUETools.Compression.Zip/CUETools.Compression.Zip.csproj
+++ b/CUETools.Compression.Zip/CUETools.Compression.Zip.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Compression.Zip
CUETools.Compression.Zip
diff --git a/CUETools.Compression/CUETools.Compression.csproj b/CUETools.Compression/CUETools.Compression.csproj
index 2b94c2cec..ae76599a1 100644
--- a/CUETools.Compression/CUETools.Compression.csproj
+++ b/CUETools.Compression/CUETools.Compression.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Compression
CUETools.Compression
diff --git a/CUETools.Converter/CUETools.Converter.csproj b/CUETools.Converter/CUETools.Converter.csproj
index 3f8e3c0ef..f0089738c 100644
--- a/CUETools.Converter/CUETools.Converter.csproj
+++ b/CUETools.Converter/CUETools.Converter.csproj
@@ -1,9 +1,7 @@
- net47;netcoreapp2.0
- false
- 2.0.9
+ net10.0
2.2.6.0
CUETools.Converter
CUETools.Converter
diff --git a/CUETools.DSP.Mixer/CUETools.DSP.Mixer.csproj b/CUETools.DSP.Mixer/CUETools.DSP.Mixer.csproj
index 286423439..ce87b37c2 100644
--- a/CUETools.DSP.Mixer/CUETools.DSP.Mixer.csproj
+++ b/CUETools.DSP.Mixer/CUETools.DSP.Mixer.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.DSP.Mixer
CUETools.DSP.Mixer
diff --git a/CUETools.DSP.Resampler/CUETools.DSP.Resampler.csproj b/CUETools.DSP.Resampler/CUETools.DSP.Resampler.csproj
index 0b3fd772f..99961d8d1 100644
--- a/CUETools.DSP.Resampler/CUETools.DSP.Resampler.csproj
+++ b/CUETools.DSP.Resampler/CUETools.DSP.Resampler.csproj
@@ -1,7 +1,7 @@
- net47;net20;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.DSP.Resampler
CUETools.DSP.Resampler
diff --git a/CUETools.FLACCL.cmd/App.config b/CUETools.FLACCL.cmd/App.config
index c8d467dcf..0f9b4a6db 100644
--- a/CUETools.FLACCL.cmd/App.config
+++ b/CUETools.FLACCL.cmd/App.config
@@ -1,8 +1,8 @@
-
+
-
\ No newline at end of file
+
diff --git a/CUETools.FLACCL.cmd/CUETools.FLACCL.cmd.csproj b/CUETools.FLACCL.cmd/CUETools.FLACCL.cmd.csproj
index 8f870ca4e..a376e3085 100644
--- a/CUETools.FLACCL.cmd/CUETools.FLACCL.cmd.csproj
+++ b/CUETools.FLACCL.cmd/CUETools.FLACCL.cmd.csproj
@@ -1,114 +1,29 @@
-
-
-
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {1FCA8834-34E6-47CF-B53F-D8DF35345363}
- Exe
- Properties
- CUETools.FLACCL.cmd
- CUETools.FLACCL.cmd
-
-
- 3.5
-
-
- v4.7
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- true
- full
- false
- ..\bin\Debug\net47\
- DEBUG;TRACE
- prompt
- 4
- AnyCPU
- AllRules.ruleset
-
-
- pdbonly
- true
- ..\bin\Release\net47\
- TRACE
- prompt
- 4
- AnyCPU
- AllRules.ruleset
-
-
-
- False
- ..\ThirdParty\openclnet\source\bin\$(Configuration)\net47\OpenCLNet.dll
-
-
-
-
-
-
-
-
-
-
-
- {082D6B9E-326E-4D15-9798-EDAE9EDE70A6}
- CUETools.Codecs.Flake
- False
-
-
- {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
- CUETools.Codecs
- False
-
-
- {DFE55765-564C-4B8F-993B-A94C4D1C212E}
- CUETools.Codecs.FLACCL
- False
-
-
-
-
-
-
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
-
-
-
-
\ No newline at end of file
+
+
+
+ net10.0-windows
+ 2.2.6.0
+ Exe
+ CUETools.FLACCL.cmd
+ CUETools.FLACCL.cmd
+ 7.0
+ false
+ ..\bin\$(Configuration)\$(TargetFramework)\
+ false
+ $(BaseIntermediateOutputPath)\$(Configuration)\$(TargetFramework)\
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CUETools.Flake/CUETools.Flake.csproj b/CUETools.Flake/CUETools.Flake.csproj
index a68dde5a2..9c8e2389c 100644
--- a/CUETools.Flake/CUETools.Flake.csproj
+++ b/CUETools.Flake/CUETools.Flake.csproj
@@ -1,9 +1,7 @@
- net47;net20;netcoreapp2.0
- false
- 2.0.9
+ net10.0
2.2.6.0
CUETools.Flake
CUETools.Flake
diff --git a/CUETools.LossyWAV/CUETools.LossyWAV.csproj b/CUETools.LossyWAV/CUETools.LossyWAV.csproj
index b7c3b0c69..5fc5d1169 100644
--- a/CUETools.LossyWAV/CUETools.LossyWAV.csproj
+++ b/CUETools.LossyWAV/CUETools.LossyWAV.csproj
@@ -1,9 +1,7 @@
- net47;net20;netcoreapp2.0
- false
- 2.0.9
+ net10.0
2.2.6.0
CUETools.LossyWAV
CUETools.LossyWAV
diff --git a/CUETools.Parity/CUETools.Parity.csproj b/CUETools.Parity/CUETools.Parity.csproj
index 136e47052..12b6fd022 100644
--- a/CUETools.Parity/CUETools.Parity.csproj
+++ b/CUETools.Parity/CUETools.Parity.csproj
@@ -1,7 +1,7 @@
- net20;net47;netstandard2.0
+ netstandard2.1
2.2.6.0
CUETools.Parity
CUETools.Parity
diff --git a/CUETools.Processor/AccurateRipMeta.cs b/CUETools.Processor/AccurateRipMeta.cs
new file mode 100644
index 000000000..d7317eddd
--- /dev/null
+++ b/CUETools.Processor/AccurateRipMeta.cs
@@ -0,0 +1,414 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading;
+using CUETools.AccurateRip;
+using CUETools.CDImage;
+using CUETools.CTDB;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace CUETools.Processor
+{
+ public static class AccurateRipMeta
+ {
+ public const string SourceKey = "accurateripmeta";
+ public const string DisplayName = "AccurateRip Meta";
+ internal const string ContentType = "application/x-www-form-urlencoded";
+ internal const string CoverArtHost = "meta.accuraterip.com";
+ // HTTPS on meta.accuraterip.com:443 was refused during contract review, so the live endpoint remains HTTP-only.
+ public static readonly string Endpoint = "http://meta.accuraterip.com/discmatch";
+ internal const int LookupTimeoutMilliseconds = 5000;
+ internal const int ReadWriteTimeoutMilliseconds = 15000;
+
+ public static bool TryParseMetadata(string json, CDImageLayout toc, out CUEMetadataEntry entry)
+ {
+ entry = null;
+
+ if (toc == null || string.IsNullOrWhiteSpace(json))
+ return false;
+
+ JObject response;
+ try
+ {
+ response = JObject.Parse(json);
+ }
+ catch (JsonException ex)
+ {
+ System.Diagnostics.Trace.WriteLine("AccurateRip Meta JSON parse failed: " + ex.Message);
+ return false;
+ }
+
+ JArray tracks = response["tracks"] as JArray;
+ int audioTracks = (int)toc.AudioTracks;
+ if (tracks == null || tracks.Count < audioTracks)
+ return false;
+
+ List orderedTracks = OrderTracksByTrackNumber(tracks, toc.FirstAudio, audioTracks);
+ if (orderedTracks == null)
+ return false;
+
+ if (string.IsNullOrWhiteSpace(Clean(response["Artist"])) && string.IsNullOrWhiteSpace(Clean(response["Album"])))
+ return false;
+
+ var metadata = new CUEMetadata(toc.TOCID, audioTracks)
+ {
+ Artist = NormalizeProviderList(response["Artist"]),
+ Title = Clean(response["Album"]),
+ Year = Clean(response["Year"]),
+ Genre = NormalizeGenreList(response["Genre"]),
+ Barcode = CleanIdentifier(response["UPC"], "UPC"),
+ Label = Clean(response["Label"]),
+ LabelNo = CleanIdentifier(response["CatalogNum"], "CatalogNum")
+ };
+
+ // AccurateRip Meta also exposes Styles, Composers, Conductors, _albumid, and _tocid. Keep them unused until CUETools has explicit fields for them; do not overwrite Genre with Styles.
+ for (int i = 0; i < audioTracks; i++)
+ {
+ JObject track = orderedTracks[i];
+
+ metadata.Tracks[i].Title = Clean(track["Title"]);
+ string trackArtist = NormalizeProviderList(track["Artist"]);
+ metadata.Tracks[i].Artist = trackArtist != "" ? trackArtist : metadata.Artist;
+ metadata.Tracks[i].ISRC = CleanIdentifier(track["ISRC"], "ISRC");
+ }
+
+ string coverUrl = NormalizeCoverUrl(response["_arturl"]);
+ if (coverUrl != "")
+ {
+ metadata.AlbumArt.Add(new CTDBResponseMetaImage
+ {
+ uri = coverUrl,
+ uri150 = coverUrl,
+ primary = true
+ });
+ }
+
+ entry = new CUEMetadataEntry(metadata, toc, SourceKey);
+ return true;
+ }
+
+ internal static string CreateRequestDiscId(CDImageLayout toc)
+ {
+ return string.Format(CultureInfo.InvariantCulture, "{0:000}-{1}", toc.AudioTracks, AccurateRipVerify.CalculateAccurateRipId(toc));
+ }
+
+ internal static string CreateRequestBody(string accurateRipDiscId)
+ {
+ return JsonConvert.SerializeObject(new AccurateRipMetaRequest
+ {
+ AccurateRipDiscId = accurateRipDiscId
+ });
+ }
+
+ private static string Clean(JToken value)
+ {
+ if (value == null || value.Type == JTokenType.Null || value.Type == JTokenType.Array || value.Type == JTokenType.Object)
+ return "";
+
+ JValue scalar = value as JValue;
+ // The live contract uses strings for identifiers such as UPC. Numeric coercion is fail-soft only and cannot preserve leading zeroes.
+ return scalar == null || scalar.Value == null ? "" : Convert.ToString(scalar.Value, CultureInfo.InvariantCulture).Trim();
+ }
+
+ private static string CleanIdentifier(JToken value, string fieldName)
+ {
+ if (value == null || value.Type == JTokenType.Null)
+ return "";
+
+ if (value.Type != JTokenType.String)
+ {
+ if (value.Type != JTokenType.Array && value.Type != JTokenType.Object)
+ System.Diagnostics.Trace.WriteLine("AccurateRip Meta ignored non-string " + fieldName + " value.");
+ return "";
+ }
+
+ return Clean(value);
+ }
+
+ private static List OrderTracksByTrackNumber(JArray tracks, int firstAudioTrackNumber, int audioTracks)
+ {
+ List orderedTracks = OrderTracksByNumberRange(tracks, firstAudioTrackNumber, audioTracks);
+ if (orderedTracks != null || firstAudioTrackNumber == 1)
+ return orderedTracks;
+
+ // Some providers normalize mixed-mode discs to audio-relative track numbers.
+ return OrderTracksByNumberRange(tracks, 1, audioTracks);
+ }
+
+ private static List OrderTracksByNumberRange(JArray tracks, int firstTrackNumber, int audioTracks)
+ {
+ var byNumber = new Dictionary();
+ foreach (JToken item in tracks)
+ {
+ JObject track = item as JObject;
+ if (track == null)
+ continue;
+
+ int trackNumber;
+ if (!int.TryParse(Clean(track["TrackNumber"]), NumberStyles.Integer, CultureInfo.InvariantCulture, out trackNumber))
+ continue;
+
+ if (trackNumber < firstTrackNumber || trackNumber >= firstTrackNumber + audioTracks)
+ continue;
+
+ int audioIndex = trackNumber - firstTrackNumber;
+ if (byNumber.ContainsKey(audioIndex))
+ return null;
+
+ byNumber.Add(audioIndex, track);
+ }
+
+ if (byNumber.Count != audioTracks)
+ return null;
+
+ return Enumerable.Range(0, audioTracks)
+ .Select(audioIndex => byNumber[audioIndex])
+ .ToList();
+ }
+
+ private static string NormalizeCoverUrl(JToken value)
+ {
+ string cleaned = Clean(value);
+ if (cleaned == "")
+ return "";
+
+ Uri uri;
+ if (!Uri.TryCreate(cleaned, UriKind.Absolute, out uri))
+ return "";
+
+ if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
+ return "";
+
+ if (!string.Equals(uri.Host, CoverArtHost, StringComparison.OrdinalIgnoreCase))
+ {
+ System.Diagnostics.Trace.WriteLine("AccurateRip Meta ignored cover art URL from unexpected host: " + uri.Host);
+ return "";
+ }
+
+ return uri.AbsoluteUri;
+ }
+
+ private static string NormalizeGenreList(JToken value)
+ {
+ string text = Clean(value);
+ if (string.IsNullOrWhiteSpace(text))
+ return "";
+
+ return string.Join("; ", text
+ .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(line => line.Trim())
+ .Where(line => line.Length > 0)
+ .Distinct()
+ .ToArray());
+ }
+
+ private static string NormalizeProviderList(JToken value)
+ {
+ string text = Clean(value);
+ if (string.IsNullOrWhiteSpace(text))
+ return "";
+
+ string[] names = text
+ .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(line => line.Trim())
+ .Where(line => line.Length > 0)
+ .Distinct()
+ .ToArray();
+
+ if (names.Length == 0)
+ return "";
+ if (names.Length == 1)
+ return names[0];
+ if (names.Length == 2)
+ return names[0] + " & " + names[1];
+
+ return string.Join(", ", names.Take(names.Length - 1).ToArray()) + " & " + names[names.Length - 1];
+ }
+ }
+
+ public sealed class AccurateRipMetaProvider
+ {
+ private readonly IAccurateRipMetaTransport transport;
+
+ public AccurateRipMetaProvider()
+ : this(new AccurateRipMetaHttpTransport())
+ {
+ }
+
+ public AccurateRipMetaProvider(IAccurateRipMetaTransport transport)
+ {
+ this.transport = transport ?? throw new ArgumentNullException(nameof(transport));
+ }
+
+ public CUEMetadataEntry Lookup(CDImageLayout toc, IWebProxy proxy)
+ {
+ return Lookup(toc, proxy, null);
+ }
+
+ public CUEMetadataEntry Lookup(CDImageLayout toc, IWebProxy proxy, Action checkStop)
+ {
+ if (toc == null)
+ return null;
+
+ try
+ {
+ string accurateRipDiscId = AccurateRipMeta.CreateRequestDiscId(toc);
+ string body = AccurateRipMeta.CreateRequestBody(accurateRipDiscId);
+ string json = transport.Post(AccurateRipMeta.Endpoint, body, proxy, checkStop);
+
+ return AccurateRipMeta.TryParseMetadata(json, toc, out CUEMetadataEntry entry) ? entry : null;
+ }
+ catch (Exception ex) when (IsCancellation(ex))
+ {
+ throw;
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine("AccurateRip Meta lookup failed: " + ex.Message);
+ return null;
+ }
+ }
+
+ private static bool IsCancellation(Exception ex)
+ {
+ return ex is StopException || ex is OperationCanceledException;
+ }
+ }
+
+ public interface IAccurateRipMetaTransport
+ {
+ string Post(string url, string body, IWebProxy proxy, Action checkStop);
+ }
+
+ public sealed class AccurateRipMetaHttpTransport : IAccurateRipMetaTransport
+ {
+ public string Post(string url, string body, IWebProxy proxy, Action checkStop)
+ {
+ var request = (HttpWebRequest)WebRequest.Create(url);
+ int[] stopped = new[] { 0 };
+ int[] stopWatcherFinished = new[] { 0 };
+ Thread stopWatcher = null;
+ try
+ {
+ stopWatcher = StartStopWatcher(request, checkStop, stopped, stopWatcherFinished);
+ request.Method = "POST";
+ // The undocumented endpoint matched the EasyEACGUI client only with this browser-style UA during contract review.
+ request.UserAgent = "Mozilla/5.0";
+ // The server expects the EasyEACGUI-compatible JSON body with this form content type.
+ request.ContentType = AccurateRipMeta.ContentType;
+ request.AllowAutoRedirect = false;
+ request.ServicePoint.Expect100Continue = false;
+ request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
+ request.Timeout = AccurateRipMeta.LookupTimeoutMilliseconds;
+ request.ReadWriteTimeout = AccurateRipMeta.ReadWriteTimeoutMilliseconds;
+ request.Proxy = proxy;
+
+ byte[] bytes = Encoding.UTF8.GetBytes(body);
+ request.ContentLength = bytes.Length;
+ using (Stream requestStream = request.GetRequestStream())
+ requestStream.Write(bytes, 0, bytes.Length);
+
+ using (var response = (HttpWebResponse)request.GetResponse())
+ using (Stream responseStream = response.GetResponseStream())
+ return ReadResponseBody(responseStream);
+ }
+ catch (WebException ex)
+ {
+ var response = ex.Response as HttpWebResponse;
+ if (response != null && (int)response.StatusCode >= 300 && (int)response.StatusCode < 400)
+ System.Diagnostics.Trace.WriteLine("AccurateRip Meta moved; update CUETools (got " + response.StatusCode + " -> " + response.Headers["Location"] + ")");
+ if (response != null)
+ response.Dispose();
+ request.Abort();
+ if (Volatile.Read(ref stopped[0]) != 0)
+ throw new StopException();
+ throw;
+ }
+ catch
+ {
+ request.Abort();
+ if (Volatile.Read(ref stopped[0]) != 0)
+ throw new StopException();
+ throw;
+ }
+ finally
+ {
+ Volatile.Write(ref stopWatcherFinished[0], 1);
+ if (stopWatcher != null)
+ stopWatcher.Join(500);
+ }
+ }
+
+ private static Thread StartStopWatcher(HttpWebRequest request, Action checkStop, int[] stopped, int[] finished)
+ {
+ if (checkStop == null)
+ return null;
+
+ var stopWatcher = new Thread(() =>
+ {
+ while (Volatile.Read(ref finished[0]) == 0)
+ {
+ try
+ {
+ checkStop();
+ }
+ catch (Exception ex) when (IsCancellation(ex))
+ {
+ Interlocked.Exchange(ref stopped[0], 1);
+ request.Abort();
+ return;
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine("AccurateRip Meta stop watcher failed: " + ex.Message);
+ return;
+ }
+
+ for (int i = 0; i < 10 && Volatile.Read(ref finished[0]) == 0; i++)
+ Thread.Sleep(10);
+ }
+ });
+ stopWatcher.IsBackground = true;
+ stopWatcher.Name = "AccurateRip Meta stop watcher";
+ stopWatcher.Start();
+ return stopWatcher;
+ }
+
+ private static string ReadResponseBody(Stream responseStream)
+ {
+ if (responseStream == null)
+ return "";
+
+ const int maxResponseBytes = 1024 * 1024;
+ byte[] buffer = new byte[8192];
+ using (var memory = new MemoryStream())
+ {
+ int read;
+ while ((read = responseStream.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ if (memory.Length + read > maxResponseBytes)
+ throw new InvalidDataException("AccurateRip Meta response exceeded the maximum supported size.");
+ memory.Write(buffer, 0, read);
+ }
+
+ return Encoding.UTF8.GetString(memory.ToArray());
+ }
+ }
+
+ private static bool IsCancellation(Exception ex)
+ {
+ return ex is StopException || ex is OperationCanceledException;
+ }
+ }
+
+ internal sealed class AccurateRipMetaRequest
+ {
+ [JsonProperty("accurateripdiscid")]
+ public string AccurateRipDiscId { get; set; }
+ }
+}
diff --git a/CUETools.Processor/CUEConfigAdvanced.cs b/CUETools.Processor/CUEConfigAdvanced.cs
index 95ef4923d..0dc31acd0 100644
--- a/CUETools.Processor/CUEConfigAdvanced.cs
+++ b/CUETools.Processor/CUEConfigAdvanced.cs
@@ -51,17 +51,19 @@ public void Init()
Init(CUEProcessorPlugins.encs, CUEProcessorPlugins.decs);
}
- [DefaultValue("i"), Category("Freedb"), DisplayName("Email user")]
- public string FreedbUser { get; set; }
-
- [DefaultValue("wont.tell"), Category("Freedb"), DisplayName("Email domain")]
- public string FreedbDomain { get; set; }
-
- [DefaultValue("gnudb.gnudb.org"), Category("Freedb"), DisplayName("Site address")]
- public string FreedbSiteAddress { get; set; }
-
- [DefaultValue(ProxyMode.System), Category("Proxy"), DisplayName("Proxy mode")]
- public ProxyMode UseProxyMode { get; set; }
+#if DORMANT_FREEDB
+ [DefaultValue("i"), Category("Freedb"), DisplayName("Email user")]
+ public string FreedbUser { get; set; }
+
+ [DefaultValue("wont.tell"), Category("Freedb"), DisplayName("Email domain")]
+ public string FreedbDomain { get; set; }
+
+ [DefaultValue("gnudb.gnudb.org"), Category("Freedb"), DisplayName("Site address")]
+ public string FreedbSiteAddress { get; set; }
+#endif
+
+ [DefaultValue(ProxyMode.System), Category("Proxy"), DisplayName("Proxy mode")]
+ public ProxyMode UseProxyMode { get; set; }
[DefaultValue("127.0.0.1"), Category("Proxy"), DisplayName("Proxy server host")]
public string ProxyServer { get; set; }
diff --git a/CUETools.Processor/CUEMetadata.cs b/CUETools.Processor/CUEMetadata.cs
index 8be378a9e..c1dab0464 100644
--- a/CUETools.Processor/CUEMetadata.cs
+++ b/CUETools.Processor/CUEMetadata.cs
@@ -176,7 +176,7 @@ public void Merge(CUEMetadata metadata, bool overwrite)
{
if ((overwrite || Tracks[i].Title == "") && metadata.Tracks[i].Title != "") Tracks[i].Title = metadata.Tracks[i].Title;
if ((overwrite || Tracks[i].Artist == "") && metadata.Tracks[i].Artist != "") Tracks[i].Artist = metadata.Tracks[i].Artist;
- if ((overwrite || Tracks[i].Comment == "") && metadata.Tracks[i].Artist != "") Tracks[i].Comment = metadata.Tracks[i].Comment;
+ if ((overwrite || Tracks[i].Comment == "") && metadata.Tracks[i].Comment != "") Tracks[i].Comment = metadata.Tracks[i].Comment;
if ((overwrite || Tracks[i].ISRC == "") && metadata.Tracks[i].ISRC != "") Tracks[i].ISRC = metadata.Tracks[i].ISRC;
}
}
@@ -250,23 +250,26 @@ public void CopyMetadata(CUEMetadata metadata)
}
}
- public void FillFromFreedb(Freedb.CDEntry cdEntry, int firstAudio)
- {
- Year = cdEntry.Year;
- Genre = cdEntry.Genre;
- Artist = cdEntry.Artist;
+#if DORMANT_FREEDB
+ // FreeDB metadata import and repair helpers are dormant. AccurateRip Meta is the active replacement provider.
+ public void FillFromFreedb(Freedb.CDEntry cdEntry, int firstAudio)
+ {
+ Year = cdEntry.Year;
+ Genre = cdEntry.Genre;
+ Artist = cdEntry.Artist;
Title = cdEntry.Title;
Comment = cdEntry.ExtendedData;
for (int i = 0; i < Tracks.Count; i++)
{
Tracks[i].Title = cdEntry.Tracks[i + firstAudio].Title;
Tracks[i].Artist = cdEntry.Artist;
- Tracks[i].Comment = cdEntry.ExtendedData;
- }
- }
-
- public void FillFromCtdb(CUETools.CTDB.CTDBResponseMeta cdEntry, int firstAudio)
- {
+ Tracks[i].Comment = cdEntry.ExtendedData;
+ }
+ }
+#endif
+
+ public void FillFromCtdb(CUETools.CTDB.CTDBResponseMeta cdEntry, int firstAudio)
+ {
this.Year = cdEntry.year ?? "";
this.Genre = cdEntry.genre ?? "";
this.Artist = cdEntry.artist ?? "";
@@ -316,10 +319,12 @@ public void FillFromCtdb(CUETools.CTDB.CTDBResponseMeta cdEntry, int firstAudio)
}
}
- private static string FreedbToEncoding(Encoding iso, Encoding def, ref bool changed, ref bool error, string s)
- {
- try
- {
+#if DORMANT_FREEDB
+ // FreeDB metadata import and repair helpers are dormant. AccurateRip Meta is the active replacement provider.
+ private static string FreedbToEncoding(Encoding iso, Encoding def, ref bool changed, ref bool error, string s)
+ {
+ try
+ {
string res = def.GetString(iso.GetBytes(s));
changed |= res != s;
return res;
@@ -367,11 +372,12 @@ public bool FreedbToVarious()
{
Tracks[i].Artist = title;
}
- }
- return found;
- }
-
- public void UpdateArtist(string artist)
+ }
+ return found;
+ }
+#endif
+
+ public void UpdateArtist(string artist)
{
for (int i = 0; i < Tracks.Count; i++)
if (Tracks[i].Artist == Artist)
diff --git a/CUETools.Processor/CUESheet.cs b/CUETools.Processor/CUESheet.cs
index d44c91cd0..41df6e9cd 100644
--- a/CUETools.Processor/CUESheet.cs
+++ b/CUETools.Processor/CUESheet.cs
@@ -1,11 +1,9 @@
using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Drawing;
-#if NET47 || NET20
-using System.Drawing.Drawing2D;
-#endif
-using System.Globalization;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
@@ -16,7 +14,9 @@
using CUETools.Codecs;
using CUETools.Compression;
using CUETools.Ripper;
-using Freedb;
+#if DORMANT_FREEDB
+using Freedb;
+#endif
namespace CUETools.Processor
{
@@ -122,29 +122,36 @@ public CDImageLayout TOC
}
}
- public List AlbumArt
- {
- get { return _albumArt; }
- }
-
-#if NET47 || NET20
- public Image Cover
- {
- get
- {
+ public List AlbumArt
+ {
+ get { return _albumArt; }
+ }
+
+ ///
+ /// Test seam for overriding the AccurateRip Meta lookup provider.
+ ///
+ public AccurateRipMetaProvider AccurateRipMetaProvider { get; internal set; }
+
+ public Image Cover
+ {
+ get
+ {
if (AlbumArt == null)
return null;
var picture = AlbumArt.Find(x => x.Type == TagLib.PictureType.FrontCover) ??
AlbumArt.Find(x => x.Type != TagLib.PictureType.NotAPicture);
if (picture == null)
- return null;
- using (MemoryStream imageStream = new MemoryStream(picture.Data.Data, 0, picture.Data.Count))
- try { return Image.FromStream(imageStream); }
- catch { }
- return null;
- }
- }
-#endif
+ return null;
+ using (MemoryStream imageStream = new MemoryStream(picture.Data.Data, 0, picture.Data.Count))
+ try
+ {
+ using (Image source = Image.FromStream(imageStream))
+ return new Bitmap(source);
+ }
+ catch { }
+ return null;
+ }
+ }
public List SourcePaths
{
@@ -534,11 +541,11 @@ public uint? MinDataTrackLength
#region Constructor
- public CUESheet(CUEConfig config)
- {
- _config = config;
- _progress = new CUEToolsProgressEventArgs();
- _progress.cueSheet = this;
+ public CUESheet(CUEConfig config)
+ {
+ _config = config;
+ _progress = new CUEToolsProgressEventArgs();
+ _progress.cueSheet = this;
_attributes = new List();
_tracks = new List();
_trackFilenames = new List();
@@ -826,11 +833,21 @@ public void ScanLocalDB(string folder)
cueSheet.Close();
}
}
- _localDB.Save();
- }
-
- public List