mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
CTDB: send drivename separately from userAgent
CTDB: include OS version in userAgent CTDB: send rip quality LAME: fix VBR options CTDB: optimize chienSearch
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace CUETools.Codecs.LAME
|
||||
|
||||
protected virtual BE_CONFIG MakeConfig()
|
||||
{
|
||||
return new BE_CONFIG(_pcm, 128);
|
||||
return new BE_CONFIG(_pcm);
|
||||
}
|
||||
|
||||
private bool inited = false;
|
||||
@@ -121,7 +121,7 @@ namespace CUETools.Codecs.LAME
|
||||
throw new ApplicationException(string.Format("Lame_encDll.beInitStream failed with the error code {0}", LameResult));
|
||||
|
||||
m_InBuffer = new byte[m_InputSamples * 2]; //Input buffer is expected as short[]
|
||||
m_OutBuffer = new byte[m_OutBufferSize];
|
||||
m_OutBuffer = new byte[Math.Max(65536, m_OutBufferSize)];
|
||||
|
||||
if (_IO == null)
|
||||
_IO = new FileStream(_path, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||
@@ -129,7 +129,7 @@ namespace CUETools.Codecs.LAME
|
||||
inited = true;
|
||||
}
|
||||
|
||||
public void Write(AudioBuffer buff)
|
||||
public unsafe void Write(AudioBuffer buff)
|
||||
{
|
||||
buff.Prepare(this);
|
||||
|
||||
@@ -142,60 +142,76 @@ namespace CUETools.Codecs.LAME
|
||||
int ToCopy = 0;
|
||||
uint EncodedSize = 0;
|
||||
uint LameResult;
|
||||
while (count > 0)
|
||||
uint outBufferIndex = 0;
|
||||
fixed (byte* pBuffer = buffer, pOutBuffer = m_OutBuffer)
|
||||
{
|
||||
if (m_InBufferPos > 0)
|
||||
while (count > 0)
|
||||
{
|
||||
ToCopy = Math.Min(count, m_InBuffer.Length - m_InBufferPos);
|
||||
Buffer.BlockCopy(buffer, index, m_InBuffer, m_InBufferPos, ToCopy);
|
||||
m_InBufferPos += ToCopy;
|
||||
index += ToCopy;
|
||||
count -= ToCopy;
|
||||
if (m_InBufferPos >= m_InBuffer.Length)
|
||||
if (m_InBufferPos > 0)
|
||||
{
|
||||
m_InBufferPos = 0;
|
||||
if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, m_OutBuffer, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
|
||||
ToCopy = Math.Min(count, m_InBuffer.Length - m_InBufferPos);
|
||||
Buffer.BlockCopy(buffer, index, m_InBuffer, m_InBufferPos, ToCopy);
|
||||
m_InBufferPos += ToCopy;
|
||||
index += ToCopy;
|
||||
count -= ToCopy;
|
||||
if (m_InBufferPos >= m_InBuffer.Length)
|
||||
{
|
||||
if (EncodedSize > 0)
|
||||
m_InBufferPos = 0;
|
||||
if (outBufferIndex > 0)
|
||||
{
|
||||
_IO.Write(m_OutBuffer, 0, (int)EncodedSize);
|
||||
bytesWritten += EncodedSize;
|
||||
_IO.Write(m_OutBuffer, 0, (int)outBufferIndex);
|
||||
bytesWritten += outBufferIndex;
|
||||
outBufferIndex = 0;
|
||||
}
|
||||
|
||||
if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, m_OutBuffer, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
|
||||
{
|
||||
outBufferIndex += EncodedSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count >= m_InBuffer.Length)
|
||||
{
|
||||
if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, buffer, index, (uint)m_InBuffer.Length, m_OutBuffer, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
|
||||
{
|
||||
if (EncodedSize > 0)
|
||||
{
|
||||
_IO.Write(m_OutBuffer, 0, (int)EncodedSize);
|
||||
bytesWritten += EncodedSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult));
|
||||
}
|
||||
count -= m_InBuffer.Length;
|
||||
index += m_InBuffer.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer.BlockCopy(buffer, index, m_InBuffer, 0, count);
|
||||
m_InBufferPos = count;
|
||||
index += count;
|
||||
count = 0;
|
||||
if (count >= m_InBuffer.Length)
|
||||
{
|
||||
if (outBufferIndex + m_OutBufferSize > m_OutBuffer.Length)
|
||||
{
|
||||
_IO.Write(m_OutBuffer, 0, (int)outBufferIndex);
|
||||
bytesWritten += outBufferIndex;
|
||||
outBufferIndex = 0;
|
||||
}
|
||||
|
||||
if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, pBuffer + index, (uint)m_InBuffer.Length, pOutBuffer + outBufferIndex, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
|
||||
{
|
||||
outBufferIndex += EncodedSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException(string.Format("Lame_encDll.EncodeChunk failed with the error code {0}", LameResult));
|
||||
}
|
||||
count -= m_InBuffer.Length;
|
||||
index += m_InBuffer.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer.BlockCopy(buffer, index, m_InBuffer, 0, count);
|
||||
m_InBufferPos = count;
|
||||
index += count;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outBufferIndex > 0)
|
||||
{
|
||||
_IO.Write(m_OutBuffer, 0, (int)outBufferIndex);
|
||||
bytesWritten += outBufferIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int CompressionLevel
|
||||
@@ -264,10 +280,23 @@ namespace CUETools.Codecs.LAME
|
||||
}
|
||||
}
|
||||
|
||||
public enum LAMEEncoderVBRProcessingQuality : uint
|
||||
{
|
||||
Best = 0,
|
||||
Normal = 5,
|
||||
}
|
||||
|
||||
public class LAMEEncoderVBRSettings
|
||||
{
|
||||
public LAMEEncoderVBRSettings() { }
|
||||
public LAMEEncoderVBRSettings()
|
||||
{
|
||||
// Iterate through each property and call ResetValue()
|
||||
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
|
||||
property.ResetValue(this);
|
||||
}
|
||||
|
||||
[DefaultValue(LAMEEncoderVBRProcessingQuality.Normal)]
|
||||
public LAMEEncoderVBRProcessingQuality Quality { get; set; }
|
||||
}
|
||||
|
||||
[AudioEncoderClass("lame VBR", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", 2, typeof(LAMEEncoderVBRSettings))]
|
||||
@@ -287,7 +316,7 @@ namespace CUETools.Codecs.LAME
|
||||
|
||||
protected override BE_CONFIG MakeConfig()
|
||||
{
|
||||
BE_CONFIG Mp3Config = new BE_CONFIG(PCM, 128);
|
||||
BE_CONFIG Mp3Config = new BE_CONFIG(PCM, 0, (uint)_settings.Quality);
|
||||
Mp3Config.format.lhv1.bWriteVBRHeader = 1;
|
||||
Mp3Config.format.lhv1.nMode = MpegMode.JOINT_STEREO;
|
||||
Mp3Config.format.lhv1.bEnableVBR = 1;
|
||||
@@ -391,7 +420,7 @@ namespace CUETools.Codecs.LAME
|
||||
|
||||
protected override BE_CONFIG MakeConfig()
|
||||
{
|
||||
BE_CONFIG Mp3Config = new BE_CONFIG(PCM, _settings.CustomBitrate > 0 ? (uint)_settings.CustomBitrate : bps);
|
||||
BE_CONFIG Mp3Config = new BE_CONFIG(PCM, _settings.CustomBitrate > 0 ? (uint)_settings.CustomBitrate : bps, 5);
|
||||
Mp3Config.format.lhv1.bWriteVBRHeader = 1;
|
||||
Mp3Config.format.lhv1.nMode = _settings.StereoMode;
|
||||
//Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NONE; // --cbr
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace CUETools.Codecs.LAME
|
||||
//[ MarshalAs( UnmanagedType.ByValArray, SizeConst=255-4*4-2 )]
|
||||
//public byte[] btReserved;//[255-4*sizeof(DWORD) - sizeof( WORD )];
|
||||
|
||||
public LHV1(AudioPCMConfig format, uint MpeBitRate)
|
||||
public LHV1(AudioPCMConfig format, uint MpeBitRate, uint quality)
|
||||
{
|
||||
dwStructVersion = 1;
|
||||
dwStructSize = (uint)Marshal.SizeOf(typeof(BE_CONFIG));
|
||||
@@ -171,6 +171,7 @@ namespace CUETools.Codecs.LAME
|
||||
}
|
||||
switch (MpeBitRate)
|
||||
{
|
||||
case 0 :
|
||||
case 32 :
|
||||
case 40 :
|
||||
case 48 :
|
||||
@@ -217,7 +218,7 @@ namespace CUETools.Codecs.LAME
|
||||
bStrictIso = 0;
|
||||
dwMaxBitrate = 0;
|
||||
dwVbrAbr_bps = 0;
|
||||
nQuality = 0;
|
||||
nQuality = (ushort)(quality | ((~quality) << 8));
|
||||
nVbrMethod = VBRMETHOD.VBR_METHOD_NONE;
|
||||
nVBRQuality = 0;
|
||||
}
|
||||
@@ -243,9 +244,9 @@ namespace CUETools.Codecs.LAME
|
||||
[FieldOffset(0)]
|
||||
public ACC acc;
|
||||
|
||||
public Format(AudioPCMConfig format, uint MpeBitRate)
|
||||
public Format(AudioPCMConfig format, uint MpeBitRate, uint quality)
|
||||
{
|
||||
lhv1 = new LHV1(format, MpeBitRate);
|
||||
lhv1 = new LHV1(format, MpeBitRate, quality);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,13 +260,13 @@ namespace CUETools.Codecs.LAME
|
||||
public uint dwConfig;
|
||||
public Format format;
|
||||
|
||||
public BE_CONFIG(AudioPCMConfig format, uint MpeBitRate)
|
||||
public BE_CONFIG(AudioPCMConfig format, uint MpeBitRate, uint quality)
|
||||
{
|
||||
this.dwConfig = BE_CONFIG_LAME;
|
||||
this.format = new Format(format, MpeBitRate);
|
||||
this.format = new Format(format, MpeBitRate, quality);
|
||||
}
|
||||
public BE_CONFIG(AudioPCMConfig format)
|
||||
: this(format, 128)
|
||||
: this(format, 0, 5)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -356,7 +357,7 @@ namespace CUETools.Codecs.LAME
|
||||
/// The amount of data written might vary from chunk to chunk</param>
|
||||
/// <returns>On success: BE_ERR_SUCCESSFUL</returns>
|
||||
[DllImport("Lame_enc.dll")]
|
||||
protected static extern uint beEncodeChunk(uint hbeStream, uint nSamples, IntPtr pSamples, [In, Out] byte[] pOutput, ref uint pdwOutput);
|
||||
protected static extern uint beEncodeChunk(uint hbeStream, uint nSamples, IntPtr pSamples, IntPtr pOutput, ref uint pdwOutput);
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a chunk of samples. Samples are contained in a byte array
|
||||
@@ -370,20 +371,27 @@ namespace CUETools.Codecs.LAME
|
||||
/// <param name="pdwOutput">Returns the number of bytes of encoded data written.
|
||||
/// The amount of data written might vary from chunk to chunk</param>
|
||||
/// <returns>On success: BE_ERR_SUCCESSFUL</returns>
|
||||
public static uint EncodeChunk(uint hbeStream, byte[] buffer, int index, uint nBytes, byte[] pOutput, ref uint pdwOutput)
|
||||
public static unsafe uint EncodeChunk(uint hbeStream, byte *pSamples, uint nBytes, byte* pOutput, ref uint pdwOutput)
|
||||
{
|
||||
uint res;
|
||||
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
IntPtr ptr = (IntPtr)(handle.AddrOfPinnedObject().ToInt32()+index);
|
||||
res = beEncodeChunk(hbeStream, nBytes/2/*Samples*/, ptr, pOutput, ref pdwOutput);
|
||||
}
|
||||
finally
|
||||
{
|
||||
handle.Free();
|
||||
}
|
||||
return res;
|
||||
return beEncodeChunk(hbeStream, nBytes / 2/*Samples*/, (IntPtr)pSamples, (IntPtr)pOutput, ref pdwOutput);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a chunk of samples. Samples are contained in a byte array
|
||||
/// </summary>
|
||||
/// <param name="hbeStream">Handle of the stream.</param>
|
||||
/// <param name="buffer">Bytes to encode</param>
|
||||
/// <param name="index">Position of the first byte to encode</param>
|
||||
/// <param name="nBytes">Number of bytes to encode (not samples, samples are two byte lenght)</param>
|
||||
/// <param name="pOutput">Buffer where to write the encoded data.
|
||||
/// This buffer should be at least of the minimum size returned by beInitStream().</param>
|
||||
/// <param name="pdwOutput">Returns the number of bytes of encoded data written.
|
||||
/// The amount of data written might vary from chunk to chunk</param>
|
||||
/// <returns>On success: BE_ERR_SUCCESSFUL</returns>
|
||||
public static unsafe uint EncodeChunk(uint hbeStream, byte[] Samples, int index, uint nBytes, byte[] Output, ref uint pdwOutput)
|
||||
{
|
||||
fixed(byte *pSamples = &Samples[index], pOutput = Output)
|
||||
return beEncodeChunk(hbeStream, nBytes / 2/*Samples*/, (IntPtr)pSamples, (IntPtr)pOutput, ref pdwOutput);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user