Exemplo n.º 1
0
        /* -------------------------------------------------------------------------- */

        public bool GetInfo(String sFile, bool bSetTags)
        {
            FileStream   fs = null;
            BinaryReader r  = null;

            byte[] aMetaDataBlockHeader = new byte[4];
            int    iBlockLength;
            int    iMetaType;
            int    iIndex;
            bool   bPaddingFound;

            bool result = true;

            bPaddingFound = false;
            FResetData(true, false);

            try
            {
                // Read data from ID3 tags
                FID3v2.ReadFromFile(sFile);

                // Set read-access and open file
                fs = new FileStream(sFile, FileMode.Open, FileAccess.Read);
                fs.Lock(0, fs.Length);
                r = new BinaryReader(fs);

                FFileLength = (int)fs.Length;
                FFileName   = sFile;

                // Seek past the ID3v2 tag, if there is one
                if (FID3v2.Exists)
                {
                    fs.Seek(FID3v2.Size, SeekOrigin.Begin);
                }

                // Read header data
                FHeader.Reset();

                FHeader.StreamMarker        = r.ReadChars(4);
                FHeader.MetaDataBlockHeader = r.ReadBytes(4);
                FHeader.Info   = r.ReadBytes(18);
                FHeader.MD5Sum = r.ReadBytes(16);

                // Process data if loaded and header valid
                if (Utils.StringEqualsArr("fLaC", FHeader.StreamMarker))
                {
                    FChannels      = (byte)(((FHeader.Info[12] >> 1) & 0x7) + 1);
                    FSampleRate    = (FHeader.Info[10] << 12 | FHeader.Info[11] << 4 | FHeader.Info[12] >> 4);
                    FBitsPerSample = (byte)(((FHeader.Info[12] & 1) << 4) | (FHeader.Info[13] >> 4) + 1);
                    FSamples       = (FHeader.Info[14] << 24 | FHeader.Info[15] << 16 | FHeader.Info[16] << 8 | FHeader.Info[17]);

                    if (0 == (FHeader.MetaDataBlockHeader[1] & 0x80))                       // metadata block exists
                    {
                        iIndex = 0;
                        do                         // read more metadata blocks if available
                        {
                            aMetaDataBlockHeader = r.ReadBytes(4);

                            iIndex++;                                                                                                // metadatablock index
                            iBlockLength = (aMetaDataBlockHeader[1] << 16 | aMetaDataBlockHeader[2] << 8 | aMetaDataBlockHeader[3]); //decode length
                            if (iBlockLength <= 0)
                            {
                                break;                                                // can it be 0 ?
                            }
                            iMetaType = (aMetaDataBlockHeader[0] & 0x7F);             // decode metablock type

                            if (iMetaType == META_VORBIS_COMMENT)
                            {                              // read vorbis block
                                FVCOffset    = (int)fs.Position;
                                FTagSize     = iBlockLength;
                                FVorbisIndex = iIndex;
                                ReadTag(r, bSetTags);                                 // set up fields
                            }
                            else
                            {
                                if ((iMetaType == META_PADDING) && (!bPaddingFound))                                    // we have padding block
                                {
                                    FPadding      = iBlockLength;                                                       // if we find more skip & put them in metablock array
                                    FPaddingLast  = ((aMetaDataBlockHeader[0] & 0x80) != 0);
                                    FPaddingIndex = iIndex;
                                    bPaddingFound = true;
                                    fs.Seek(FPadding, SeekOrigin.Current); // advance into file till next block or audio data start
                                }
                                else                                       // all other
                                {
                                    if (iMetaType <= 5)                    // is it a valid metablock ?
                                    {
                                        if (META_PADDING == iMetaType)     // set flag for fragmented padding blocks
                                        {
                                            FPaddingFragments = true;
                                        }
                                        AddMetaDataOther(aMetaDataBlockHeader, r, iBlockLength, iIndex);
                                    }
                                    else
                                    {
                                        FSamples = 0;                                         //ops...
                                        break;
                                    }
                                }
                            }
                        }while (0 == (aMetaDataBlockHeader[0] & 0x80));                          // while is not last flag ( first bit == 1 )
                    }
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.StackTrace);
                //LogDelegator.GetLogDelegate()(Log.LV_ERROR,e.Message);
                result = false;
            }

            if (FIsValid())
            {
                FAudioOffset = (int)fs.Position;                                                               // we need that to rebuild the file if nedeed
                FBitrate     = Math.Round(((double)(FFileLength - FAudioOffset) / 1000) * 8 / FGetDuration()); //time to calculate average bitrate
            }
            else
            {
                result = false;
            }

            if (fs != null)
            {
                fs.Unlock(0, fs.Length);
                fs.Close();
            }

            return(result);
        }