/*else if (mAudioFileTrack == AUDIO_OGG) * { * unsigned char *vc = new unsigned char[TagSize+10]; * * // Vendor size, Vendor * sprintf(vc, "%c%c%c%c%s%c%c%c%c", mVendor.Length() & 0xFF, (mVendor.Length() >> 8) & 0xFF, (mVendor.Length() >> 16) & 0xFF, (mVendor.Length() >> 24) & 0xFF, mVendor.c_str(), \ * elements & 0xFF, (elements >> 8) & 0xFF, (elements >> 16) & 0xFF, (elements >> 24) & 0xFF); * * unsigned long offset = 4 + mVendor.Length() + 4; * if (Field != NULL) * { * Rewind(); * do * { * String Vector = Field->ItemKey + "=" + Field->ItemValue; * * // Vector size, Vector * vc[offset++] = Vector.Length() & 0xFF; * vc[offset++] = (Vector.Length() >> 8) & 0xFF; * vc[offset++] = (Vector.Length() >> 16) & 0xFF; * vc[offset++] = (Vector.Length() >> 24) & 0xFF; * * for (i=0; i<Vector.Length(); i++) * { * vc[offset++] = Vector.c_str()[i]; * } * * } while (this->NextField()); * } * * if (NewPaddingSize > 3) * { * NewPaddingSize -= 1; * * fseek(fp, mvcoffset, SEEK_SET); * fwrite(vc, offset, 1, fp); * fputc(0x01, fp); * for (i=0; i<NewPaddingSize; i++) fputc(0x00, fp); * } * else * { * fclose(fp); * * sprintf(buf, "%s__tmpaudio%lu", DirTrunc(Filename), releasetotalcount+16); * * if (rename(Filename.c_str(), buf) != 0) * { * String msg = ""; * fp = fopen(buf, "rb"); * if (fp != NULL) * { * fclose(fp); * msg = String((char *)buf) + " exists; "; * throw Exception(String(msg + "rename(\"" + FilenameTrunc(Filename) + "\", \"" + String(FilenameTrunc((char *)buf)) + "\"); failed").c_str()); * } * else * { * msg = String((char *)buf) + " does not exist; "; * fp = fopen(buf, "wb"); * if (fp == NULL) * { * msg = "cant open " + String((char *)buf) + "; "; * throw Exception(String(msg + "rename(\"" + FilenameTrunc(Filename) + "\", \"" + String(FilenameTrunc((char *)buf)) + "\"); failed").c_str()); * } * FILE *ren = fopen(Filename.c_str(), "rb"); * if (ren == NULL) * { * msg = Filename + " does not exist; "; * throw Exception(String(msg + "rename(\"" + FilenameTrunc(Filename) + "\", \"" + String(FilenameTrunc((char *)buf)) + "\"); failed").c_str()); * } * * iRead = fread(buf, 1, cuiReadBufSize, ren); * while (iRead) * { * fwrite(buf, iRead, 1, fp); * iRead = fread(buf, 1, cuiReadBufSize, ren); * } * * fclose(fp); * fclose(ren); * } * * sprintf(buf, "%s__tmpaudio%lu", DirTrunc(Filename), releasetotalcount+16); * } * * fp = fopen(buf, "rb"); * out = fopen(Filename.c_str(), "wb+"); * * unsigned long curpos = 0; * step = "initial read"; * iRead = fread(buf, 1, cuiReadBufSize, fp); * while (iRead) * { * curpos += iRead; * if (curpos > lSPageStart) * { * iRead -= (curpos - lSPageStart); * fwrite(buf, iRead, 1, out); * break; * } * else * { * fwrite(buf, iRead, 1, out); * iRead = fread(buf, 1, cuiReadBufSize, fp); * } * } * * step = "read second page header"; * fseek(fp, lSPageStart, SEEK_SET); * fread(buf, 1, 27, fp); * * buf[22] = 0; // clear CRC * buf[23] = 0; * buf[24] = 0; * buf[25] = 0; * * step = "set up new lace vals"; * int origlace = ((mOrigVorbisCommentSize + mOrigPaddingSize + 7) / 255) + 1; * int newlace = ((offset + 1000 + 8) / 255) + 1; * int oldlace = buf[26]; * * buf[26] += (newlace - origlace); * * step = "output header"; * fwrite(buf, 27, 1, out); * * step = "output new lacing vals"; * int toffset = offset + 1000 + 8; // 0x03 + 'vorbis' + 0x01 * while (toffset >= 0) * { * fputc((toffset >= 255 ? 255 : toffset) & 0xFF, out); * toffset -= 255; * } * step = "skip old lacing vals"; * fread(buf, 1, origlace, fp); * step = "output last lacing vals"; * for (i=origlace; i<oldlace; i++) * { * fputc(fgetc(fp), out); * } * * sprintf(buf, "%cvorbis", 0x03); * fwrite(buf, 7, 1, out); * * step = "write vorbis comment"; * fwrite(vc, offset, 1, out); * * int a = FileSize/cuiReadBufSize / 21; * int b = a, x, y; * * if (Progress != NULL) * { * Progress->SetVisible(); * } * * // write stop bit * fputc(1, out); * for (i=0; i<1000; i++) fputc(0x00, out); * * // seek past vorbis comment * fseek(fp, mvcoffset + mOrigVorbisCommentSize + mOrigPaddingSize, SEEK_SET); * // copy rest of file * iRead = fread(buf, 1, cuiReadBufSize, fp); * while (iRead) * { * fwrite(buf, iRead, 1, out); * iRead = fread(buf, 1, cuiReadBufSize, fp); * } * * fclose(fp); * fclose(out); * * sprintf(buf, "%s__tmpaudio%lu", DirTrunc(Filename), releasetotalcount+16); * unlink(buf); * * fp = fopen(Filename.c_str(), "rb+"); * } * * delete[] vc; * * // crc: clear current crc * fseek(fp, lSPageStart+22, SEEK_SET); * fputc(0x00, fp); * fputc(0x00, fp); * fputc(0x00, fp); * fputc(0x00, fp); * * // crc: reseek * fseek(fp, lSPageStart+26, SEEK_SET); * int lacings = fgetc(fp); * unsigned char LacingSize[255]; * step = "crc: get lacings (" + String(lacings) + ")"; * for (i=0; i<lacings; i++) * { * LacingSize[i] = fgetc(fp); * } * * // Go to start of 2nd page * * unsigned long iCRC = 0x00; * unsigned long iRead; * unsigned long count; * unsigned char uiOffset; * * // crc: go to 2nd page start * fseek(fp, lSPageStart, SEEK_SET); * * // crc: fread begin * iRead = count = fread(buf, 1, 27+lacings, fp); * do * { * uiOffset = ((iCRC >> 24) & 0xFF) ^ buf[iRead - count]; * iCRC = (iCRC << 8) ^ VCCRCTAB[uiOffset]; * } while (--count); * * for (i=0; i<lacings; i++) * { * if (LacingSize[i]) * { * step = "crc: fread(" + String(LacingSize[i]) + ")"; * iRead = count = fread(buf, 1, LacingSize[i], fp); * do * { * uiOffset = ((iCRC >> 24) & 0xFF) ^ buf[iRead - count]; * iCRC = (iCRC << 8) ^ VCCRCTAB[uiOffset]; * } while (--count); * } * } * * // crc: parse crc * unsigned char a = (iCRC >> 24) & 0xFF; * unsigned char b = (iCRC >> 16) & 0xFF; * unsigned char c = (iCRC >> 8) & 0xFF; * unsigned char d = iCRC & 0xFF; * * // crc: seek to write pos * fseek(fp, lSPageStart+22, SEEK_SET); * fputc(d, fp); * fputc(c, fp); * fputc(b, fp); * fputc(a, fp); * * // crc: close file * fclose(fp); * } * }*/ private InternalInfo ReadTagInternal(Stream stream) { InternalInfo info = new InternalInfo(); info.OrigPaddingSize = 0; info.OrigVorbisCommentSize = 0; // Skip ID3v2 tag int id3v2TagSize = ID3v2.ID3v2Tag.GetTagSize(stream); stream.Seek(id3v2TagSize, SeekOrigin.Begin); if (IsFlac(stream)) { ReadTag_FLAC(stream, info); } /*else if (mAudioFileTrack == AUDIO_OGG) * { * return ReadTag_OGG(fp); * }*/ else { throw new InvalidDataException("FLAC marker not found"); //throw new InvalidDataException(String.Format("File '{0}' is not a valid FLAC or Ogg-Vorbis file", path)); } info.Vendor = _vendor; return(info); }
/// <summary> /// Function to edit inter info section. /// </summary> /// <returns></returns> public QuotePage UpdateInternalInfo() { driver.WaitForElementToBecomeVisibleWithinTimeout(InternalInfo, 10000); InternalInfo.Clickme(driver); _logger.Info($": Start Internal Information section update."); return(this); }
private void ReadTag_FLAC(Stream stream, InternalInfo info) { info.FileType = FileType.Flac; // Skip "fLaC" marker stream.Seek(4, SeekOrigin.Current); bool isLastMetaDataBlock; List <FlacMetaDataBlock> metaDataBlockList = new List <FlacMetaDataBlock>(); do { int c = stream.ReadByte(); isLastMetaDataBlock = (((c >> 7) & 0x01) == 1); int blocksize = stream.ReadInt24(); FlacMetaDataBlockType blockType = (FlacMetaDataBlockType)(c & 0x07); if (blockType == FlacMetaDataBlockType.VorbisComment) // Vorbis comment { info.OrigVorbisCommentSize = blocksize; long mvcoffset = stream.Position - 4; ReadTag_VorbisComment(stream); stream.Seek(mvcoffset + 4, SeekOrigin.Begin); } FlacMetaDataBlock metaDataBlock = new FlacMetaDataBlock(blockType); metaDataBlock.SetBlockData(stream, blocksize); metaDataBlockList.Add(metaDataBlock); } while (isLastMetaDataBlock == false); info.MetaDataBlockList = metaDataBlockList; _metaDataBlockList = metaDataBlockList; }
private void WriteTagFlac(string path, InternalInfo targetFile) { // This will store the metadata blocks we're actually going to write List <FlacMetaDataBlock> myMetaDataBlocks = new List <FlacMetaDataBlock>(); // Get byte array of new vorbis comment block byte[] newTagArray; using (MemoryStream newTag = new MemoryStream()) { // Write vendor byte[] vendorBytes = Encoding.UTF8.GetBytes(_vendor); newTag.WriteInt32LittleEndian(vendorBytes.Length); newTag.Write(vendorBytes); // Remove dead items and replace commonly misnamed items foreach (NameValueItem item in new List <NameValueItem>(_items)) { if (string.IsNullOrEmpty(item.Value)) { _items.Remove(item); } else if (string.Compare(item.Name, "YEAR", true) == 0) { if (string.IsNullOrEmpty(_items.GetValue("DATE"))) { _items.SetValue("DATE", item.Value); } _items.Remove(item); } } // Write item count newTag.WriteInt32LittleEndian(_items.Count); // Write items foreach (NameValueItem item in _items) { if (string.IsNullOrEmpty(item.Value)) { continue; } byte[] keyBytes = Encoding.ASCII.GetBytes(item.Name); byte[] valueBytes = Encoding.UTF8.GetBytes(item.Value); newTag.WriteInt32LittleEndian(keyBytes.Length + 1 + valueBytes.Length); newTag.Write(keyBytes); newTag.WriteByte((byte)'='); newTag.Write(valueBytes); } newTagArray = newTag.ToArray(); } // 1. Get old size of metadata blocks. // 2. Find StreamInfo, SeekTable, and Padding blocks. // These blocks should occur only once. If not, an exception is thrown. The padding // block we don't really care about so no exception is thrown if it's duplicated. FlacMetaDataBlock paddingBlock = null; FlacMetaDataBlock streamInfoBlock = null; FlacMetaDataBlock seekTableBlock = null; long origMetaDataSize = 0; foreach (FlacMetaDataBlock metaDataBlock in targetFile.MetaDataBlockList) { origMetaDataSize += 4; // Identifier + Size origMetaDataSize += metaDataBlock.Size; if (metaDataBlock.BlockType == FlacMetaDataBlockType.Padding) { paddingBlock = metaDataBlock; } else if (metaDataBlock.BlockType == FlacMetaDataBlockType.StreamInfo) { if (streamInfoBlock != null) { throw new InvalidDataException("Multiple stream info blocks"); } streamInfoBlock = metaDataBlock; } else if (metaDataBlock.BlockType == FlacMetaDataBlockType.SeekTable) { if (seekTableBlock != null) { throw new InvalidDataException("Multiple seek tables"); } seekTableBlock = metaDataBlock; } } // No Padding block found, create one if (paddingBlock == null) { paddingBlock = new FlacMetaDataBlock(FlacMetaDataBlockType.Padding); paddingBlock.SetBlockDataZeroed(2000); } // Padding block found, adjust size else { // TODO: This is not entirely accurate, since we may be reading from one file // and writing to another. The other blocks need to be accounted for, however for // same file read/write this works. Not high priority. int adjustPadding = targetFile.OrigVorbisCommentSize - newTagArray.Length; int newSize = paddingBlock.Size + adjustPadding; if (newSize < 10) { paddingBlock.SetBlockDataZeroed(2000); } else { paddingBlock.SetBlockDataZeroed(newSize); } } // Set Vorbis-Comment block data FlacMetaDataBlock vorbisCommentBlock = new FlacMetaDataBlock(FlacMetaDataBlockType.VorbisComment); vorbisCommentBlock.SetBlockData(newTagArray); // Create list of blocks to write myMetaDataBlocks.Add(streamInfoBlock); // StreamInfo MUST be first if (seekTableBlock != null) { myMetaDataBlocks.Add(seekTableBlock); } // Add other blocks we read from the original file. foreach (FlacMetaDataBlock metaDataBlock in _metaDataBlockList) { if (metaDataBlock.BlockType == FlacMetaDataBlockType.Application || metaDataBlock.BlockType == FlacMetaDataBlockType.CueSheet || metaDataBlock.BlockType == FlacMetaDataBlockType.Picture) { myMetaDataBlocks.Add(metaDataBlock); } } // Add our new vorbis comment and padding blocks myMetaDataBlocks.Add(vorbisCommentBlock); myMetaDataBlocks.Add(paddingBlock); // Get new size of metadata blocks long newMetaDataSize = 0; foreach (FlacMetaDataBlock metaDataBlock in myMetaDataBlocks) { newMetaDataSize += 4; // Identifier + Size newMetaDataSize += metaDataBlock.Size; } // If the new metadata size is less than the original, increase the padding if (newMetaDataSize != origMetaDataSize) { int newPaddingSize = paddingBlock.Size + (int)(origMetaDataSize - newMetaDataSize); if (newPaddingSize > 0) { paddingBlock.SetBlockDataZeroed(newPaddingSize); // Get new size of metadata blocks newMetaDataSize = 0; foreach (FlacMetaDataBlock metaDataBlock in myMetaDataBlocks) { newMetaDataSize += 4; // Identifier + Size newMetaDataSize += metaDataBlock.Size; } } } string tempFilename = null; // no rewrite necessary if (newMetaDataSize == origMetaDataSize) { // } // rewrite necessary - grab a snickers. else if (newMetaDataSize > origMetaDataSize) { // rename tempFilename = PathUtils.GetTemporaryFileNameBasedOnFileName(path); File.Move(path, tempFilename); // open for read, open for write using (FileStream fsRead = File.Open(tempFilename, FileMode.Open, FileAccess.Read, FileShare.None)) using (FileStream fsWrite = File.Open(path, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { // copy ID3v2 tag.. technically there shouldn't be one, but we don't want to destroy data int tmpID3v2TagSize = ID3v2.ID3v2Tag.GetTagSize(fsRead); if (tmpID3v2TagSize != 0) { byte[] id3v2 = fsRead.Read(tmpID3v2TagSize); fsWrite.Write(id3v2); } fsWrite.Write(FLAC_MARKER); // create blankspace byte[] blankSpace = new Byte[newMetaDataSize]; fsWrite.Write(blankSpace); fsRead.Seek(4 + origMetaDataSize, SeekOrigin.Current); byte[] buf = new byte[32768]; int bytesRead = fsRead.Read(buf, 0, 32768); while (bytesRead != 0) { fsWrite.Write(buf, 0, bytesRead); bytesRead = fsRead.Read(buf, 0, 32768); } } } // newMetaDataSize < origMetaDataSize is an error else { throw new Exception(String.Format("Internal Error: newMetaDataSize ({0}) < origMetaDataSize ({1})", newMetaDataSize, origMetaDataSize)); } using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { // skip fLaC marker and ID3v2 tag size int tmpID3v2TagSize = ID3v2.ID3v2Tag.GetTagSize(fs); fs.Position = tmpID3v2TagSize + 4; byte blockType; foreach (FlacMetaDataBlock metaDataBlock in myMetaDataBlocks) { // always write padding last if (metaDataBlock == paddingBlock) { continue; } blockType = (byte)metaDataBlock.BlockType; fs.WriteByte(blockType); fs.WriteInt24(metaDataBlock.Size); fs.Write(metaDataBlock.BlockData); } // write padding, add stop bit to block type blockType = (byte)(paddingBlock.BlockType + 0x80); fs.WriteByte(blockType); fs.WriteInt24(paddingBlock.Size); fs.Write(paddingBlock.BlockData); } if (!string.IsNullOrEmpty(tempFilename)) { File.Delete(tempFilename); } }