コード例 #1
0
        public VorbisFile(VorbisFile original, VorbisComments replacement)
        {
            // Extract comments from original file
            VorbisHeader           commentHeader    = original.GetPageHeaders().Select(p => p.GetCommentHeader()).Single(h => h != null);
            VorbisCommentsFromFile originalComments = commentHeader.ExtractComments();

            // Get new comments header into byte array
            byte[] replacementData;
            using (var ms = new MemoryStream()) {
                replacement.WriteTo(ms);
                replacementData = ms.ToArray();
            }
            if (replacementData.Length + 7 >= 255)
            {
                throw new Exception("Comment header is too long for this program to handle (must be under 248 bytes)");
            }

            // Calculate new filesize and allocate memory
            this.Length = original.Length
                          - (int)(originalComments.OrigEnd - originalComments.OrigStart)
                          + replacementData.Length;
            this.Data = Marshal.AllocHGlobal(this.Length);

            // Copy section before comment header
            byte *sourcePtr      = (byte *)original.Data;
            byte *endPtr         = sourcePtr + original.Length;
            byte *destinationPtr = (byte *)this.Data;

            while (sourcePtr < originalComments.OrigStart)
            {
                *destinationPtr++ = *sourcePtr++;
            }

            // Copy new comment header
            Marshal.Copy(replacementData, 0, (IntPtr)destinationPtr, replacementData.Length);
            destinationPtr += replacementData.Length;

            // Copy section after comment header
            sourcePtr = originalComments.OrigEnd;
            while (sourcePtr < endPtr)
            {
                *destinationPtr++ = *sourcePtr++;
            }

            if (destinationPtr - this.Length != (byte *)this.Data)
            {
                throw new Exception("not enough data written");
            }

            // Update length of segment containing comments
            byte *comment_header_segment_table_entry = (byte *)this.Data + (commentHeader.segment_table_entry - (byte *)original.Data);

            *comment_header_segment_table_entry = (byte)(replacementData.Length + 7);

            // Recalculate all checksums
            foreach (OggPage page in GetPageHeaders())
            {
                page.RecalculateCrc32();
            }
        }
コード例 #2
0
        public unsafe VorbisHeader GetCommentHeader()
        {
            byte *table  = (byte *)Header + 27;
            byte *header = table + Header->PageSegments;

            for (int i = 0; i < Header->PageSegments; i++)
            {
                // Don't check a segment if its length is greater than 254 bytes (data is probably split across segments)
                if (table[i] < 255)
                {
                    VorbisHeader test = new VorbisHeader(this, &table[i], header);
                    if (test.PacketType == 3 && test.VorbisTag == "vorbis")
                    {
                        return(test);
                    }
                }
                header += table[i];
            }
            return(null);
        }