예제 #1
0
        public int Read(AudioBuffer buff, int maxLength)
        {
            buff.Prepare(this, maxLength);
            while (_samplePos >= nextPos)
            {
                currentSource++;
                if (currentSource >= cueSheet._sources.Count)
                {
                    buff.Length = 0;
                    return(0);
                }
                if (currentAudio != null)
                {
                    currentAudio.Close();
                }
                currentAudio = cueSheet.GetAudioSource(currentSource, false);
                int offset = (int)(_samplePos - nextPos);
                if (offset != 0)
                {
                    currentAudio.Position += offset;
                }
                nextPos += cueSheet._sources[currentSource].Length;
            }
            int count = (int)(nextPos - _samplePos);

            if (maxLength >= 0)
            {
                count = Math.Min(count, maxLength);
            }
            count       = currentAudio.Read(buff, count);
            _samplePos += count;
            return(count);
        }
예제 #2
0
        public void Encode()
        {
            if (this.trackGain == null && this.drMeter == null)
            {
                throw new SkipEncodingItemException("Neither ReplayGain nor DynamicRange to calculate.");
            }

            AudioBuffer buffer = new AudioBuffer(audioSource.PCM, FileEncoderBase.BufferSize);

            while (audioSource.Read(buffer, FileEncoderBase.BufferSize) > 0)
            {
                if (this.trackGain != null)
                {
                    DspHelper.AnalyzeSamples(this.trackGain, buffer);
                }
                if (this.drMeter != null)
                {
                    this.drMeter.Feed(buffer.Samples, buffer.Length);
                }

                ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs((double)this.audioSource.Position / this.audioSource.Length);
                this.OnProgressChanged(eventArgs);
                if (eventArgs.Cancel)
                {
                    this.trackGain = null;
                    this.drMeter   = null;
                    return;
                }
            }

            if (this.drMeter != null)
            {
                this.drMeter.Finish();
            }
        }
예제 #3
0
        public void Encode()
        {
            AudioBuffer buffer = new AudioBuffer(audioSource.PCM, BufferSize);

            this.AudioDest.FinalSampleCount = this.audioSource.Length;

            while (audioSource.Read(buffer, BufferSize) > 0)
            {
                if (this.trackGain != null)
                {
                    DspHelper.AnalyzeSamples(this.trackGain, buffer);
                }
                if (this.drMeter != null)
                {
                    this.drMeter.Feed(buffer.Samples, buffer.Length);
                }

                this.AudioDest.Write(buffer);

                ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs((double)this.audioSource.Position / this.audioSource.Length);
                this.OnProgressChanged(eventArgs);
                if (eventArgs.Cancel)
                {
                    this.AudioDest.Close();
                    this.AudioDest = null;
                    Utility.TryDeleteFile(this.targetFilename);
                    return;
                }
            }

            if (this.drMeter != null)
            {
                this.drMeter.Finish();
            }

            this.AudioDest.Close();
            this.AudioDest = null;

            if (this.tags != null)
            {
                this.tags.WriteToFile(this.targetFilename);
            }
        }
예제 #4
0
        public int Read(AudioBuffer buff, int maxLength)
        {
            if (lwcdfBuffer == null || lwcdfBuffer.Size < buff.Size)
            {
                lwcdfBuffer = new AudioBuffer(_lwcdfSource, buff.Size);
            }
            int sampleCount = _audioSource.Read(buff, maxLength);

            if (sampleCount != _lwcdfSource.Read(lwcdfBuffer, maxLength))
            {
                throw new Exception("size mismatch"); // Very likely to happen (depending on lwcdfSource implementation)
            }
            for (uint i = 0; i < sampleCount; i++)
            {
                for (int c = 0; c < buff.PCM.ChannelCount; c++)
                {
                    buff.Samples[i, c] = (int)Math.Round(buff.Samples[i, c] / scaling_factor + lwcdfBuffer.Samples[i, c]);
                }
            }
            return(sampleCount);
        }
예제 #5
0
        private void Decompress(object o)
        {
#if !DEBUG
            try
#endif
            {
                bool done = false;
                do
                {
                    done = _source.Read(_writeBuffer, -1) == 0;
                    lock (this)
                    {
                        while (_haveData && !_close)
                        {
                            Monitor.Wait(this);
                        }
                        if (_close)
                        {
                            break;
                        }
                        AudioBuffer temp = _writeBuffer;
                        _writeBuffer = _readBuffer;
                        _readBuffer  = temp;
                        _haveData    = true;
                        Monitor.Pulse(this);
                    }
                } while (!done);
            }
#if !DEBUG
            catch (Exception ex)
            {
                lock (this)
                {
                    _ex = ex;
                    Monitor.Pulse(this);
                }
            }
#endif
        }
예제 #6
0
        void workerExtract_DoWork(object sender, DoWorkEventArgs e)
        {
            IAudioSource reader = null;

            try
            {
                var decoderSettings = new CUETools.Codecs.MPEG.MPLS.DecoderSettings()
                {
                    StreamId = pid
                };
                reader = decoderSettings.Open(chosenReader.Path);
                Directory.CreateDirectory(outputFolderPath);
                if (File.Exists(outputCuePath))
                {
                    throw new Exception(string.Format("File \"{0}\" already exists", outputCuePath));
                }
                if (File.Exists(outputAudioPath))
                {
                    throw new Exception(string.Format("File \"{0}\" already exists", outputAudioPath));
                }
                AudioBuffer buff = new AudioBuffer(reader, 0x10000);
                CUETools.Codecs.Flake.EncoderSettings settings = new CUETools.Codecs.Flake.EncoderSettings()
                {
                    PCM         = reader.PCM,
                    Padding     = 16536,
                    EncoderMode = "5"
                };
                if (ctdb != null)
                {
                    using (StreamWriter cueWriter = new StreamWriter(outputCuePath, false, Encoding.UTF8))
                    {
                        cueWriter.WriteLine("REM COMMENT \"{0}\"", "Created by CUETools.eac3to");
                        if (metaresult != null && metaresult.metadata.Year != "")
                        {
                            cueWriter.WriteLine("REM DATE {0}", metaresult.metadata.Year);
                        }
                        else
                        {
                            cueWriter.WriteLine("REM DATE XXXX");
                        }
                        if (metaresult != null)
                        {
                            cueWriter.WriteLine("PERFORMER \"{0}\"", metaresult.metadata.Artist);
                            cueWriter.WriteLine("TITLE \"{0}\"", metaresult.metadata.Title);
                        }
                        else
                        {
                            cueWriter.WriteLine("PERFORMER \"\"");
                            cueWriter.WriteLine("TITLE \"\"");
                        }
                        cueWriter.WriteLine("FILE \"{0}\" WAVE", Path.GetFileName(outputAudioPath));
                        var toc = ctdb.TOC;
                        for (int track = 1; track <= toc.TrackCount; track++)
                        {
                            if (toc[track].IsAudio)
                            {
                                cueWriter.WriteLine("  TRACK {0:00} AUDIO", toc[track].Number);
                                if (metaresult != null && metaresult.metadata.Tracks.Count >= toc[track].Number)
                                {
                                    cueWriter.WriteLine("    TITLE \"{0}\"", metaresult.metadata.Tracks[(int)toc[track].Number - 1].Title);
                                    if (metaresult.metadata.Tracks[(int)toc[track].Number - 1].Artist != "")
                                    {
                                        cueWriter.WriteLine("    PERFORMER \"{0}\"", metaresult.metadata.Tracks[(int)toc[track].Number - 1].Artist);
                                    }
                                }
                                else
                                {
                                    cueWriter.WriteLine("    TITLE \"\"");
                                }
                                if (toc[track].ISRC != null)
                                {
                                    cueWriter.WriteLine("    ISRC {0}", toc[track].ISRC);
                                }
                                for (int index = toc[track].Pregap > 0 ? 0 : 1; index <= toc[track].LastIndex; index++)
                                {
                                    cueWriter.WriteLine("    INDEX {0:00} {1}", index, toc[track][index].MSF);
                                }
                            }
                        }
                    }
                }
                var      start     = DateTime.Now;
                TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
                var      writer    = new CUETools.Codecs.Flake.AudioEncoder(settings, outputAudioPath);
                try
                {
                    while (reader.Read(buff, -1) != 0)
                    {
                        writer.Write(buff);
                        TimeSpan elapsed = DateTime.Now - start;
                        if ((elapsed - lastPrint).TotalMilliseconds > 60)
                        {
                            long length = Math.Max((long)(reader.Duration.TotalSeconds * reader.PCM.SampleRate), Math.Max(reader.Position, 1));
                            this.Dispatcher.Invoke((Action)(() =>
                            {
                                pbStatus.Value = 100.0 * reader.Position / length;
                            }));
                            lastPrint = elapsed;
                        }
                        if (workerExtract.CancellationPending)
                        {
                            throw new Exception("aborted");
                        }
                    }
                }
                catch (Exception ex)
                {
                    writer.Delete();
                    try { File.Delete(outputCuePath); } catch (Exception) { }
                    throw ex;
                }
                writer.Close();
            }
            catch (Exception ex)
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    MessageBox.Show(this, ex.Message, "Extraction failed");
                }));
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }

            this.Dispatcher.Invoke((Action)(() =>
            {
                pbStatus.Visibility = Visibility.Collapsed;
                //pbStatus.IsIndeterminate = false;
                stackParams.IsEnabled = true;
                buttonExtract.IsEnabled = true;
                buttonExtract.Visibility = Visibility.Visible;
                buttonStop.Visibility = Visibility.Hidden;
                buttonStop.IsEnabled = false;
            }));
        }
예제 #7
0
        static int Main(string[] args)
        {
            bool             ok = true;
            string           sourceFile = null, destFile = null;
            int              padding            = 8192;
            string           encoderMode        = null;
            string           decoderName        = null;
            string           encoderName        = null;
            string           encoderFormat      = null;
            bool             ignore_chunk_sizes = false;
            AudioEncoderType audioEncoderType   = AudioEncoderType.NoAudio;
            var              decoderOptions     = new Dictionary <string, string>();

            for (int arg = 0; arg < args.Length; arg++)
            {
                if (args[arg].Length == 0)
                {
                    ok = false;
                }
                else if (args[arg] == "--ignore-chunk-sizes")
                {
                    ignore_chunk_sizes = true;
                }
                else if (args[arg] == "--decoder" && ++arg < args.Length)
                {
                    decoderName = args[arg];
                }
                else if (args[arg] == "--decoder-option" && arg + 2 < args.Length)
                {
                    var optionName  = args[++arg];
                    var optionValue = args[++arg];
                    decoderOptions.Add(optionName, optionValue);
                }
                else if (args[arg] == "--encoder" && ++arg < args.Length)
                {
                    encoderName = args[arg];
                }
                else if (args[arg] == "--encoder-format" && ++arg < args.Length)
                {
                    encoderFormat = args[arg];
                }
                else if ((args[arg] == "-p" || args[arg] == "--padding") && ++arg < args.Length)
                {
                    ok = int.TryParse(args[arg], out padding);
                }
                else if ((args[arg] == "-m" || args[arg] == "--mode") && ++arg < args.Length)
                {
                    encoderMode = args[arg];
                }
                else if (args[arg] == "--lossy")
                {
                    audioEncoderType = AudioEncoderType.Lossy;
                }
                else if (args[arg] == "--lossless")
                {
                    audioEncoderType = AudioEncoderType.Lossless;
                }
                else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile == null)
                {
                    sourceFile = args[arg];
                }
                else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile != null && destFile == null)
                {
                    destFile = args[arg];
                }
                else
                {
                    ok = false;
                }
                if (!ok)
                {
                    break;
                }
            }

            Console.Error.WriteLine("CUETools.Converter, Copyright (C) 2009-2020 Grigory Chudov.");
            Console.Error.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
            Console.Error.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details.");
            if (!ok || sourceFile == null || destFile == null)
            {
                Usage();
                return(22);
            }

            if (destFile != "-" && destFile != "nul" && File.Exists(destFile))
            {
                Console.Error.WriteLine("Error: file already exists.");
                return(17);
            }

            DateTime start     = DateTime.Now;
            TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
            var      config    = new CUEConfigAdvanced();

            config.Init();

#if !DEBUG
            try
#endif
            {
                IAudioSource audioSource = null;
                IAudioDest   audioDest   = null;
                TagLib.UserDefined.AdditionalFileTypes.Config = config;
                TagLib.File sourceInfo = sourceFile == "-" ? null : TagLib.File.Create(new TagLib.File.LocalFileAbstraction(sourceFile));

#if !DEBUG
                try
#endif
                {
                    audioSource = Program.GetAudioSource(config, sourceFile, decoderName, ignore_chunk_sizes, decoderOptions);

                    AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
                    Console.Error.WriteLine("Filename  : {0}", sourceFile);
                    Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample, audioSource.Duration);

                    CUEToolsFormat fmt;
                    if (encoderFormat == null)
                    {
                        if (destFile == "-" || destFile == "nul")
                        {
                            encoderFormat = "wav";
                        }
                        else
                        {
                            string extension = Path.GetExtension(destFile).ToLower();
                            if (!extension.StartsWith("."))
                            {
                                throw new Exception("Unknown encoder format: " + destFile);
                            }
                            encoderFormat = extension.Substring(1);
                        }
                    }
                    if (!config.formats.TryGetValue(encoderFormat, out fmt))
                    {
                        throw new Exception("Unsupported encoder format: " + encoderFormat);
                    }
                    AudioEncoderSettingsViewModel encoder =
                        audioEncoderType == AudioEncoderType.Lossless ? Program.GetEncoder(config, fmt, true, encoderName) :
                        audioEncoderType == AudioEncoderType.Lossy ? Program.GetEncoder(config, fmt, false, encoderName) :
                        Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName);
                    if (encoder == null)
                    {
                        var lst = new List <AudioEncoderSettingsViewModel>(config.encodersViewModel).FindAll(
                            e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))).
                                  ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)"));
                        throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray())));
                    }
                    var settings = encoder.Settings.Clone();
                    settings.PCM         = audioSource.PCM;
                    settings.Padding     = padding;
                    settings.EncoderMode = encoderMode ?? settings.EncoderMode;
                    object o = null;
                    try
                    {
                        o = destFile == "-" ? Activator.CreateInstance(settings.EncoderType, settings, "", Console.OpenStandardOutput()) :
                            destFile == "nul" ? Activator.CreateInstance(settings.EncoderType, settings, "", new NullStream()) :
                            Activator.CreateInstance(settings.EncoderType, settings, destFile, null);
                    }
                    catch (System.Reflection.TargetInvocationException ex)
                    {
                        throw ex.InnerException;
                    }
                    if (o == null || !(o is IAudioDest))
                    {
                        throw new Exception("Unsupported audio type: " + destFile + ": " + settings.EncoderType.FullName);
                    }
                    audioDest = o as IAudioDest;
                    audioDest.FinalSampleCount = audioSource.Length;

                    bool keepRunning = true;
                    Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
                    {
                        keepRunning = false;
                        if (e.SpecialKey == ConsoleSpecialKey.ControlC)
                        {
                            e.Cancel = true;
                        }
                        else
                        {
                            audioDest.Delete();
                        }
                    };

                    while (audioSource.Read(buff, -1) != 0)
                    {
                        audioDest.Write(buff);
                        TimeSpan elapsed = DateTime.Now - start;
                        if ((elapsed - lastPrint).TotalMilliseconds > 60)
                        {
                            var duration = audioSource.Duration;
                            var position = TimeSpan.FromSeconds((double)audioSource.Position / audioSource.PCM.SampleRate);
                            if (duration == TimeSpan.Zero && sourceInfo != null)
                            {
                                duration = sourceInfo.Properties.Duration;
                            }
                            if (duration < position)
                            {
                                duration = position;
                            }
                            if (duration < TimeSpan.FromSeconds(1))
                            {
                                duration = TimeSpan.FromSeconds(1);
                            }
                            Console.Error.Write("\rProgress  : {0:00}%; {1:0.00}x; {2}/{3}",
                                                100.0 * position.TotalSeconds / duration.TotalSeconds,
                                                position.TotalSeconds / elapsed.TotalSeconds,
                                                elapsed,
                                                TimeSpan.FromSeconds(elapsed.TotalSeconds / position.TotalSeconds * duration.TotalSeconds)
                                                );
                            lastPrint = elapsed;
                        }
                        if (!keepRunning)
                        {
                            throw new Exception("Aborted");
                        }
                    }

                    TimeSpan totalElapsed = DateTime.Now - start;
                    Console.Error.Write("\r                                                                         \r");
                    Console.Error.WriteLine("Results   : {0:0.00}x; {1}",
                                            audioSource.Position / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
                                            totalElapsed
                                            );
                }
#if !DEBUG
                catch (Exception ex)
                {
                    if (audioSource != null)
                    {
                        audioSource.Close();
                    }
                    if (audioDest != null)
                    {
                        audioDest.Delete();
                    }
                    throw ex;
                }
#endif
                audioSource.Close();
                audioDest.Close();

                if (sourceFile != "-" && destFile != "-" && destFile != "nul")
                {
                    TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile));
                    if (Tagging.UpdateTags(destInfo, Tagging.Analyze(sourceInfo), config, false))
                    {
                        sourceInfo.Tag.CopyTo(destInfo.Tag, true);
                        destInfo.Tag.Pictures = sourceInfo.Tag.Pictures;
                        destInfo.Save();
                    }
                }
            }
#if !DEBUG
            catch (Exception ex)
            {
                Console.Error.Write("\r                                                                         \r");
                Console.Error.WriteLine("Error     : {0}", ex.Message);
                return(1);
                //Console.WriteLine("{0}", ex.StackTrace);
            }
#endif
            return(0);
        }
예제 #8
0
파일: Deck.cs 프로젝트: dan-huang/CUETools
 private void PlayThread()
 {
     try
     {
         do
         {
             if (playingSource == null)
             {
                 writer.Pause();
             }
             else
             {
                 if (seekTo >= 0 && playingStart + seekTo < playingFinish)
                 {
                     playingSource.Position = playingStart + seekTo;
                     seekTo = -1;
                 }
                 if (playingSource.Position == playingFinish || stopNow || seekTo == (int)(playingFinish - playingStart))
                 {
                     seekTo = -1;
                     playingSource.Close();
                     playingSource = null;
                     if (playingCue != null)
                     {
                         playingCue.Close();
                         playingCue = null;
                     }
                     playingFinish = 0;
                     playingStart  = 0;
                     playingRow    = -1;
                     if (stopNow || nextDeck == null || nextDeck.playingSource == null)
                     {
                         writer.Flush();
                         stopNow = false;
                         mixer.BufferPlaying(iSource, false);
                         needUpdate = true;
                         playThread = null;
                         return;
                     }
                     playingSource          = nextDeck.playingSource;
                     playingCue             = nextDeck.playingCue;
                     playingStart           = nextDeck.playingStart;
                     playingFinish          = nextDeck.playingFinish;
                     playingRow             = nextDeck.playingRow;
                     needUpdate             = true;
                     nextDeck.playingSource = null;
                     nextDeck.playingCue    = null;
                     nextDeck.playingStart  = 0;
                     nextDeck.playingFinish = 0;
                     nextDeck.playingRow    = -1;
                     nextDeck.needUpdate    = true;
                 }
                 if (buff == null || buff.PCM.SampleRate != playingSource.PCM.SampleRate || buff.PCM.ChannelCount != playingSource.PCM.ChannelCount || buff.PCM.BitsPerSample != playingSource.PCM.BitsPerSample)
                 {
                     buff = new AudioBuffer(playingSource.PCM, 0x2000);
                 }
                 playingSource.Read(buff, Math.Min(buff.Size, (int)(playingFinish - playingSource.Position)));
                 writer.Write(buff);
             }
         } while (true);
     }
     catch (Exception ex)
     {
     }
     if (playingCue != null)
     {
         playingCue.Close();
         playingCue = null;
     }
     if (playingSource != null)
     {
         playingSource.Close();
         playingSource = null;
     }
     playThread = null;
 }
예제 #9
0
        static int Main(string[] args)
        {
            bool             ok = true;
            string           sourceFile = null, destFile = null;
            int              padding          = 8192;
            int              stream           = 0;
            string           encoderMode      = null;
            string           encoderName      = null;
            string           encoderFormat    = null;
            AudioEncoderType audioEncoderType = AudioEncoderType.NoAudio;
            var              decoderOptions   = new Dictionary <string, string>();
            bool             queryMeta        = false;

            for (int arg = 0; arg < args.Length; arg++)
            {
                if (args[arg].Length == 0)
                {
                    ok = false;
                }
                else if (args[arg] == "--encoder" && ++arg < args.Length)
                {
                    encoderName = args[arg];
                }
                else if (args[arg] == "--encoder-format" && ++arg < args.Length)
                {
                    encoderFormat = args[arg];
                }
                else if ((args[arg] == "-p" || args[arg] == "--padding") && ++arg < args.Length)
                {
                    ok = int.TryParse(args[arg], out padding);
                }
                else if ((args[arg] == "-m" || args[arg] == "--mode") && arg + 1 < args.Length)
                {
                    encoderMode = args[++arg];
                }
                else if (args[arg] == "--lossy")
                {
                    audioEncoderType = AudioEncoderType.Lossy;
                }
                else if (args[arg] == "--lossless")
                {
                    audioEncoderType = AudioEncoderType.Lossless;
                }
                else if (args[arg] == "--ctdb")
                {
                    queryMeta = true;
                }
                else if (args[arg] == "--decoder-option" && arg + 2 < args.Length)
                {
                    var optionName  = args[++arg];
                    var optionValue = args[++arg];
                    decoderOptions.Add(optionName, optionValue);
                }
                else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile == null)
                {
                    sourceFile = args[arg];
                }
                else if ((args[arg][0] != '-' || args[arg] == "-") && sourceFile != null && destFile == null)
                {
                    destFile = args[arg];
                    var x = destFile.Split(':');
                    if (x.Length > 1)
                    {
                        stream = int.Parse(x[0]);
                        if (x[1] != "")
                        {
                            destFile = x[1];
                        }
                        else
                        {
                            arg++;
                            if (arg >= args.Length)
                            {
                                ok = false;
                                break;
                            }
                            destFile = args[arg];
                        }
                    }
                }
                else
                {
                    ok = false;
                }
                if (!ok)
                {
                    break;
                }
            }

            if (!ok || sourceFile == null)
            {
                Usage();
                return(22);
            }

            if (destFile != null && destFile != "-" && destFile != "nul" && File.Exists(destFile))
            {
                Console.Error.WriteLine("Error: file {0} already exists.", destFile);
                return(17);
            }

            DateTime start     = DateTime.Now;
            TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
            var      config    = new CUEConfigAdvanced();

            config.Init();

#if !DEBUG
            try
#endif
            {
                IAudioSource       audioSource    = null;
                IAudioTitleSet     audioContainer = null;
                IAudioDest         audioDest      = null;
                var                videos         = new List <Codecs.MPEG.MPLS.MPLSStream>();
                List <IAudioTitle> audios         = null;
                List <TimeSpan>    chapters       = null;
                TagLib.UserDefined.AdditionalFileTypes.Config = config;

#if !DEBUG
                try
#endif
                {
                    if (true)
                    {
                        IAudioDecoderSettings decoderSettings = null;
                        if (Path.GetExtension(sourceFile) == ".mpls")
                        {
                            decoderSettings = new Codecs.MPEG.MPLS.DecoderSettings();
                        }
                        else
                        {
                            decoderSettings = new Codecs.MPEG.ATSI.DecoderSettings();
                        }
                        foreach (var decOpt in decoderOptions)
                        {
                            var property = TypeDescriptor.GetProperties(decoderSettings).Find(decOpt.Key, true);
                            if (property == null)
                            {
                                throw new Exception($"{decoderSettings.Name} {decoderSettings.Extension} decoder settings object (of type {decoderSettings.GetType().FullName}) doesn't have a property named {decOpt.Key}.");
                            }
                            property.SetValue(decoderSettings,
                                              TypeDescriptor.GetConverter(property.PropertyType).ConvertFromString(decOpt.Value));
                        }
                        audioSource    = decoderSettings.Open(sourceFile);
                        audioContainer = audioSource as IAudioTitleSet;
                        if (audioContainer == null)
                        {
                            audioContainer = new SingleAudioTitleSet(audioSource);
                        }
                        Console.ForegroundColor = ConsoleColor.White;
                        int  frameRate  = 0;
                        bool interlaced = false;
                        audios = audioContainer.AudioTitles;
                        audios.ForEach(t => chapters = t.Chapters);
                        if (audioSource is Codecs.MPEG.MPLS.AudioDecoder)
                        {
                            var mpls = audioSource as Codecs.MPEG.MPLS.AudioDecoder;
                            mpls.MPLSHeader.play_item.ForEach(i => i.video.ForEach(v => { if (!videos.Exists(v1 => v1.pid == v.pid))
                                                                                          {
                                                                                              videos.Add(v);
                                                                                          }
                                                                                   }));
                        }
                        videos.ForEach(v => { frameRate = v.FrameRate; interlaced = v.Interlaced; });
                        Console.Error.Write($@"M2TS, {
                            videos.Count} video track{(videos.Count != 1 ? "s" : "")}, {
                            audios.Count} audio track{(audios.Count != 1 ? "s" : "")}, {
                            CDImageLayout.TimeToString(audios[0].GetDuration(), "{0:0}:{1:00}:{2:00}")}, {
                            (frameRate * (interlaced ? 2 : 1))}{
                            (interlaced ? "i" : "p")}");
                        Console.Error.WriteLine();
                        //foreach (var item in mpls.MPLSHeader.play_item)
                        //Console.Error.WriteLine("{0}.m2ts", item.clip_id);
                        {
                            Console.ForegroundColor = ConsoleColor.Gray;
                            int id = 1;
                            if (chapters.Count > 1)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.Error.Write(id++);
                                Console.Error.Write(": ");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.Error.WriteLine("Chapters, {0} chapters", chapters.Count - 1);
                            }
                            foreach (var video in videos)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.Error.Write(id++);
                                Console.Error.Write(": ");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.Error.WriteLine("{0}, {1}{2}", video.CodecString, video.FormatString, video.FrameRate * (video.Interlaced ? 2 : 1));
                            }
                            foreach (var audio in audios)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.Error.Write(id++);
                                Console.Error.Write(": ");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.Error.WriteLine("{0}, {1}, {2}, {3}", audio.Codec, audio.Language, audio.GetFormatString(), audio.GetRateString());
                            }
                        }
                    }

                    if (destFile == null)
                    {
                        return(0);
                    }

                    string strtoc = "";
                    for (int i = 0; i < chapters.Count; i++)
                    {
                        strtoc += string.Format(" {0}", (int)Math.Round((chapters[i].TotalSeconds * 75)));
                    }
                    strtoc = strtoc.Substring(1);
                    CDImageLayout    toc  = new CDImageLayout(strtoc);
                    CTDBResponseMeta meta = null;
                    if (queryMeta)
                    {
                        var ctdb = new CUEToolsDB(toc, null);
                        Console.Error.WriteLine("Contacting CTDB...");
                        ctdb.ContactDB(null, "CUETools.eac3to 2.1.8", "", false, true, CTDBMetadataSearch.Extensive);
                        foreach (var imeta in ctdb.Metadata)
                        {
                            meta = imeta;
                            break;
                        }
                    }

                    if (stream > 0)
                    {
                        int chapterStreams = chapters.Count > 1 ? 1 : 0;
                        if (stream <= chapterStreams)
                        {
                            if (destFile == "-" || destFile == "nul")
                            {
                                encoderFormat = "txt";
                            }
                            else
                            {
                                string extension = Path.GetExtension(destFile).ToLower();
                                if (!extension.StartsWith("."))
                                {
                                    encoderFormat = destFile;
                                    if (meta == null || meta.artist == null || meta.album == null)
                                    {
                                        destFile = string.Format("{0}.{1}", Path.GetFileNameWithoutExtension(sourceFile), destFile);
                                    }
                                    else
                                    {
                                        destFile = string.Format("{0} - {1} - {2}.{3}", meta.artist, meta.year, meta.album, destFile);
                                    }
                                }
                                else
                                {
                                    encoderFormat = extension.Substring(1);
                                }
                                if (encoderFormat != "txt" && encoderFormat != "cue")
                                {
                                    throw new Exception(string.Format("Unsupported chapters file format \"{0}\"", encoderFormat));
                                }
                            }

                            Console.Error.WriteLine("Creating file \"{0}\"...", destFile);

                            if (encoderFormat == "txt")
                            {
                                using (TextWriter sw = destFile == "nul" ? (TextWriter) new StringWriter() : destFile == "-" ? Console.Out : (TextWriter) new StreamWriter(destFile))
                                {
                                    for (int i = 0; i < chapters.Count - 1; i++)
                                    {
                                        sw.WriteLine("CHAPTER{0:00}={1}", i + 1,
                                                     CDImageLayout.TimeToString(chapters[i]));
                                        if (meta != null && meta.track.Length >= toc[i + 1].Number)
                                        {
                                            sw.WriteLine("CHAPTER{0:00}NAME={1}", i + 1, meta.track[(int)toc[i + 1].Number - 1].name);
                                        }
                                        else
                                        {
                                            sw.WriteLine("CHAPTER{0:00}NAME=", i + 1);
                                        }
                                    }
                                }
                                Console.BackgroundColor = ConsoleColor.DarkGreen;
                                Console.Error.Write("Done.");
                                Console.BackgroundColor = ConsoleColor.Black;
                                Console.Error.WriteLine();
                                return(0);
                            }

                            if (encoderFormat == "cue")
                            {
                                using (StreamWriter cueWriter = new StreamWriter(destFile, false, Encoding.UTF8))
                                {
                                    cueWriter.WriteLine("REM COMMENT \"{0}\"", "Created by CUETools.eac3to");
                                    if (meta != null && meta.year != null)
                                    {
                                        cueWriter.WriteLine("REM DATE {0}", meta.year);
                                    }
                                    else
                                    {
                                        cueWriter.WriteLine("REM DATE XXXX");
                                    }
                                    if (meta != null)
                                    {
                                        cueWriter.WriteLine("PERFORMER \"{0}\"", meta.artist);
                                        cueWriter.WriteLine("TITLE \"{0}\"", meta.album);
                                    }
                                    else
                                    {
                                        cueWriter.WriteLine("PERFORMER \"\"");
                                        cueWriter.WriteLine("TITLE \"\"");
                                    }
                                    if (meta != null)
                                    {
                                        //cueWriter.WriteLine("FILE \"{0}\" WAVE", Path.GetFileNameWithoutExtension(destFile) + (extension ?? ".wav"));
                                        cueWriter.WriteLine("FILE \"{0}\" WAVE", Path.GetFileNameWithoutExtension(destFile) + (".wav"));
                                    }
                                    else
                                    {
                                        cueWriter.WriteLine("FILE \"{0}\" WAVE", "");
                                    }
                                    for (int track = 1; track <= toc.TrackCount; track++)
                                    {
                                        if (toc[track].IsAudio)
                                        {
                                            cueWriter.WriteLine("  TRACK {0:00} AUDIO", toc[track].Number);
                                            if (meta != null && meta.track.Length >= toc[track].Number)
                                            {
                                                cueWriter.WriteLine("    TITLE \"{0}\"", meta.track[(int)toc[track].Number - 1].name);
                                                if (meta.track[(int)toc[track].Number - 1].artist != null)
                                                {
                                                    cueWriter.WriteLine("    PERFORMER \"{0}\"", meta.track[(int)toc[track].Number - 1].artist);
                                                }
                                            }
                                            else
                                            {
                                                cueWriter.WriteLine("    TITLE \"\"");
                                            }
                                            if (toc[track].ISRC != null)
                                            {
                                                cueWriter.WriteLine("    ISRC {0}", toc[track].ISRC);
                                            }
                                            for (int index = toc[track].Pregap > 0 ? 0 : 1; index <= toc[track].LastIndex; index++)
                                            {
                                                cueWriter.WriteLine("    INDEX {0:00} {1}", index, toc[track][index].MSF);
                                            }
                                        }
                                    }
                                }
                                Console.BackgroundColor = ConsoleColor.DarkGreen;
                                Console.Error.Write("Done.");
                                Console.BackgroundColor = ConsoleColor.Black;
                                Console.Error.WriteLine();
                                return(0);
                            }

                            throw new Exception("Unknown encoder format: " + destFile);
                        }
                        if (stream - chapterStreams <= videos.Count)
                        {
                            throw new Exception("Video extraction not supported.");
                        }
                        if (stream - chapterStreams - videos.Count > audios.Count)
                        {
                            throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream));
                        }
                        int streamId = audios[stream - chapterStreams - videos.Count - 1].StreamId;
                        if (audioSource is Codecs.MPEG.MPLS.AudioDecoder)
                        {
                            (audioSource.Settings as Codecs.MPEG.MPLS.DecoderSettings).StreamId = streamId;
                        }
                    }

                    AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
                    Console.Error.WriteLine("Filename  : {0}", sourceFile);
                    Console.Error.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.PCM.SampleRate, audioSource.PCM.ChannelCount, audioSource.PCM.BitsPerSample,
                                            audioSource.Duration);

                    CUEToolsFormat fmt;
                    if (encoderFormat == null)
                    {
                        if (destFile == "-" || destFile == "nul")
                        {
                            encoderFormat = "wav";
                        }
                        else
                        {
                            string extension = Path.GetExtension(destFile).ToLower();
                            if (!extension.StartsWith("."))
                            {
                                encoderFormat = destFile;
                                if (meta == null || meta.artist == null || meta.album == null)
                                {
                                    destFile = string.Format("{0} - {1}.{2}", Path.GetFileNameWithoutExtension(sourceFile), stream, destFile);
                                }
                                else
                                {
                                    destFile = string.Format("{0} - {1} - {2}.{3}", meta.artist, meta.year, meta.album, destFile);
                                }
                            }
                            else
                            {
                                encoderFormat = extension.Substring(1);
                            }
                            if (File.Exists(destFile))
                            {
                                throw new Exception(string.Format("Error: file {0} already exists.", destFile));
                            }
                        }
                    }
                    if (!config.formats.TryGetValue(encoderFormat, out fmt))
                    {
                        throw new Exception("Unsupported encoder format: " + encoderFormat);
                    }
                    AudioEncoderSettingsViewModel encoder =
                        audioEncoderType == AudioEncoderType.Lossless ? Program.GetEncoder(config, fmt, true, encoderName) :
                        audioEncoderType == AudioEncoderType.Lossy ? Program.GetEncoder(config, fmt, false, encoderName) :
                        Program.GetEncoder(config, fmt, true, encoderName) ?? Program.GetEncoder(config, fmt, false, encoderName);
                    if (encoder == null)
                    {
                        var lst = new List <AudioEncoderSettingsViewModel>(config.encodersViewModel).FindAll(
                            e => e.Extension == fmt.extension && (audioEncoderType == AudioEncoderType.NoAudio || audioEncoderType == (e.Lossless ? AudioEncoderType.Lossless : AudioEncoderType.Lossy))).
                                  ConvertAll(e => e.Name + (e.Lossless ? " (lossless)" : " (lossy)"));
                        throw new Exception("Encoders available for format " + fmt.extension + ": " + (lst.Count == 0 ? "none" : string.Join(", ", lst.ToArray())));
                    }
                    Console.Error.WriteLine("Output {0}  : {1}", stream, destFile);
                    var settings = encoder.Settings.Clone();
                    settings.PCM         = audioSource.PCM;
                    settings.Padding     = padding;
                    settings.EncoderMode = encoderMode ?? settings.EncoderMode;
                    object o = null;
                    try
                    {
                        o = destFile == "-" ? Activator.CreateInstance(settings.EncoderType, settings, "", Console.OpenStandardOutput()) :
                            destFile == "nul" ? Activator.CreateInstance(settings.EncoderType, settings, "", new NullStream()) :
                            Activator.CreateInstance(settings.EncoderType, settings, destFile, null);
                    }
                    catch (System.Reflection.TargetInvocationException ex)
                    {
                        throw ex.InnerException;
                    }
                    if (o == null || !(o is IAudioDest))
                    {
                        throw new Exception("Unsupported audio type: " + destFile + ": " + settings.EncoderType.FullName);
                    }
                    audioDest = o as IAudioDest;
                    audioDest.FinalSampleCount = audioSource.Length;

                    bool keepRunning = true;
                    Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
                    {
                        keepRunning = false;
                        if (e.SpecialKey == ConsoleSpecialKey.ControlC)
                        {
                            e.Cancel = true;
                        }
                        else
                        {
                            audioDest.Delete();
                        }
                    };

                    while (audioSource.Read(buff, -1) != 0)
                    {
                        audioDest.Write(buff);
                        TimeSpan elapsed = DateTime.Now - start;
                        if ((elapsed - lastPrint).TotalMilliseconds > 60)
                        {
                            var duration = audioSource.Duration;
                            var position = TimeSpan.FromSeconds((double)audioSource.Position / audioSource.PCM.SampleRate);
                            if (duration < position)
                            {
                                duration = position;
                            }
                            if (duration < TimeSpan.FromSeconds(1))
                            {
                                duration = TimeSpan.FromSeconds(1);
                            }
                            Console.Error.Write("\rProgress  : {0:00}%; {1:0.00}x; {2}/{3}",
                                                100.0 * position.TotalSeconds / duration.TotalSeconds,
                                                position.TotalSeconds / elapsed.TotalSeconds,
                                                elapsed,
                                                TimeSpan.FromSeconds(elapsed.TotalSeconds / position.TotalSeconds * duration.TotalSeconds)
                                                );
                            lastPrint = elapsed;
                        }
                        if (!keepRunning)
                        {
                            throw new Exception("Aborted");
                        }
                    }

                    TimeSpan totalElapsed = DateTime.Now - start;
                    Console.Error.Write("\r                                                                         \r");
                    Console.Error.WriteLine("Results   : {0:0.00}x; {1}",
                                            audioSource.Position / totalElapsed.TotalSeconds / audioSource.PCM.SampleRate,
                                            totalElapsed
                                            );
                }
#if !DEBUG
                catch (Exception ex)
                {
                    if (audioSource != null)
                    {
                        audioSource.Close();
                    }
                    if (audioDest != null)
                    {
                        audioDest.Delete();
                    }
                    throw ex;
                }
#endif
                audioSource.Close();
                audioDest.Close();

                if (sourceFile != "-" && destFile != "-" && destFile != "nul")
                {
                    //TagLib.File destInfo = TagLib.File.Create(new TagLib.File.LocalFileAbstraction(destFile));
                    //NameValueCollection tags;
                    //if (Tagging.UpdateTags(destInfo, tags, config, false))
                    //{
                    //    destInfo.Save();
                    //}
                }
            }
#if !DEBUG
            catch (Exception ex)
            {
                Console.Error.Write("\r                                                                         \r");
                Console.BackgroundColor = ConsoleColor.DarkRed;
                Console.Error.Write("Error     : {0}", ex.Message);
                Console.BackgroundColor = ConsoleColor.Black;
                Console.Error.WriteLine();
                return(1);
                //Console.WriteLine("{0}", ex.StackTrace);
            }
#endif
            return(0);
        }
예제 #10
0
 public int Read(AudioBuffer buffer, int maxLength)
 {
     return(audioSource.Read(buffer, (int)Math.Min(maxLength, this.sampleEnd - audioSource.Position)));
 }
예제 #11
0
        public void WriteAudioFiles(string dir, CUEStyle style, SetStatus statusDel)
        {
            const int buffLen = 16384;
            int       iTrack, iIndex, iSource, iDest, i, j, samplesRemIndex, samplesRemSource, copyCount;

            string[]     destPaths;
            int[]        destLengths;
            byte[]       buff = new byte[buffLen * 2 * 2];
            TrackInfo    track;
            IAudioSource audioSource = null;
            IAudioDest   audioDest   = null;
            bool         htoaToFile  = ((style == CUEStyle.GapsAppended) && _preserveHTOA &&
                                        (_tracks[0].IndexLengths[0] != 0));
            bool discardOutput;

            if (_usePregapForFirstTrackInSingleFile)
            {
                throw new Exception("UsePregapForFirstTrackInSingleFile is not supported for writing audio files.");
            }

            if (style == CUEStyle.SingleFile)
            {
                destPaths    = new string[1];
                destPaths[0] = Path.Combine(dir, _singleFilename);
            }
            else
            {
                destPaths = new string[TrackCount + (htoaToFile ? 1 : 0)];
                if (htoaToFile)
                {
                    destPaths[0] = Path.Combine(dir, _htoaFilename);
                }
                for (i = 0; i < TrackCount; i++)
                {
                    destPaths[i + (htoaToFile ? 1 : 0)] = Path.Combine(dir, _trackFilenames[i]);
                }
            }
            for (i = 0; i < destPaths.Length; i++)
            {
                for (j = 0; j < _sourcePaths.Count; j++)
                {
                    if (destPaths[i].ToLower() == _sourcePaths[j].ToLower())
                    {
                        throw new Exception("Source and destination audio file paths cannot be the same.");
                    }
                }
            }

            if (_writeOffset != 0)
            {
                int        absOffset = Math.Abs(_writeOffset);
                SourceInfo sourceInfo;

                sourceInfo.Path   = null;
                sourceInfo.Offset = 0;
                sourceInfo.Length = absOffset;

                if (_writeOffset < 0)
                {
                    _sources.Insert(0, sourceInfo);

                    int last = _sources.Count - 1;
                    while (absOffset >= _sources[last].Length)
                    {
                        absOffset -= _sources[last].Length;
                        _sources.RemoveAt(last--);
                    }
                    sourceInfo         = _sources[last];
                    sourceInfo.Length -= absOffset;
                    _sources[last]     = sourceInfo;
                }
                else
                {
                    _sources.Add(sourceInfo);

                    while (absOffset >= _sources[0].Length)
                    {
                        absOffset -= _sources[0].Length;
                        _sources.RemoveAt(0);
                    }
                    sourceInfo         = _sources[0];
                    sourceInfo.Offset += absOffset;
                    sourceInfo.Length -= absOffset;
                    _sources[0]        = sourceInfo;
                }

                _appliedWriteOffset = true;
            }

            destLengths = CalculateAudioFileLengths(style);

            iSource          = -1;
            iDest            = -1;
            samplesRemSource = 0;

            if (style == CUEStyle.SingleFile)
            {
                iDest++;
                audioDest = GetAudioDest(destPaths[iDest], destLengths[iDest]);
            }

            for (iTrack = 0; iTrack < TrackCount; iTrack++)
            {
                statusDel(String.Format("Writing track {0:00}...", iTrack + 1));

                track = _tracks[iTrack];

                if ((style == CUEStyle.GapsPrepended) || (style == CUEStyle.GapsLeftOut))
                {
                    if (audioDest != null)
                    {
                        audioDest.Close();
                    }
                    iDest++;
                    audioDest = GetAudioDest(destPaths[iDest], destLengths[iDest]);
                }

                for (iIndex = 0; iIndex <= track.LastIndex; iIndex++)
                {
                    if ((style == CUEStyle.GapsAppended) && (iIndex == 1))
                    {
                        if (audioDest != null)
                        {
                            audioDest.Close();
                        }
                        iDest++;
                        audioDest = GetAudioDest(destPaths[iDest], destLengths[iDest]);
                    }

                    samplesRemIndex = track.IndexLengths[iIndex] * 588;

                    if ((style == CUEStyle.GapsAppended) && (iIndex == 0) && (iTrack == 0))
                    {
                        discardOutput = !htoaToFile;
                        if (htoaToFile)
                        {
                            iDest++;
                            audioDest = GetAudioDest(destPaths[iDest], destLengths[iDest]);
                        }
                    }
                    else if ((style == CUEStyle.GapsLeftOut) && (iIndex == 0))
                    {
                        discardOutput = true;
                    }
                    else
                    {
                        discardOutput = false;
                    }

                    while (samplesRemIndex != 0)
                    {
                        if (samplesRemSource == 0)
                        {
                            if (audioSource != null)
                            {
                                audioSource.Close();
                            }
                            audioSource      = GetAudioSource(++iSource);
                            samplesRemSource = _sources[iSource].Length;
                        }

                        copyCount = Math.Min(Math.Min(samplesRemIndex, samplesRemSource), buffLen);

                        audioSource.Read(buff, copyCount);
                        if (!discardOutput)
                        {
                            audioDest.Write(buff, copyCount);
                        }

                        samplesRemIndex  -= copyCount;
                        samplesRemSource -= copyCount;

                        lock (this) {
                            if (_stop)
                            {
                                audioSource.Close();
                                try { audioDest.Close(); } catch {}
                                throw new StopException();
                            }
                        }
                    }
                }
            }

            if (audioSource != null)
            {
                audioSource.Close();
            }
            audioDest.Close();
        }
예제 #12
0
 public int Read(AudioBuffer buff, int maxLength)
 {
     buff.Prepare(this, maxLength);
     while (_samplePos >= nextPos)
     {
         currentSource++;
         if (currentSource >= cueSheet._sources.Count)
         {
             buff.Length = 0;
             return 0;
         }
         if (currentAudio != null)
             currentAudio.Close();
         currentAudio = cueSheet.GetAudioSource(currentSource, false);
         int offset = (int)(_samplePos - nextPos);
         if (offset != 0)
             currentAudio.Position += offset;
         nextPos += cueSheet._sources[currentSource].Length;
     }
     int count = (int)(nextPos - _samplePos);
     if (maxLength >= 0)
         count = Math.Min(count, maxLength);
     count = currentAudio.Read(buff, count);
     _samplePos += count;
     return count;
 }