示例#1
0
 private void ReadContentDescription(Stream stream, Tag tag)
 {
     BinaryReader reader = new BinaryReader(stream);
     ushort [] sizes = new ushort[5];
     
     for(int i = 0; i < sizes.Length; i++) {
         sizes[i] = reader.ReadUInt16();
     }
     
     string [] strings = new string[sizes.Length];
     
     for(int i = 0; i < strings.Length; i++) {
         strings[i] = ReadUtf16String(reader, sizes[i]).Trim();
     }
     
     if(sizes[0] > 0 && strings[0] != String.Empty) {
         tag.SetTitle(strings[0]);
     }
     
     if(sizes[1] > 0 && strings[1] != String.Empty) {
         tag.SetArtist(strings[1]);
     }
     
     if(sizes[3] > 0 && strings[3] != String.Empty) {
         tag.SetComment(strings[3]);
     }
 }
示例#2
0
        public Tag Read(Stream stream) 
        {
            /* Assuming we are at the start of the ASF header GUID */
            GUID header_guid = GUID.ReadGUID(stream);
            
            if(!GUID.GUID_HEADER.Equals(header_guid)) {
                return null;
            }
            
            Tag tag = new Tag();
            BinaryReader reader = new BinaryReader(stream);
            
            // Skip length of header
            stream.Seek(8, SeekOrigin.Current);

            // Read the number of chunks
            uint chunk_count = reader.ReadUInt32();

            // Skip unknown bytes
            stream.Seek(2, SeekOrigin.Current);

            // Two flags, When both are set, all Information needed has ben read
            bool is_content_parsed = false;
            bool is_extended_parsed = false;

            // Now read the chunks
            for(int i = 0; i < chunk_count && !(is_content_parsed && is_extended_parsed); i++) {
                long chunk_start = stream.Position;
                GUID current_guid = GUID.ReadGUID(stream);
                ulong chunk_len = reader.ReadUInt64();

                if(GUID.GUID_CONTENTDESCRIPTION.Equals(current_guid)) {
                    ReadContentDescription(stream, tag);
                    is_content_parsed = true;
                } else if(GUID.GUID_EXTENDED_CONTENT_DESCRIPTION.Equals(current_guid)) {
                    ReadExtendedDescription(stream, tag);
                    is_extended_parsed = true;
                }

                stream.Seek ((long)((ulong)chunk_start + chunk_len - (ulong)stream.Position), SeekOrigin.Current);
            }
        
            return tag;
        }
示例#3
0
		public void Write(Tag tag, Stream raf, Stream rafTemp) {
			//Read firstPage----------------------------------------------------
			raf.Seek(26, SeekOrigin.Begin);
			byte[] b = new byte[4];
			int pageSegments = raf.ReadByte()&0xFF; //Unsigned
			raf.Seek(0, SeekOrigin.Begin);

			b = new byte[27 + pageSegments];
			raf.Read(b, 0, b.Length);

			OggPageHeader firstPage = new OggPageHeader(b);
			//------------------------------------------------------------------

			raf.Seek(0, SeekOrigin.Begin);
			//write 1st page (unchanged)----------------------------------------
			byte[] pageBytes = new byte[firstPage.PageLength + 27 + pageSegments];
			raf.Read(pageBytes, 0, pageBytes.Length);
			rafTemp.Write(pageBytes, 0, pageBytes.Length);
			//rafTemp.Seek(firstPage.PageLength + raf.Position, SeekOrigin.Current);
			//------------------------------------------------------------------
			
			//Read 2nd page-----------------------------------------------------
			long pos = raf.Position;
			raf.Seek(raf.Position + 26, SeekOrigin.Begin);
			pageSegments = raf.ReadByte()&0xFF; //Unsigned
			raf.Seek(pos, SeekOrigin.Begin);
			
			b = new byte[27 + pageSegments];
			raf.Read(b, 0, b.Length);
			OggPageHeader secondPage = new OggPageHeader(b);
			long secondPageEndPos = raf.Position;
			//------------------------------------------------------------------

			//Compute old comment length----------------------------------------
			int oldCommentLength = 7; // [.vorbis]
			raf.Seek(raf.Position + 7, SeekOrigin.Begin);

			b = new byte[4];
			raf.Read(b, 0, b.Length);
			int vendorstringLength = Utils.GetNumber(b, 0,3);
			oldCommentLength += 4 + vendorstringLength;

			raf.Seek(raf.Position + vendorstringLength, SeekOrigin.Begin);

			b = new byte[4];
			raf.Read(b, 0, b.Length);
			int userComments = Utils.GetNumber(b, 0,3);
			oldCommentLength += 4;

			for (int i = 0; i < userComments; i++) {
				b = new byte[4];
				raf.Read(b, 0, b.Length);
				int commentLength = Utils.GetNumber(b, 0,3);
				oldCommentLength += 4 + commentLength;

				raf.Seek(raf.Position + commentLength, SeekOrigin.Begin);
			}

			int isValid = raf.ReadByte();
			oldCommentLength += 1;
			if (isValid != 1)
				throw new CannotWriteException("Unable to retreive old tag informations");
			//------------------------------------------------------------------

			//Get the new comment and create the container bytebuffer for 2nd page---
			ByteBuffer newComment = tc.Convert(tag);

			int newCommentLength = newComment.Capacity;
			int newSecondPageLength = secondPage.PageLength - oldCommentLength + newCommentLength;

			byte[] segmentTable = CreateSegmentTable(oldCommentLength,newCommentLength,secondPage);
			int newSecondPageHeaderLength = 27 + segmentTable.Length;

			ByteBuffer secondPageBuffer = new ByteBuffer(newSecondPageLength + newSecondPageHeaderLength);
			//------------------------------------------------------------------

			//Build the new second page header----------------------------------
			//OggS capture
			secondPageBuffer.Put(Utils.GetBytes("OggS"));
			//Stream struct revision
			secondPageBuffer.Put((byte) 0);
			//header_type_flag
			secondPageBuffer.Put((byte) 0);
			//absolute granule position
			secondPageBuffer.Put(
				new byte[] {
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0 });

			//stream serial number
			secondPageBuffer.Put(Utils.GetNumber(secondPage.SerialNumber));

			//page sequence no
			secondPageBuffer.Put(Utils.GetNumber(secondPage.PageSequence));

			//CRC (to be computed later)
			secondPageBuffer.Put(new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0 });
			int crcOffset = 22;
			
			if (segmentTable.Length > 255) {
			    throw new CannotWriteException ("In this special case we need to " +
			    		"create a new page, since we still hadn't the time for that " +
			    		"we won't write because it wouldn't create an ogg file.");
			}
			//page_segments nb.
			secondPageBuffer.Put((byte)segmentTable.Length);

			//page segment table
			for (int i = 0; i < segmentTable.Length; i++)
				secondPageBuffer.Put(segmentTable[i]);
			//------------------------------------------------------------------

			//Add to the new second page the new comment------------------------
			secondPageBuffer.Put(newComment);
			//------------------------------------------------------------------

			//Add the remaining old second page (encoding infos, etc)-----------
			raf.Seek(secondPageEndPos+oldCommentLength, SeekOrigin.Begin);
			secondPageBuffer.Put(raf);
			//------------------------------------------------------------------

			//Compute CRC over the new second page------------------------------
			byte[] crc = OggCRCFactory.ComputeCRC(secondPageBuffer.Data);
			for (int i = 0; i < crc.Length; i++) {
				secondPageBuffer.Put(crcOffset + i, crc[i]);
			}
			//------------------------------------------------------------------

			//Transfer the second page bytebuffer content-----------------------
			secondPageBuffer.Rewind();
			rafTemp.Write(secondPageBuffer.Data, 0, secondPageBuffer.Data.Length);
			//------------------------------------------------------------------

			//Write the rest of the original file-------------------------------
			byte[] buf = new byte[65536];
			int read = raf.Read(buf, 0, buf.Length);
			while (read != 0) {
				rafTemp.Write(buf, 0, read);
				read = raf.Read(buf, 0, buf.Length);
			}
			//rafTemp.getChannel().transferFrom(raf.getChannel(), 	rafTemp.Position, raf.Length() - raf.Position);
			//------------------------------------------------------------------
		}
示例#4
0
		public void Write( Tag tag, Stream raf, Stream rafTemp ) {
			//Clean up old datas
			ArrayList metadataBlockPadding = new ArrayList(1);
			ArrayList metadataBlocks = new ArrayList();
			
			byte[] b = new byte[4];
			raf.Read(b, 0, b.Length);
			if(new string(System.Text.Encoding.ASCII.GetChars(b)) != "fLaC")
				throw new CannotWriteException("This is not a FLAC file");
			
			bool isLastBlock = false;
			while(!isLastBlock) {
				b = new byte[4];
				raf.Read(b, 0, 4);
				MetadataBlockHeader mbh = new MetadataBlockHeader(b);
									
				if (mbh.BlockType == MetadataBlockHeader.BlockTypes.Padding) {
					raf.Seek(mbh.DataLength, SeekOrigin.Current);
					metadataBlockPadding.Add(mbh.DataLength+4);
				}
				else {
					b = new byte[mbh.DataLength];
					raf.Read(b, 0, b.Length);
					metadataBlocks.Add(new MetadataBlockData(mbh, b));
				}
			
				isLastBlock = mbh.IsLastBlock;
			}
			
			int availableRoom =  ComputeAvailableRoom(metadataBlockPadding, metadataBlocks);
			int newTagSize = tc.GetTagLength(tag);
			int neededRoom = newTagSize + ComputeNeededRoom(metadataBlockPadding, metadataBlocks);
			raf.Seek(0, SeekOrigin.Begin);
			
			if(availableRoom>=neededRoom) {
				//OVERWRITE EXISTING TAG
				raf.Seek(42, SeekOrigin.Begin);
				
				foreach (MetadataBlockData data in metadataBlocks) {
					raf.Write(data.Header.Data, 0, data.Header.Data.Length);
					raf.Write(data.Bytes, 0, data.Bytes.Length);
				}
				
				byte[] newTagBytes = tc.Create(tag, availableRoom-neededRoom).Data;
				raf.Write(newTagBytes, 0, newTagBytes.Length);
			} else {
				//create new tag with padding (we remove the header and keep the audio data)
				b = new byte[42];
				raf.Read(b, 0, b.Length);
				raf.Seek(availableRoom+42, SeekOrigin.Begin);
				
				rafTemp.Write(b, 0, b.Length);
				
				foreach (MetadataBlockData data in metadataBlocks) {
					raf.Write(data.Header.Data, 0, data.Header.Data.Length);
					raf.Write(data.Bytes, 0, data.Bytes.Length);
				}
				
				byte[] newTagBytes = tc.Create(tag, FlacTagCreator.DEFAULT_PADDING).Data;
				rafTemp.Write(newTagBytes, 0, newTagBytes.Length);
				
				b = new byte[65536];
				int read = raf.Read(b, 0, b.Length);
				while (read != 0) {
					rafTemp.Write(b, 0, read);
					read = raf.Read(b, 0, b.Length);
				}
				//tempFC.transferFrom( fc, tempFC.position(), fc.size() );
			}
		}
示例#5
0
 private void ReadExtendedDescription(Stream stream, Tag tag) 
 {
     BinaryReader reader = new BinaryReader(stream);
     ushort field_count = reader.ReadUInt16();
     
     for(int i = 0; i < field_count; i++) {
         ushort field_length = reader.ReadUInt16();
         string property_name = ReadUtf16String(reader, field_length);
         ushort property_type = reader.ReadUInt16();
         string property_value = String.Empty;
         
         switch(property_type) {
             case 0:
                 property_value = ReadUtf16String(reader, reader.ReadUInt16());
                 break;
             case 1:
                 stream.Seek(reader.ReadUInt16(), SeekOrigin.Current);
                 break;
             case 2:
                 reader.ReadUInt16();
                 property_value = (reader.ReadUInt32() == 1).ToString();
                 break;
             case 3:
                 property_value = reader.ReadUInt32().ToString();
                 break;
             case 4:
                 property_value = reader.ReadUInt64().ToString();
                 break;
             case 5:
                 property_value = reader.ReadUInt16().ToString();
                 break;
         }
         
         switch(property_name) {
             case "WM/AlbumTitle":
                 tag.SetAlbum(property_value);
                 break;
             case "WM/AlbumArtist": 
                 tag.SetArtist(property_value);
                 break;
             case "WM/TrackNumber":
                 tag.SetTrack(property_value);
                 break;
             case "WM/Year": 
                 tag.SetYear(property_value);
                 break;
             case "WM/Genre": 
                 tag.SetGenre(property_value);
                 break;
         }
     }
 }
示例#6
0
 public AudioFileContainer(EncodingInfo info, Tag tag) 
 {
     this.info = info;
     this.tag = tag;
 }
示例#7
0
 public AudioFile(string s, EncodingInfo info)
 {
     this.s = s;
     this.info = info;
     this.tag = new GenericTag();
 }
示例#8
0
 public AudioFile(string s, EncodingInfo info, Tag tag)
 {
     this.s = s;
     this.info = info;
     this.tag = tag;
 }