Exemple #1
0
		// ---------------------------------------------------------------------------

		// No explicit destructors in C#

		// ---------------------------------------------------------------------------

		public bool ReadFromFile(String FileName)
		{
   
			APE_HEADER APE = new APE_HEADER();				// common header
			APE_HEADER_OLD APE_OLD = new APE_HEADER_OLD();	// old header   <= 3.97
			APE_HEADER_NEW APE_NEW = new APE_HEADER_NEW();	// new header   >= 3.98
			APE_DESCRIPTOR APE_DESC = new APE_DESCRIPTOR(); // extra header >= 3.98

			FileStream fs = null;
			BinaryReader SourceFile = null;

			int BlocksPerFrame;
			bool LoadSuccess;
			int TagSize;
			bool result = false;
   
			FResetData();
   
			// load tags first
			FID3v2.ReadFromFile(FileName);
			FID3v1.ReadFromFile(FileName);
			FAPEtag.ReadFromFile(FileName);
   
			// calculate total tag size
			TagSize = 0;
			if (FID3v1.Exists) TagSize += 128;
			if (FID3v2.Exists) TagSize += FID3v2.Size;
			if (FAPEtag.Exists) TagSize += FAPEtag.Size;
   
			// reading data from file
			LoadSuccess = false;

			try
			{
				try
				{         
					fs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
					fs.Lock(0,fs.Length);
					SourceFile = new BinaryReader(fs);
					FFileSize = fs.Length;

					// seek past id3v2-tag
					if (FID3v2.Exists)
					{
						fs.Seek(FID3v2.Size, SeekOrigin.Begin);
					}
					// Read APE Format Header         
					Array.Clear(APE.cID,0,APE.cID.Length);
					APE.nVersion = 0;
	  
					APE.cID = SourceFile.ReadChars(4);
					APE.nVersion = SourceFile.ReadUInt16();

					if ( Utils.StringEqualsArr("MAC ",APE.cID) )
					{            
						FVersion = APE.nVersion;

						FVersionStr = ((double)FVersion / 1000).ToString().Substring(0,4); //Str(FVersion / 1000 : 4 : 2, FVersionStr);
            
						// Load New Monkey's Audio Header for version >= 3.98
						if (APE.nVersion >= 3980) 
						{
							APE_DESC.padded = 0;
							APE_DESC.nDescriptorBytes = 0;
							APE_DESC.nHeaderBytes = 0;
							APE_DESC.nSeekTableBytes = 0;
							APE_DESC.nHeaderDataBytes = 0;
							APE_DESC.nAPEFrameDataBytes = 0;
							APE_DESC.nAPEFrameDataBytesHigh = 0;
							APE_DESC.nTerminatingDataBytes = 0;
							Array.Clear(APE_DESC.cFileMD5,0,APE_DESC.cFileMD5.Length);

							APE_DESC.padded = SourceFile.ReadUInt16();
							APE_DESC.nDescriptorBytes = SourceFile.ReadUInt32();
							APE_DESC.nHeaderBytes = SourceFile.ReadUInt32();
							APE_DESC.nSeekTableBytes = SourceFile.ReadUInt32();
							APE_DESC.nHeaderDataBytes = SourceFile.ReadUInt32();
							APE_DESC.nAPEFrameDataBytes = SourceFile.ReadUInt32();
							APE_DESC.nAPEFrameDataBytesHigh = SourceFile.ReadUInt32();
							APE_DESC.nTerminatingDataBytes = SourceFile.ReadUInt32();
							APE_DESC.cFileMD5 = SourceFile.ReadBytes(16);

							// seek past description header
							if (APE_DESC.nDescriptorBytes != 52) fs.Seek(APE_DESC.nDescriptorBytes - 52, SeekOrigin.Current);
							// load new ape_header
							if (APE_DESC.nHeaderBytes > 24/*sizeof(APE_NEW)*/) APE_DESC.nHeaderBytes = 24/*sizeof(APE_NEW)*/;
                  				
							APE_NEW.nCompressionLevel = 0;
							APE_NEW.nFormatFlags = 0;
							APE_NEW.nBlocksPerFrame = 0;
							APE_NEW.nFinalFrameBlocks = 0;
							APE_NEW.nTotalFrames = 0;
							APE_NEW.nBitsPerSample = 0;
							APE_NEW.nChannels = 0;
							APE_NEW.nSampleRate = 0;

							APE_NEW.nCompressionLevel = SourceFile.ReadUInt16();
							APE_NEW.nFormatFlags = SourceFile.ReadUInt16();
							APE_NEW.nBlocksPerFrame = SourceFile.ReadUInt32();
							APE_NEW.nFinalFrameBlocks = SourceFile.ReadUInt32();
							APE_NEW.nTotalFrames = SourceFile.ReadUInt32();
							APE_NEW.nBitsPerSample = SourceFile.ReadUInt16();
							APE_NEW.nChannels = SourceFile.ReadUInt16();
							APE_NEW.nSampleRate = SourceFile.ReadUInt32();
				
							// based on MAC SDK 3.98a1 (APEinfo.h)
							FSampleRate       = (int)APE_NEW.nSampleRate;
							FChannels         = APE_NEW.nChannels;
							FFormatFlags      = APE_NEW.nFormatFlags;
							FBits             = APE_NEW.nBitsPerSample;
							FCompressionMode  = APE_NEW.nCompressionLevel;
							// calculate total uncompressed samples
							if (APE_NEW.nTotalFrames > 0)
							{
								FTotalSamples     = (long)(APE_NEW.nBlocksPerFrame) *
									(long)(APE_NEW.nTotalFrames-1) +
									(long)(APE_NEW.nFinalFrameBlocks);
							}
							LoadSuccess = true;
						}
						else 
						{
							// Old Monkey <= 3.97               

							APE_OLD.nCompressionLevel = 0;
							APE_OLD.nFormatFlags = 0;
							APE_OLD.nChannels = 0;
							APE_OLD.nSampleRate = 0;
							APE_OLD.nHeaderBytes = 0;
							APE_OLD.nTerminatingBytes = 0;
							APE_OLD.nTotalFrames = 0;
							APE_OLD.nFinalFrameBlocks = 0;
							APE_OLD.nInt = 0;

							APE_OLD.nCompressionLevel = SourceFile.ReadUInt16();
							APE_OLD.nFormatFlags = SourceFile.ReadUInt16();
							APE_OLD.nChannels = SourceFile.ReadUInt16();
							APE_OLD.nSampleRate = SourceFile.ReadUInt32();
							APE_OLD.nHeaderBytes = SourceFile.ReadUInt32();
							APE_OLD.nTerminatingBytes = SourceFile.ReadUInt32();
							APE_OLD.nTotalFrames = SourceFile.ReadUInt32();
							APE_OLD.nFinalFrameBlocks = SourceFile.ReadUInt32();
							APE_OLD.nInt = SourceFile.ReadInt32();				

							FCompressionMode  = APE_OLD.nCompressionLevel;
							FSampleRate       = (int)APE_OLD.nSampleRate;
							FChannels         = APE_OLD.nChannels;
							FFormatFlags      = APE_OLD.nFormatFlags;
							FBits = 16;
							if ( (APE_OLD.nFormatFlags & MONKEY_FLAG_8_BIT ) != 0) FBits =  8;
							if ( (APE_OLD.nFormatFlags & MONKEY_FLAG_24_BIT) != 0) FBits = 24;

							FHasSeekElements  = ( (APE_OLD.nFormatFlags & MONKEY_FLAG_PEAK_LEVEL   )  != 0);
							FWavNotStored     = ( (APE_OLD.nFormatFlags & MONKEY_FLAG_SEEK_ELEMENTS) != 0);
							FHasPeakLevel     = ( (APE_OLD.nFormatFlags & MONKEY_FLAG_WAV_NOT_STORED) != 0);
                  
							if (FHasPeakLevel)
							{
								FPeakLevel        = (uint)APE_OLD.nInt;
								FPeakLevelRatio   = (FPeakLevel / (1 << FBits) / 2.0) * 100.0;
							}

							// based on MAC_SDK_397 (APEinfo.cpp)
							if (FVersion >= 3950) 
								BlocksPerFrame = 73728 * 4;
							else if ( (FVersion >= 3900) || ((FVersion >= 3800) && (MONKEY_COMPRESSION_EXTRA_HIGH == APE_OLD.nCompressionLevel)) )
								BlocksPerFrame = 73728;
							else
								BlocksPerFrame = 9216;

							// calculate total uncompressed samples
							if (APE_OLD.nTotalFrames>0)
							{
								FTotalSamples =  (long)(APE_OLD.nTotalFrames-1) *
									(long)(BlocksPerFrame) +
									(long)(APE_OLD.nFinalFrameBlocks);
							}
							LoadSuccess = true;
               
						}
						if (LoadSuccess) 
						{
							// compression profile name
							if ( (0 == (FCompressionMode % 1000)) && (FCompressionMode<=6000) )
							{
								FCompressionModeStr = MONKEY_COMPRESSION[FCompressionMode / 1000]; // int division
							}
							else 
							{
								FCompressionModeStr = FCompressionMode.ToString();
							}
							// length
							if (FSampleRate>0) FDuration = ((double)FTotalSamples / FSampleRate);
							// average bitrate
							if (FDuration>0) FBitrate = 8*(FFileSize - (long)(TagSize)) / (FDuration*1000);
							// some extra sanity checks
							FValid   = ((FBits>0) && (FSampleRate>0) && (FTotalSamples>0) && (FChannels>0));
							result   = FValid;
						}
					}
				}
				finally
				{
					if (fs != null)
					{
						fs.Unlock(0,fs.Length);
						if (SourceFile != null) SourceFile.Close();
					}
				}
			}
			catch (Exception e)
			{
				System.Console.WriteLine(e.StackTrace);
				result = false;
			}
			return result;
		}
Exemple #2
0
        // ---------------------------------------------------------------------------

        // No explicit destructors in C#

        // ---------------------------------------------------------------------------

        public bool ReadFromFile(String FileName)
        {
            APE_HEADER     APE      = new APE_HEADER();                 // common header
            APE_HEADER_OLD APE_OLD  = new APE_HEADER_OLD();             // old header   <= 3.97
            APE_HEADER_NEW APE_NEW  = new APE_HEADER_NEW();             // new header   >= 3.98
            APE_DESCRIPTOR APE_DESC = new APE_DESCRIPTOR();             // extra header >= 3.98

            FileStream   fs         = null;
            BinaryReader SourceFile = null;

            int  BlocksPerFrame;
            bool LoadSuccess;
            int  TagSize;
            bool result = false;

            FResetData();

            // load tags first
            FID3v2.ReadFromFile(FileName);
            FID3v1.ReadFromFile(FileName);
            FAPEtag.ReadFromFile(FileName);

            // calculate total tag size
            TagSize = 0;
            if (FID3v1.Exists)
            {
                TagSize += 128;
            }
            if (FID3v2.Exists)
            {
                TagSize += FID3v2.Size;
            }
            if (FAPEtag.Exists)
            {
                TagSize += FAPEtag.Size;
            }

            // reading data from file
            LoadSuccess = false;

            try
            {
                try
                {
                    fs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
                    fs.Lock(0, fs.Length);
                    SourceFile = new BinaryReader(fs);
                    FFileSize  = fs.Length;

                    // seek past id3v2-tag
                    if (FID3v2.Exists)
                    {
                        fs.Seek(FID3v2.Size, SeekOrigin.Begin);
                    }
                    // Read APE Format Header
                    Array.Clear(APE.cID, 0, APE.cID.Length);
                    APE.nVersion = 0;

                    APE.cID      = SourceFile.ReadChars(4);
                    APE.nVersion = SourceFile.ReadUInt16();

                    if (Utils.StringEqualsArr("MAC ", APE.cID))
                    {
                        FVersion = APE.nVersion;

                        FVersionStr = ((double)FVersion / 1000).ToString().Substring(0, 4);                        //Str(FVersion / 1000 : 4 : 2, FVersionStr);

                        // Load New Monkey's Audio Header for version >= 3.98
                        if (APE.nVersion >= 3980)
                        {
                            APE_DESC.padded                 = 0;
                            APE_DESC.nDescriptorBytes       = 0;
                            APE_DESC.nHeaderBytes           = 0;
                            APE_DESC.nSeekTableBytes        = 0;
                            APE_DESC.nHeaderDataBytes       = 0;
                            APE_DESC.nAPEFrameDataBytes     = 0;
                            APE_DESC.nAPEFrameDataBytesHigh = 0;
                            APE_DESC.nTerminatingDataBytes  = 0;
                            Array.Clear(APE_DESC.cFileMD5, 0, APE_DESC.cFileMD5.Length);

                            APE_DESC.padded                 = SourceFile.ReadUInt16();
                            APE_DESC.nDescriptorBytes       = SourceFile.ReadUInt32();
                            APE_DESC.nHeaderBytes           = SourceFile.ReadUInt32();
                            APE_DESC.nSeekTableBytes        = SourceFile.ReadUInt32();
                            APE_DESC.nHeaderDataBytes       = SourceFile.ReadUInt32();
                            APE_DESC.nAPEFrameDataBytes     = SourceFile.ReadUInt32();
                            APE_DESC.nAPEFrameDataBytesHigh = SourceFile.ReadUInt32();
                            APE_DESC.nTerminatingDataBytes  = SourceFile.ReadUInt32();
                            APE_DESC.cFileMD5               = SourceFile.ReadBytes(16);

                            // seek past description header
                            if (APE_DESC.nDescriptorBytes != 52)
                            {
                                fs.Seek(APE_DESC.nDescriptorBytes - 52, SeekOrigin.Current);
                            }
                            // load new ape_header
                            if (APE_DESC.nHeaderBytes > 24 /*sizeof(APE_NEW)*/)
                            {
                                APE_DESC.nHeaderBytes = 24 /*sizeof(APE_NEW)*/;
                            }

                            APE_NEW.nCompressionLevel = 0;
                            APE_NEW.nFormatFlags      = 0;
                            APE_NEW.nBlocksPerFrame   = 0;
                            APE_NEW.nFinalFrameBlocks = 0;
                            APE_NEW.nTotalFrames      = 0;
                            APE_NEW.nBitsPerSample    = 0;
                            APE_NEW.nChannels         = 0;
                            APE_NEW.nSampleRate       = 0;

                            APE_NEW.nCompressionLevel = SourceFile.ReadUInt16();
                            APE_NEW.nFormatFlags      = SourceFile.ReadUInt16();
                            APE_NEW.nBlocksPerFrame   = SourceFile.ReadUInt32();
                            APE_NEW.nFinalFrameBlocks = SourceFile.ReadUInt32();
                            APE_NEW.nTotalFrames      = SourceFile.ReadUInt32();
                            APE_NEW.nBitsPerSample    = SourceFile.ReadUInt16();
                            APE_NEW.nChannels         = SourceFile.ReadUInt16();
                            APE_NEW.nSampleRate       = SourceFile.ReadUInt32();

                            // based on MAC SDK 3.98a1 (APEinfo.h)
                            FSampleRate      = (int)APE_NEW.nSampleRate;
                            FChannels        = APE_NEW.nChannels;
                            FFormatFlags     = APE_NEW.nFormatFlags;
                            FBits            = APE_NEW.nBitsPerSample;
                            FCompressionMode = APE_NEW.nCompressionLevel;
                            // calculate total uncompressed samples
                            if (APE_NEW.nTotalFrames > 0)
                            {
                                FTotalSamples = (long)(APE_NEW.nBlocksPerFrame) *
                                                (long)(APE_NEW.nTotalFrames - 1) +
                                                (long)(APE_NEW.nFinalFrameBlocks);
                            }
                            LoadSuccess = true;
                        }
                        else
                        {
                            // Old Monkey <= 3.97

                            APE_OLD.nCompressionLevel = 0;
                            APE_OLD.nFormatFlags      = 0;
                            APE_OLD.nChannels         = 0;
                            APE_OLD.nSampleRate       = 0;
                            APE_OLD.nHeaderBytes      = 0;
                            APE_OLD.nTerminatingBytes = 0;
                            APE_OLD.nTotalFrames      = 0;
                            APE_OLD.nFinalFrameBlocks = 0;
                            APE_OLD.nInt = 0;

                            APE_OLD.nCompressionLevel = SourceFile.ReadUInt16();
                            APE_OLD.nFormatFlags      = SourceFile.ReadUInt16();
                            APE_OLD.nChannels         = SourceFile.ReadUInt16();
                            APE_OLD.nSampleRate       = SourceFile.ReadUInt32();
                            APE_OLD.nHeaderBytes      = SourceFile.ReadUInt32();
                            APE_OLD.nTerminatingBytes = SourceFile.ReadUInt32();
                            APE_OLD.nTotalFrames      = SourceFile.ReadUInt32();
                            APE_OLD.nFinalFrameBlocks = SourceFile.ReadUInt32();
                            APE_OLD.nInt = SourceFile.ReadInt32();

                            FCompressionMode = APE_OLD.nCompressionLevel;
                            FSampleRate      = (int)APE_OLD.nSampleRate;
                            FChannels        = APE_OLD.nChannels;
                            FFormatFlags     = APE_OLD.nFormatFlags;
                            FBits            = 16;
                            if ((APE_OLD.nFormatFlags & MONKEY_FLAG_8_BIT) != 0)
                            {
                                FBits = 8;
                            }
                            if ((APE_OLD.nFormatFlags & MONKEY_FLAG_24_BIT) != 0)
                            {
                                FBits = 24;
                            }

                            FHasSeekElements = ((APE_OLD.nFormatFlags & MONKEY_FLAG_PEAK_LEVEL) != 0);
                            FWavNotStored    = ((APE_OLD.nFormatFlags & MONKEY_FLAG_SEEK_ELEMENTS) != 0);
                            FHasPeakLevel    = ((APE_OLD.nFormatFlags & MONKEY_FLAG_WAV_NOT_STORED) != 0);

                            if (FHasPeakLevel)
                            {
                                FPeakLevel      = (uint)APE_OLD.nInt;
                                FPeakLevelRatio = (FPeakLevel / (1 << FBits) / 2.0) * 100.0;
                            }

                            // based on MAC_SDK_397 (APEinfo.cpp)
                            if (FVersion >= 3950)
                            {
                                BlocksPerFrame = 73728 * 4;
                            }
                            else if ((FVersion >= 3900) || ((FVersion >= 3800) && (MONKEY_COMPRESSION_EXTRA_HIGH == APE_OLD.nCompressionLevel)))
                            {
                                BlocksPerFrame = 73728;
                            }
                            else
                            {
                                BlocksPerFrame = 9216;
                            }

                            // calculate total uncompressed samples
                            if (APE_OLD.nTotalFrames > 0)
                            {
                                FTotalSamples = (long)(APE_OLD.nTotalFrames - 1) *
                                                (long)(BlocksPerFrame) +
                                                (long)(APE_OLD.nFinalFrameBlocks);
                            }
                            LoadSuccess = true;
                        }
                        if (LoadSuccess)
                        {
                            // compression profile name
                            if ((0 == (FCompressionMode % 1000)) && (FCompressionMode <= 6000))
                            {
                                FCompressionModeStr = MONKEY_COMPRESSION[FCompressionMode / 1000];                                 // int division
                            }
                            else
                            {
                                FCompressionModeStr = FCompressionMode.ToString();
                            }
                            // length
                            if (FSampleRate > 0)
                            {
                                FDuration = ((double)FTotalSamples / FSampleRate);
                            }
                            // average bitrate
                            if (FDuration > 0)
                            {
                                FBitrate = 8 * (FFileSize - (long)(TagSize)) / (FDuration * 1000);
                            }
                            // some extra sanity checks
                            FValid = ((FBits > 0) && (FSampleRate > 0) && (FTotalSamples > 0) && (FChannels > 0));
                            result = FValid;
                        }
                    }
                }
                finally
                {
                    if (fs != null)
                    {
                        fs.Unlock(0, fs.Length);
                        if (SourceFile != null)
                        {
                            SourceFile.Close();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.StackTrace);
                result = false;
            }
            return(result);
        }