const int HEADERS_TO_VERIFY = 5; var headers = new List(HEADERS_TO_VERIFY); MP3Header header = null; //MP3Header is a class for the headers' properties. while (headers.Count < HEADERS_TO_VERIFY) { header = ParseHeader(); if (header == null) { headers.Clear(); Source.Position = ++pos; continue; } header.Position = Source.Position - 4; //Source is the MP3 bitstream. headers.Add(header); Debug.WriteLine($"Found MPEG {header.Version} layer {header.Layer} at {Source.Position}."); Source.Position += header.SizeData - 4; } private MP3Header ParseHeader() { //A frame starts with 11 set bits. The 12th bit should also always be set. if (Source.Read(12).Any(bit => !bit)) return null; //Read 12 bits from the bitstream. //Parse the four bytes into a frame header. var header = new MP3Header(); header.Version = Source.Read() ? 1 : 2; //Read 1 bit from the bitstream. header.Layer = 4 - Source.Read(2).ToInt(); header.IsCRCProtected = Source.Read(); if (!header.Layer.Between(1, 3)) return null; header.SetKilobitsSecond(Source.Read(4).ToInt()); header.SetSamplesSecond(Source.Read(2).ToInt()); header.IsPadded = Source.Read(); Source.Read(); //Private bit header.Channeling = (MP3Channeling)Source.Read(2).ToInt(); header.IsMSStereo = Source.Read(); header.IsIntensityStereo = Source.Read(); Source.Read(2); //Copyright bit, is original bit header.Emphasis = (MP3Emphasis)Source.Read(2).ToInt(); //Verify the header is good. if (header.Emphasis == MP3Emphasis.Reserved || header.SamplesSecond <= 0 || header.KilobitsSecond <= 0) return null; return header; }
14 May 2016
MP3 - Step 1 - Find the first header
An MP3 frame header starts with 11 set bits, and the 12th should also always be set. But finding 12 set bits doesn't garantee you found a frame header, so to make sure, you should verify several succeeding headers as well.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment