示例#1
0
		/**********************************************************************************************

			 clock_adpcm -- clock the next ADPCM byte

		***********************************************************************************************/

		public short clock_adpcm(adpcm_state state, byte nibble)
		{
//            System.Console.Write("nibble={0} diff_lookup[{1}]={2}\n", nibble, state.step * 16 + (nibble & 15), diff_lookup[state.step * 16 + (nibble & 15)]);
//            System.Console.Write("1state.signal={0}\n", state.signal);
			state.signal += diff_lookup[state.step * 16 + (nibble & 15)];

			/* clamp to the maximum */
			if (state.signal > 2047)
				state.signal = 2047;
			else if (state.signal < -2048)
				state.signal = -2048;

//            System.Console.Write("2state.signal={0}\n", state.signal);
			/* adjust the step size and clamp */
			state.step += index_shift[nibble & 7];
//            System.Console.Write("3state.signal={0}\n", state.signal);
			if (state.step > 48)
				state.step = 48;
			else if (state.step < 0)
				state.step = 0;

//            System.Console.Write("4state.signal={0}\n", state.signal);
			/* return the signal */
			return (short)state.signal;
		}
示例#2
0
		/**********************************************************************************************

			 reset_adpcm -- reset the ADPCM stream

		***********************************************************************************************/

		public void reset_adpcm(adpcm_state state)
		{
			/* make sure we have our tables */
			if (tables_computed == 0) compute_tables();

			/* reset the signal/step */
			state.signal = -2;
			state.step = 0;
		}
        static unsafe void adpcm_coder(short *indata, byte *outdata, int len, adpcm_state *state, int cBits, bool fPreClamp)
        {
            short *inp;			/* Input buffer pointer */
            byte *outp;		/* output buffer pointer */
            int val;			/* Current input sample value */
            int sign;			/* Current adpcm sign bit */
            int delta;			/* Current adpcm output value */
            int diff;			/* Difference between val and valprev */
            int step;			/* Stepsize */
            int valpred;		/* Predicted output value */
            int vpdiff;			/* Current change to valpred */
            int index;			/* Current step change index */
            int outputbuffer;		/* place to keep previous 4-bit value */
            int bufferstep;		/* toggle between outputbuffer/output */

            outp = outdata;
            inp = indata;

            valpred = state->valprev;
            index = state->index;
            step = stepsizeTable[index];

            outputbuffer = 0;
            bufferstep = 1;

            for ( ; len > 0 ; len-- ) {
                val = *inp++;

                /* Step 1 - compute difference with previous value */
                diff = val - valpred;
                sign = (diff < 0) ? 8 : 0;
                if (sign != 0) diff = (-diff);

                // If we preclamp, then at decode time we don't need to clamp
                // at all. It results in some quantization error however, but
                // it is so slight it fails the blind test.

                int vpdiffMax = int.MaxValue;
                if (fPreClamp) {
                    if (sign != 0) {
                        vpdiffMax = valpred - -32768;
                    } else {
                        vpdiffMax = 32767 - valpred;
                    }
                }

                /* Step 2 - Divide and clamp */
                /* Note:
                ** This code *approximately* computes:
                **    delta = diff*4/step;
                **    vpdiff = (delta+0.5)*step/4;
                ** but in shift step bits are dropped. The net result of this is
                ** that even if you have fast mul/div hardware you cannot put it to
                ** good use since the fixup would be too expensive.
                */
                delta = 0;

                if (fPreClamp) {
                    vpdiff = 0;
                } else {
                    vpdiff = (step >> 3);
                }

                if ( diff >= step ) {
                    delta = 4;
                    diff -= step;
                    vpdiff += step;

                    if (vpdiff > vpdiffMax) {
                        vpdiff -= step;
                        delta &= ~4;
                    }
                }

                if (cBits > 2) {
                    step >>= 1;
                    if ( diff >= step  ) {
                        delta |= 2;
                        diff -= step;
                        vpdiff += step;

                        if (vpdiff > vpdiffMax) {
                            vpdiff -= step;
                            delta &= ~2;
                        }
                    }
                }

                if (cBits > 3) {
                    step >>= 1;
                    if ( diff >= step ) {
                        delta |= 1;
                        vpdiff += step;

                        if (vpdiff > vpdiffMax) {
                            vpdiff -= step;
                            delta &= ~1;
                        }
                    }
                }

                /* Step 3 - Update previous value */
                if (sign != 0)
                    valpred -= vpdiff;
                else
                    valpred += vpdiff;

                /* Step 4 - Clamp previous value to 16 bits */
                if ( valpred > 32767 ) {
                    valpred = 32767;
                    Debug.Assert(!fPreClamp);
                } else if ( valpred < -32768 ) {
                    valpred = -32768;
                    Debug.Assert(!fPreClamp);
                }

                /* Step 5 - Assemble value, update index and step values */
                delta |= sign;

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

                /* Step 6 - Output value */
                if (bufferstep != 0 ) {
                    outputbuffer = (delta << 4) & 0xf0;
                } else {
                    *outp++ = (byte)((delta & 0x0f) | outputbuffer);
                }
                bufferstep ^= 1;
            }

            /* Output last step, if needed */
            if (bufferstep == 0)
                *outp++ = (byte)outputbuffer;

            state->valprev = valpred;
            state->index = index;
        }
        static unsafe void adpcm_decoder(byte *indata, short *outdata, int len, adpcm_state *state, bool fPreClamp)
        {
            byte *inp;		/* Input buffer pointer */
            short *outp;		/* output buffer pointer */
            int sign;			/* Current adpcm sign bit */
            int delta;			/* Current adpcm output value */
            int step;			/* Stepsize */
            int valpred;		/* Predicted value */
            int vpdiff;			/* Current change to valpred */
            int index;			/* Current step change index */
            int inputbuffer;		/* place to keep next 4-bit value */
            int bufferstep;		/* toggle between inputbuffer/input */

            outp = outdata;
            inp = indata;

            valpred = state->valprev;
            index = state->index;
            step = stepsizeTable[index];

            inputbuffer = 0;
            bufferstep = 0;

            for ( ; len > 0 ; len-- ) {

                /* Step 1 - get the delta value */
                if (bufferstep != 0) {
                    delta = inputbuffer & 0xf;
                } else {
                    inputbuffer = *inp++;
                    delta = (inputbuffer >> 4) & 0xf;
                }
                bufferstep ^= 1;

                /* Step 2 - Find new index value (for later) */
                index += indexTable[delta];
                if ( index < 0 ) index = 0;
                if ( index > 88 ) index = 88;

                /* Step 3 - Separate sign and magnitude */
                sign = delta & 8;
                delta = delta & 7;

                /* Step 4 - Compute difference and new predicted value */
                /*
                ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
                ** in adpcm_coder.
                */

                if (fPreClamp) {
                    vpdiff = 0;
                } else {
                    vpdiff = step >> 3;
                }

                if ((delta & 4) != 0) vpdiff += step;
                if ((delta & 2) != 0) vpdiff += step>>1;
                if ((delta & 1) != 0) vpdiff += step>>2;

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

                /* Step 5 - clamp output value */
                if (!fPreClamp) {
                    if ( valpred > 32767 )
                        valpred = 32767;
                    else if ( valpred < -32768 )
                        valpred = -32768;
                }

                /* Step 6 - Update step value */
                step = stepsizeTable[index];

                /* Step 7 - Output value */
                *outp++ = (short)valpred;
            }

            state->valprev = valpred;
            state->index = index;
        }