00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 using System;
00020 using System.IO;
00021
00022 namespace CSharp_ClassLib.FileTypes.FLAC
00023 {
00024
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
00051 public class STREAM : System.Object
00052 {
00053
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
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
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
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
00154 oMETADATA_BLOCK_TEMP.Data = new METADATA_BLOCK_DATA(bBuffer);
00155 break;
00156 }
00157
00158
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
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
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
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
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 }