protected override bool read(BinaryReader source, ReadTagParams readTagParams) { bool result = true; SPCHeader header = new SPCHeader(); SPCExTags footer = new SPCExTags(); header.Reset(); footer.Reset(); resetData(); source.BaseStream.Seek(sizeInfo.ID3v2Size, SeekOrigin.Begin); if (!readHeader(source, ref header)) { throw new InvalidDataException("Not a SPC file"); } // Reads the header tag if (SPCHeader.TAG_IN_HEADER == header.TagInHeader) { tagExists = true; source.BaseStream.Seek(REGISTERS_LENGTH, SeekOrigin.Current); readHeaderTags(source, ref header, readTagParams); } AudioDataOffset = source.BaseStream.Position; // Reads extended tag if (source.BaseStream.Length > SPC_RAW_LENGTH) { source.BaseStream.Seek(SPC_RAW_LENGTH, SeekOrigin.Begin); readExtendedData(source, ref footer, readTagParams); } else { if (readTagParams.PrepareForWriting) { structureHelper.AddZone(SPC_RAW_LENGTH, 0, ZONE_EXTENDED); } } AudioDataSize = sizeInfo.FileSize - header.Size - footer.Size; bitrate = AudioDataSize * 8 / duration; return(result); }
protected override Boolean read(BinaryReader source, MetaDataIO.ReadTagParams readTagParams) { var result = true; var header = new SPCHeader(); var footer = new SPCExTags(); header.Reset(); footer.Reset(); resetData(); source.BaseStream.Seek(sizeInfo.ID3v2Size, SeekOrigin.Begin); isValid = readHeader(source, ref header); if (!isValid) { throw new Exception("Not a SPC file"); } // Reads the header tag if (SPCHeader.TAG_IN_HEADER == header.TagInHeader) { tagExists = true; source.BaseStream.Seek(REGISTERS_LENGTH, SeekOrigin.Current); readHeaderTags(source, ref header, readTagParams); } // Reads extended tag if (source.BaseStream.Length > SPC_RAW_LENGTH) { source.BaseStream.Seek(SPC_RAW_LENGTH, SeekOrigin.Begin); readExtendedData(source, ref footer, readTagParams); } else { if (readTagParams.PrepareForWriting) { structureHelper.AddZone(SPC_RAW_LENGTH, 0, ZONE_EXTENDED); } } bitrate = (sizeInfo.FileSize - header.Size) * 8 / duration; return(result); }
private void readExtendedData(ref BinaryReader source, ref SPCExTags footer) { footer.FooterTag = Utils.GetStringFromCharArray(Utils.ReadTrueChars(source, 4)); if (XTENDED_TAG == footer.FooterTag) { footer.FooterSize = source.ReadUInt32(); ExtendedItem anItem; long i = source.BaseStream.Position; while (source.BaseStream.Position - i < footer.FooterSize) { anItem = new ExtendedItem(); anItem.ID = source.ReadByte(); anItem.Type = source.ReadByte(); anItem.Length = source.ReadUInt16(); switch (anItem.Type) { case XID6_TVAL: // nothing; value is stored into the Length field break; case XID6_TSTR: anItem.Data = Utils.GetStringFromCharArray(Utils.ReadTrueChars(source, anItem.Length)); while (0 == source.ReadByte()) { ; // Ending zeroes } source.BaseStream.Seek(-1, SeekOrigin.Current); break; case XID6_TINT: anItem.Data = source.ReadInt32(); break; } footer.Items.Add(anItem.ID, anItem); } } }
private void readExtendedData(BinaryReader source, ref SPCExTags footer, ReadTagParams readTagParams) { long initialPosition = source.BaseStream.Position; footer.FormatTag = Utils.Latin1Encoding.GetString(source.ReadBytes(4)); if (XTENDED_TAG == footer.FormatTag) { tagExists = true; footer.Size = source.ReadUInt32(); byte ID, type; ushort size; string strData = ""; int intData = 0; long ticks = 0; long dataPosition = source.BaseStream.Position; while (source.BaseStream.Position < dataPosition + footer.Size - 4) { ID = source.ReadByte(); type = source.ReadByte(); size = source.ReadUInt16(); switch (type) { case XID6_TVAL: // Value is stored into the Size field if (ID == XID6_TRACK) // Specific case : upper byte is the number 0-99, lower byte is an optional ASCII character { intData = size >> 8; strData = intData.ToString(); byte optionalChar = (byte)(size & 0x00FF); if (optionalChar > 0x20) // Character is displayable { strData += (char)optionalChar; } } else { intData = size; strData = intData.ToString(); } break; case XID6_TSTR: intData = 0; strData = Utils.Latin1Encoding.GetString(source.ReadBytes(size)).Replace("\0", "").Trim(); while (source.BaseStream.Position < source.BaseStream.Length && 0 == source.ReadByte()) { ; // Skip parasite ending zeroes } if (source.BaseStream.Position < source.BaseStream.Length) { source.BaseStream.Seek(-1, SeekOrigin.Current); } break; case XID6_TINT: intData = source.ReadInt32(); strData = intData.ToString(); break; } if (XID6_LOOP == ID) { ticks += Math.Min(XID6_MAXTICKS, intData); } else if (XID6_LOOPX == ID) { ticks = ticks * Math.Min(XID6_MAXLOOP, (int)size); } else if (XID6_INTRO == ID) { ticks += Math.Min(XID6_MAXTICKS, intData); } else if (XID6_END == ID) { ticks += Math.Min(XID6_MAXTICKS, intData); } else if (XID6_FADE == ID) { ticks += Math.Min(XID6_MAXTICKS, intData); } SetMetaField(ID.ToString(), strData, readTagParams.ReadAllMetaFrames, ZONE_EXTENDED); } if (ticks > 0) { duration = Math.Round((double)ticks / XID6_TICKSSEC); } if (readTagParams.PrepareForWriting) { structureHelper.AddZone(initialPosition, (int)(source.BaseStream.Position - initialPosition), ZONE_EXTENDED); } } }
// === PUBLIC METHODS === public bool ReadFromFile(String fileName) { bool result = true; SPCHeader header = new SPCHeader(); SPCExTags footer = new SPCExTags(); FResetData(); header.Reset(); footer.Reset(); FileStream fs = null; BinaryReader source = null; try { fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); fs.Lock(0, fs.Length); source = new BinaryReader(fs); if (!readHeader(ref source, ref header)) { throw new Exception("Not a PSF file"); } // Reads the header tag if (SPCHeader.TAG_IN_HEADER == header.TagInHeader) { source.BaseStream.Seek(REGISTERS_LENGTH, SeekOrigin.Current); readHeaderTags(ref source); } // Reads extended tag if (fs.Length > SPC_RAW_LENGTH) { source.BaseStream.Seek(SPC_RAW_LENGTH, SeekOrigin.Begin); readExtendedData(ref source, ref footer); if (footer.Items.ContainsKey(XID6_ARTIST)) { FArtist = (String)((ExtendedItem)footer.Items[XID6_ARTIST]).Data; } if (footer.Items.ContainsKey(XID6_CMNTS)) { FComment = (String)((ExtendedItem)footer.Items[XID6_CMNTS]).Data; } if (footer.Items.ContainsKey(XID6_SONG)) { FTitle = (String)((ExtendedItem)footer.Items[XID6_SONG]).Data; } if (footer.Items.ContainsKey(XID6_COPY)) { FYear = ((ExtendedItem)footer.Items[XID6_COPY]).Length.ToString(); } if (footer.Items.ContainsKey(XID6_TRACK)) { FTrack = ((ExtendedItem)footer.Items[XID6_TRACK]).Length >> 8; } if (footer.Items.ContainsKey(XID6_OST)) { FAlbum = (String)((ExtendedItem)footer.Items[XID6_OST]).Data; } if (("" == FAlbum) && (footer.Items.ContainsKey(XID6_GAME))) { FAlbum = (String)((ExtendedItem)footer.Items[XID6_GAME]).Data; } long ticks = 0; if (footer.Items.ContainsKey(XID6_LOOP)) { ticks += Math.Min(XID6_MAXTICKS, (int)((ExtendedItem)footer.Items[XID6_LOOP]).Data); } if (footer.Items.ContainsKey(XID6_LOOPX)) { ticks = ticks * Math.Min(XID6_MAXLOOP, (int)((ExtendedItem)footer.Items[XID6_LOOPX]).Length); } if (footer.Items.ContainsKey(XID6_INTRO)) { ticks += Math.Min(XID6_MAXTICKS, (int)((ExtendedItem)footer.Items[XID6_INTRO]).Data); } if (footer.Items.ContainsKey(XID6_END)) { ticks += Math.Min(XID6_MAXTICKS, (int)((ExtendedItem)footer.Items[XID6_END]).Data); } if (ticks > 0) { FDuration = Math.Round((double)ticks / XID6_TICKSSEC); } } } catch (Exception e) { System.Console.WriteLine(e.StackTrace); //LogDelegator.GetLogDelegate()(Log.LV_ERROR, e.Message); result = false; } if (fs != null) { fs.Unlock(0, fs.Length); fs.Close(); } return(result); }
// === PUBLIC METHODS === public bool ReadFromFile(String fileName) { bool result = true; SPCHeader header = new SPCHeader(); SPCExTags footer = new SPCExTags(); FResetData(); header.Reset(); footer.Reset(); FileStream fs = null; BinaryReader source = null; try { fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); fs.Lock(0,fs.Length); source = new BinaryReader(fs); if ( !readHeader(ref source, ref header) ) throw new Exception("Not a PSF file"); // Reads the header tag if (SPCHeader.TAG_IN_HEADER == header.TagInHeader) { source.BaseStream.Seek(REGISTERS_LENGTH,SeekOrigin.Current); readHeaderTags(ref source); } // Reads extended tag if (fs.Length > SPC_RAW_LENGTH) { source.BaseStream.Seek(SPC_RAW_LENGTH,SeekOrigin.Begin); readExtendedData(ref source, ref footer); if (footer.Items.ContainsKey(XID6_ARTIST)) FArtist = (String)((ExtendedItem)footer.Items[XID6_ARTIST]).Data; if (footer.Items.ContainsKey(XID6_CMNTS)) FComment = (String)((ExtendedItem)footer.Items[XID6_CMNTS]).Data; if (footer.Items.ContainsKey(XID6_SONG)) FTitle = (String)((ExtendedItem)footer.Items[XID6_SONG]).Data; if (footer.Items.ContainsKey(XID6_COPY)) FYear = ((ExtendedItem)footer.Items[XID6_COPY]).Length.ToString(); if (footer.Items.ContainsKey(XID6_TRACK)) FTrack = ((ExtendedItem)footer.Items[XID6_TRACK]).Length >> 8; if (footer.Items.ContainsKey(XID6_OST)) FAlbum = (String)((ExtendedItem)footer.Items[XID6_OST]).Data; if (("" == FAlbum) && (footer.Items.ContainsKey(XID6_GAME))) FAlbum = (String)((ExtendedItem)footer.Items[XID6_GAME]).Data; long ticks = 0; if (footer.Items.ContainsKey(XID6_LOOP)) ticks += Math.Min(XID6_MAXTICKS, (int)((ExtendedItem)footer.Items[XID6_LOOP]).Data); if (footer.Items.ContainsKey(XID6_LOOPX)) ticks = ticks * Math.Min(XID6_MAXLOOP, (int)((ExtendedItem)footer.Items[XID6_LOOPX]).Length ); if (footer.Items.ContainsKey(XID6_INTRO)) ticks += Math.Min(XID6_MAXTICKS, (int)((ExtendedItem)footer.Items[XID6_INTRO]).Data); if (footer.Items.ContainsKey(XID6_END)) ticks += Math.Min(XID6_MAXTICKS, (int)((ExtendedItem)footer.Items[XID6_END]).Data); if (ticks > 0) FDuration = Math.Round( (double)ticks / XID6_TICKSSEC ); } } catch (Exception e) { System.Console.WriteLine(e.StackTrace); //LogDelegator.GetLogDelegate()(Log.LV_ERROR, e.Message); result = false; } if (fs != null) { fs.Unlock(0,fs.Length); fs.Close(); } return result; }
private void readExtendedData(ref BinaryReader source, ref SPCExTags footer) { footer.FooterTag = Utils.GetStringFromCharArray(Utils.ReadTrueChars(source,4)); if (XTENDED_TAG == footer.FooterTag) { footer.FooterSize = source.ReadUInt32(); ExtendedItem anItem; long i=source.BaseStream.Position; while(source.BaseStream.Position-i < footer.FooterSize) { anItem = new ExtendedItem(); anItem.ID = source.ReadByte(); anItem.Type = source.ReadByte(); anItem.Length = source.ReadUInt16(); switch(anItem.Type) { case XID6_TVAL : // nothing; value is stored into the Length field break; case XID6_TSTR : anItem.Data = Utils.GetStringFromCharArray(Utils.ReadTrueChars(source,anItem.Length)); while(0 == source.ReadByte()); // Ending zeroes source.BaseStream.Seek(-1,SeekOrigin.Current); break; case XID6_TINT : anItem.Data = source.ReadInt32(); break; } footer.Items.Add( anItem.ID, anItem ); } } }