示例#1
0
        public UserDefinedWriter(string path, Stream IO, AudioPCMConfig pcm, string encoder, string encoderParams, string encoderMode, int padding)
        {
            Path           = path;
            _encoder       = encoder;
            _encoderParams = encoderParams;
            _encoderMode   = encoderMode;
            useTempFile    = _encoderParams.Contains("%I");
            tempFile       = path + ".tmp.wav";

            _encoderProcess = new Process();
            _encoderProcess.StartInfo.FileName       = _encoder;
            _encoderProcess.StartInfo.Arguments      = _encoderParams.Replace("%O", "\"" + path + "\"").Replace("%M", encoderMode).Replace("%P", padding.ToString()).Replace("%I", "\"" + tempFile + "\"");
            _encoderProcess.StartInfo.CreateNoWindow = true;
            if (!useTempFile)
            {
                _encoderProcess.StartInfo.RedirectStandardInput = true;
            }
            _encoderProcess.StartInfo.UseShellExecute = false;
            if (!_encoderParams.Contains("%O"))
            {
                _encoderProcess.StartInfo.RedirectStandardOutput = true;
            }
            if (useTempFile)
            {
                wrt = new WAVWriter(tempFile, null, pcm);
                return;
            }
            bool      started = false;
            Exception ex      = null;

            try
            {
                started = _encoderProcess.Start();
                if (started)
                {
                    _encoderProcess.PriorityClass = Process.GetCurrentProcess().PriorityClass;
                }
            }
            catch (Exception _ex)
            {
                ex = _ex;
            }
            if (!started)
            {
                throw new Exception(_encoder + ": " + (ex == null ? "please check the path" : ex.Message));
            }
            if (_encoderProcess.StartInfo.RedirectStandardOutput)
            {
                Stream outputStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
                outputBuffer = new CyclicBuffer(2 * 1024 * 1024, _encoderProcess.StandardOutput.BaseStream, outputStream);
            }
            Stream inputStream = new CyclicBufferOutputStream(_encoderProcess.StandardInput.BaseStream, 128 * 1024);

            wrt = new WAVWriter(path, inputStream, pcm);
        }
示例#2
0
 public void Close()
 {
     if (closed)
     {
         return;
     }
     closed = true;
     wrt.Close();
     if (useTempFile && (_finalSampleCount < 0 || wrt.Position == _finalSampleCount))
     {
         bool      started = false;
         Exception ex      = null;
         try
         {
             started = _encoderProcess.Start();
             if (started)
             {
                 _encoderProcess.PriorityClass = Process.GetCurrentProcess().PriorityClass;
             }
         }
         catch (Exception _ex)
         {
             ex = _ex;
         }
         if (!started)
         {
             throw new Exception(m_settings.Path + ": " + (ex == null ? "please check the path" : ex.Message));
         }
     }
     wrt = null;
     if (!_encoderProcess.HasExited)
     {
         _encoderProcess.WaitForExit();
     }
     if (useTempFile)
     {
         File.Delete(tempFile);
     }
     if (outputBuffer != null)
     {
         outputBuffer.Close();
     }
     if (_encoderProcess.ExitCode != 0)
     {
         throw new Exception(String.Format("{0} returned error code {1}", m_settings.Path, _encoderProcess.ExitCode));
     }
 }
        public UserDefinedWriter(string path, Stream IO, AudioPCMConfig pcm, string encoder, string encoderParams, string encoderMode, int padding)
        {
            _path = path;
            _encoder = encoder;
            _encoderParams = encoderParams;
            _encoderMode = encoderMode;
            useTempFile = _encoderParams.Contains("%I");
            tempFile = path + ".tmp.wav";

            _encoderProcess = new Process();
            _encoderProcess.StartInfo.FileName = _encoder;
            _encoderProcess.StartInfo.Arguments = _encoderParams.Replace("%O", "\"" + path + "\"").Replace("%M", encoderMode).Replace("%P", padding.ToString()).Replace("%I", "\"" + tempFile + "\"");
            _encoderProcess.StartInfo.CreateNoWindow = true;
            if (!useTempFile)
                _encoderProcess.StartInfo.RedirectStandardInput = true;
            _encoderProcess.StartInfo.UseShellExecute = false;
            if (!_encoderParams.Contains("%O"))
                _encoderProcess.StartInfo.RedirectStandardOutput = true;
            if (useTempFile)
            {
                wrt = new WAVWriter(tempFile, null, pcm);
                return;
            }
            bool started = false;
            Exception ex = null;
            try
            {
                started = _encoderProcess.Start();
                if (started)
                    _encoderProcess.PriorityClass = Process.GetCurrentProcess().PriorityClass;
            }
            catch (Exception _ex)
            {
                ex = _ex;
            }
            if (!started)
                throw new Exception(_encoder + ": " + (ex == null ? "please check the path" : ex.Message));
            if (_encoderProcess.StartInfo.RedirectStandardOutput)
            {
                Stream outputStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
                outputBuffer = new CyclicBuffer(2 * 1024 * 1024, _encoderProcess.StandardOutput.BaseStream, outputStream);
            }
            Stream inputStream = new CyclicBufferOutputStream(_encoderProcess.StandardInput.BaseStream, 128 * 1024);
            wrt = new WAVWriter(path, inputStream, pcm);
        }
示例#4
0
 private byte[] Wav2FlacBuffConverter(byte[] Buffer)
 {
     Stream OutWavStream = new MemoryStream();
     Stream OutFlacStream = new MemoryStream();
     AudioPCMConfig pcmconf = new AudioPCMConfig(16, 1, 16000);
     WAVWriter wr = new WAVWriter(null, OutWavStream, pcmconf);
     wr.Write(new AudioBuffer(pcmconf, Buffer, Buffer.Length / 2));
     OutWavStream.Seek(0, SeekOrigin.Begin);
     WAVReader audioSource = new WAVReader(null, OutWavStream);
     if (audioSource.PCM.SampleRate != 16000) 
     return null;
     AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
     FlakeWriter flakeWriter = new FlakeWriter(null, OutFlacStream, audioSource.PCM);
     flakeWriter.CompressionLevel = 8;
     while (audioSource.Read(buff, -1) != 0)
     {
         flakeWriter.Write(buff);
     }
     OutFlacStream.Seek(0, SeekOrigin.Begin);
     byte[] barr = new byte[OutFlacStream.Length];
     OutFlacStream.Read(barr, 0, (int)OutFlacStream.Length);
     return barr;
 }
示例#5
0
文件: Codecs.cs 项目: kidinfo/AI_Eva
 public void Close()
 {
     if (closed)
         return;
     closed = true;
     wrt.Close();
     if (useTempFile && (_finalSampleCount < 0 || wrt.Position == _finalSampleCount))
     {
             bool started = false;
             Exception ex = null;
             try
             {
                 started = _encoderProcess.Start();
                 if (started)
                     _encoderProcess.PriorityClass = Process.GetCurrentProcess().PriorityClass;
             }
             catch (Exception _ex)
             {
                 ex = _ex;
             }
             if (!started)
                 throw new Exception(_encoder + ": " + (ex == null ? "please check the path" : ex.Message));
     }
     wrt = null;
     if (!_encoderProcess.HasExited)
         _encoderProcess.WaitForExit();
     if (useTempFile)
         File.Delete(tempFile);
     if (outputBuffer != null)
         outputBuffer.Close();
     if (_encoderProcess.ExitCode != 0)
         throw new Exception(String.Format("{0} returned error code {1}", _encoder, _encoderProcess.ExitCode));
 }
示例#6
0
		public void ConstructorTest()
		{
			AudioBuffer buff = WAVReader.ReadAllSamples("test.wav", null);
			WAVWriter target;

			target = new WAVWriter("wavwriter0.wav", null, buff.PCM);
			//target.FinalSampleCount = buff.Length;
			target.Write(buff);
			target.Close();
			CollectionAssert.AreEqual(File.ReadAllBytes("test.wav"), File.ReadAllBytes("wavwriter0.wav"), "wavwriter0.wav doesn't match.");

			target = new WAVWriter("wavwriter1.wav", null, buff.PCM);
			target.FinalSampleCount = buff.Length;
			target.Write(buff);
			target.Close();
			CollectionAssert.AreEqual(File.ReadAllBytes("test.wav"), File.ReadAllBytes("wavwriter1.wav"), "wavwriter1.wav doesn't match.");
		}
示例#7
0
        private void SaveChunksToWaveFile(IList<AudioChunk> batchOfChunks)
        {
            if (batchOfChunks == null || !batchOfChunks.Any())
              {
            return;
              }

              string token = batchOfChunks[0].Token;

              byte[] combinedChunks = Combine(batchOfChunks);
              _logger.Debug("Combine batch of chunks - Token: {0} Total length: {1}", token, combinedChunks.Length);

              var batchInd = IncreaseBatchChunkIndex(token);

              var flakeBuffer = WaveSamplesToFlake(combinedChunks);

              /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
              // Save to .wav file
              var audioBuffer = new AudioBuffer(new AudioPCMConfig(16, 1, 22050), combinedChunks, combinedChunks.Length / 2);
              string wavFilePath = HostingEnvironment.MapPath(String.Format("~/Media/Records/{0}-{1}.wav", token, batchInd));
              var wavWriter = new WAVWriter(wavFilePath, new WAVWriterSettings(new AudioPCMConfig(16, 1, 22050)));
              wavWriter.Write(audioBuffer);
              wavWriter.Close();

              ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
              // Save to .flac file
              string flacFilePath = HostingEnvironment.MapPath(String.Format("~/Media/Records/{0}-{1}.flac", token, batchInd));
              using (var fs = new FileStream(flacFilePath, FileMode.Create))
              {
            using (var bw = new BinaryWriter(fs))
            {
              bw.Write(flakeBuffer);
              bw.Flush();
            }
            fs.Close();
              }
        }
示例#8
0
        private ActionBlock<WaveSampleBuffer> GetSaveToWaveFileBlock()
        {
            return new ActionBlock<WaveSampleBuffer>(waveSamples =>
              {
            var audioBuffer = new AudioBuffer(
              new AudioPCMConfig(16, 1, 22050),
              waveSamples.Buffer,
              waveSamples.Buffer.Length / 2);

            var wavFilePath = HostingEnvironment.MapPath(String.Format("~/Media/Records/{0}-{1}.wav", waveSamples.Token, waveSamples.Id));

            var wavWriter = new WAVWriter(wavFilePath, new WAVWriterSettings(new AudioPCMConfig(16, 1, 22050)));
            wavWriter.Write(audioBuffer);
            wavWriter.Close();
              });
        }
示例#9
0
		static void Main(string[] args)
		{
			Console.SetOut(Console.Error);
			Console.WriteLine("LossyWAV {0}, Copyright (C) 2007,2008 Nick Currie, Copyleft.", LossyWAVWriter.version_string);
			Console.WriteLine("C# port Copyright (C) 2008 Grigory Chudov.");
			Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
			Console.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details.");
			if (args.Length < 1 || (args[0].StartsWith("-") && args[0] != "-"))
			{
				Usage();
				return;
			}
			string sourceFile = args[0];
			string stdinName = null;
			double quality = 5.0;
			bool createCorrection = false;
			bool toStdout = false;
			int outputBPS = 0;

			for (int arg = 1; arg < args.Length; arg++)
			{
				bool ok = true;
				if (args[arg] == "-I" || args[arg] == "--insane")
					quality = 10;
				else if (args[arg] == "-E" || args[arg] == "--extreme")
					quality = 7.5;
				else if (args[arg] == "-S" || args[arg] == "--standard")
					quality = 5.0;
				else if (args[arg] == "-P" || args[arg] == "--portable")
					quality = 2.5;
				else if (args[arg] == "-C" || args[arg] == "--correction")
					createCorrection = true;
				else if (args[arg] == "--16")
					outputBPS = 16;
				else if ((args[arg] == "-N" || args[arg] == "--stdinname") && ++arg < args.Length)
					stdinName = args[arg];
				else if ((args[arg] == "-q" || args[arg] == "--quality") && ++arg < args.Length)
					ok = double.TryParse(args[arg], out quality);
				else if (args[arg] == "--stdout")
					toStdout = true;
				else
					ok = false;
				if (!ok)
				{
					Usage();
					return;
				}
			}
			DateTime start = DateTime.Now;
			TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
#if !DEBUG
			try
#endif
			{
				WAVReader audioSource = new WAVReader(sourceFile, (sourceFile == "-" ? Console.OpenStandardInput() : null));
				if (sourceFile == "-" && stdinName != null) sourceFile = stdinName;
				AudioPCMConfig pcm = outputBPS == 0 ? audioSource.PCM : new AudioPCMConfig(outputBPS, audioSource.PCM.ChannelCount, audioSource.PCM.SampleRate);
				WAVWriter audioDest = new WAVWriter(Path.ChangeExtension(sourceFile, ".lossy.wav"), toStdout ? Console.OpenStandardOutput() : null, pcm);
				WAVWriter lwcdfDest = createCorrection ? new WAVWriter(Path.ChangeExtension(sourceFile, ".lwcdf.wav"), null, audioSource.PCM) : null;
				LossyWAVWriter lossyWAV = new LossyWAVWriter(audioDest, lwcdfDest, quality, audioSource.PCM);
				AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);

				Console.WriteLine("Filename  : {0}", sourceFile);
				Console.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, TimeSpan.FromSeconds(audioSource.Length * 1.0 / audioSource.PCM.SampleRate));
				lossyWAV.FinalSampleCount = audioSource.Length;

				while (audioSource.Read(buff, -1) != 0)
				{
					lossyWAV.Write(buff);
					TimeSpan elapsed = DateTime.Now - start;
					if ((elapsed - lastPrint).TotalMilliseconds > 60)
					{
						Console.Error.Write("\rProgress  : {0:00}%; {1:0.0000} bits; {2:0.00}x; {3}/{4}",
							100.0 * audioSource.Position / audioSource.Length,
							1.0 * lossyWAV.OverallBitsRemoved / audioSource.PCM.ChannelCount / lossyWAV.BlocksProcessed,
							lossyWAV.SamplesProcessed / elapsed.TotalSeconds / audioSource.PCM.SampleRate,
							elapsed,
							TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / lossyWAV.SamplesProcessed * audioSource.Length)
							);
						lastPrint = elapsed;
					}
				}

				TimeSpan totalElapsed = DateTime.Now - start;
				Console.Error.Write("\r                                                                         \r");
				Console.WriteLine("Results   : {0:0.0000} bits; {1:0.00}x; {2}",
					(1.0 * lossyWAV.OverallBitsRemoved) / audioSource.PCM.ChannelCount / lossyWAV.BlocksProcessed,
					lossyWAV.SamplesProcessed / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
					totalElapsed
					);
				audioSource.Close();
				lossyWAV.Close();
			}
#if !DEBUG
			catch (Exception ex)
			{
				Console.WriteLine();
				Console.WriteLine("Error: {0}", ex.Message);
				//Console.WriteLine("{0}", ex.StackTrace);
			}
#endif
		}
示例#10
0
		static void Main(string[] args)
		{
			Console.SetOut(Console.Error);
			Console.WriteLine("CUERipper v2.1.4 Copyright (C) 2008-10 Grigory Chudov");
			Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
			Console.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details.");

			int correctionQuality = 1;
			string driveLetter = null;
			int driveOffset = 0;
			bool test = false;
			bool forceD8 = false, forceBE = false, quiet = false;
			for (int arg = 0; arg < args.Length; arg++)
			{
				bool ok = true;
				if (args[arg] == "-P" || args[arg] == "--paranoid")
					correctionQuality = 2;
				else if (args[arg] == "-S" || args[arg] == "--secure")
					correctionQuality = 1;
				else if (args[arg] == "-B" || args[arg] == "--burst")
					correctionQuality = 0;
				else if (args[arg] == "-T" || args[arg] == "--test")
					test = true;
				else if (args[arg] == "--d8")
					forceD8 = true;
				else if (args[arg] == "--be")
					forceBE = true;
				else if (args[arg] == "-Q" || args[arg] == "--quiet")
					quiet = true;
				else if ((args[arg] == "-D" || args[arg] == "--drive") && ++arg < args.Length)
					driveLetter = args[arg];
				else if ((args[arg] == "-O" || args[arg] == "--offset") && ++arg < args.Length)
					ok = int.TryParse(args[arg], out driveOffset);
				else
					ok = false;
				if (!ok)
				{
					Usage();
					return;
				}
			}
			
			char[] drives;
			if (driveLetter == null || driveLetter.Length < 1)
			{
				drives = CDDrivesList.DrivesAvailable();
				if (drives.Length < 1)
				{
					Console.WriteLine("No CD drives found.");
					return;
				}
			}
			else
			{
				drives = new char[1];
				drives[0] = driveLetter[0];
			}

#if !DEBUG
			try
#endif
			{
				CDDriveReader audioSource = new CDDriveReader();
				audioSource.Open(drives[0]);
				
				if (audioSource.TOC.AudioTracks < 1)
				{
					Console.WriteLine("{0}: CD does not contain any audio tracks.", audioSource.Path);
					audioSource.Close();
					return;
				}
				if (driveOffset == 0)
					if (!AccurateRipVerify.FindDriveReadOffset(audioSource.ARName, out driveOffset))
						Console.WriteLine("Unknown read offset for drive {0}!!!", audioSource.Path);
						//throw new Exception("Failed to find drive read offset for drive" + audioSource.ARName);

				audioSource.DriveOffset = driveOffset;
				audioSource.CorrectionQuality = correctionQuality;
				audioSource.DebugMessages = !quiet;
				if (forceD8) audioSource.ForceD8 = true;
				if (forceBE) audioSource.ForceBE = true;
				string readCmd = audioSource.AutoDetectReadCommand;
				if (test)
				{
					Console.Write(readCmd);
					return;
				}

				AccurateRipVerify arVerify = new AccurateRipVerify(audioSource.TOC, WebRequest.GetSystemWebProxy());
				AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
				string CDDBId = AccurateRipVerify.CalculateCDDBId(audioSource.TOC);
				string ArId = AccurateRipVerify.CalculateAccurateRipId(audioSource.TOC);
				var ctdb = new CUEToolsDB(audioSource.TOC, null);
				ctdb.Init(arVerify);
				ctdb.ContactDB(null, "CUETools.ConsoleRipper 2.1.4", audioSource.ARName, true, false, CTDBMetadataSearch.Fast);
				arVerify.ContactAccurateRip(ArId);
				CTDBResponseMeta meta = null;
				foreach (var imeta in ctdb.Metadata)
				{
					meta = imeta;
					break;
				}

				//string destFile = (release == null) ? "cdimage.flac" : release.GetArtist() + " - " + release.GetTitle() + ".flac";
				string destFile = (meta == null) ? "cdimage.wav" : meta.artist + " - " + meta.album + ".wav";

				Console.WriteLine("Drive       : {0}", audioSource.Path);
				Console.WriteLine("Read offset : {0}", audioSource.DriveOffset);
				Console.WriteLine("Read cmd    : {0}", audioSource.CurrentReadCommand);
				Console.WriteLine("Secure mode : {0}", audioSource.CorrectionQuality);
				Console.WriteLine("Filename    : {0}", destFile);
				Console.WriteLine("Disk length : {0}", CDImageLayout.TimeToString(audioSource.TOC.AudioLength));
				Console.WriteLine("AccurateRip : {0}", arVerify.ARStatus == null ? "ok" : arVerify.ARStatus);
				Console.WriteLine("MusicBrainz : {0}", meta == null ? "not found" : meta.artist + " - " + meta.album);

				ProgressMeter meter = new ProgressMeter();
				audioSource.ReadProgress += new EventHandler<ReadProgressArgs>(meter.ReadProgress);

				audioSource.DetectGaps();

				StringWriter cueWriter = new StringWriter();
				cueWriter.WriteLine("REM DISCID {0}", CDDBId);
				cueWriter.WriteLine("REM ACCURATERIPID {0}", ArId);
				cueWriter.WriteLine("REM COMMENT \"{0}\"", audioSource.RipperVersion);
				if (meta != null && meta.year != "")
					cueWriter.WriteLine("REM DATE {0}", meta.year);
				if (audioSource.TOC.Barcode != null)
					cueWriter.WriteLine("CATALOG {0}", audioSource.TOC.Barcode);
				if (meta != null)
				{
					cueWriter.WriteLine("PERFORMER \"{0}\"", meta.artist);
					cueWriter.WriteLine("TITLE \"{0}\"", meta.album);
				}
				cueWriter.WriteLine("FILE \"{0}\" WAVE", destFile);
				for (int track = 1; track <= audioSource.TOC.TrackCount; track++)
					if (audioSource.TOC[track].IsAudio)
					{
						cueWriter.WriteLine("  TRACK {0:00} AUDIO", audioSource.TOC[track].Number);
						if (meta != null && meta.track.Length >= audioSource.TOC[track].Number)
						{
							cueWriter.WriteLine("    TITLE \"{0}\"", meta.track[(int)audioSource.TOC[track].Number - 1].name);
							cueWriter.WriteLine("    PERFORMER \"{0}\"", meta.track[(int)audioSource.TOC[track].Number - 1].artist);
						}
						if (audioSource.TOC[track].ISRC != null)
							cueWriter.WriteLine("    ISRC {0}", audioSource.TOC[track].ISRC);
						if (audioSource.TOC[track].DCP || audioSource.TOC[track].PreEmphasis)
							cueWriter.WriteLine("    FLAGS{0}{1}", audioSource.TOC[track].PreEmphasis ? " PRE" : "", audioSource.TOC[track].DCP ? " DCP" : "");
						for (int index = audioSource.TOC[track].Pregap > 0 ? 0 : 1; index <= audioSource.TOC[track].LastIndex; index++)
							cueWriter.WriteLine("    INDEX {0:00} {1}", index, audioSource.TOC[track][index].MSF);
					}
				cueWriter.Close();
				StreamWriter cueFile = new StreamWriter(Path.ChangeExtension(destFile, ".cue"));
				cueFile.Write(cueWriter.ToString());
				cueFile.Close();

				//IAudioDest audioDest = new FLACWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate);
				IAudioDest audioDest = new WAVWriter(destFile, null, audioSource.PCM);
				audioDest.FinalSampleCount = audioSource.Length;
				while (audioSource.Read(buff, -1) != 0)
				{
					arVerify.Write(buff);
					audioDest.Write(buff);
				}

				TimeSpan totalElapsed = DateTime.Now - meter.realStart;
				Console.Write("\r                                                                             \r");
				Console.WriteLine("Results     : {0:0.00}x; {1:d5} errors; {2:d2}:{3:d2}:{4:d2}",
					audioSource.Length / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
					audioSource.ErrorsCount,
					totalElapsed.Hours, totalElapsed.Minutes, totalElapsed.Seconds
					);
				audioDest.Close();

				StringWriter logWriter = new StringWriter();
				logWriter.WriteLine("{0}", audioSource.RipperVersion);
				logWriter.WriteLine("Extraction logfile from {0}", DateTime.Now);
				logWriter.WriteLine("Used drive  : {0}", audioSource.Path);
				logWriter.WriteLine("Read offset correction                      : {0}", audioSource.DriveOffset);
				bool wereErrors = false;
				for (int iTrack = 1; iTrack <= audioSource.TOC.AudioTracks; iTrack++)
					for (uint iSector = audioSource.TOC[iTrack].Start; iSector <= audioSource.TOC[iTrack].End; iSector ++)
						if (audioSource.Errors[(int)iSector])
						{
							if (!wereErrors)
							{
								logWriter.WriteLine();
								logWriter.WriteLine("Errors detected");
								logWriter.WriteLine();
							}
							wereErrors = true;
							logWriter.WriteLine("Track {0} contains errors", iTrack);
							break;
						}
				logWriter.WriteLine();
				logWriter.WriteLine("TOC of the extracted CD");
				logWriter.WriteLine();
				logWriter.WriteLine("     Track |   Start  |  Length  | Start sector | End sector");
				logWriter.WriteLine("    ---------------------------------------------------------");
				for (int track = 1; track <= audioSource.TOC.TrackCount; track++)
					logWriter.WriteLine("{0,9}  | {1,8} | {2,8} | {3,9}    | {4,9}",
						audioSource.TOC[track].Number,
						audioSource.TOC[track].StartMSF,
						audioSource.TOC[track].LengthMSF,
						audioSource.TOC[track].Start,
						audioSource.TOC[track].End);
				logWriter.WriteLine();
				logWriter.WriteLine("AccurateRip summary");
				logWriter.WriteLine();
				arVerify.GenerateFullLog(logWriter, true, ArId);
				logWriter.WriteLine();
				logWriter.WriteLine("End of status report");
				logWriter.Close();				
				StreamWriter logFile = new StreamWriter(Path.ChangeExtension(destFile, ".log"));
				logFile.Write(logWriter.ToString());
				logFile.Close();

				audioSource.Close();

				//FLACReader tagger = new FLACReader(destFile, null);
				//tagger.Tags.Add("CUESHEET", cueWriter.ToString());
				//tagger.Tags.Add("LOG", logWriter.ToString());
				//tagger.UpdateTags(false);
			}
#if !DEBUG
			catch (Exception ex)
			{
				Console.WriteLine();
				Console.WriteLine("Error: {0}", ex.Message);
				Console.WriteLine("{0}", ex.StackTrace);
			}
#endif
		}