clsFLACFile.cs

00001 //
00002 // Copyright (C) 2005 Marcel Joachim Kloubert
00003 // 
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00019 using System;
00020 using System.IO;
00021 
00022 namespace CSharp_ClassLib.FileTypes.FLAC
00023 {       
00024         // Tools
00025         public sealed class Tools
00026         {
00027                 public static System.UInt16 ToUInt16 (byte[] Bytes, int Start) { return (System.UInt16)(Bytes[Start] * 256 + (System.UInt16)Bytes[Start + 1]); }
00028                 
00029                 public static System.UInt32 ToUInt32 (byte[] Bytes, int Start, int Length)
00030                 {
00031                         switch (Length)
00032                         {
00033                                 case 1:
00034                                         return (System.UInt32)Bytes[Start];                             
00035                                 case 2:
00036                                         return (System.UInt32)ToUInt16(Bytes, Start);                           
00037                                 case 3:
00038                                         return (System.UInt16)(Bytes[Start] * 65536 + Bytes[Start + 1] * 256 + (System.UInt16)Bytes[Start + 2]);                                        
00039                                 case 4:
00040                                         return ToUInt32(Bytes, Start);
00041                                         
00042                                 default:
00043                                         throw ( new System.ArgumentException("Invalid length!", "Length") );
00044                         }                       
00045                 }
00046                 
00047                 public static System.UInt32 ToUInt32 (byte[] Bytes, int Start) { return (System.UInt16)(Bytes[Start] * 16777216 + Bytes[Start + 1] * 65536 + Bytes[Start + 2] * 256 + (System.UInt16)Bytes[Start + 3]); }
00048         }
00049         
00050         // STREAM
00051         public class STREAM : System.Object
00052         {
00053                 // stream marker ("fLaC")
00054                 private byte[] m_bStreamMarker = { 0x66, 0x4C, 0x61, 0x43 };
00055                 
00056                 private System.IO.Stream m_oStream;
00057                 private System.Collections.ArrayList m_oMetadataBlocks;
00058                 
00059                 public STREAM()
00060                 {
00061                         this.Stream = null;
00062                         this.InitRest();
00063                         
00064                         return;
00065                 }
00066                 
00067                 public STREAM (string Filename)
00068                 {
00069                         this.Stream = new System.IO.FileStream(Filename, System.IO.FileMode.Open);
00070                         this.InitRest();
00071                         
00072                         return;
00073                 }
00074                 
00075                 public STREAM(System.IO.Stream stream)
00076                 {
00077                         this.Stream = stream;
00078                         this.InitRest();
00079                         
00080                         return;
00081                 }
00082                 
00083                 public System.IO.Stream Stream
00084                 {
00085                         set
00086                         {
00087                                 int i = 0;
00088                                 byte[] bBuffer;
00089                                 
00090                                 this.m_oMetadataBlocks = new System.Collections.ArrayList();
00091                                 METADATA_BLOCK oMETADATA_BLOCK_TEMP;
00092                                 
00093                                 m_oStream = value;
00094                                 
00095                                 if (null == m_oStream)
00096                                         return;
00097                                 
00098                                 if (!value.CanRead)
00099                                         throw ( new System.Exception("Cannot read FLAC data!") );
00100                                 
00101                                 // get stream marker
00102                                 try
00103                                 {
00104                                         bBuffer = new byte[4];
00105                                         
00106                                         this.Stream.Read(bBuffer, 0, 4);
00107                                         
00108                                         if ( 4 != bBuffer.GetLength(0) )
00109                                                 throw ( new System.Exception("Invalid stream marker!") );
00110                                         
00111                                         for (i = 0; i < 4; i++)
00112                                         {
00113                                                 if (bBuffer[i] != StreamMarker[i])
00114                                                         throw ( new System.Exception("Invalid stream marker!") );
00115                                         }                                                                               
00116                                 }
00117                                 catch (Exception e) { throw ( new System.Exception("Cannot read FLAC stream marker! Reason: " + e.Message) ); }
00118                                 
00119                                 while ( true )
00120                                 {
00121                                         oMETADATA_BLOCK_TEMP = new METADATA_BLOCK();
00122                                         
00123                                         // get metablock header
00124                                         try
00125                                         {
00126                                                 bBuffer = new byte[4];                                  
00127                                                 this.Stream.Read(bBuffer, 0, 4);                                        
00128                                                 if ( 4 != bBuffer.GetLength(0) )
00129                                                         throw ( new System.Exception("Invalid metadata block header!") );
00130                                                 
00131                                                 oMETADATA_BLOCK_TEMP.Header.RawData = bBuffer;  
00132                                                 
00133                                                 bBuffer = new byte[oMETADATA_BLOCK_TEMP.Header.Length];
00134                                                 this.Stream.Read(bBuffer, 0, (int)oMETADATA_BLOCK_TEMP.Header.Length);
00135                                                 if ( oMETADATA_BLOCK_TEMP.Header.Length != bBuffer.GetLength(0) )
00136                                                         throw ( new System.Exception("Invalid metadata block data!") );
00137                                                 
00138                                                 switch (oMETADATA_BLOCK_TEMP.Header.Type)
00139                                                 {
00140                                                         case METADATA_BLOCK_HEADER.BLOCK_TYPE.STREAMINFO:
00141                                                                 // STREAMINFO
00142                                                                 oMETADATA_BLOCK_TEMP.Data = new METADATA_BLOCK_STREAMINFO(bBuffer);
00143                                                                 
00144                                                                 Console.WriteLine("BlockLength: " + oMETADATA_BLOCK_TEMP.Header.Length.ToString());
00145                                                                 Console.WriteLine("MinSampleSize: " + ((METADATA_BLOCK_STREAMINFO)oMETADATA_BLOCK_TEMP.Data).MinimumBlockSize.ToString());
00146                                                                 Console.WriteLine("MaxSampleSize: " + ((METADATA_BLOCK_STREAMINFO)oMETADATA_BLOCK_TEMP.Data).MaximumBlockSize.ToString());
00147                                                                 Console.WriteLine("MinFrameSize: " + ((METADATA_BLOCK_STREAMINFO)oMETADATA_BLOCK_TEMP.Data).MinimumFrameSize.ToString());
00148                                                                 Console.WriteLine("MaxFrameSize: " + ((METADATA_BLOCK_STREAMINFO)oMETADATA_BLOCK_TEMP.Data).MaximumFrameSize.ToString());
00149                                                                 
00150                                                                 break;
00151                                                         
00152                                                         default:
00153                                                                 // unknown
00154                                                                 oMETADATA_BLOCK_TEMP.Data = new METADATA_BLOCK_DATA(bBuffer);
00155                                                                 break;
00156                                                 }
00157                                                 
00158                                                 // oMETADATA_BLOCK_TEMP.Header.RawData = bBuffer;                                       
00159                                         }
00160                                         catch (Exception e) { throw ( new System.Exception("Cannot read FLAC metadata block header! Reason: " + e.Message) ); }
00161                                         
00162                                         this.m_oMetadataBlocks.Add(oMETADATA_BLOCK_TEMP);                                       
00163                                         if (oMETADATA_BLOCK_TEMP.Header.IsLastBlock)
00164                                                 break;
00165                                 }                                                               
00166                         }
00167                         
00168                         get { return m_oStream; }
00169                 }
00170                 
00171                 public byte[] StreamMarker { get { return m_bStreamMarker; } }
00172                 
00173                 public METADATA_BLOCK[] MetadataBlocks
00174                 {
00175                         get
00176                         {
00177                                 METADATA_BLOCK[] oBuffer = new METADATA_BLOCK[m_oMetadataBlocks.Count];
00178                                 m_oMetadataBlocks.CopyTo(oBuffer);
00179                                 
00180                                 return oBuffer;
00181                         }
00182                 }
00183                 
00184                 private void InitRest()
00185                 {
00186                         m_oMetadataBlocks = new System.Collections.ArrayList();
00187                         return;
00188                 }
00189         }       
00190         
00191         // METADATA_BLOCK
00192         public class METADATA_BLOCK : System.Object
00193         {
00194                 private METADATA_BLOCK_HEADER m_oHeader;
00195                 private METADATA_BLOCK_DATA m_oData;
00196                 
00197                 public METADATA_BLOCK()
00198                 {
00199                         m_oHeader = new METADATA_BLOCK_HEADER();
00200                         m_oData = new METADATA_BLOCK_DATA( new byte[0] );
00201                         
00202                         return;
00203                 }
00204                 
00205                 public METADATA_BLOCK_HEADER Header { get { return m_oHeader; } }
00206                 
00207                 public METADATA_BLOCK_DATA Data
00208                 {
00209                         get { return m_oData; }
00210                         set { m_oData = value; }
00211                 }
00212         }       
00213         
00214         // METADATA_BLOCK_HEADER
00215         public class METADATA_BLOCK_HEADER : System.Object
00216         {
00217                 private bool m_boolIsLastBlock;
00218                 private BLOCK_TYPE m_BLOCK_TYPE;
00219                 private uint m_uiBlockLength;
00220                 
00221                 public enum BLOCK_TYPE : byte
00222                 {
00223                         STREAMINFO = 0,
00224                         PADDING,
00225                         APPLICATION,
00226                         SEEKTABLE,
00227                         VORBIS_COMMENT,
00228                         CUESHEET,
00229                         INVALID = 127
00230                 }
00231                 
00232                 
00233                 public METADATA_BLOCK_HEADER()
00234                 {
00235                         m_boolIsLastBlock = false;                                              
00236                         m_BLOCK_TYPE = BLOCK_TYPE.INVALID;
00237                         m_uiBlockLength = 0;
00238                         
00239                         return;
00240                 }
00241                 
00242                 public byte[] RawData
00243                 {
00244                         set
00245                         {
00246                                 byte[] bBuffer = value;                                 
00247                                 if ( 4 != bBuffer.GetLength(0) )
00248                                         throw ( new System.Exception("Invalid metadata block header!") );
00249                                 
00250                                 this.m_boolIsLastBlock = ( 1 == (byte)((byte)(bBuffer[0] << 7) >> 7) ) ? true : false;
00251                                 this.m_BLOCK_TYPE = (BLOCK_TYPE)(byte)(bBuffer[0] >> 1);
00252                                 this.m_uiBlockLength = Tools.ToUInt32(bBuffer, 1, 3);
00253                                 
00254                                 return;
00255                         }
00256                 }
00257                 
00258                 public bool IsLastBlock { get { return this.m_boolIsLastBlock; } }
00259                 public BLOCK_TYPE Type { get { return this.m_BLOCK_TYPE; } }
00260                 public uint Length { get { return this.m_uiBlockLength; } }
00261         }       
00262         
00263         // METADATA_BLOCK_DATA
00264         public class METADATA_BLOCK_DATA : System.Object
00265         {
00266                 public METADATA_BLOCK_DATA (byte[] Raw_Data)
00267                 {
00268                         this.RawData = Raw_Data;
00269                         
00270                         return;
00271                 }                               
00272                 
00273                 public byte[] RawData
00274                 {
00275                         set
00276                         {
00277                                 return;
00278                         }
00279                 }                               
00280         }       
00281         
00282         // METADATA_BLOCK_STREAMINFO
00283         public class METADATA_BLOCK_STREAMINFO : METADATA_BLOCK_DATA
00284         {
00285                 private ushort m_usMinimumSamples;
00286                 private ushort m_usMaximumSamples;
00287                 private uint m_uiMinimumFrameSize;
00288                 private uint m_uiMaximumFrameSize;
00289                 
00290                 public METADATA_BLOCK_STREAMINFO (byte[] Raw_Data) : base(Raw_Data)
00291                 {
00292                         m_usMinimumSamples = 0;
00293                         m_usMaximumSamples = 0;
00294                         m_uiMinimumFrameSize = 0;
00295                         m_uiMaximumFrameSize = 0;
00296                         
00297                         this.RawData = Raw_Data;
00298                         
00299                         return;
00300                 }
00301                 
00302                 public ushort MinimumBlockSize { get { return this.m_usMinimumSamples; }        }
00303                 public ushort MaximumBlockSize { get { return this.m_usMaximumSamples; }        }
00304                 public uint MinimumFrameSize { get { return this.m_uiMinimumFrameSize; }        }
00305                 public uint MaximumFrameSize { get { return this.m_uiMaximumFrameSize; }        }
00306                 
00307                 public bool IsFixedStream { get { return (this.MinimumBlockSize == this.MaximumBlockSize); } }
00308                 
00309                 public byte[] RawData
00310                 {
00311                         set
00312                         {
00313                                 System.UInt32 a = 0;
00314                                 byte b = 0;
00315                                 
00316                                 byte[] bBuffer = value;
00317                                 if ( 34 != bBuffer.GetLength(0) )
00318                                         throw ( new System.ArgumentException("Invalid metadata block data (wrong size)!", "value") );
00319                                 
00320                                 this.m_usMinimumSamples = Tools.ToUInt16(bBuffer, 0);
00321                                 this.m_usMaximumSamples = Tools.ToUInt16(bBuffer, 2);
00322                                 this.m_uiMinimumFrameSize = Tools.ToUInt32(bBuffer, 4, 3);
00323                                 this.m_uiMaximumFrameSize = Tools.ToUInt32(bBuffer, 7, 3);
00324                                 
00325                                 a = (System.UInt32)Tools.ToUInt16(bBuffer, 10) * 256 + (System.UInt32)(byte)(bBuffer[12] >> 4);
00326                                 b = (byte)(bBuffer[12] >> 4);
00327                                 Console.WriteLine(a.ToString());
00328                                 
00329                                 return;
00330                         }
00331                 }
00332         }       
00333 }

Generated on Thu Jun 2 08:41:49 2005 for C# ClassLib by  doxygen 1.4.1