public unsafe void writeints(int len, int pos, byte *buf) { int old_pos = BitLength; int start = old_pos / 8; int start1 = pos / 8; int end = (old_pos + len) / 8; int end1 = (pos + len) / 8; flush(); byte start_val = old_pos % 8 != 0 ? buffer[start] : (byte)0; fixed(byte *buf1 = &buffer[0]) { if (old_pos % 8 != 0) { crc16_m = Crc16.Substract(crc16_m, 0, 1); } crc16_m = Crc16.ComputeChecksum(crc16_m, buf + start1, end - start); AudioSamples.MemCpy(buf1 + start, buf + start1, end - start); buf1[start] |= start_val; } buf_ptr_m = end; if ((old_pos + len) % 8 != 0) { writebits((old_pos + len) % 8, buf[end1] >> (8 - ((old_pos + len) % 8))); } }
unsafe void fill_frames_buffer() { if (_framesBufferLength == 0) { _framesBufferOffset = 0; } else if (_framesBufferLength < _framesBuffer.Length / 2 && _framesBufferOffset >= _framesBuffer.Length / 2) { fixed(byte *buff = _framesBuffer) AudioSamples.MemCpy(buff, buff + _framesBufferOffset, _framesBufferLength); _framesBufferOffset = 0; } long readCount = 0; while (_framesBufferLength < _framesBuffer.Length / 2) { readCount++; int read = _IO.Read(_framesBuffer, _framesBufferOffset + _framesBufferLength, _framesBuffer.Length - _framesBufferOffset - _framesBufferLength); _framesBufferLength += read; if (read == 0) { break; } } }
unsafe void Restore_samples_fixed(FlacFrame frame, int ch) { FlacSubframeInfo sub = frame.subframes[ch]; AudioSamples.MemCpy(sub.samples, sub.best.residual, sub.best.order); int *data = sub.samples + sub.best.order; int *residual = sub.best.residual + sub.best.order; int data_len = frame.blocksize - sub.best.order; int s0, s1, s2; switch (sub.best.order) { case 0: AudioSamples.MemCpy(data, residual, data_len); break; case 1: s1 = data[-1]; for (int i = data_len; i > 0; i--) { s1 += *(residual++); *(data++) = s1; } //data[i] = residual[i] + data[i - 1]; break; case 2: s2 = data[-2]; s1 = data[-1]; for (int i = data_len; i > 0; i--) { s0 = *(residual++) + (s1 << 1) - s2; *(data++) = s0; s2 = s1; s1 = s0; } //data[i] = residual[i] + data[i - 1] * 2 - data[i - 2]; break; case 3: for (int i = 0; i < data_len; i++) { data[i] = residual[i] + (((data[i - 1] - data[i - 2]) << 1) + (data[i - 1] - data[i - 2])) + data[i - 3]; } break; case 4: for (int i = 0; i < data_len; i++) { data[i] = residual[i] + ((data[i - 1] + data[i - 3]) << 2) - ((data[i - 2] << 2) + (data[i - 2] << 1)) - data[i - 4]; } break; } }
unsafe void Restore_samples(FlacFrame frame) { for (int ch = 0; ch < PCM.ChannelCount; ch++) { switch (frame.subframes[ch].best.type) { case SubframeType.Constant: AudioSamples.MemSet(frame.subframes[ch].samples, frame.subframes[ch].best.residual[0], frame.blocksize); break; case SubframeType.Verbatim: AudioSamples.MemCpy(frame.subframes[ch].samples, frame.subframes[ch].best.residual, frame.blocksize); break; case SubframeType.Fixed: Restore_samples_fixed(frame, ch); break; case SubframeType.LPC: Restore_samples_lpc(frame, ch); break; } if (frame.subframes[ch].wbits != 0) { int *s = frame.subframes[ch].samples; int x = (int)frame.subframes[ch].wbits; for (int i = frame.blocksize; i > 0; i--) { *(s++) <<= x; } } } if (frame.ch_mode != ChannelMode.NotStereo) { int *l = frame.subframes[0].samples; int *r = frame.subframes[1].samples; switch (frame.ch_mode) { case ChannelMode.LeftRight: break; case ChannelMode.MidSide: for (int i = frame.blocksize; i > 0; i--) { int mid = *l; int side = *r; mid <<= 1; mid |= (side & 1); /* i.e. if 'side' is odd... */ *(l++) = (mid + side) >> 1; *(r++) = (mid - side) >> 1; } break; case ChannelMode.LeftSide: for (int i = frame.blocksize; i > 0; i--) { int _l = *(l++), _r = *r; *(r++) = _l - _r; } break; case ChannelMode.RightSide: for (int i = frame.blocksize; i > 0; i--) { *(l++) += *(r++); } break; } } }