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; }
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); }
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)); }
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); }
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); }
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)); } }
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); }
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; } }
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); } }
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); }
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)); }