using System;
using System.IO;
using System.Security.Permissions;
using System.Globalization;
using BSE.Platten.Ripper.Properties;
namespace BSE.Platten.Ripper
{
/// <summary>
/// Zusammendfassende Beschreibung f�r CMP3Writer.
/// </summary>
public class CMP3Writer : AudioWriter
{
#region FieldsPrivate
private bool m_bClosed;
private BE_CONFIG m_mp3Configuration;
private byte[] m_inBuffer;
private byte[] m_outBuffer;
private uint m_iLameStream;
private uint m_iInputSamples;
private uint m_iOutBufferSize;
private int m_iInBufferPosition;
#endregion
#region MethodsPublic
public CMP3Writer(Stream output, CWaveFormat inputDataFormat)
: this(output, inputDataFormat, new BE_CONFIG(inputDataFormat))
{
}
public CMP3Writer(Stream output, MP3Configuration configuration)
: this(output, configuration.WaveFormat, configuration.Mp3Configuration)
{
if (configuration == null)
{
throw new ArgumentNullException(
string.Format(
CultureInfo.InvariantCulture,
Resources.IDS_ArgumentNullException, "configuration"));
}
}
public CMP3Writer(Stream output, CWaveFormat inputDataFormat, BE_CONFIG mp3Configuration)
:base(output, inputDataFormat)
{
try
{
this.m_mp3Configuration = mp3Configuration;
uint LameResult = LameEncDll.NativeMethods.beInitStream(this.m_mp3Configuration, ref this.m_iInputSamples, ref this.m_iOutBufferSize, ref this.m_iLameStream);
if ( LameResult != LameEncDll.BE_ERR_SUCCESSFUL)
{
throw new ApplicationException(string.Format("Lame_encDll.beInitStream failed with the error code {0}", LameResult));
}
this.m_inBuffer = new byte[this.m_iInputSamples * 2]; //Input buffer is expected as short[]
this.m_outBuffer = new byte[m_iOutBufferSize];
}
catch
{
base.Close();
throw;
}
}
public override void Close()
{
if (!this.m_bClosed)
{
try
{
uint iEncodedSize = 0;
if ( this.m_iInBufferPosition > 0)
{
if ( LameEncDll.EncodeChunk(this.m_iLameStream, this.m_inBuffer, 0, (uint)this.m_iInBufferPosition, this.m_outBuffer, ref iEncodedSize) == LameEncDll.BE_ERR_SUCCESSFUL )
{
if ( iEncodedSize > 0)
{
base.Write(this.m_outBuffer, 0, (int)iEncodedSize);
}
}
}
iEncodedSize = 0;
if (LameEncDll.NativeMethods.beDeinitStream(this.m_iLameStream, this.m_outBuffer, ref iEncodedSize) == LameEncDll.BE_ERR_SUCCESSFUL)
{
if ( iEncodedSize > 0)
{
base.Write(this.m_outBuffer, 0, (int)iEncodedSize);
}
}
}
finally
{
LameEncDll.NativeMethods.beCloseStream(this.m_iLameStream);
}
}
this.m_bClosed = true;
base.Close ();
}
public override void Write(byte[] buffer, int index, int count)
{
int iToCopy = 0;
uint iEncodedSize = 0;
uint iLameResult;
while (count > 0)
{
if ( this.m_iInBufferPosition > 0 )
{
iToCopy = Math.Min(count, this.m_inBuffer.Length - this.m_iInBufferPosition);
Buffer.BlockCopy(buffer, index, this.m_inBuffer, this.m_iInBufferPosition , iToCopy);
this.m_iInBufferPosition += iToCopy;
index += iToCopy;
count -= iToCopy;
if (this.m_iInBufferPosition >= this.m_inBuffer.Length)
{
this.m_iInBufferPosition = 0;
if ( (iLameResult = LameEncDll.EncodeChunk(this.m_iLameStream, this.m_inBuffer, this.m_outBuffer, ref iEncodedSize)) == LameEncDll.BE_ERR_SUCCESSFUL )
{
if ( iEncodedSize > 0)
{
base.Write(this.m_outBuffer, 0, (int)iEncodedSize);
}
}
else
{
throw new ApplicationException(string.Format("Lame.LameEncDll.EncodeChunk failed with the error code {0}", iLameResult));
}
}
}
else
{
if (count >= this.m_inBuffer.Length)
{
if ( (iLameResult = LameEncDll.EncodeChunk(this.m_iLameStream, buffer, index, (uint)this.m_inBuffer.Length, this.m_outBuffer, ref iEncodedSize)) == LameEncDll.BE_ERR_SUCCESSFUL )
{
if ( iEncodedSize > 0)
{
base.Write(this.m_outBuffer, 0, (int)iEncodedSize);
}
}
else
{
throw new ApplicationException(string.Format("Lame.LameEncDll.EncodeChunk failed with the error code {0}", iLameResult));
}
count -= this.m_inBuffer.Length;
index += this.m_inBuffer.Length;
}
else
{
Buffer.BlockCopy(buffer, index, this.m_inBuffer, 0, count);
this.m_iInBufferPosition = count;
index += count;
count = 0;
}
}
}
}
#endregion
}
}