int DecodeFrameImpl(IMpegFrame frame, Array dest, int destOffset)
        {
            Decoder.LayerDecoderBase curDecoder = null;
            switch (frame.Layer)
            {
                case MpegLayer.LayerI:
                    if (_layerIDecoder == null)
                    {
                        _layerIDecoder = new Decoder.LayerIDecoder();
                    }
                    curDecoder = _layerIDecoder;
                    break;
                case MpegLayer.LayerII:
                    if (_layerIIDecoder == null)
                    {
                        _layerIIDecoder = new Decoder.LayerIIDecoder();
                    }
                    curDecoder = _layerIIDecoder;
                    break;
                case MpegLayer.LayerIII:
                    if (_layerIIIDecoder == null)
                    {
                        _layerIIIDecoder = new Decoder.LayerIIIDecoder();
                    }
                    curDecoder = _layerIIIDecoder;
                    break;
            }

            if (curDecoder != null)
            {
                curDecoder.SetEQ(_eqFactors);
                curDecoder.StereoMode = StereoMode;

                var cnt = curDecoder.DecodeFrame(frame, _ch0, _ch1);

                if (frame.ChannelMode == MpegChannelMode.Mono)
                {
                    Buffer.BlockCopy(_ch0, 0, dest, destOffset * sizeof(float), cnt * sizeof(float));
                }
                else
                {
                    // This is kinda annoying...  if we're doing a downmix, we should technically only output a single channel
                    //  The problem is, our caller is probably expecting stereo output.  Grrrr....

                    // We use Buffer.BlockCopy here because we don't know dest's type, but do know it's big enough to do the copy
                    for (int i = 0; i < cnt; i++)
                    {
                        Buffer.BlockCopy(_ch0, i * sizeof(float), dest, destOffset * sizeof(float), sizeof(float));
                        ++destOffset;
                        Buffer.BlockCopy(_ch1, i * sizeof(float), dest, destOffset * sizeof(float), sizeof(float));
                        ++destOffset;
                    }
                    cnt *= 2;
                }

                return cnt;
            }

            return 0;
        }
예제 #2
0
        bool ValidateCRC()
        {
            var crc = 0xFFFFU;

            // process the common bits...
            UpdateCRC(_syncBits, 16, ref crc);

            var apply = false;

            switch (Layer)
            {
            case MpegLayer.LayerI:
                apply = LayerIDecoder.GetCRC(this, ref crc);
                break;

            case MpegLayer.LayerII:
                apply = LayerIIDecoder.GetCRC(this, ref crc);
                break;

            case MpegLayer.LayerIII:
                apply = LayerIIIDecoder.GetCRC(this, ref crc);
                break;
            }

            if (apply)
            {
                var checkCrc = ReadByte(4) << 8 | ReadByte(5);
                return(checkCrc == crc);
            }

            return(true);
        }
예제 #3
0
        protected IFrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer)
        {
            IFrameDecoder decoder = null;

            // REVIEW: allow channel output selection type
            // (LEFT, RIGHT, BOTH, DOWNMIX)
            switch (layer)
            {
            case 3:
                if (l3decoder == null)
                {
                    l3decoder = new LayerIIIDecoder(stream,
                                                    header, filter1, filter2,
                                                    output, OutputChannels.Both);
                }

                decoder = l3decoder;
                break;

            case 2:
                if (l2decoder == null)
                {
                    l2decoder = new LayerIIDecoder();
                    l2decoder.create(stream,
                                     header, filter1, filter2,
                                     output, OutputChannels.Both);
                }
                decoder = l2decoder;
                break;

            case 1:
                if (l1decoder == null)
                {
                    l1decoder = new LayerIDecoder();
                    l1decoder.create(stream,
                                     header, filter1, filter2,
                                     output, OutputChannels.Both);
                }
                decoder = l1decoder;
                break;
            }

            if (decoder == null)
            {
                throw new DecoderException(Errors.UNSUPPORTED_LAYER);
            }

            return(decoder);
        }
예제 #4
0
        int DecodeFrameImpl(IMpegFrame frame, Array dest, int destOffset)
        {
            frame.Reset();

            Decoder.LayerDecoderBase curDecoder = null;
            switch (frame.Layer)
            {
            case MpegLayer.LayerI:
                if (_layerIDecoder == null)
                {
                    _layerIDecoder = new Decoder.LayerIDecoder();
                }
                curDecoder = _layerIDecoder;
                break;

            case MpegLayer.LayerII:
                if (_layerIIDecoder == null)
                {
                    _layerIIDecoder = new Decoder.LayerIIDecoder();
                }
                curDecoder = _layerIIDecoder;
                break;

            case MpegLayer.LayerIII:
                if (_layerIIIDecoder == null)
                {
                    _layerIIIDecoder = new Decoder.LayerIIIDecoder();
                }
                curDecoder = _layerIIIDecoder;
                break;
            }

            if (curDecoder != null)
            {
                curDecoder.SetEQ(_eqFactors);
                curDecoder.StereoMode = StereoMode;

                var cnt = curDecoder.DecodeFrame(frame, _ch0, _ch1);

                if (frame.ChannelMode == MpegChannelMode.Mono)
                {
                    Buffer.BlockCopy(_ch0, 0, dest, destOffset * sizeof(float), cnt * sizeof(float));
                }
                else
                {
                    // This is kinda annoying...  if we're doing a downmix, we should technically only output a single channel
                    //  The problem is, our caller is probably expecting stereo output.  Grrrr....

                    // We use Buffer.BlockCopy here because we don't know dest's type, but do know it's big enough to do the copy
                    for (int i = 0; i < cnt; i++)
                    {
                        Buffer.BlockCopy(_ch0, i * sizeof(float), dest, destOffset * sizeof(float), sizeof(float));
                        ++destOffset;
                        Buffer.BlockCopy(_ch1, i * sizeof(float), dest, destOffset * sizeof(float), sizeof(float));
                        ++destOffset;
                    }
                    cnt *= 2;
                }

                return(cnt);
            }

            return(0);
        }