Beispiel #1
0
        /// <summary>
        /// Spawns a new SoX process using the specified options in this instance.
        /// </summary>
        /// <param name="inputFiles">Audio files to be processed.</param>
        /// <param name="outputFile">Output file.</param>
        /// <param name="combination">How to combine the input files.</param>
        public void Process(InputFile[] inputFiles, string outputFile, CombinationType combination)
        {
            soxProcess_ = SoxProcess.Create(Path);

            lastError_       = null;
            lastErrorSource_ = null;

            try
            {
                soxProcess_.ErrorDataReceived  += OnSoxProcessOutputReceived;
                soxProcess_.OutputDataReceived += OnSoxProcessOutputReceived;

                List <string> args = new List <string>();

                // Global options.

                if (Buffer.HasValue)
                {
                    args.Add("--buffer " + Buffer.Value);
                }

                if (Multithreaded.HasValue)
                {
                    args.Add(Multithreaded.Value ? "--multi-threaded" : "--single-threaded");
                }

                if (!String.IsNullOrEmpty(CustomArgs))
                {
                    args.Add(CustomArgs);
                }

                switch (combination)
                {
                case CombinationType.Concatenate:
                    args.Add("--combine concatenate");
                    break;

                case CombinationType.Merge:
                    args.Add("--combine merge");
                    break;

                case CombinationType.Mix:
                    args.Add("--combine mix");
                    break;

                case CombinationType.MixPower:
                    args.Add("--combine mix-power");
                    break;

                case CombinationType.Multiply:
                    args.Add("--combine multiply");
                    break;

                case CombinationType.Sequence:
                    args.Add("--combine sequence");
                    break;

                default:
                    // Do nothing.
                    break;
                }

                args.Add("--show-progress");

                // Input options and files.

                if ((inputFiles != null) && (inputFiles.Length > 0))
                {
                    foreach (InputFile inputFile in inputFiles)
                    {
                        args.Add(inputFile.ToString());
                    }
                }
                else
                {
                    args.Add("--null");
                }

                // Output options and file.

                args.Add(Output.ToString());

                if (!string.IsNullOrEmpty(outputFile))
                {
                    if (outputFile.Contains(" "))
                    {
                        if ((Environment.OSVersion.Platform == PlatformID.Win32NT) ||
                            (Environment.OSVersion.Platform == PlatformID.Win32Windows) ||
                            (Environment.OSVersion.Platform == PlatformID.Win32S) ||
                            (Environment.OSVersion.Platform == PlatformID.WinCE))
                        {
                            args.Add("\"" + outputFile + "\"");
                        }
                        else
                        {
                            args.Add("'" + outputFile + "'");
                        }
                    }
                    else
                    {
                        args.Add(outputFile);
                    }
                }
                else
                {
                    args.Add("--null");
                }

                // Effects.
                foreach (IBaseEffect effect in Effects)
                {
                    args.Add(effect.ToString());
                }

                // Custom effects.
                args.Add(CustomEffects);

                soxProcess_.StartInfo.Arguments = String.Join(" ", args);
                LastCommand = Path + " " + soxProcess_.StartInfo.Arguments;

                try
                {
                    soxProcess_.Start();
                    soxProcess_.BeginOutputReadLine();
                    soxProcess_.BeginErrorReadLine();
                    soxProcess_.WaitForExit();
                }

                catch (Exception ex)
                {
                    throw new SoxException("Cannot spawn SoX process", ex);
                }

                if (!String.IsNullOrEmpty(lastError_))
                {
                    if (String.IsNullOrEmpty(lastErrorSource_))
                    {
                        throw new SoxException(lastError_);
                    }

                    switch (lastErrorSource_)
                    {
                    case "getopt":
                        throw new SoxException("Invalid parameter: " + lastError_);

                    default:
                        throw new SoxException("Processing error: " + lastError_);
                    }
                }
            }

            finally
            {
                if (soxProcess_ != null)
                {
                    soxProcess_.Dispose();
                    soxProcess_ = null;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Create a new <see cref="T:SoxSharp.SoxProcess"/> instance prepared to run SoX.
        /// </summary>
        /// <returns>The SoX process instance.</returns>
        public static SoxProcess Create(string path)
        {
            string soxExecutable;

            if (String.IsNullOrEmpty(path))
            {
                throw new SoxException("SoX path not specified");
            }

            if (File.Exists(path))
            {
                soxExecutable = path;
            }
            else
            {
                throw new FileNotFoundException("SoX executable not found");
            }

            using (SoxProcess versionCheck = new SoxProcess())
            {
                versionCheck.StartInfo.RedirectStandardOutput = true;
                versionCheck.StartInfo.FileName  = soxExecutable;
                versionCheck.StartInfo.Arguments = "--version";
                versionCheck.Start();

                string output = versionCheck.StandardOutput.ReadLine();

                if (versionCheck.WaitForExit(1000) == false)
                {
                    throw new TimeoutException("Cannot obtain SoX version: response timeout");
                }

                Match versionMatch = new Regex(@"\sSoX v(\d{1,2})\.(\d{1,2})\.(\d{1,2})").Match(output);

                if (!versionMatch.Success)
                {
                    throw new SoxException("Cannot obtain SoX version: unable to fetch info from Sox");
                }

                try
                {
                    int majorVersion = Int32.Parse(versionMatch.Groups[1].Value);
                    int minorVersion = Int32.Parse(versionMatch.Groups[2].Value);
                    int fixVersion   = Int32.Parse(versionMatch.Groups[3].Value);

                    if ((majorVersion < 14) ||
                        ((majorVersion == 14) && (minorVersion < 3)) ||
                        ((majorVersion == 14) && (minorVersion == 3) && (fixVersion < 1)))
                    {
                        throw new SoxException(versionMatch.Groups[0] + " not currently supported");
                    }
                }

                catch (Exception ex)
                {
                    throw new SoxException("Cannot obtain SoX version", ex);
                }
            }

            SoxProcess soxProc = new SoxProcess();

            soxProc.StartInfo.FileName         = soxExecutable;
            soxProc.StartInfo.WorkingDirectory = Environment.CurrentDirectory;

            string soxPath = Path.GetDirectoryName(soxExecutable);

            if (!String.IsNullOrEmpty(soxPath))
            {
                string pathEnv = Environment.GetEnvironmentVariable("PATH");
                pathEnv += Path.PathSeparator + soxPath;
                soxProc.StartInfo.EnvironmentVariables["PATH"] = pathEnv;
            }

            return(soxProc);
        }
Beispiel #3
0
        /// <summary>
        /// Gets information about the given file.
        /// </summary>
        /// <returns>File information as a <see cref="SoxSharp.AudioInfo"/> instance.</returns>
        /// <param name="inputFile">Input file.</param>
        public AudioInfo GetInfo(string inputFile)
        {
            if (!File.Exists(inputFile))
            {
                throw new FileNotFoundException("File not found: " + inputFile);
            }

            soxProcess_ = SoxProcess.Create(Path);

            lastError_       = null;
            lastErrorSource_ = null;

            try
            {
                soxProcess_.StartInfo.RedirectStandardOutput = true;

                if (inputFile.Contains(" "))
                {
                    if ((Environment.OSVersion.Platform == PlatformID.Win32NT) ||
                        (Environment.OSVersion.Platform == PlatformID.Win32Windows) ||
                        (Environment.OSVersion.Platform == PlatformID.Win32S) ||
                        (Environment.OSVersion.Platform == PlatformID.WinCE))
                    {
                        soxProcess_.StartInfo.Arguments = "--info \"" + inputFile + "\"";
                    }
                    else
                    {
                        soxProcess_.StartInfo.Arguments = "--info '" + inputFile + "'";
                    }
                }
                else
                {
                    soxProcess_.StartInfo.Arguments = "--info " + inputFile;
                }

                soxProcess_.Start();

                LastCommand = Path + " " + soxProcess_.StartInfo.Arguments;

                string output = soxProcess_.StandardOutput.ReadToEnd();

                if (String.IsNullOrEmpty(output))
                {
                    output = soxProcess_.StandardError.ReadToEnd();
                }

                if (soxProcess_.WaitForExit(10000) == false)
                {
                    throw new TimeoutException("SoX response timeout");
                }

                CheckForLogMessage(output);

                if (output != null)
                {
                    Match matchInfo = SoxProcess.InfoRegex.Match(output);

                    if (matchInfo.Success)
                    {
                        try
                        {
                            UInt16   channels   = Convert.ToUInt16(double.Parse(matchInfo.Groups[1].Value, CultureInfo.InvariantCulture));
                            UInt32   sampleRate = Convert.ToUInt32(double.Parse(matchInfo.Groups[2].Value, CultureInfo.InvariantCulture));
                            UInt16   sampleSize = Convert.ToUInt16(double.Parse(new string(matchInfo.Groups[3].Value.Where(Char.IsDigit).ToArray()), CultureInfo.InvariantCulture));
                            TimeSpan duration   = Utils.TimeSpanFromString(matchInfo.Groups[4].Value);
                            UInt64   size       = FormattedSize.ToUInt64(matchInfo.Groups[5].Value);
                            UInt32   bitRate    = FormattedSize.ToUInt32(matchInfo.Groups[6].Value);
                            string   encoding   = matchInfo.Groups[7].Value;

                            return(new AudioInfo(channels, sampleRate, sampleSize, duration, size, bitRate, encoding));
                        }

                        catch (Exception ex)
                        {
                            throw new SoxUnexpectedOutputException(output, ex);
                        }
                    }
                }

                throw new SoxUnexpectedOutputException(output != null ? output : "No output received");
            }

            finally
            {
                if (soxProcess_ != null)
                {
                    soxProcess_.Dispose();
                    soxProcess_ = null;
                }
            }
        }