/// <summary> /// Initialize the CueSheetTrack. /// </summary> /// <param name="data">The full data array.</param> /// <param name="dataOffset">Where the cuesheet track begins.</param> public CueSheetTrack(byte[] data, int dataOffset) { this.trackOffset = BinaryDataHelper.GetUInt64(data, dataOffset); this.trackNumber = (byte)BinaryDataHelper.GetUInt64(data, dataOffset + 8, 8); this.isrc = System.Text.Encoding.ASCII.GetString(data, dataOffset + 9, 12).Trim(new char[] { '\0' }); this.isAudioTrack = !BinaryDataHelper.GetBoolean(data, dataOffset + 21, 1); // 0 for audio this.isPreEmphasis = BinaryDataHelper.GetBoolean(data, dataOffset + 21, 2); // 6 bits + 13 bytes need to be zero, won't check this byte indexPointCount = (byte)BinaryDataHelper.GetUInt64(data, dataOffset + 35, 8); if (indexPointCount > 100) { throw new FlacLibSharp.Exceptions.FlacLibSharpInvalidFormatException(string.Format("CueSheet track nr {0} has an invalid Track Index Count of {1}. Maximum allowed is 100.", this.TrackNumber, indexPointCount)); } // For all tracks, except the lead-in track, one or more track index points dataOffset += 36; for (int i = 0; i < indexPointCount; i++) { this.IndexPoints.Add(new CueSheetTrackIndex(data, dataOffset)); dataOffset += 12; // Index points are always 12 bytes long } if (indexPointCount != this.IndexPoints.Count) { // Should we be so strict? throw new FlacLibSharp.Exceptions.FlacLibSharpInvalidFormatException(string.Format("CueSheet track nr {0} indicates {1} index points, but actually {2} index points are present.", this.TrackNumber, indexPointCount, this.IndexPoints.Count)); } }
/// <summary> /// Interprets the meta data block header. /// </summary> /// <param name="data"></param> protected void ParseData(byte[] data) { // Parses the 4 byte header data: // Bit 1: Last-metadata-block flag: '1' if this block is the last metadata block before the audio blocks, '0' otherwise. // Bit 2-8: Block Type, // 0 : STREAMINFO // 1 : PADDING // 2 : APPLICATION // 3 : SEEKTABLE // 4 : VORBIS_COMMENT // 5 : CUESHEET // 6 : PICTURE // 7-126 : reserved // 127 : invalid, to avoid confusion with a frame sync code // Next 3 bytes: Length (in bytes) of metadata to follow (does not include the size of the METADATA_BLOCK_HEADER) this.isLastMetaDataBlock = BinaryDataHelper.GetBoolean(data, 0, 0); typeID = data[0] & 0x7F; switch (typeID) { case 0: this.type = MetadataBlockType.StreamInfo; this.metaDataBlockLength = 34; break; case 1: this.type = MetadataBlockType.Padding; break; case 2: this.type = MetadataBlockType.Application; break; case 3: this.type = MetadataBlockType.Seektable; break; case 4: this.type = MetadataBlockType.VorbisComment; break; case 5: this.type = MetadataBlockType.CueSheet; break; case 6: this.type = MetadataBlockType.Picture; break; } if (typeID > 6 && typeID < 127) { this.type = MetadataBlockType.None; } else if(typeID >= 127) { this.type = MetadataBlockType.Invalid; } this.metaDataBlockLength = (BinaryDataHelper.GetUInt24(data, 1)); }
/// <summary> /// Parses the binary metadata from the flac file into a CueSheet object. /// </summary> /// <param name="data">The binary data from the flac file.</param> public override void LoadBlockData(byte[] data) { this.mediaCatalog = Encoding.ASCII.GetString(data, 0, 128).Trim(new char[] { '\0' }); this.leadInSampleCount = BinaryDataHelper.GetUInt64(data, 128); this.isCDCueSheet = BinaryDataHelper.GetBoolean(data, 136, 0); // We're skipping 7 bits + 258 bytes which is reserved null data byte trackCount = data[395]; if (trackCount > 100) { // Do we really need to throw an exception here? throw new Exceptions.FlacLibSharpInvalidFormatException(string.Format("CueSheet has invalid track count {0}. Cannot be more than 100.", trackCount)); } int cueSheetTrackOffset = 396; for (int i = 0; i < trackCount; i++) { CueSheetTrack newTrack = new CueSheetTrack(data, cueSheetTrackOffset); cueSheetTrackOffset += 36 + (12 * newTrack.IndexPointCount); // 36 bytes for the cueSheetTrack and 12 bytes per index point ... this.Tracks.Add(newTrack); } }