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")]