Пример #1
0
        /// <summary>
        /// Opens MP3 from a stream rather than a file
        /// Will not dispose of this stream itself
        /// </summary>
        /// <param name="inputStream"></param>
        public Mp3FileReader(Stream inputStream)
        {
            int sampleRate;
            int bitRate;

            mp3Stream = inputStream;
            id3v2Tag = Id3v2Tag.ReadTag(mp3Stream);

            dataStartPosition = mp3Stream.Position;
            Mp3Frame mp3Frame = new Mp3Frame(mp3Stream);
            sampleRate = mp3Frame.SampleRate;
            frameLengthInBytes = mp3Frame.FrameLength;
            bitRate = mp3Frame.BitRate;
            xingHeader = XingHeader.LoadXingHeader(mp3Frame);

            this.length = mp3Stream.Length - dataStartPosition;

            // try for an ID3v1 tag as well
            mp3Stream.Position = mp3Stream.Length - 128;
            byte[] tag = new byte[128];
            mp3Stream.Read(tag, 0, 3);
            if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'G')
            {
                id3v1Tag = tag;
                this.length -= 128;
            }

            mp3Stream.Position = dataStartPosition;

            // TODO: choose more appropriately
            waveFormat = new Mp3WaveFormat(sampleRate, 2, frameLengthInBytes, bitRate);
        }
        /// <summary>
        /// Reads an ID3v2 tag from a stream
        /// </summary>
        public static Id3v2Tag ReadTag(Stream input)
        {
            try
            {
                long start;
                long end;
                byte[] data;
                if (ReadId3v2Tag(out start, out end, out data, input))
                {
                    var ret = new Id3v2Tag();
                    ret.rawData = data;
                    ret.tagStartPosition = start;
                    ret.tagEndPosition = end;
                    return ret;
                }
                //return new Id3v2Tag(input);
                else
                {
                    return null;
                }

            }
            catch (FormatException)
            {
                return null;
            }
        }
Пример #3
0
        /// <summary>
        /// Opens MP3 from a stream rather than a file
        /// Will not dispose of this stream itself
        /// </summary>
        /// <param name="inputStream">The incoming stream containing MP3 data</param>
        /// <param name="frameDecompressorBuilder">Factory method to build a frame decompressor</param>
        public Mp3FileReader(Stream inputStream, FrameDecompressorBuilder frameDecompressorBuilder)
        {
            // Calculated as a double to minimize rounding errors

            mp3Stream = inputStream;
            id3v2Tag = Id3v2Tag.ReadTag(mp3Stream);

            dataStartPosition = mp3Stream.Position;
            var mp3Frame = Mp3Frame.LoadFromStream(mp3Stream);
            sampleRate = mp3Frame.SampleRate;
            frameLengthInBytes = mp3Frame.FrameLength;
            double bitRate = mp3Frame.BitRate;
            xingHeader = XingHeader.LoadXingHeader(mp3Frame);
            // If the header exists, we can skip over it when decoding the rest of the file
            if (xingHeader != null) dataStartPosition = mp3Stream.Position;

            this.mp3DataLength = mp3Stream.Length - dataStartPosition;

            // try for an ID3v1 tag as well
            mp3Stream.Position = mp3Stream.Length - 128;
            byte[] tag = new byte[128];
            mp3Stream.Read(tag, 0, 3);
            if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'G')
            {
                id3v1Tag = tag;
                this.mp3DataLength -= 128;
            }

            mp3Stream.Position = dataStartPosition;

            // create a temporary MP3 format before we know the real bitrate
            this.Mp3WaveFormat = new Mp3WaveFormat(sampleRate, mp3Frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frameLengthInBytes, (int)bitRate);

            CreateTableOfContents();
            this.tocIndex = 0;

            // [Bit rate in Kilobits/sec] = [Length in kbits] / [time in seconds]
            //                            = [Length in bits ] / [time in milliseconds]

            // Note: in audio, 1 kilobit = 1000 bits.
            bitRate = (mp3DataLength * 8.0 / TotalSeconds());

            mp3Stream.Position = dataStartPosition;

            // now we know the real bitrate we can create an accurate
            this.Mp3WaveFormat = new Mp3WaveFormat(sampleRate, mp3Frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frameLengthInBytes, (int)bitRate);
            decompressor = frameDecompressorBuilder(Mp3WaveFormat);
            this.waveFormat = decompressor.OutputFormat;
            this.bytesPerSample = (decompressor.OutputFormat.BitsPerSample) / 8 * decompressor.OutputFormat.Channels;
            // no MP3 frames have more than 1152 samples in them
            // some MP3s I seem to get double
            this.decompressBuffer = new byte[1152 * bytesPerSample * 2];
        }
Пример #4
0
        /// <summary>
        /// Opens MP3 from a stream rather than a file
        /// Will not dispose of this stream itself
        /// </summary>
        /// <param name="inputStream">The incoming stream containing MP3 data</param>
        /// <param name="frameDecompressorBuilder">Factory method to build a frame decompressor</param>
        public Mp3FileReader(Stream inputStream, FrameDecompressorBuilder frameDecompressorBuilder)
        {
            // Calculated as a double to minimize rounding errors

            mp3Stream = inputStream;
            id3v2Tag = Id3v2Tag.ReadTag(mp3Stream);

            dataStartPosition = mp3Stream.Position;
            var firstFrame = Mp3Frame.LoadFromStream(mp3Stream);
            double bitRate = firstFrame.BitRate;
            xingHeader = XingHeader.LoadXingHeader(firstFrame);
            // If the header exists, we can skip over it when decoding the rest of the file
            if (xingHeader != null) dataStartPosition = mp3Stream.Position;

            // workaround for a longstanding issue with some files failing to load
            // because they report a spurious sample rate change
            var secondFrame = Mp3Frame.LoadFromStream(mp3Stream);
            if (secondFrame != null &&
                (secondFrame.SampleRate != firstFrame.SampleRate ||
                secondFrame.ChannelMode != firstFrame.ChannelMode))
            {
                // assume that the first frame was some kind of VBR/LAME header that we failed to recognise properly
                dataStartPosition = secondFrame.FileOffset;
                // forget about the first frame, the second one is the first one we really care about
                firstFrame = secondFrame;
            }

            this.mp3DataLength = mp3Stream.Length - dataStartPosition;

            // try for an ID3v1 tag as well
            mp3Stream.Position = mp3Stream.Length - 128;
            byte[] tag = new byte[128];
            mp3Stream.Read(tag, 0, 128);
            if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'G')
            {
                id3v1Tag = tag;
                this.mp3DataLength -= 128;
            }

            mp3Stream.Position = dataStartPosition;

            // create a temporary MP3 format before we know the real bitrate
            this.Mp3WaveFormat = new Mp3WaveFormat(firstFrame.SampleRate, firstFrame.ChannelMode == ChannelMode.Mono ? 1 : 2, firstFrame.FrameLength, (int)bitRate);

            CreateTableOfContents();
            this.tocIndex = 0;

            // [Bit rate in Kilobits/sec] = [Length in kbits] / [time in seconds]
            //                            = [Length in bits ] / [time in milliseconds]

            // Note: in audio, 1 kilobit = 1000 bits.
            bitRate = (mp3DataLength * 8.0 / TotalSeconds());

            mp3Stream.Position = dataStartPosition;

            // now we know the real bitrate we can create an accurate
            this.Mp3WaveFormat = new Mp3WaveFormat(firstFrame.SampleRate, firstFrame.ChannelMode == ChannelMode.Mono ? 1 : 2, firstFrame.FrameLength, (int)bitRate);
            decompressor = frameDecompressorBuilder(Mp3WaveFormat);
            this.waveFormat = decompressor.OutputFormat;
            this.bytesPerSample = (decompressor.OutputFormat.BitsPerSample) / 8 * decompressor.OutputFormat.Channels;
            // no MP3 frames have more than 1152 samples in them
            // some MP3s I seem to get double
            this.decompressBuffer = new byte[1152 * bytesPerSample * 2];
        }
Пример #5
0
        private static byte[] CreateId3v2Frame(string key, string value)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }
            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException("value");
            }
            if (key.Length != 4)
            {
                throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long");
            }
            byte[] array = new byte[]
            {
                byte.MaxValue,
                254
            };
            byte[] array2 = new byte[3];
            byte[] array3 = array2;
            byte[] array4 = new byte[2];
            byte[] array5 = array4;
            byte[] array6;
            if (key == "COMM")
            {
                array6 = ByteArrayExtensions.Concat(new byte[][]
                {
                    new byte[]
                    {
                        1
                    },
                    array3,
                    array5,
                    array,
                    Encoding.Unicode.GetBytes(value)
                });
            }
            else
            {
                array6 = ByteArrayExtensions.Concat(new byte[][]
                {
                    new byte[]
                    {
                        1
                    },
                    array,
                    Encoding.Unicode.GetBytes(value)
                });
            }
            byte[][] array7 = new byte[4][];
            array7[0] = Encoding.UTF8.GetBytes(key);
            array7[1] = Id3v2Tag.FrameSizeToBytes(array6.Length);
            byte[][] array8 = array7;
            int      num    = 2;

            byte[] array9 = new byte[2];
            array8[num] = array9;
            array7[3]   = array6;
            return(ByteArrayExtensions.Concat(array7));
        }
Пример #6
0
 public static Id3v2Tag Create(IEnumerable <KeyValuePair <string, string> > tags)
 {
     return(Id3v2Tag.ReadTag(Id3v2Tag.CreateId3v2TagStream(tags)));
 }
Пример #7
0
        /// <summary>
        /// Opens MP3 from a stream rather than a file
        /// Will not dispose of this stream itself
        /// </summary>
        /// <param name="inputStream">The incoming stream containing MP3 data</param>
        /// <param name="frameDecompressorBuilder">Factory method to build a frame decompressor</param>
        public Mp3FileReader(Stream inputStream, FrameDecompressorBuilder frameDecompressorBuilder)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }
            try
            {
                mp3Stream = inputStream;
                id3v2Tag  = Id3v2Tag.ReadTag(mp3Stream);

                dataStartPosition = mp3Stream.Position;
                var firstFrame = Mp3Frame.LoadFromStream(mp3Stream);
                if (firstFrame == null)
                {
                    throw new InvalidDataException("Invalid MP3 file - no MP3 Frames Detected");
                }
                double bitRate = firstFrame.BitRate;
                xingHeader = XingHeader.LoadXingHeader(firstFrame);
                // If the header exists, we can skip over it when decoding the rest of the file
                if (xingHeader != null)
                {
                    dataStartPosition = mp3Stream.Position;
                }

                // workaround for a longstanding issue with some files failing to load
                // because they report a spurious sample rate change
                var secondFrame = Mp3Frame.LoadFromStream(mp3Stream);
                if (secondFrame != null &&
                    (secondFrame.SampleRate != firstFrame.SampleRate ||
                     secondFrame.ChannelMode != firstFrame.ChannelMode))
                {
                    // assume that the first frame was some kind of VBR/LAME header that we failed to recognise properly
                    dataStartPosition = secondFrame.FileOffset;
                    // forget about the first frame, the second one is the first one we really care about
                    firstFrame = secondFrame;
                }

                this.mp3DataLength = mp3Stream.Length - dataStartPosition;

                // try for an ID3v1 tag as well
                mp3Stream.Position = mp3Stream.Length - 128;
                byte[] tag = new byte[128];
                mp3Stream.Read(tag, 0, 128);
                if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'G')
                {
                    id3v1Tag            = tag;
                    this.mp3DataLength -= 128;
                }

                mp3Stream.Position = dataStartPosition;

                // create a temporary MP3 format before we know the real bitrate
                this.Mp3WaveFormat = new Mp3WaveFormat(firstFrame.SampleRate,
                                                       firstFrame.ChannelMode == ChannelMode.Mono ? 1 : 2, firstFrame.FrameLength, (int)bitRate);

                CreateTableOfContents();
                this.tocIndex = 0;

                // [Bit rate in Kilobits/sec] = [Length in kbits] / [time in seconds]
                //                            = [Length in bits ] / [time in milliseconds]

                // Note: in audio, 1 kilobit = 1000 bits.
                // Calculated as a double to minimize rounding errors
                bitRate = (mp3DataLength * 8.0 / TotalSeconds());

                mp3Stream.Position = dataStartPosition;

                // now we know the real bitrate we can create an accurate MP3 WaveFormat
                this.Mp3WaveFormat = new Mp3WaveFormat(firstFrame.SampleRate,
                                                       firstFrame.ChannelMode == ChannelMode.Mono ? 1 : 2, firstFrame.FrameLength, (int)bitRate);
                decompressor        = frameDecompressorBuilder(Mp3WaveFormat);
                this.waveFormat     = decompressor.OutputFormat;
                this.bytesPerSample = (decompressor.OutputFormat.BitsPerSample) / 8 * decompressor.OutputFormat.Channels;
                // no MP3 frames have more than 1152 samples in them
                this.bytesPerDecodedFrame = 1152 * bytesPerSample;
                // some MP3s I seem to get double
                this.decompressBuffer = new byte[this.bytesPerDecodedFrame * 2];
            }
            catch (Exception)
            {
                if (ownInputStream)
                {
                    inputStream.Dispose();
                }

                throw;
            }
        }