Beispiel #1
0
        public Mp3File(Stream aStream)
        {
            ToyMP3        mp3     = new ToyMP3(aStream);
            ToyMP3Frame   frame   = new ToyMP3Frame();
            ToyMP3Decoder decoder = new ToyMP3Decoder();

            channels     = 2;
            sampleRate   = 44100;
            sampleLength = 0;
            sampleList   = new List <Int16>();

            try
            {
                while (mp3.SeekMP3Frame(frame))
                {
                    decoder.DecodeFrame(frame);

                    for (int i = 0; i < decoder.Pcm.Length; i++)
                    {
                        sampleList.Add(decoder.Pcm[i]);
                    }

                    sampleLength += decoder.Pcm.Length / 2;
                }
            }
            catch (Exception e)
            {
                // Exist BitStream Error.
                Debug.LogError("Mp3 Error:" + e);
            }

            Debug.Log("clpped_samples:" + decoder.Clip);
        }
Beispiel #2
0
        private bool DecodeSideTableInformation(ToyMP3Frame frame)
        {
            frame.MainDataBegin = byteArray.ReadBitsAsUInt16(9);

            // Skipping Private Bits
            if (frame.Channels == 1)
            {
                byteArray.AddBitPosition(5);
            }
            else
            {
                byteArray.AddBitPosition(3);
            }

            // Get Scfsi
            for (int ch = 0; ch < frame.Channels; ch++)
            {
                for (int i = 0; i < 4; i++)
                {
                    frame.SetScfsi(ch, i, byteArray.ReadBitsAsUInt16(1));
                }
            }

            // Get Granule Info
            for (int g = 0; g < 2; g++)
            {
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    frame.granule[ch, g].Part23Length        = byteArray.ReadBitsAsUInt16(12);
                    frame.granule[ch, g].BigValues           = byteArray.ReadBitsAsUInt16(9);
                    frame.granule[ch, g].GlobalGain          = byteArray.ReadBitsAsUInt16(8);
                    frame.granule[ch, g].ScalefacCompress    = byteArray.ReadBitsAsUInt16(4);
                    frame.granule[ch, g].WindowSwitchingFlag = byteArray.ReadBitsAsUInt16(1);

                    if (frame.granule[ch, g].WindowSwitchingFlag == 1)
                    {
                        frame.granule[ch, g].BlockType      = byteArray.ReadBitsAsUInt16(2);
                        frame.granule[ch, g].MixedBlockFlag = byteArray.ReadBitsAsUInt16(1);

                        if (frame.granule[ch, g].BlockType == 0)
                        {
                            return(false);
                        }

                        for (int w = 0; w < 2; w++)
                        {
                            frame.granule[ch, g].SetTableSelect(w, byteArray.ReadBitsAsUInt16(5));
                        }

                        for (int w = 0; w < 3; w++)
                        {
                            frame.granule[ch, g].SetSubblockGain(w, byteArray.ReadBitsAsUInt16(3));
                        }

                        if ((frame.granule[ch, g].BlockType == 2) && (frame.granule[ch, g].MixedBlockFlag == 0))
                        {
                            frame.granule[ch, g].Region0Count = 8;
                            frame.granule[ch, g].Region1Count = 36;
                        }
                        else
                        {
                            frame.granule[ch, g].Region0Count = 7;
                            frame.granule[ch, g].Region1Count = 36;
                        }
                    }
                    else
                    {
                        for (int w = 0; w < 3; w++)
                        {
                            frame.granule[ch, g].SetTableSelect(w, byteArray.ReadBitsAsUInt16(5));
                        }

                        frame.granule[ch, g].Region0Count   = byteArray.ReadBitsAsUInt16(4);
                        frame.granule[ch, g].Region1Count   = byteArray.ReadBitsAsUInt16(3);
                        frame.granule[ch, g].MixedBlockFlag = 0;
                        frame.granule[ch, g].BlockType      = 0;
                    }

                    frame.granule[ch, g].PreFlag           = byteArray.ReadBitsAsUInt16(1);
                    frame.granule[ch, g].ScalefacScale     = byteArray.ReadBitsAsUInt16(1);
                    frame.granule[ch, g].Count1TableSelect = byteArray.ReadBitsAsUInt16(1);
                }
            }

            return(true);
        }
Beispiel #3
0
        public bool SeekMP3Frame(ToyMP3Frame frame)
        {
            try
            {
                for ( ; ;)
                {
                    for (int i = 0; ; i++)
                    {
                        if (byteArray.ReadBitsAsUInt16(12) != 4095)
                        {
                            if (i > FRAME_SEEK_LIMIT || byteArray.Position >= byteArray.Length)
                            {
                                return(false);
                            }

                            // back 1 byte (in order to check byte by byte)
                            byteArray.SubBitPosition(4);

                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }

                    frame.Id             = ( int )byteArray.ReadBitsAsUInt16(1);
                    frame.Layer          = ( int )byteArray.ReadBitsAsUInt16(2);
                    frame.ProtectionBit  = ( int )byteArray.ReadBitsAsUInt16(1);
                    frame.BitrateIndex   = ( int )byteArray.ReadBitsAsUInt16(4);
                    frame.FrequencyIndex = ( int )byteArray.ReadBitsAsUInt16(2);
                    frame.PaddingBit     = ( int )byteArray.ReadBitsAsUInt16(1);
                    frame.PrivateBit     = ( int )byteArray.ReadBitsAsUInt16(1);
                    frame.Mode           = ( int )byteArray.ReadBitsAsUInt16(2);
                    frame.ModeExtention  = ( int )byteArray.ReadBitsAsUInt16(2);
                    frame.Copyright      = ( int )byteArray.ReadBitsAsUInt16(1);
                    frame.Original       = ( int )byteArray.ReadBitsAsUInt16(1);
                    frame.Emphasis       = ( int )byteArray.ReadBitsAsUInt16(2);

                    if (frame.IsValidHeader)
                    {
                        break;
                    }
                    else
                    {
                        byteArray.SubBitPosition(24);
                    }
                }
            }
            catch (Exception e)
            {
                // Exist BitStream Error.
                UnityEngine.Debug.LogError("Toy Error:" + e);
            }

            // CRC word
            if (frame.ProtectionBit == 0)
            {
                frame.CRCCheck = byteArray.ReadBitsAsUInt16(16);
            }
            else
            {
                frame.CRCCheck = 0;
            }

            if (!DecodeSideTableInformation(frame))
            {
                return(false);
            }

            // Format check
            if (frame.Id != 1 || frame.Layer != 1 || frame.BitrateIndex == 0)
            {
                return(false);
            }

            // MainData
            if (frame.MainDataSize < 0)
            {
                return(false);
            }

            if ((byteArray.PositionBit & 7) != 0)
            {
                throw new Exception("GetByByteArray can be used only at byte border.");
            }

            frame.MainData = byteArray.ReadBytes(frame.MainDataSize);

            return(true);
        }
        public bool DecodeFrame(ToyMP3Frame f)
        {
            frame = f;
            int PcmPoint = 0;

            // Adding data to the buffer
            bs.AddByteArray(frame.MainData);

            // Checking the buffer size and removing used data.
            if (bs.LengthBit > BufferSize)
            {
                bs.RemoveRange(bs.Length - (frame.MainData.Length + frame.MainDataBegin));
            }

            // Checking if position of the buffer to read exists.
            if (frame.MainDataBegin > (bs.Length - frame.MainDataSize))
            {
                return(false);
            }

            // Set reading location.
            bs.SetBitPosition(bs.LengthBit - (frame.MainData.Length * 8 + frame.MainDataBegin * 8));

            // 1つのフレームは2個のグラニュールセットを持つ。
            for (int gr = 0; gr < 2; gr++)
            {
                // Insie of granule-set, there exists glanule*frame.Channels
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    // End position of "Part2~3" (Scalefactor + Huffmancode)
                    int p23_end_pos = bs.PositionBit + frame.granule[ch, gr].Part23Length;

                    DecodeScalefactor(frame.granule[ch, gr], ch, gr);

                    if (!DecodeHuffmanCode(ch, gr, p23_end_pos))
                    {
                        return(false);
                    }

                    bs.SetBitPosition(p23_end_pos);
                }

                // Generate sample map
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    CreateSampleMap(ch, gr);
                }

                // Dequantize(and reorder)
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    Dequantize(ch, gr);
                }

                // Joint Stereo decode
                JointStereoDecode();

                // AntiAlias
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    Antialias(ch, gr);
                }

                // InverseMDCTSynthesys
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    InverseMDCTSynthesys(ch, gr);
                }

                // SubbandSynthesys
                for (int ch = 0; ch < frame.Channels; ch++)
                {
                    SubbandSynthesys(ch);
                }

                // Generate PCM
                CreatePcm(gr);
                PcmPoint += 576 * frame.Channels;
            }

            //PcmDataNum = PcmPoint;
            return(true);
        }