示例#1
0
        public static short decodeADPCM(byte input, ref ADPCMState state)
        {
            int index = state.index;
            int step = stepsizeTable[index];
            int valpred = state.valprev;
            int delta = input;

            index += indexTable[delta];
            if (index < 0) index = 0;
            if (index > 88) index = 88;

            bool sign = ((delta & 8) == 8);
            delta = delta & 7;

            int vpdiff = step >> 3;
            if ((delta & 4) == 4) vpdiff += step;
            if ((delta & 2) == 2) vpdiff += step >> 1;
            if ((delta & 1) == 1) vpdiff += step >> 2;

            if (sign) valpred -= vpdiff;
            else valpred += vpdiff;

            if (valpred > 32767) valpred = 32767;
            else if (valpred < -32768) valpred = -32768;

            state.valprev = (short) valpred;
            state.index = (byte) index;
            return (short) valpred;
        }
示例#2
0
    public static short decodeADPCM(byte input, ref ADPCMState state)
    {
        int index   = state.index;
        int step    = stepsizeTable[index];
        int valpred = state.valprev;
        int delta   = input;

        index += indexTable[delta];
        if (index < 0)
        {
            index = 0;
        }
        if (index > 88)
        {
            index = 88;
        }

        bool sign = ((delta & 8) == 8);

        delta = delta & 7;

        int vpdiff = step >> 3;

        if ((delta & 4) == 4)
        {
            vpdiff += step;
        }
        if ((delta & 2) == 2)
        {
            vpdiff += step >> 1;
        }
        if ((delta & 1) == 1)
        {
            vpdiff += step >> 2;
        }

        if (sign)
        {
            valpred -= vpdiff;
        }
        else
        {
            valpred += vpdiff;
        }

        if (valpred > 32767)
        {
            //Debug.Log("valpred overflow");
            valpred = 32767;
        }
        else if (valpred < -32768)
        {
            //Debug.Log("valpred underflow");
            valpred = -32768;
        }

        state.valprev = (short)valpred;
        state.index   = (byte)index;
        return((short)valpred);
    }
示例#3
0
 private static short ADPCMYamahaExpandNibble(ref ADPCMState s, byte nibble)
 {
     s.predictor += (s.step * YamahaDiffLookup[nibble]) / 8;
     s.predictor  = AVClip16(s.predictor);
     s.step       = (s.step * YamahaIndexScale[nibble]) >> 8;
     s.step       = AVClip(s.step, 0x7F, 0x6000);
     return(unchecked ((short)s.predictor));
 }
示例#4
0
 private void PrepareAdpcmState(ADPCMState pc, Stream inStream, MemoryStream decodedStream)
 {
     pc.Predictor = inStream.ReadUInt16();
     pc.Index     = inStream.ReadUInt8();
     inStream.ReadUInt8(); //advance by 1
     //if (pc.Index > StepTable.Count() - 1) pc.Index = StepTable.Count() - 1;
     pc.StepSize = StepTable[pc.Index];
     decodedStream.WriteUInt16(pc.Predictor);
 }
示例#5
0
        public static byte encodeADPCM(short input, ref ADPCMState state)
        {
            int index = state.index;
            int step = stepsizeTable[index];
            int valpred = state.valprev;
            int delta = input;
            int code;

            int diff = delta - valpred;

            if(diff >= 0) code = 0;
            else { code = 8; diff = -diff; }

            int tempstep = step;

            if(diff >= tempstep){
                code = (code | 4);
                diff = diff - tempstep;
            }

            tempstep = tempstep >> 1;

            if(diff >= tempstep){
                code = (code | 2);
                diff = diff - tempstep;
            }

            tempstep = tempstep >> 1;

            if(diff >= tempstep){
                code = (code | 1);
            }

            int diffq = step >> 3;
            if ((code & 4) == 4) diffq += step;
            if ((code & 2) == 2) diffq += step >> 1;
            if ((code & 1) == 1) diffq += step >> 2;

            bool sign = ((code & 8) == 8);

            if (sign) valpred -= diffq;
            else valpred += diffq;

            if (valpred > 32767) valpred = 32767;
            else if (valpred < -32768) valpred = -32768;

            index += indexTable[code];

            if (index < 0) index = 0;
            if (index > 88) index = 88;

            state.valprev = (short) valpred;
            state.index = (byte) index;
            return (byte) (code & 15);
        }
示例#6
0
        private static void ADPCM2PCM2(short[] dst, int dstIndex, byte[] src, int srcIndex)
        {
            ADPCMState state = new ADPCMState {
                predictor = 0,
                step      = 0x7F,
            };

            // 4 bit Yamaha ADPCM (same as dreamcast)
            for (int i = 0; i < src.Length; i++)
            {
                dst[i * 2]     = ADPCMYamahaExpandNibble(ref state, (byte)((src[i] >> 4) & 0xf));
                dst[i * 2 + 1] = ADPCMYamahaExpandNibble(ref state, (byte)(src[i] & 0xf));
            }
        }
示例#7
0
        private int DecodeSample(uint Code, ADPCMState State)
        {
            int result = 0;
            int delta  = 0;

            if ((Code & 0x4) == 4)
            {
                delta += State.StepSize;
            }
            if ((Code & 0x2) == 2)
            {
                delta += State.StepSize >> 1;
            }
            if ((Code & 0x1) == 1)
            {
                delta += State.StepSize >> 2;
            }
            delta += State.StepSize >> 3;
            //Check for sign bit and flip result
            if ((Code & 0x8) == 8)
            {
                delta = -delta;
            }
            result = State.Predictor + delta;

            //clip the sample
            if (result > short.MaxValue)
            {
                result = short.MaxValue;
            }
            else if (result < short.MinValue)
            {
                result = short.MinValue;
            }
            State.Index += IndexTable[Code];
            //clip the index
            if (State.Index < 0)
            {
                State.Index = 0;
            }
            else if (State.Index > 88)
            {
                State.Index = 88;
            }

            State.StepSize  = StepTable[State.Index];
            State.Predictor = (ushort)result;
            return(result);
        }
示例#8
0
        private static void PCM2ADPCM2(byte[] dst, int dstIndex, short[] src, int srcIndex)
        {
            ADPCMState state = new ADPCMState {
                predictor = 0,
                step      = 0x7F,
            };
            int nibble;

            // 4 bit Yamaha ADPCM (same as dreamcast)
            for (int i = 0; i < dst.Length; i++)
            {
                nibble  = ADPCMYamahaCompressSample(ref state, src[i * 2 + 0]);
                nibble |= ADPCMYamahaCompressSample(ref state, src[i * 2 + 1]) << 4;
                dst[i]  = (byte)nibble;
            }
        }
示例#9
0
        public THPStream(THPNode node)
        {
            byte *sPtr;
            short yn1 = 0, yn2 = 0;

            _numChannels = (int)node.Channels;
            _sampleRate  = (int)node.Frequency;
            _numSamples  = (int)node.NumSamples;
            _numBlocks   = (int)node.NumFrames;

            _blockStates   = new ADPCMState[_numChannels, _numBlocks];
            _currentStates = new ADPCMState[_numChannels];
            _audioBlocks   = new THPAudioBlock[_numBlocks];

            //Fill block states in a linear fashion
            for (int frame = 0; frame < node.NumFrames; frame++)
            {
                THPFrame             f      = node._frames[frame];
                ThpAudioFrameHeader *header = f.Audio;
                for (int channel = 0; channel < _numChannels; channel++)
                {
                    sPtr = header->GetAudioChannel(channel);

                    short[] coefs;
                    if (channel == 0)
                    {
                        yn1   = header->_c1yn1;
                        yn2   = header->_c1yn2;
                        coefs = header->Coefs1;
                    }
                    else
                    {
                        yn1   = header->_c2yn1;
                        yn2   = header->_c2yn2;
                        coefs = header->Coefs2;
                    }

                    //Get block state
                    _blockStates[channel, frame] =
                        new ADPCMState(sPtr, *sPtr, yn1, yn2, coefs); //Use ps from data stream
                }

                _audioBlocks[frame] = new THPAudioBlock(header->_blockSize, header->_numSamples);
            }
        }
示例#10
0
        private static byte ADPCMYamahaCompressSample(ref ADPCMState s, short sample)
        {
            byte nibble;
            int  delta;

            if (s.step == 0)
            {
                s.predictor = 0;
                s.step      = 0x7F;
            }

            delta = sample - s.predictor;

            nibble = (byte)(Math.Min(7, Math.Abs(delta) * 4 / s.step) + (delta < 0 ? 8 : 0));

            s.predictor += (s.step * YamahaDiffLookup[nibble]) / 8;
            s.predictor  = AVClip16(s.predictor);
            s.step       = (s.step * YamahaIndexScale[nibble]) >> 8;
            s.step       = AVClip(s.step, 0x7F, 0x6000);

            return(nibble);
        }
示例#11
0
    public static byte encodeADPCM(short input, ref ADPCMState state)
    {
        int index   = state.index;
        int step    = stepsizeTable[index];
        int valpred = state.valprev;
        int delta   = input;
        int code;

        int diff = delta - valpred;     //écart

        if (diff >= 0)
        {
            code = 0;
        }
        else
        {
            code = 8;
            diff = -diff;
        }

        int tempstep = step;

        if (diff >= tempstep)
        {
            code = (code | 4);
            diff = diff - tempstep;
        }

        tempstep = tempstep >> 1;

        if (diff >= tempstep)
        {
            code = (code | 2);
            diff = diff - tempstep;
        }

        tempstep = tempstep >> 1;

        if (diff >= tempstep)
        {
            code = (code | 1);
        }

        int diffq = step >> 3;

        if ((code & 4) == 4)
        {
            diffq += step;
        }
        if ((code & 2) == 2)
        {
            diffq += step >> 1;
        }
        if ((code & 1) == 1)
        {
            diffq += step >> 2;
        }

        bool sign = ((code & 8) == 8);

        if (sign)
        {
            valpred -= diffq;
        }
        else
        {
            valpred += diffq;
        }

        if (valpred > 32767)
        {
            valpred = 32767;
        }
        else if (valpred < -32768)
        {
            valpred = -32768;
        }

        index += indexTable[code];

        if (index < 0)
        {
            index = 0;
        }
        if (index > 88)
        {
            index = 88;
        }

        state.valprev = (short)valpred;
        state.index   = (byte)index;
        return((byte)(code & 15));
    }