diff --git a/CUETools.Codecs.LAME/CUETools.Codecs.LAME.csproj b/CUETools.Codecs.LAME/CUETools.Codecs.LAME.csproj
new file mode 100644
index 0000000..644a684
--- /dev/null
+++ b/CUETools.Codecs.LAME/CUETools.Codecs.LAME.csproj
@@ -0,0 +1,57 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {1AF02E2C-2CB2-44B5-B417-37653071FEC6}
+ Library
+ Properties
+ CUETools.Codecs.LAME
+ CUETools.Codecs.LAME
+ v2.0
+ 512
+
+
+ true
+ full
+ false
+ ..\bin\Debug\plugins %28win32%29\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\bin\Release\plugins %28win32%29\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {6458A13A-30EF-45A9-9D58-E5031B17BEE2}
+ CUETools.Codecs
+
+
+
+
+
\ No newline at end of file
diff --git a/CUETools.Codecs.LAME/Encoder.cs b/CUETools.Codecs.LAME/Encoder.cs
new file mode 100644
index 0000000..00fe2f8
--- /dev/null
+++ b/CUETools.Codecs.LAME/Encoder.cs
@@ -0,0 +1,343 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using CUETools.Codecs;
+
+namespace CUETools.Codecs.LAME
+{
+ public class LAMEEncoder : IAudioDest
+ {
+ private bool closed = false;
+ private BE_CONFIG m_Mp3Config = null;
+ private uint m_hLameStream = 0;
+ private uint m_InputSamples = 0;
+ private uint m_OutBufferSize = 0;
+ private byte[] m_InBuffer = null;
+ private int m_InBufferPos = 0;
+ private byte[] m_OutBuffer = null;
+ private AudioPCMConfig _pcm;
+ private string _path;
+ private Stream _IO;
+ private long position = 0, sample_count = -1;
+
+ public LAMEEncoder(string path, Stream IO, AudioPCMConfig pcm)
+ {
+ _pcm = pcm;
+ _path = path;
+ _IO = IO;
+ }
+
+ public LAMEEncoder(string path, AudioPCMConfig pcm)
+ : this(path, null, pcm)
+ {
+ }
+
+ public void DeInit()
+ {
+ if (!inited || closed)
+ return;
+
+ try
+ {
+ uint EncodedSize = 0;
+ if (m_InBufferPos > 0)
+ {
+ if (Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, 0, (uint)m_InBufferPos, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
+ {
+ if (EncodedSize > 0)
+ {
+ _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ }
+ }
+ }
+ EncodedSize = 0;
+ if (Lame_encDll.beDeinitStream(m_hLameStream, m_OutBuffer, ref EncodedSize) == Lame_encDll.BE_ERR_SUCCESSFUL)
+ {
+ if (EncodedSize > 0)
+ {
+ _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ }
+ }
+ }
+ finally
+ {
+ Lame_encDll.beCloseStream(m_hLameStream);
+ _IO.Close();
+ }
+ closed = true;
+ }
+
+ public void Close()
+ {
+ bool needTag = !closed && _path != null && _path != "";
+ DeInit();
+ if (needTag)
+ {
+ try
+ {
+ Lame_encDll.beWriteInfoTag(m_hLameStream, _path);
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ public void Delete()
+ {
+ if (!closed)
+ {
+ DeInit();
+ if (_path != "")
+ File.Delete(_path);
+ }
+ }
+
+ protected virtual BE_CONFIG MakeConfig()
+ {
+ return new BE_CONFIG(_pcm, 128);
+ }
+
+ private bool inited = false;
+ private void Init()
+ {
+ if (inited)
+ return;
+
+ m_Mp3Config = MakeConfig();
+
+ uint LameResult = Lame_encDll.beInitStream(m_Mp3Config, ref m_InputSamples, ref m_OutBufferSize, ref m_hLameStream);
+ if (LameResult != Lame_encDll.BE_ERR_SUCCESSFUL)
+ 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];
+
+ if (_IO == null)
+ _IO = new FileStream(_path, FileMode.Create, FileAccess.Write, FileShare.Read);
+
+ inited = true;
+ }
+
+ public void Write(AudioBuffer buff)
+ {
+ buff.Prepare(this);
+
+ Init();
+
+ byte[] buffer = buff.Bytes;
+ int index = 0;
+ int count = buff.ByteLength;
+
+ int ToCopy = 0;
+ uint EncodedSize = 0;
+ uint LameResult;
+ while (count > 0)
+ {
+ if (m_InBufferPos > 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)
+ {
+ m_InBufferPos = 0;
+ if ((LameResult = Lame_encDll.EncodeChunk(m_hLameStream, m_InBuffer, m_OutBuffer, ref EncodedSize)) == Lame_encDll.BE_ERR_SUCCESSFUL)
+ {
+ if (EncodedSize > 0)
+ {
+ _IO.Write(m_OutBuffer, 0, (int)EncodedSize);
+ }
+ }
+ 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);
+ }
+ }
+ 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;
+ }
+ }
+ }
+ }
+
+ public virtual int CompressionLevel
+ {
+ get
+ {
+ return 0;
+ }
+ set
+ {
+ if (value != 0)
+ throw new Exception("unsupported compression level");
+ }
+ }
+
+ public virtual string Options
+ {
+ set
+ {
+ if (value == null || value == "") return;
+ throw new Exception("Unsupported options " + value);
+ }
+ }
+
+ public long Position
+ {
+ get
+ {
+ return position;
+ }
+ }
+
+ public long FinalSampleCount
+ {
+ set { sample_count = (int)value; }
+ }
+
+ public long BlockSize
+ {
+ set { }
+ get { return 0; }
+ }
+
+ public AudioPCMConfig PCM
+ {
+ get { return _pcm; }
+ }
+
+ public string Path { get { return _path; } }
+ }
+
+
+ [AudioEncoderClass("lame VBR", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", 2)]
+ public class LAMEEncoderVBR : LAMEEncoder
+ {
+ private int quality = 0;
+
+ public LAMEEncoderVBR(string path, Stream IO, AudioPCMConfig pcm)
+ : base(path, IO, pcm)
+ {
+ }
+
+ public LAMEEncoderVBR(string path, AudioPCMConfig pcm)
+ : base(path, null, pcm)
+ {
+ }
+
+ protected override BE_CONFIG MakeConfig()
+ {
+ BE_CONFIG Mp3Config = new BE_CONFIG(PCM, 128);
+ Mp3Config.format.lhv1.bWriteVBRHeader = 1;
+ Mp3Config.format.lhv1.nMode = MpegMode.JOINT_STEREO;
+ Mp3Config.format.lhv1.bEnableVBR = 1;
+ Mp3Config.format.lhv1.nVBRQuality = quality;
+ Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NEW; // --vbr-new
+ return Mp3Config;
+ }
+
+ public override int CompressionLevel
+ {
+ get
+ {
+ return 9 - quality;
+ }
+ set
+ {
+ if (value < 0 || value > 9)
+ throw new Exception("unsupported compression level");
+ quality = 9 - value;
+ }
+ }
+
+ public override string Options
+ {
+ set
+ {
+ if (value == null || value == "") return;
+ string[] args = value.Split();
+ for (int i = 0; i < args.Length; i++)
+ {
+ //if (args[i] == "--padding-length" && (++i) < args.Length)
+ //{
+ // PaddingLength = int.Parse(args[i]);
+ // continue;
+ //}
+ //if (args[i] == "--verify")
+ //{
+ // DoVerify = true;
+ // continue;
+ //}
+ throw new Exception("Unsupported options " + value);
+ }
+ }
+ }
+ }
+
+ [AudioEncoderClass("lame CBR", "mp3", false, "96 128 192 256 320", "256", 2)]
+ public class LAMEEncoderCBR : LAMEEncoder
+ {
+ private int bps_index;
+ private static readonly uint[] bps_table = new uint[] {96, 128, 192, 256, 320};
+
+ public LAMEEncoderCBR(string path, Stream IO, AudioPCMConfig pcm)
+ : base(path, IO, pcm)
+ {
+ }
+
+ public LAMEEncoderCBR(string path, AudioPCMConfig pcm)
+ : base(path, null, pcm)
+ {
+ }
+
+ public override int CompressionLevel
+ {
+ get
+ {
+ return bps_index;
+ }
+ set
+ {
+ if (value < 0 || value > bps_table.Length)
+ throw new Exception("unsupported compression level");
+ bps_index = value;
+ }
+ }
+
+ protected override BE_CONFIG MakeConfig()
+ {
+ BE_CONFIG Mp3Config = new BE_CONFIG(PCM, bps_table[bps_index]);
+ Mp3Config.format.lhv1.bWriteVBRHeader = 1;
+ //Mp3Config.format.lhv1.nVbrMethod = VBRMETHOD.VBR_METHOD_NONE; // --cbr
+ //Mp3Config.format.lhv1.nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY;
+ return Mp3Config;
+ }
+ }
+}
diff --git a/CUETools.Codecs.LAME/Lame.cs b/CUETools.Codecs.LAME/Lame.cs
new file mode 100644
index 0000000..3a887a5
--- /dev/null
+++ b/CUETools.Codecs.LAME/Lame.cs
@@ -0,0 +1,450 @@
+//
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+// PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER
+// REMAINS UNCHANGED.
+//
+// Email: yetiicb@hotmail.com
+//
+// Copyright (C) 2002-2003 Idael Cardoso.
+//
+// LAME ( LAME Ain't an Mp3 Encoder )
+// You must call the fucntion "beVersion" to obtain information like version
+// numbers (both of the DLL and encoding engine), release date and URL for
+// lame_enc's homepage. All this information should be made available to the
+// user of your product through a dialog box or something similar.
+// You must see all information about LAME project and legal license infos at
+// http://www.mp3dev.org/ The official LAME site
+//
+//
+// About Thomson and/or Fraunhofer patents:
+// Any use of this product does not convey a license under the relevant
+// intellectual property of Thomson and/or Fraunhofer Gesellschaft nor imply
+// any right to use this product in any finished end user or ready-to-use final
+// product. An independent license for such use is required.
+// For details, please visit http://www.mp3licensing.com.
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using CUETools.Codecs;
+
+namespace CUETools.Codecs.LAME
+{
+ public enum VBRMETHOD : int
+ {
+ VBR_METHOD_NONE = -1,
+ VBR_METHOD_DEFAULT = 0,
+ VBR_METHOD_OLD = 1,
+ VBR_METHOD_NEW = 2,
+ VBR_METHOD_MTRH = 3,
+ VBR_METHOD_ABR = 4
+ }
+
+ /* MPEG modes */
+ public enum MpegMode : uint
+ {
+ STEREO = 0,
+ JOINT_STEREO,
+ DUAL_CHANNEL, /* LAME doesn't supports this! */
+ MONO,
+ NOT_SET,
+ MAX_INDICATOR /* Don't use this! It's used for sanity checks. */
+ }
+
+ public enum LAME_QUALITY_PRESET : int
+ {
+ LQP_NOPRESET =-1,
+ // QUALITY PRESETS
+ LQP_NORMAL_QUALITY = 0,
+ LQP_LOW_QUALITY = 1,
+ LQP_HIGH_QUALITY = 2,
+ LQP_VOICE_QUALITY = 3,
+ LQP_R3MIX = 4,
+ LQP_VERYHIGH_QUALITY = 5,
+ LQP_STANDARD = 6,
+ LQP_FAST_STANDARD = 7,
+ LQP_EXTREME = 8,
+ LQP_FAST_EXTREME = 9,
+ LQP_INSANE = 10,
+ LQP_ABR = 11,
+ LQP_CBR = 12,
+ LQP_MEDIUM = 13,
+ LQP_FAST_MEDIUM = 14,
+ // NEW PRESET VALUES
+ LQP_PHONE =1000,
+ LQP_SW =2000,
+ LQP_AM =3000,
+ LQP_FM =4000,
+ LQP_VOICE =5000,
+ LQP_RADIO =6000,
+ LQP_TAPE =7000,
+ LQP_HIFI =8000,
+ LQP_CD =9000,
+ LQP_STUDIO =10000
+ }
+
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ public struct MP3 //BE_CONFIG_MP3
+ {
+ public uint dwSampleRate; // 48000, 44100 and 32000 allowed
+ public byte byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
+ public ushort wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed
+ public int bPrivate;
+ public int bCRC;
+ public int bCopyright;
+ public int bOriginal;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Size=327), Serializable]
+ public struct LHV1 // BE_CONFIG_LAME LAME header version 1
+ {
+ public const uint MPEG1 = 1;
+ public const uint MPEG2 = 0;
+
+ // STRUCTURE INFORMATION
+ public uint dwStructVersion;
+ public uint dwStructSize;
+ // BASIC ENCODER SETTINGS
+ public uint dwSampleRate; // SAMPLERATE OF INPUT FILE
+ public uint dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES
+ public MpegMode nMode; // STEREO, MONO
+ public uint dwBitrate; // CBR bitrate, VBR min bitrate
+ public uint dwMaxBitrate; // CBR ignored, VBR Max bitrate
+ public LAME_QUALITY_PRESET nPreset; // Quality preset
+ public uint dwMpegVersion; // MPEG-1 OR MPEG-2
+ public uint dwPsyModel; // FUTURE USE, SET TO 0
+ public uint dwEmphasis; // FUTURE USE, SET TO 0
+ // BIT STREAM SETTINGS
+ public int bPrivate; // Set Private Bit (TRUE/FALSE)
+ public int bCRC; // Insert CRC (TRUE/FALSE)
+ public int bCopyright; // Set Copyright Bit (TRUE/FALSE)
+ public int bOriginal; // Set Original Bit (TRUE/FALSE)
+ // VBR STUFF
+ public int bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE)
+ public int bEnableVBR; // USE VBR ENCODING (TRUE/FALSE)
+ public int nVBRQuality; // VBR QUALITY 0..9
+ public uint dwVbrAbr_bps; // Use ABR in stead of nVBRQuality
+ public VBRMETHOD nVbrMethod;
+ public int bNoRes; // Disable Bit resorvoir (TRUE/FALSE)
+ // MISC SETTINGS
+ public int bStrictIso; // Use strict ISO encoding rules (TRUE/FALSE)
+ public ushort nQuality; // Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5
+ // FUTURE USE, SET TO 0, align strucutre to 331 bytes
+ //[ MarshalAs( UnmanagedType.ByValArray, SizeConst=255-4*4-2 )]
+ //public byte[] btReserved;//[255-4*sizeof(DWORD) - sizeof( WORD )];
+
+ public LHV1(AudioPCMConfig format, uint MpeBitRate)
+ {
+ if ( format.BitsPerSample != 16)
+ throw new ArgumentOutOfRangeException("format", "Only 16 bits samples supported");
+
+ dwStructVersion = 1;
+ dwStructSize = (uint)Marshal.SizeOf(typeof(BE_CONFIG));
+ switch (format.SampleRate)
+ {
+ case 16000 :
+ case 22050 :
+ case 24000 :
+ dwMpegVersion = MPEG2;
+ break;
+ case 32000 :
+ case 44100 :
+ case 48000 :
+ dwMpegVersion = MPEG1;
+ break;
+ default :
+ throw new ArgumentOutOfRangeException("format", "Unsupported sample rate");
+ }
+ dwSampleRate = (uint)format.SampleRate; // INPUT FREQUENCY
+ dwReSampleRate = 0; // DON'T RESAMPLE
+ switch (format.ChannelCount)
+ {
+ case 1 :
+ nMode = MpegMode.MONO;
+ break;
+ case 2 :
+ nMode = MpegMode.STEREO;
+ break;
+ default:
+ throw new ArgumentOutOfRangeException("format", "Invalid number of channels");
+ }
+ switch (MpeBitRate)
+ {
+ case 32 :
+ case 40 :
+ case 48 :
+ case 56 :
+ case 64 :
+ case 80 :
+ case 96 :
+ case 112 :
+ case 128 :
+ case 160 : //Allowed bit rates in MPEG1 and MPEG2
+ break;
+ case 192 :
+ case 224 :
+ case 256 :
+ case 320 : //Allowed only in MPEG1
+ if (dwMpegVersion != MPEG1)
+ {
+ throw new ArgumentOutOfRangeException("MpsBitRate", "Bit rate not compatible with input format");
+ }
+ break;
+ case 8 :
+ case 16 :
+ case 24 :
+ case 144 : //Allowed only in MPEG2
+ if (dwMpegVersion != MPEG2)
+ {
+ throw new ArgumentOutOfRangeException("MpsBitRate", "Bit rate not compatible with input format");
+ }
+ break;
+ default :
+ throw new ArgumentOutOfRangeException("MpsBitRate", "Unsupported bit rate");
+ }
+ dwBitrate = MpeBitRate; // MINIMUM BIT RATE
+ nPreset = LAME_QUALITY_PRESET.LQP_NORMAL_QUALITY; // QUALITY PRESET SETTING
+ dwPsyModel = 0; // USE DEFAULT PSYCHOACOUSTIC MODEL
+ dwEmphasis = 0; // NO EMPHASIS TURNED ON
+ bOriginal = 1; // SET ORIGINAL FLAG
+ bWriteVBRHeader = 0;
+ bNoRes = 0; // No Bit resorvoir
+ bCopyright = 0;
+ bCRC = 0;
+ bEnableVBR = 0;
+ bPrivate = 0;
+ bStrictIso = 0;
+ dwMaxBitrate = 0;
+ dwVbrAbr_bps = 0;
+ nQuality = 0;
+ nVbrMethod = VBRMETHOD.VBR_METHOD_NONE;
+ nVBRQuality = 0;
+ }
+ }
+
+
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ public struct ACC
+ {
+ public uint dwSampleRate;
+ public byte byMode;
+ public ushort wBitrate;
+ public byte byEncodingMethod;
+ }
+
+ [StructLayout(LayoutKind.Explicit), Serializable]
+ public class Format
+ {
+ [FieldOffset(0)]
+ public MP3 mp3;
+ [FieldOffset(0)]
+ public LHV1 lhv1;
+ [FieldOffset(0)]
+ public ACC acc;
+
+ public Format(AudioPCMConfig format, uint MpeBitRate)
+ {
+ lhv1 = new LHV1(format, MpeBitRate);
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ public class BE_CONFIG
+ {
+ // encoding formats
+ public const uint BE_CONFIG_MP3 = 0;
+ public const uint BE_CONFIG_LAME = 256;
+
+ public uint dwConfig;
+ public Format format;
+
+ public BE_CONFIG(AudioPCMConfig format, uint MpeBitRate)
+ {
+ this.dwConfig = BE_CONFIG_LAME;
+ this.format = new Format(format, MpeBitRate);
+ }
+ public BE_CONFIG(AudioPCMConfig format)
+ : this(format, 128)
+ {
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
+ public class BE_VERSION
+ {
+ public const uint BE_MAX_HOMEPAGE = 256;
+ public byte byDLLMajorVersion;
+ public byte byDLLMinorVersion;
+ public byte byMajorVersion;
+ public byte byMinorVersion;
+ // DLL Release date
+ public byte byDay;
+ public byte byMonth;
+ public ushort wYear;
+ //Homepage URL
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst=257/*BE_MAX_HOMEPAGE+1*/)]
+ public string zHomepage;
+ public byte byAlphaLevel;
+ public byte byBetaLevel;
+ public byte byMMXEnabled;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst=125)]
+ public byte[] btReserved;
+ public BE_VERSION()
+ {
+ btReserved = new byte[125];
+ }
+ }
+
+ ///
+ /// Lame_enc DLL functions
+ ///
+ public class Lame_encDll
+ {
+ //Error codes
+ public const uint BE_ERR_SUCCESSFUL = 0;
+ public const uint BE_ERR_INVALID_FORMAT = 1;
+ public const uint BE_ERR_INVALID_FORMAT_PARAMETERS = 2;
+ public const uint BE_ERR_NO_MORE_HANDLES = 3;
+ public const uint BE_ERR_INVALID_HANDLE = 4;
+
+ ///
+ /// This function is the first to call before starting an encoding stream.
+ ///
+ /// Encoder settings
+ /// Receives the number of samples (not bytes, each sample is a SHORT) to send to each beEncodeChunk() on return.
+ /// Receives the minimun number of bytes that must have the output(result) buffer
+ /// Receives the stream handle on return
+ /// On success: BE_ERR_SUCCESSFUL
+ [DllImport("Lame_enc.dll")]
+ public static extern uint beInitStream(BE_CONFIG pbeConfig, ref uint dwSamples, ref uint dwBufferSize, ref uint phbeStream);
+
+ ///
+ /// Encodes a chunk of samples. Please note that if you have set the output to
+ /// generate mono MP3 files you must feed beEncodeChunk() with mono samples
+ ///
+ /// Handle of the stream.
+ /// Number of samples to be encoded for this call.
+ /// This should be identical to what is returned by beInitStream(),
+ /// unless you are encoding the last chunk, which might be smaller.
+ /// Array of 16-bit signed samples to be encoded.
+ /// These should be in stereo when encoding a stereo MP3
+ /// and mono when encoding a mono MP3
+ /// Buffer where to write the encoded data.
+ /// This buffer should be at least of the minimum size returned by beInitStream().
+ /// Returns the number of bytes of encoded data written.
+ /// The amount of data written might vary from chunk to chunk
+ /// On success: BE_ERR_SUCCESSFUL
+ [DllImport("Lame_enc.dll")]
+ public static extern uint beEncodeChunk(uint hbeStream, uint nSamples, short[] pInSamples, [In, Out] byte[] pOutput, ref uint pdwOutput);
+
+ ///
+ /// Encodes a chunk of samples. Please note that if you have set the output to
+ /// generate mono MP3 files you must feed beEncodeChunk() with mono samples
+ ///
+ /// Handle of the stream.
+ /// Number of samples to be encoded for this call.
+ /// This should be identical to what is returned by beInitStream(),
+ /// unless you are encoding the last chunk, which might be smaller.
+ /// Pointer at the 16-bit signed samples to be encoded.
+ /// InPtr is used to pass any type of array without need of make memory copy,
+ /// then gaining in performance. Note that nSamples is not the number of bytes,
+ /// but samples (is sample is a SHORT)
+ /// Buffer where to write the encoded data.
+ /// This buffer should be at least of the minimum size returned by beInitStream().
+ /// Returns the number of bytes of encoded data written.
+ /// The amount of data written might vary from chunk to chunk
+ /// On success: BE_ERR_SUCCESSFUL
+ [DllImport("Lame_enc.dll")]
+ protected static extern uint beEncodeChunk(uint hbeStream, uint nSamples, IntPtr pSamples, [In, Out] byte[] pOutput, ref uint pdwOutput);
+
+ ///
+ /// Encodes a chunk of samples. Samples are contained in a byte array
+ ///
+ /// Handle of the stream.
+ /// Bytes to encode
+ /// Position of the first byte to encode
+ /// Number of bytes to encode (not samples, samples are two byte lenght)
+ /// Buffer where to write the encoded data.
+ /// This buffer should be at least of the minimum size returned by beInitStream().
+ /// Returns the number of bytes of encoded data written.
+ /// The amount of data written might vary from chunk to chunk
+ /// On success: BE_ERR_SUCCESSFUL
+ public static uint EncodeChunk(uint hbeStream, byte[] buffer, int index, 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;
+ }
+
+ ///
+ /// Encodes a chunk of samples. Samples are contained in a byte array
+ ///
+ /// Handle of the stream.
+ /// Bytes to encode
+ /// Buffer where to write the encoded data.
+ /// This buffer should be at least of the minimum size returned by beInitStream().
+ /// Returns the number of bytes of encoded data written.
+ /// The amount of data written might vary from chunk to chunk
+ /// On success: BE_ERR_SUCCESSFUL
+ public static uint EncodeChunk(uint hbeStream, byte[] buffer, byte[] pOutput, ref uint pdwOutput)
+ {
+ return EncodeChunk(hbeStream, buffer, 0, (uint)buffer.Length, pOutput, ref pdwOutput);
+ }
+
+ ///
+ /// This function should be called after encoding the last chunk in order to flush
+ /// the encoder. It writes any encoded data that still might be left inside the
+ /// encoder to the output buffer. This function should NOT be called unless
+ /// you have encoded all of the chunks in your stream.
+ ///
+ /// Handle of the stream.
+ /// Where to write the encoded data. This buffer should be
+ /// at least of the minimum size returned by beInitStream().
+ /// Returns number of bytes of encoded data written.
+ /// On success: BE_ERR_SUCCESSFUL
+ [DllImport("Lame_enc.dll")]
+ public static extern uint beDeinitStream(uint hbeStream, [In, Out] byte[] pOutput, ref uint pdwOutput);
+
+ ///
+ /// Last function to be called when finished encoding a stream.
+ /// Should unlike beDeinitStream() also be called if the encoding is canceled.
+ ///
+ /// Handle of the stream.
+ /// On success: BE_ERR_SUCCESSFUL
+ [DllImport("Lame_enc.dll")]
+ public static extern uint beCloseStream(uint hbeStream);
+
+ ///
+ /// Returns information like version numbers (both of the DLL and encoding engine),
+ /// release date and URL for lame_enc's homepage.
+ /// All this information should be made available to the user of your product
+ /// through a dialog box or something similar.
+ ///
+ ///
+ [DllImport("Lame_enc.dll")]
+ public static extern void beVersion([Out] BE_VERSION pbeVersion);
+
+ [DllImport("Lame_enc.dll", CharSet=CharSet.Ansi)]
+ public static extern void beWriteVBRHeader(string pszMP3FileName);
+ [DllImport("Lame_enc.dll")]
+ public static extern uint beEncodeChunkFloatS16NI(uint hbeStream, uint nSamples, [In]float[] buffer_l, [In]float[] buffer_r, [In, Out]byte[] pOutput, ref uint pdwOutput);
+ [DllImport("Lame_enc.dll")]
+ public static extern uint beFlushNoGap(uint hbeStream, [In, Out]byte[] pOutput, ref uint pdwOutput);
+ [DllImport("Lame_enc.dll", CharSet=CharSet.Ansi)]
+ public static extern uint beWriteInfoTag(uint hbeStream, string lpszFileName);
+ }
+}
diff --git a/CUETools.Codecs.LAME/Properties/AssemblyInfo.cs b/CUETools.Codecs.LAME/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a1f9d09
--- /dev/null
+++ b/CUETools.Codecs.LAME/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CUETools.Codecs.LAME")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("CUETools.Codecs.LAME")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e367e520-a7ab-4911-9dc5-25a2d3c9159d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]