mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
138 lines
4.9 KiB
C#
138 lines
4.9 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
|
|
namespace CUETools.Codecs.CommandLine
|
|
{
|
|
public class AudioEncoder : IAudioDest
|
|
{
|
|
string _path;
|
|
Process _encoderProcess;
|
|
WAV.AudioEncoder wrt;
|
|
CyclicBuffer outputBuffer = null;
|
|
bool useTempFile = false;
|
|
string tempFile = null;
|
|
long _finalSampleCount = -1;
|
|
bool closed = false;
|
|
|
|
public long Position
|
|
{
|
|
get
|
|
{
|
|
return wrt.Position;
|
|
}
|
|
}
|
|
|
|
public long FinalSampleCount
|
|
{
|
|
set { _finalSampleCount = wrt.FinalSampleCount = value; }
|
|
}
|
|
|
|
// !!!! Must not start the process in constructor, so that we can set CompressionLevel via Settings!
|
|
private EncoderSettings m_settings;
|
|
public IAudioEncoderSettings Settings => m_settings;
|
|
|
|
public string Path { get { return _path; } }
|
|
|
|
public AudioEncoder(EncoderSettings settings, string path, Stream IO = null)
|
|
{
|
|
m_settings = settings;
|
|
_path = path;
|
|
useTempFile = m_settings.Parameters.Contains("%I");
|
|
tempFile = path + ".tmp.wav";
|
|
|
|
_encoderProcess = new Process();
|
|
_encoderProcess.StartInfo.FileName = m_settings.Path;
|
|
_encoderProcess.StartInfo.Arguments = m_settings.Parameters.Replace("%O", "\"" + path + "\"").Replace("%M", m_settings.EncoderMode).Replace("%P", m_settings.Padding.ToString()).Replace("%I", "\"" + tempFile + "\"");
|
|
_encoderProcess.StartInfo.CreateNoWindow = true;
|
|
if (!useTempFile)
|
|
_encoderProcess.StartInfo.RedirectStandardInput = true;
|
|
_encoderProcess.StartInfo.UseShellExecute = false;
|
|
if (!m_settings.Parameters.Contains("%O"))
|
|
_encoderProcess.StartInfo.RedirectStandardOutput = true;
|
|
if (useTempFile)
|
|
{
|
|
wrt = new WAV.AudioEncoder(new WAV.EncoderSettings(settings.PCM), tempFile);
|
|
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(m_settings.Path + ": " + (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 WAV.AudioEncoder(new WAV.EncoderSettings(settings.PCM), path, inputStream);
|
|
}
|
|
|
|
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 void Delete()
|
|
{
|
|
Close();
|
|
File.Delete(_path);
|
|
}
|
|
|
|
public void Write(AudioBuffer buff)
|
|
{
|
|
try
|
|
{
|
|
wrt.Write(buff);
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
if (_encoderProcess.HasExited)
|
|
throw new IOException(string.Format("{0} has exited prematurely with code {1}", m_settings.Path, _encoderProcess.ExitCode), ex);
|
|
else
|
|
throw ex;
|
|
}
|
|
//_sampleLen += sampleCount;
|
|
}
|
|
}
|
|
}
|