/// <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; } } }
/// <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); }
/// <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; } } }