static int read_itcompr16(ITPACK status, ModuleReader reader, short[] buffer, ushort count, ref ushort incnt) { int x, y, needbits, havebits, new_count = 0; ushort bits = status.bits; ushort bufbits = status.bufbits; short last = status.last; byte buf = status.buf; int place = 0; while (place < count) { needbits = new_count != 0 ? 4 : bits; x = havebits = 0; while (needbits != 0) { /* feed buffer */ if (bufbits == 0) { if (incnt-- > 0) { // Turns out the normal mikmod implementation just sorta ignores EOF when reading samples... // so in this situation I've changed the mikMod test application to fail in these situations // and going to get sharpMik todo the same. buf = reader.Read_byte(); if (reader.isEOF()) { throw new Exception("EOF while reading the samples!"); } } else { buf = 0; } bufbits = 8; } /* get as many bits as necessary */ y = needbits < bufbits ? needbits : bufbits; x |= (buf & ((1 << y) - 1)) << havebits; buf >>= y; bufbits = (ushort)(bufbits - (ushort)y); needbits -= y; havebits += y; } if (new_count != 0) { new_count = 0; if (++x >= bits) { x++; } bits = (ushort)x; continue; } if (bits < 7) { if (x == (1 << (bits - 1))) { new_count = 1; continue; } } else if (bits < 17) { y = (0xffff >> (17 - bits)) - 8; if ((x > y) && (x <= y + 16)) { if ((x -= y) >= bits) { x++; } bits = (ushort)(x); continue; } } else if (bits < 18) { if (x >= 0x10000) { bits = (ushort)(x - 0x10000 + 1); continue; } } else { /* error in compressed data... */ throw new Exception("Invalid data"); } if (bits < 16) /* extend sign */ { x = ((short)(x << (16 - bits))) >> (16 - bits); } buffer[place++] = (last += (short)x); } status.bits = bits; status.bufbits = bufbits; status.last = last; status.buf = buf; return(place); }
static bool SL_LoadInternal(short[] buffer, uint infmt, uint outfmt, int scalefactor, uint length, ModuleReader reader, bool dither) { //SBYTE *bptr = (SBYTE*)buffer; //SWORD *wptr = (SWORD*)buffer; int stodo, t, u; // sbyte[] buf = new sbyte[buffer.Length * 2]; int result, c_block = 0; /* compression bytes until next block */ ITPACK status = new ITPACK(); status.buf = 0; status.last = 0; status.bufbits = 0; status.bits = 0; ushort incnt = 0; int index = 0; while (length != 0) { stodo = (int)((length < SLBUFSIZE) ? length : SLBUFSIZE); if ((infmt & SharpMikCommon.SF_ITPACKED) == SharpMikCommon.SF_ITPACKED) { sl_rlength = 0; if (c_block == 0) { status.bits = (ushort)((infmt & SharpMikCommon.SF_16BITS) == SharpMikCommon.SF_16BITS ? 17 : 9); status.last = 0; status.bufbits = 0; incnt = reader.Read_Intel_ushort();// _mm_read_I_UWORD(reader); c_block = (infmt & SharpMikCommon.SF_16BITS) == SharpMikCommon.SF_16BITS ? 0x4000 : 0x8000; if ((infmt & SharpMikCommon.SF_DELTA) == SharpMikCommon.SF_DELTA) { sl_old = 0; } } if ((infmt & SharpMikCommon.SF_16BITS) == SharpMikCommon.SF_16BITS) { result = read_itcompr16(status, reader, sl_buffer, (ushort)stodo, ref incnt); if (result == 0) { return(true); } } else { result = read_itcompr8(status, reader, sl_buffer, (ushort)stodo, ref incnt); if (result == 0) { return(true); } } if (result != stodo) { throw new Exception("Invalid packed data"); } c_block -= stodo; } else { if ((infmt & SharpMikCommon.SF_16BITS) == SharpMikCommon.SF_16BITS) { if ((infmt & SharpMikCommon.SF_BIG_ENDIAN) == SharpMikCommon.SF_BIG_ENDIAN) { reader.read_Motorola_shorts(sl_buffer, stodo); } else { reader.read_Intel_shorts(sl_buffer, stodo); } } else { sbyte[] bufff = new sbyte[stodo]; int read = stodo; long left = reader.BaseStream.Length - reader.BaseStream.Position; if (left < read) { read = (int)left; } reader.Read_bytes(bufff, read); if (read != stodo) { sbyte[] tempBuf = new sbyte[stodo]; Buffer.BlockCopy(sl_buffer, 0, tempBuf, 0, stodo); for (int i = read; i < stodo; i++) { bufff[i] = tempBuf[i]; } } for (int i = 0; i < stodo; i++) { sl_buffer[i] = (short)(bufff[i] << 8); } } sl_rlength -= stodo; } if ((infmt & SharpMikCommon.SF_DELTA) == SharpMikCommon.SF_DELTA) { for (t = 0; t < stodo; t++) { sl_buffer[t] += sl_old; sl_old = sl_buffer[t]; } } if (((infmt ^ outfmt) & SharpMikCommon.SF_SIGNED) == SharpMikCommon.SF_SIGNED) { for (t = 0; t < stodo; t++) { int s = sl_buffer[t]; s ^= 0x8000; sl_buffer[t] = (short)s; } } if (scalefactor != 0) { int idx = 0; int scaleval; /* Sample Scaling... average values for better results. */ t = 0; while (t < stodo && length != 0) { scaleval = 0; for (u = scalefactor; u != 0 && t < stodo; u--, t++) { scaleval += sl_buffer[t]; } sl_buffer[idx++] = (short)(scaleval / (scalefactor - u)); length--; } stodo = idx; } else { length -= (uint)stodo; } if (dither) { if ((infmt & SharpMikCommon.SF_STEREO) == SharpMikCommon.SF_STEREO && !((outfmt & SharpMikCommon.SF_STEREO) == SharpMikCommon.SF_STEREO)) { /* dither stereo to mono, average together every two samples */ int avgval; int idx = 0; t = 0; while (t < stodo && length != 0) { avgval = sl_buffer[t++]; avgval += sl_buffer[t++]; sl_buffer[idx++] = (short)(avgval >> 1); length -= 2; } stodo = idx; } } if ((outfmt & SharpMikCommon.SF_16BITS) == SharpMikCommon.SF_16BITS) { for (t = 0; t < stodo; t++) { buffer[index++] = sl_buffer[t]; //buf[index++] = (sbyte)(sl_buffer[t] & 0xFF); //buf[index++] = (sbyte)((sl_buffer[t] >> 8) & 0xFF); } } else { for (t = 0; t < stodo; t++) { buf[index++] = (sbyte)(sl_buffer[t] >> 8); } } } if (!((outfmt & SharpMikCommon.SF_16BITS) == SharpMikCommon.SF_16BITS)) { int j = 0; for (int i = 0; i < buffer.Length; i++) { short value1 = buf[j++]; short value2 = buf[j++]; short put = (short)((ushort)value1 | (ushort)(value2 << 8)); buffer[i] = put; } } return(false); }
static int read_itcompr8(ITPACK status, ModuleReader reader, short[] buffer, ushort count, ref ushort incnt) { ushort x; int y, needbits, havebits, new_count = 0; ushort bits = status.bits; ushort bufbits = status.bufbits; sbyte last = (sbyte)status.last; byte buf = status.buf; int place = 0; while (place < count) { needbits = (new_count != 0 ? 3 : bits); x = 0; havebits = 0; while (needbits != 0) { /* feed buffer */ if (bufbits == 0) { if (incnt-- > 0) { buf = reader.Read_byte(); } else { buf = 0; } bufbits = 8; } /* get as many bits as necessary */ y = needbits < bufbits ? needbits : bufbits; x |= (ushort)((buf & ((1 << y) - 1)) << havebits); buf >>= y; bufbits -= (ushort)y; needbits -= y; havebits += y; } if (new_count != 0) { new_count = 0; if (++x >= bits) { x++; } bits = (ushort)x; continue; } if (bits < 7) { if (x == (1 << (bits - 1))) { new_count = 1; continue; } } else if (bits < 9) { y = (0xff >> (9 - bits)) - 4; if ((x > y) && (x <= y + 8)) { if ((x -= (ushort)y) >= bits) { x++; } bits = (ushort)x; continue; } } else if (bits < 10) { if (x >= 0x100) { bits = (ushort)(x - 0x100 + 1); continue; } } else { /* error in compressed data... */ throw new Exception("Invalid Data"); } if (bits < 8) /* extend sign */ { x = (ushort)(((sbyte)(x << (8 - bits))) >> (8 - bits)); } short val = (short)((last += (sbyte)x) << 8); buffer[place++] = (short)val; } status.bits = bits; status.bufbits = bufbits; status.last = last; status.buf = buf; return(place); }