Files
cuetools.net/CUERipper/frmCUERipper.cs

472 lines
14 KiB
C#
Raw Normal View History

2008-12-08 05:09:35 +00:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
2008-12-10 06:48:38 +00:00
using System.IO;
2008-12-08 05:09:35 +00:00
using System.Text;
using System.Threading;
using System.Windows.Forms;
2008-12-10 19:44:09 +00:00
using System.Configuration;
2008-12-09 07:25:48 +00:00
using CUETools.AccurateRip;
2008-12-08 05:09:35 +00:00
using CUETools.CDImage;
2008-12-09 07:25:48 +00:00
using CUETools.Codecs;
using CUETools.Processor;
using CUETools.Ripper.SCSI;
2008-12-08 05:09:35 +00:00
using MusicBrainz;
2008-12-10 19:44:09 +00:00
using Freedb;
2008-12-08 05:09:35 +00:00
namespace CUERipper
{
public partial class frmCUERipper : Form
{
private Thread _workThread = null;
2008-12-09 07:25:48 +00:00
private CDDriveReader _reader = null;
2008-12-08 05:09:35 +00:00
private StartStop _startStop;
2008-12-09 07:25:48 +00:00
private CUEConfig _config;
private OutputAudioFormat _format;
private CUEStyle _style;
private CUESheet _cueSheet;
2008-12-10 06:48:38 +00:00
private string _pathOut;
2008-12-08 05:09:35 +00:00
public frmCUERipper()
{
InitializeComponent();
2008-12-09 07:25:48 +00:00
_config = new CUEConfig();
2008-12-08 05:09:35 +00:00
_startStop = new StartStop();
}
private void frmCUERipper_Load(object sender, EventArgs e)
{
//byte[] _subchannelBuffer0 = { 0x1, 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x10, 0x75, 0x4E };
//byte[] _subchannelBuffer1 = { 0x21, 0x01, 0x01, 0x00, 0x00, 0x11, 0x00, 0x00, 0x02, 0x11, 0xCF, 0x3E };
//byte[] _subchannelBuffer2 = { 0x21, 0x01, 0x01, 0x00, 0x00, 0x12, 0x00, 0x00, 0x02, 0x12, 0x11, 0x8F };
//Crc16Ccitt _crc = new Crc16Ccitt(InitialCrcValue.Zeros);
//ushort crc0a = (ushort)(_crc.ComputeChecksum(_subchannelBuffer0, 0, 10) ^ 0xffff);
//ushort crc0b = (ushort)(_subchannelBuffer0[11] + (_subchannelBuffer0[10] << 8));
//ushort crc1a = (ushort)(_crc.ComputeChecksum(_subchannelBuffer1, 0, 10) ^ 0xffff);
//ushort crc1b = (ushort)(_subchannelBuffer1[11] + (_subchannelBuffer1[10] << 8));
//ushort crc2a = (ushort)(_crc.ComputeChecksum(_subchannelBuffer2, 0, 10) ^ 0xffff);
//ushort crc2b = (ushort)(_subchannelBuffer2[11] + (_subchannelBuffer2[10] << 8));
//if (crc0a != crc0b || crc1a != crc1b || crc2a != crc2b)
//{
//}
2008-12-08 05:09:35 +00:00
foreach(char drive in CDDriveReader.DrivesAvailable())
{
CDDriveReader reader = new CDDriveReader();
if (reader.Open(drive))
2008-12-10 06:48:38 +00:00
{
int driveOffset;
if (!AccurateRipVerify.FindDriveReadOffset(reader.ARName, out driveOffset))
; //throw new Exception("Failed to find drive read offset for drive" + _ripper.ARName);
reader.DriveOffset = driveOffset;
2008-12-08 05:09:35 +00:00
comboDrives.Items.Add(reader);
2008-12-10 06:48:38 +00:00
}
2008-12-08 05:09:35 +00:00
}
if (comboDrives.Items.Count == 0)
comboDrives.Items.Add("No CD drives found");
comboDrives.SelectedIndex = 0;
comboLossless.SelectedIndex = 0;
comboCodec.SelectedIndex = 0;
comboImage.SelectedIndex = 0;
}
private void SetupControls ()
{
bool running = _workThread != null;
2008-12-09 07:25:48 +00:00
listTracks.Enabled =
comboDrives.Enabled =
comboRelease.Enabled =
comboCodec.Enabled =
comboImage.Enabled =
comboLossless.Enabled = !running;
2008-12-08 05:09:35 +00:00
buttonPause.Visible = buttonPause.Enabled = buttonAbort.Visible = buttonAbort.Enabled = running;
buttonGo.Visible = buttonGo.Enabled = !running;
toolStripStatusLabel1.Text = String.Empty;
toolStripProgressBar1.Value = 0;
toolStripProgressBar2.Value = 0;
}
private void CDReadProgress(object sender, ReadProgressArgs e)
{
CDDriveReader audioSource = (CDDriveReader)sender;
lock (_startStop)
{
if (_startStop._stop)
{
_startStop._stop = false;
_startStop._pause = false;
throw new StopException();
}
if (_startStop._pause)
{
this.BeginInvoke((MethodInvoker)delegate()
{
toolStripStatusLabel1.Text = "Paused...";
});
Monitor.Wait(_startStop);
}
}
int processed = e.Position - e.PassStart;
TimeSpan elapsed = DateTime.Now - e.PassTime;
double speed = elapsed.TotalSeconds > 0 ? processed / elapsed.TotalSeconds / 75 : 1.0;
double percentDisk = (double)(e.PassStart + (processed + e.Pass * (e.PassEnd - e.PassStart)) / (audioSource.CorrectionQuality + 1)) / audioSource.TOC.AudioLength;
double percentTrck = (double)(e.Position - e.PassStart) / (e.PassEnd - e.PassStart);
string status = string.Format("Ripping @{0:00.00}x {1}", speed, e.Pass > 0 ? " (Retry " + e.Pass.ToString() + ")" : "");
this.BeginInvoke((MethodInvoker)delegate()
{
toolStripStatusLabel1.Text = status;
toolStripProgressBar1.Value = Math.Max(0, Math.Min(100, (int)(percentTrck * 100)));
toolStripProgressBar2.Value = Math.Max(0, Math.Min(100, (int)(percentDisk * 100)));
});
}
private void Rip(object o)
{
CDDriveReader audioSource = (CDDriveReader)o;
audioSource.ReadProgress += new EventHandler<ReadProgressArgs>(CDReadProgress);
2008-12-10 06:48:38 +00:00
CUESheet.WriteText(_pathOut, _cueSheet.CUESheetContents(_style));
CUESheet.WriteText(Path.ChangeExtension(_pathOut, ".log"), _cueSheet.LOGContents());
2008-12-08 05:09:35 +00:00
try
{
2008-12-10 06:48:38 +00:00
_cueSheet.WriteAudioFiles(".", _style);
2008-12-08 05:09:35 +00:00
}
catch (StopException)
{
}
catch (Exception ex)
{
this.Invoke((MethodInvoker)delegate()
{
string message = "Exception";
for (Exception e = ex; e != null; e = e.InnerException)
message += ": " + e.Message;
DialogResult dlgRes = MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
});
}
2008-12-10 06:48:38 +00:00
audioSource.ReadProgress -= new EventHandler<ReadProgressArgs>(CDReadProgress);
2008-12-08 05:09:35 +00:00
_workThread = null;
2008-12-08 11:18:15 +00:00
this.BeginInvoke((MethodInvoker)delegate()
{
SetupControls();
});
2008-12-08 05:09:35 +00:00
}
private void buttonGo_Click(object sender, EventArgs e)
{
if (_reader == null)
return;
2008-12-10 06:48:38 +00:00
_style = comboImage.SelectedIndex == 0 ? CUEStyle.SingleFileWithCUE :
CUEStyle.GapsAppended;
_pathOut = _config.CleanseString(_cueSheet.Artist) + " - " +
_config.CleanseString(_cueSheet.Title) + ".cue";
2008-12-09 07:25:48 +00:00
_config.lossyWAVHybrid = comboLossless.SelectedIndex == 1; // _cueSheet.Config?
2008-12-10 06:48:38 +00:00
if (_style == CUEStyle.SingleFileWithCUE)
_cueSheet.SingleFilename = Path.GetFileName(_pathOut);
2008-12-09 07:25:48 +00:00
_format = (string)comboCodec.SelectedItem == "wav" ? OutputAudioFormat.WAV :
(string)comboCodec.SelectedItem == "flac" ? OutputAudioFormat.FLAC :
(string)comboCodec.SelectedItem == "wv" ? OutputAudioFormat.WavPack :
(string)comboCodec.SelectedItem == "ape" ? OutputAudioFormat.APE :
OutputAudioFormat.NoAudio;
2008-12-10 06:48:38 +00:00
_cueSheet.GenerateFilenames(_format, comboLossless.SelectedIndex != 0, _pathOut);
2008-12-09 07:25:48 +00:00
2008-12-08 05:09:35 +00:00
_workThread = new Thread(Rip);
_workThread.Priority = ThreadPriority.BelowNormal;
_workThread.IsBackground = true;
SetupControls();
_workThread.Start(_reader);
}
private void buttonAbort_Click(object sender, EventArgs e)
{
2008-12-10 06:48:38 +00:00
_startStop.Stop();
2008-12-08 05:09:35 +00:00
}
private void buttonPause_Click(object sender, EventArgs e)
{
2008-12-10 06:48:38 +00:00
_startStop.Pause();
2008-12-08 05:09:35 +00:00
}
private void comboRelease_Format(object sender, ListControlConvertEventArgs e)
{
if (e.ListItem is string)
return;
2008-12-09 07:25:48 +00:00
CUELine date = General.FindCUELine(((CUESheet)e.ListItem).Attributes, "REM", "DATE");
e.Value = string.Format("{0}{1} - {2}", date != null ? date.Params[2] + ": " : "", ((CUESheet)e.ListItem).Artist, ((CUESheet)e.ListItem).Title);
2008-12-08 05:09:35 +00:00
}
private void comboRelease_SelectedIndexChanged(object sender, EventArgs e)
{
listTracks.Items.Clear();
if (comboRelease.SelectedItem == null || comboRelease.SelectedItem is string)
return;
2008-12-09 07:25:48 +00:00
_cueSheet = (CUESheet)comboRelease.SelectedItem;
2008-12-08 05:09:35 +00:00
for (int i = 1; i <= _reader.TOC.AudioTracks; i++)
2008-12-09 07:25:48 +00:00
listTracks.Items.Add(new ListViewItem(new string[] {
_cueSheet.Tracks[i-1].Title,
_reader.TOC[i].Number.ToString(),
_reader.TOC[i].StartMSF,
_reader.TOC[i].LengthMSF }));
2008-12-08 05:09:35 +00:00
}
private void MusicBrainz_LookupProgress(object sender, XmlRequestEventArgs e)
{
//_progress.percentDisk = (1.0 + _progress.percentDisk) / 2;
//_progress.input = e.Uri.ToString();
lock (_startStop)
{
if (_startStop._stop)
{
_startStop._stop = false;
_startStop._pause = false;
throw new StopException();
}
if (_startStop._pause)
{
this.BeginInvoke((MethodInvoker)delegate()
{
toolStripStatusLabel1.Text = "Paused...";
});
Monitor.Wait(_startStop);
}
}
this.BeginInvoke((MethodInvoker)delegate()
{
toolStripStatusLabel1.Text = "Looking up album via MusicBrainz";
toolStripProgressBar1.Value = 0;
toolStripProgressBar2.Value = (100 + toolStripProgressBar2.Value) / 2;
});
}
2008-12-10 19:44:09 +00:00
private CUESheet CreateCUESheet(CDDriveReader audioSource, Release release, CDEntry cdEntry)
{
CUESheet cueSheet = new CUESheet(_config);
cueSheet.OpenCD(audioSource);
General.SetCUELine(cueSheet.Attributes, "REM", "DISCID", AccurateRipVerify.CalculateCDDBId(audioSource.TOC), false);
General.SetCUELine(cueSheet.Attributes, "REM", "COMMENT", CDDriveReader.RipperVersion(), true);
if (release != null)
cueSheet.FillFromMusicBrainz(release);
else if (cdEntry != null)
{
cueSheet.Artist = cdEntry.Artist;
cueSheet.Title = cdEntry.Title;
General.SetCUELine(cueSheet.Attributes, "REM", "DATE", cdEntry.Year, false);
General.SetCUELine(cueSheet.Attributes, "REM", "GENRE", cdEntry.Genre, true);
for (int i = 0; i < audioSource.TOC.AudioTracks; i++)
cueSheet.Tracks[i].Title = cdEntry.Tracks[i].Title;
}
else
{
cueSheet.Artist = "Unknown Artist";
cueSheet.Title = "Unknown Title";
for (int i = 0; i < audioSource.TOC.AudioTracks; i++)
cueSheet.Tracks[i].Title = string.Format("Track {0:00}", i + 1);
}
cueSheet.AccurateRip = AccurateRipMode.VerifyAndConvert;
cueSheet.ArVerify.ContactAccurateRip(AccurateRipVerify.CalculateAccurateRipId(audioSource.TOC));
return cueSheet;
}
2008-12-08 05:09:35 +00:00
private void Lookup(object o)
{
CDDriveReader audioSource = (CDDriveReader)o;
ReleaseQueryParameters p = new ReleaseQueryParameters();
2008-12-09 07:25:48 +00:00
p.DiscId = audioSource.TOC.MusicBrainzId;
2008-12-08 05:09:35 +00:00
Query<Release> results = Release.Query(p);
MusicBrainzService.XmlRequest += new EventHandler<XmlRequestEventArgs>(MusicBrainz_LookupProgress);
2008-12-10 06:48:38 +00:00
try
2008-12-08 05:09:35 +00:00
{
2008-12-10 06:48:38 +00:00
foreach (Release release in results)
2008-12-08 05:09:35 +00:00
{
2008-12-10 06:48:38 +00:00
release.GetEvents();
release.GetTracks();
2008-12-10 19:44:09 +00:00
CUESheet cueSheet = CreateCUESheet(audioSource, release, null);
2008-12-10 06:48:38 +00:00
this.BeginInvoke((MethodInvoker)delegate()
2008-12-09 07:25:48 +00:00
{
2008-12-10 06:48:38 +00:00
comboRelease.Items.Add(cueSheet);
});
}
}
catch (Exception)
{
2008-12-08 05:09:35 +00:00
}
MusicBrainzService.XmlRequest -= new EventHandler<XmlRequestEventArgs>(MusicBrainz_LookupProgress);
2008-12-10 19:44:09 +00:00
FreedbHelper m_freedb = new FreedbHelper();
m_freedb.UserName = "gchudov";
m_freedb.Hostname = "gmail.com";
m_freedb.ClientName = "CUERipper";
m_freedb.Version = "1.0";
m_freedb.SetDefaultSiteAddress(Properties.Settings.Default.MAIN_FREEDB_SITEADDRESS);
QueryResult queryResult;
QueryResultCollection coll;
string code = string.Empty;
try
{
code = m_freedb.Query(AccurateRipVerify.CalculateCDDBQuery(audioSource.TOC), out queryResult, out coll);
if (code == FreedbHelper.ResponseCodes.CODE_200)
{
CDEntry cdEntry;
code = m_freedb.Read(queryResult, out cdEntry);
if (code == FreedbHelper.ResponseCodes.CODE_210)
{
CUESheet cueSheet = CreateCUESheet(audioSource, null, cdEntry);
this.BeginInvoke((MethodInvoker)delegate()
{
comboRelease.Items.Add(cueSheet);
});
}
}
else
if (code == FreedbHelper.ResponseCodes.CODE_210 ||
code == FreedbHelper.ResponseCodes.CODE_211 )
{
foreach (QueryResult qr in coll)
{
CDEntry cdEntry;
code = m_freedb.Read(qr, out cdEntry);
if (code == FreedbHelper.ResponseCodes.CODE_210)
{
CUESheet cueSheet = CreateCUESheet(audioSource, null, cdEntry);
this.BeginInvoke((MethodInvoker)delegate()
{
comboRelease.Items.Add(cueSheet);
});
}
}
}
}
catch (Exception)
{
}
2008-12-08 05:09:35 +00:00
this.BeginInvoke((MethodInvoker)delegate()
{
if (comboRelease.Items.Count == 0)
2008-12-09 07:25:48 +00:00
{
2008-12-10 19:44:09 +00:00
CUESheet cueSheet = CreateCUESheet(audioSource, null, null);
2008-12-09 07:25:48 +00:00
comboRelease.Items.Add(cueSheet);
}
2008-12-08 05:09:35 +00:00
});
_workThread = null;
this.BeginInvoke((MethodInvoker)delegate()
{
2008-12-08 11:18:15 +00:00
SetupControls();
2008-12-08 05:09:35 +00:00
comboRelease.SelectedIndex = 0;
});
}
private void comboDrives_SelectedIndexChanged(object sender, EventArgs e)
{
comboRelease.Items.Clear();
listTracks.Items.Clear();
if (comboDrives.SelectedItem is string)
return;
_reader = (CDDriveReader)comboDrives.SelectedItem;
if (_reader.TOC.AudioTracks == 0)
{
comboRelease.Items.Add("No audio tracks");
return;
}
comboRelease_SelectedIndexChanged(sender, e);
_workThread = new Thread(Lookup);
_workThread.Priority = ThreadPriority.BelowNormal;
_workThread.IsBackground = true;
SetupControls();
_workThread.Start(_reader);
}
2008-12-08 11:18:15 +00:00
private void listTracks_DoubleClick(object sender, EventArgs e)
{
listTracks.FocusedItem.BeginEdit();
}
private void listTracks_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F2)
{
listTracks.FocusedItem.BeginEdit();
}
}
private void listTracks_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (listTracks.FocusedItem.Index + 1 < listTracks.Items.Count)// && e.Label != null)
{
listTracks.FocusedItem.Selected = false;
listTracks.FocusedItem = listTracks.Items[listTracks.FocusedItem.Index + 1];
listTracks.FocusedItem.Selected = true;
listTracks.FocusedItem.BeginEdit();
}
}
}
2008-12-08 05:09:35 +00:00
2008-12-10 06:48:38 +00:00
private void listTracks_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
CUESheet cueSheet = (CUESheet)comboRelease.SelectedItem;
2008-12-10 19:44:09 +00:00
if (e.Label != null)
cueSheet.Tracks[e.Item].Title = e.Label;
2008-12-10 06:48:38 +00:00
}
private void editToolStripMenuItem_Click(object sender, EventArgs e)
2008-12-08 05:09:35 +00:00
{
2008-12-10 06:48:38 +00:00
CUESheet cueSheet = (CUESheet)comboRelease.SelectedItem;
frmRelease frm = new frmRelease();
frm.CUE = cueSheet;
frm.ShowDialog();
comboRelease.Items[comboRelease.SelectedIndex] = cueSheet;
2008-12-08 05:09:35 +00:00
}
}
public class StartStop
{
public bool _stop, _pause;
public StartStop()
{
_stop = false;
_pause = false;
}
2008-12-10 06:48:38 +00:00
public void Stop()
{
lock (this)
{
if (_pause)
{
_pause = false;
Monitor.Pulse(this);
}
_stop = true;
}
}
public void Pause()
{
lock (this)
{
if (_pause)
{
_pause = false;
Monitor.Pulse(this);
}
else
{
_pause = true;
}
}
}
2008-12-08 05:09:35 +00:00
}
}