443 lines
15 KiB
C#
443 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace m3uTool
|
|
{
|
|
/// <summary>
|
|
/// LAME 32bits version 3.97 (beta 1, Oct 16 2005) (http://www.mp3dev.org/)
|
|
///
|
|
/// usage: lame [options] <infile> [outfile]
|
|
///
|
|
/// <infile> and/or <outfile> 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 <arg> scale input (multiply PCM data) by <arg>
|
|
/// --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>
|
|
/// --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>
|
|
/// --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 <file1> <file2> <...>
|
|
/// gapless encoding for a set of contiguous files
|
|
/// --nogapout <dir>
|
|
/// 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 <mode> (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 <arg> choose bitrate to achive a compression ratio of <arg>
|
|
/// --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 <arg>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 <arg> <arg> = 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 <bitrate> set the bitrate in kbps, default 128 kbps
|
|
/// --cbr enforce use of constant bitrate
|
|
///
|
|
/// ABR options:
|
|
/// --abr <bitrate> 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 <bitrate> specify minimum allowed bitrate, default 32 kbps
|
|
/// -B <bitrate> 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 <arg> 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 <emp> 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 <freq> frequency(kHz), lowpass filter cutoff above freq
|
|
/// --lowpass-width <freq> frequency(kHz) - default 15% of lowpass freq
|
|
/// --highpass <freq> frequency(kHz), highpass filter cutoff below freq
|
|
/// --highpass-width <freq> frequency(kHz) - default 15% of highpass freq
|
|
/// --resample <sfreq> sampling frequency of output file(kHz)- default=automatic
|
|
///
|
|
///
|
|
/// ID3 tag options:
|
|
/// --tt <title> audio/song title (max 30 chars for version 1 tag)
|
|
/// --ta <artist> audio/song artist (max 30 chars for version 1 tag)
|
|
/// --tl <album> audio/song album (max 30 chars for version 1 tag)
|
|
/// --ty <year> audio/song year of issue (1 to 9999)
|
|
/// --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)
|
|
/// --tn <track> audio/song track number (1 to 255, creates v1.1 tag)
|
|
/// --tg <genre> audio/song genre (name or number in list)
|
|
/// --add-id3v2 force addition of version 2 tag
|
|
/// --id3v1-only add only a version 1 tag
|
|
/// --id3v2-only add only a version 2 tag
|
|
/// --space-id3v1 pad version 1 tag with spaces instead of nulls
|
|
/// --pad-id3v2 pad version 2 tag with extra 128 bytes
|
|
/// --genre-list print alphabetically sorted ID3 genre list and exit
|
|
/// --ignore-tag-errors ignore errors in values passed for tags
|
|
///
|
|
/// Note: A version 2 tag will NOT be added unless one of the input fields
|
|
/// won't fit in a version 1 tag (e.g. the title string is longer than 30
|
|
/// characters), or the '--add-id3v2' or '--id3v2-only' options are used,
|
|
/// or output is redirected to stdout.
|
|
///
|
|
///
|
|
/// MS-Windows-specific options:
|
|
/// --priority <type> sets the process priority:
|
|
/// 0,1 = Low priority (IDLE_PRIORITY_CLASS)
|
|
/// 2 = normal priority (NORMAL_PRIORITY_CLASS, defau
|
|
/// lt)
|
|
/// 3,4 = High priority (HIGH_PRIORITY_CLASS))
|
|
/// Note: Calling '--priority' without a parameter will select priority 0.
|
|
///
|
|
///
|
|
/// Platform specific:
|
|
/// --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse
|
|
///
|
|
///
|
|
///
|
|
/// MPEG-1 layer III sample frequencies (kHz): 32 48 44.1
|
|
/// bitrates (kbps): 32 40 48 56 64 80 96 112 128 160 192 224 256 320
|
|
///
|
|
/// MPEG-2 layer III sample frequencies (kHz): 16 24 22.05
|
|
/// bitrates (kbps): 8 16 24 32 40 48 56 64 80 96 112 128 144 160
|
|
///
|
|
/// MPEG-2.5 layer III sample frequencies (kHz): 8 12 11.025
|
|
/// bitrates (kbps): 8 16 24 32 40 48 56 64 80 96 112 128 144 160
|
|
/// </summary>
|
|
public class Mp3EncodingOptions : ProcessArguments
|
|
{
|
|
#region Private variables
|
|
/// <summary>
|
|
/// Input filename. Can be "-", which means stdin.
|
|
/// </summary>
|
|
private string mInfile = null;
|
|
|
|
/// <summary>
|
|
/// Output filename. Can be "-", which means stdout.
|
|
/// </summary>
|
|
private string mOutfile = null;
|
|
|
|
/// <summary>
|
|
/// input is raw pcm (-r)
|
|
/// </summary>
|
|
private bool mRawPCMInputMode = false;
|
|
|
|
/// <summary>
|
|
/// force byte-swapping of input (-x)
|
|
/// </summary>
|
|
private bool mForceByteSwappingOfInput = false;
|
|
|
|
/// <summary>
|
|
/// sampling frequency of input file (kHz) - default 44.1 kHz (-s sfreq)
|
|
/// </summary>
|
|
private SampleRateFrequency mRawPCMInputSampleSize = SampleRateFrequency.Hz_44100;
|
|
|
|
/// <summary>
|
|
/// input bit width is w (default 16) (--bitwidth w)
|
|
/// </summary>
|
|
private int mRawPCMInputSampleRate = 16;
|
|
|
|
/// <summary>
|
|
/// input file is a MPEG Layer III file (--mp3input)
|
|
/// </summary>
|
|
private bool mMp3Input = false;
|
|
|
|
/// <summary>
|
|
/// downmix from stereo to mono file for mono encoding (-a)
|
|
/// </summary>
|
|
private bool mMonoDownmixing = false;
|
|
|
|
/// <summary>
|
|
/// (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono (-m)
|
|
/// </summary>
|
|
private ChannelMode mChannelMode = ChannelMode.JointStereo;
|
|
|
|
/// <summary>
|
|
/// produce a free format bitstream (--freeformat)
|
|
/// </summary>
|
|
private bool mFreeFormat = false;
|
|
|
|
/// <summary>
|
|
/// input=mp3 file, output=wav (--decode)
|
|
/// </summary>
|
|
private bool mDecodeWav = false;
|
|
|
|
/// <summary>
|
|
/// disable writing wav header when using --decode (-t)
|
|
/// </summary>
|
|
private bool mDisableWavHeader = false;
|
|
|
|
/// <summary>
|
|
/// Set the bitrate in kbps, default 128 kbps -b <bitrate>
|
|
/// </summary>
|
|
private BitRate mBitRate = BitRate.KBPS_0;
|
|
|
|
#endregion
|
|
|
|
#region Public properties
|
|
/// <summary>
|
|
/// Input filename. Can be "-", which means stdin.
|
|
/// </summary>
|
|
public string Infile
|
|
{
|
|
get { return mInfile; }
|
|
set { mInfile = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Output filename. Can be "-", which means stdout.
|
|
/// </summary>
|
|
public string Outfile
|
|
{
|
|
get { return mOutfile; }
|
|
set { mOutfile = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// input is raw pcm (-r)
|
|
/// </summary>
|
|
public bool RawPCMInputMode
|
|
{
|
|
get { return mRawPCMInputMode; }
|
|
set
|
|
{
|
|
mRawPCMInputMode = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// force byte-swapping of input (-x)
|
|
/// </summary>
|
|
public bool ForceByteSwappingOfInput
|
|
{
|
|
get { return mForceByteSwappingOfInput; }
|
|
set
|
|
{
|
|
mForceByteSwappingOfInput = value;
|
|
mRawPCMInputMode = true;
|
|
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// sampling frequency of input file (kHz) - default 44.1 kHz (-s sfreq)
|
|
/// </summary>
|
|
public SampleRateFrequency RawPCMInputSampleSize
|
|
{
|
|
get { return mRawPCMInputSampleSize; }
|
|
set
|
|
{
|
|
mRawPCMInputSampleSize = value;
|
|
mRawPCMInputMode = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// input bit width is w (default 16) (--bitwidth w)
|
|
/// </summary>
|
|
public int RawPCMInputSampleRate
|
|
{
|
|
get { return mRawPCMInputSampleRate; }
|
|
set
|
|
{
|
|
mRawPCMInputSampleRate = value;
|
|
mRawPCMInputMode = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// input file is a MPEG Layer III file (--mp3input)
|
|
/// </summary>
|
|
public bool Mp3Input
|
|
{
|
|
get { return mMp3Input; }
|
|
set
|
|
{
|
|
mMp3Input = value;
|
|
if (mMp3Input)
|
|
mRawPCMInputMode = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// downmix from stereo to mono file for mono encoding (-a)
|
|
/// </summary>
|
|
public bool MonoDownmixing
|
|
{
|
|
get { return mMonoDownmixing; }
|
|
set { mMonoDownmixing = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono (-m)
|
|
/// </summary>
|
|
public ChannelMode ChannelMode
|
|
{
|
|
get { return mChannelMode; }
|
|
set { mChannelMode = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// produce a free format bitstream (--freeformat)
|
|
/// </summary>
|
|
public bool Freeformat
|
|
{
|
|
get { return mFreeFormat; }
|
|
set { mFreeFormat = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// input=mp3 file, output=wav (--decode)
|
|
/// </summary>
|
|
public bool DecodeWav
|
|
{
|
|
get { return mDecodeWav; }
|
|
set { mDecodeWav = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// disable writing wav header when using --decode (-t)
|
|
/// </summary>
|
|
public bool DisableWavHeader
|
|
{
|
|
get { return mDisableWavHeader; }
|
|
set
|
|
{
|
|
mDisableWavHeader = value;
|
|
if (mDisableWavHeader)
|
|
DecodeWav = true;
|
|
}
|
|
}
|
|
|
|
public BitRate BitRate
|
|
{
|
|
get { return mBitRate; }
|
|
set
|
|
{
|
|
mBitRate = value;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Gets a string representing the command line arguments specified by the properties in the object.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string GetCommandLineArguments()
|
|
{
|
|
StringBuilder 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();
|
|
}
|
|
}
|
|
}
|