Click here to Skip to main content
15,892,965 members
Articles / Desktop Programming / Windows Forms

BSEtunes

Rate me:
Please Sign up or sign in to vote.
4.67/5 (11 votes)
24 Apr 2010CPOL4 min read 64.8K   4.3K   58  
BSEtunes is a MySQL based, full manageable, networkable single or multiuser jukebox application
using System;
using System.IO;
using System.Security.Permissions;
using System.Globalization;
using BSE.Platten.Ripper.Properties;
using BSE.Platten.Ripper.Lame;
using System.Diagnostics.CodeAnalysis;

namespace BSE.Platten.Ripper.AudioWriters
{
	/// <summary>
    /// Writes mp3 types in binary to a stream and supports writing strings in a specific mp3 encoding.
	/// </summary>
	public class MP3Writer :  AudioWriter
	{
		#region FieldsPrivate
		
		private bool m_bClosed;
        private BeConfiguration 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
        /// <summary>
        /// Initializes a new instance of the <see cref="MP3Writer"/> class based on the supplied stream using ASCII as the encoding for strings and the given input format.
        /// </summary>
        /// <param name="output">The output stream.</param>
        /// <param name="inputDataFormat">The <see cref="WaveFormat"/> input data format.</param>
        public MP3Writer(Stream output, WaveFormat inputDataFormat)
            : this(output, inputDataFormat, new BeConfiguration(inputDataFormat))
		{
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="MP3Writer"/> class based on the supplied stream using ASCII as the encoding for strings and the given configuration.
        /// </summary>
        /// <param name="output">The output stream.</param>
        /// <param name="configuration">The <see cref="MP3WriterConfiguration"/> configuration.</param>
        public MP3Writer(Stream output, MP3WriterConfiguration configuration)
            : this(output, configuration.WaveFormat, configuration.BeConfiguration)
		{
            if (configuration == null)
            {
                throw new ArgumentNullException(
                    string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.IDS_ArgumentNullException, "configuration"));
            }
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="MP3Writer"/> class based on the supplied stream using ASCII as the encoding for strings with the given input format and the mp3 configuration.
        /// </summary>
        /// <param name="output">The output stream.</param>
        /// <param name="inputFormat">The <see cref="WaveFormat"/> input format.</param>
        /// <param name="mp3Configuration">The <see cref="BeConfiguration"/> configuration.</param>
        public MP3Writer(Stream output, WaveFormat inputFormat, BeConfiguration mp3Configuration)
			:base(output, inputFormat)
		{
			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(CultureInfo.InvariantCulture, "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;
			}
		}
        /// <summary>
        /// Closes the current <see cref="MP3Writer"/> and the underlying stream.
        /// </summary>
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public override void Close()
		{
			if (this.m_bClosed == false)
			{
				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)
							{
                                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)
						{
                            Write(this.m_outBuffer, 0, (int)iEncodedSize);
						}
					}
				}
				finally
				{
                    LameEncDll.NativeMethods.beCloseStream(this.m_iLameStream);
				}
			}
			this.m_bClosed = true;
		}
		/// <summary>
        /// Writes a region of a byte array to the current stream.
		/// </summary>
        /// <param name="buffer">A byte array containing the data to write.</param>
        /// <param name="index">The starting point in buffer at which to begin writing.</param>
        /// <param name="count">The number of bytes to write.</param>
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        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(
                                CultureInfo.InvariantCulture,
                                "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(
                                CultureInfo.InvariantCulture,
                                "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
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions