using System.Text;
namespace m3uTool
{
///
/// LAME 32bits version 3.97 (beta 1, Oct 16 2005) (http://www.mp3dev.org/)
///
/// usage: lame [options] [outfile]
///
/// and/or can be "-", which means stdin/stdout.
///
/// RECOMMENDED:
/// lame -V2 input.wav output.mp3
///
/// OPTIONS:
/// Input options:
/// -r input is raw pcm
/// -x force byte-swapping of input
/// -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz
/// --bitwidth w input bit width is w (default 16)
/// --scale scale input (multiply PCM data) by
/// --scale-l scale channel 0 (left) input (multiply PCM data) by
/// --scale-r scale channel 1 (right) input (multiply PCM data) by
/// --mp1input input file is a MPEG Layer I file
/// --mp2input input file is a MPEG Layer II file
/// --mp3input input file is a MPEG Layer III file
/// --nogap <...>
/// gapless encoding for a set of contiguous files
/// --nogapout
/// output dir for gapless encoding (must precede --nogap)
/// --nogaptags allow the use of VBR tags in gapless encoding
///
/// Operational options:
/// -a downmix from stereo to mono file for mono encoding
/// -m (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono
/// default is (j) or (s) depending on bitrate
/// joint = joins the best possible of MS and LR stereo
/// simple = force LR stereo on all frames
/// force = force MS stereo on all frames.
/// --preset type type must be "medium", "standard", "extreme", "insane",
/// or a value for an average desired bitrate and depending
/// on the value specified, appropriate quality settings will
/// be used.
/// "--preset help" gives more info on these
/// --comp choose bitrate to achive a compression ratio of
/// --replaygain-fast compute RG fast but slightly inaccurately (default)
/// --replaygain-accurate compute RG more accurately and find the peak sample
/// --noreplaygain disable ReplayGain analysis
/// --clipdetect enable --replaygain-accurate and print a message whether
/// clipping occurs and how far the waveform is from full scale
/// --freeformat produce a free format bitstream
/// --decode input=mp3 file, output=wav
/// -t disable writing wav header when using --decode
///
///
/// Verbosity:
/// --disptime print progress report every arg seconds
/// -S don't print progress report, VBR histograms
/// --nohist disable VBR histogram display
/// --silent don't print anything on screen
/// --quiet don't print anything on screen
/// --brief print more useful information
/// --verbose print a lot of useful information
///
/// Noise shaping & psycho acoustic algorithms:
/// -q = 0...9. Default -q 5
/// -q 0: Highest quality, very slow
/// -q 9: Poor quality, but fast
/// -h Same as -q 2. Recommended.
/// -f Same as -q 7. Fast, ok quality
///
///
/// CBR (constant bitrate, the default) options:
/// -b set the bitrate in kbps, default 128 kbps
/// --cbr enforce use of constant bitrate
///
/// ABR options:
/// --abr specify average bitrate desired (instead of quality)
///
/// VBR options:
/// -v use variable bitrate (VBR) (--vbr-old)
/// --vbr-old use old variable bitrate (VBR) routine
/// --vbr-new use new variable bitrate (VBR) routine
/// -V n quality setting for VBR. default n=4
/// 0=high quality,bigger files. 9=smaller files
/// -b specify minimum allowed bitrate, default 32 kbps
/// -B specify maximum allowed bitrate, default 320 kbps
/// -F strictly enforce the -b option, for use with players that
/// do not support low bitrate mp3
/// -t disable writing LAME Tag
/// -T enable and force writing LAME Tag
///
///
/// PSY related:
/// --short use short blocks when appropriate
/// --noshort do not use short blocks
/// --allshort use only short blocks
/// --notemp disable temporal masking effect
/// --nssafejoint M/S switching criterion
/// --nsmsfix M/S switching tuning [effective 0-3.5]
/// --interch x adjust inter-channel masking ratio
/// --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)
/// --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)
/// --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)
/// --ns-sfb21 x change ns-treble by x dB for sfb21
///
///
/// experimental switches:
/// -X n[,m] selects between different noise measurements
/// n for long block, m for short. if m is omitted, m = n
/// -Y lets LAME ignore noise in sfb21, like in CBR
/// -Z [n] currently no effects
///
///
/// MP3 header/stream options:
/// -e de-emphasis n/5/c (obsolete)
/// -c mark as copyright
/// -o mark as non-original
/// -p error protection. adds 16 bit checksum to every frame
/// (the checksum is computed correctly)
/// --nores disable the bit reservoir
/// --strictly-enforce-ISO comply as much as possible to ISO MPEG spec
///
/// Filter options:
/// -k keep ALL frequencies (disables all filters),
/// Can cause ringing and twinkling
/// --lowpass frequency(kHz), lowpass filter cutoff above freq
/// --lowpass-width frequency(kHz) - default 15% of lowpass freq
/// --highpass frequency(kHz), highpass filter cutoff below freq
/// --highpass-width frequency(kHz) - default 15% of highpass freq
/// --resample sampling frequency of output file(kHz)- default=automatic
///
///
/// ID3 tag options:
/// --tt audio/song title (max 30 chars for version 1 tag)
/// --ta audio/song artist (max 30 chars for version 1 tag)
/// --tl audio/song album (max 30 chars for version 1 tag)
/// --ty audio/song year of issue (1 to 9999)
/// --tc user-defined text (max 30 chars for v1 tag, 28 for v1.1)
/// --tn
public class Mp3EncodingOptions : ProcessArguments
{
#region Private variables
///
/// Set the bitrate in kbps, default 128 kbps -b
///
private BitRate mBitRate = BitRate.KBPS_0;
///
/// (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono (-m)
///
private ChannelMode mChannelMode = ChannelMode.JointStereo;
///
/// input=mp3 file, output=wav (--decode)
///
private bool mDecodeWav;
///
/// disable writing wav header when using --decode (-t)
///
private bool mDisableWavHeader;
///
/// force byte-swapping of input (-x)
///
private bool mForceByteSwappingOfInput;
///
/// produce a free format bitstream (--freeformat)
///
private bool mFreeFormat;
///
/// Input filename. Can be "-", which means stdin.
///
private string mInfile;
///
/// downmix from stereo to mono file for mono encoding (-a)
///
private bool mMonoDownmixing;
///
/// input file is a MPEG Layer III file (--mp3input)
///
private bool mMp3Input;
///
/// Output filename. Can be "-", which means stdout.
///
private string mOutfile;
///
/// input is raw pcm (-r)
///
private bool mRawPCMInputMode;
///
/// input bit width is w (default 16) (--bitwidth w)
///
private int mRawPCMInputSampleRate = 16;
///
/// sampling frequency of input file (kHz) - default 44.1 kHz (-s sfreq)
///
private SampleRateFrequency mRawPCMInputSampleSize = SampleRateFrequency.Hz_44100;
#endregion
#region Public properties
///
/// Input filename. Can be "-", which means stdin.
///
public string Infile
{
get { return mInfile; }
set { mInfile = value; }
}
///
/// Output filename. Can be "-", which means stdout.
///
public string Outfile
{
get { return mOutfile; }
set { mOutfile = value; }
}
///
/// input is raw pcm (-r)
///
public bool RawPCMInputMode
{
get { return mRawPCMInputMode; }
set { mRawPCMInputMode = value; }
}
///
/// force byte-swapping of input (-x)
///
public bool ForceByteSwappingOfInput
{
get { return mForceByteSwappingOfInput; }
set
{
mForceByteSwappingOfInput = value;
mRawPCMInputMode = true;
}
}
///
/// sampling frequency of input file (kHz) - default 44.1 kHz (-s sfreq)
///
public SampleRateFrequency RawPCMInputSampleSize
{
get { return mRawPCMInputSampleSize; }
set
{
mRawPCMInputSampleSize = value;
mRawPCMInputMode = true;
}
}
///
/// input bit width is w (default 16) (--bitwidth w)
///
public int RawPCMInputSampleRate
{
get { return mRawPCMInputSampleRate; }
set
{
mRawPCMInputSampleRate = value;
mRawPCMInputMode = true;
}
}
///
/// input file is a MPEG Layer III file (--mp3input)
///
public bool Mp3Input
{
get { return mMp3Input; }
set
{
mMp3Input = value;
if (mMp3Input)
mRawPCMInputMode = false;
}
}
///
/// downmix from stereo to mono file for mono encoding (-a)
///
public bool MonoDownmixing
{
get { return mMonoDownmixing; }
set { mMonoDownmixing = value; }
}
///
/// (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono (-m)
///
public ChannelMode ChannelMode
{
get { return mChannelMode; }
set { mChannelMode = value; }
}
///
/// produce a free format bitstream (--freeformat)
///
public bool Freeformat
{
get { return mFreeFormat; }
set { mFreeFormat = value; }
}
///
/// input=mp3 file, output=wav (--decode)
///
public bool DecodeWav
{
get { return mDecodeWav; }
set { mDecodeWav = value; }
}
///
/// disable writing wav header when using --decode (-t)
///
public bool DisableWavHeader
{
get { return mDisableWavHeader; }
set
{
mDisableWavHeader = value;
if (mDisableWavHeader)
DecodeWav = true;
}
}
public BitRate BitRate
{
get { return mBitRate; }
set { mBitRate = value; }
}
#endregion
///
/// Gets a string representing the command line arguments specified by the properties in the object.
///
///
public override string GetCommandLineArguments()
{
var stringBuilder = new StringBuilder();
if (mRawPCMInputMode)
{
stringBuilder.Append(" -r");
if (mForceByteSwappingOfInput)
stringBuilder.Append(" -x");
if (mRawPCMInputSampleSize != SampleRateFrequency.Hz_44100)
stringBuilder.Append(" -s " +
SampleRateFrequencyUtility.GetSampleRateFrequencyInt(mRawPCMInputSampleSize));
if (mRawPCMInputSampleRate != 16)
stringBuilder.Append(" --bandwidth " + mRawPCMInputSampleRate);
}
if (mMp3Input)
stringBuilder.Append(" --mp3input");
if (mMonoDownmixing)
stringBuilder.Append(" -a");
if (mChannelMode != ChannelMode.JointStereo)
stringBuilder.Append(" -m " + ChannelModeUtility.GetChannelModeChar(mChannelMode));
if (mFreeFormat)
{
stringBuilder.Append(" --freeformat");
stringBuilder.Append(" -b " + BitRateFrequencyUtility.GetBitRateInt(BitRate));
}
if (mDecodeWav)
{
stringBuilder.Append(" --decode");
if (mDisableWavHeader)
stringBuilder.Append(" -t");
}
if (!string.IsNullOrEmpty(mInfile))
stringBuilder.Append(" " + GetQuotedCommandLineArgument(mInfile));
if (!string.IsNullOrEmpty(mOutfile))
stringBuilder.Append(" " + (mOutfile));
return stringBuilder.ToString();
}
}
}