public void StartStreamFastCall(byte CurChip, uint TempSht, byte mode) { if (CurChip == 0xFF || !DacCtrl[CurChip].Enable || PCMBank[DacCtrl[CurChip].Bank].BankCount == 0) { return; } VGM_PCM_BANK TempPCM = PCMBank[DacCtrl[CurChip].Bank]; if (TempSht >= TempPCM.BankCount) { TempSht = 0x00; } VGM_PCM_DATA TempBnk = TempPCM.Bank[(int)TempSht]; byte TempByt = (byte)(dacControl.DCTRL_LMODE_BYTES | (mode & 0x10) | // Reverse Mode ((mode & 0x01) << 7)); // Looping start(CurChip, TempBnk.DataStart, TempByt, TempBnk.DataSize); }
private bool DecompressDataBlk(byte[] vgmBuf, VGM_PCM_DATA Bank, uint DataSize, uint Adr) { byte ComprType; byte BitDec; byte BitCmp; byte CmpSubType; uint AddVal; uint InPos; uint InDataEnd; uint OutPos; uint OutDataEnd; uint InVal; uint OutVal = 0;// FUINT16 OutVal; byte ValSize; byte InShift; byte OutShift; uint Ent1B = 0; // UINT8* Ent1B; uint Ent2B = 0; // UINT16* Ent2B; //#if defined(_DEBUG) && defined(WIN32) // UINT32 Time; //#endif // ReadBits Variables byte BitsToRead; byte BitReadVal; byte InValB; byte BitMask; byte OutBit; // Variables for DPCM uint OutMask; //#if defined(_DEBUG) && defined(WIN32) // Time = GetTickCount(); //#endif ComprType = vgmBuf[Adr + 0]; Bank.DataSize = getLE32(vgmBuf, Adr + 1); switch (ComprType) { case 0x00: // n-Bit compression BitDec = vgmBuf[Adr + 5]; BitCmp = vgmBuf[Adr + 6]; CmpSubType = vgmBuf[Adr + 7]; AddVal = getLE16(vgmBuf, Adr + 8); if (CmpSubType == 0x02) { //Bank.DataSize = 0x00; //return false; Ent1B = 0; // (UINT8*)PCMTbl.Entries; // Big Endian note: Those are stored in LE and converted when reading. Ent2B = 0; // (UINT16*)PCMTbl.Entries; if (PCMTbl.EntryCount == 0) { Bank.DataSize = 0x00; //printf("Error loading table-compressed data block! No table loaded!\n"); return(false); } else if (BitDec != PCMTbl.BitDec || BitCmp != PCMTbl.BitCmp) { Bank.DataSize = 0x00; //printf("Warning! Data block and loaded value table incompatible!\n"); return(false); } } ValSize = (byte)((BitDec + 7) / 8); InPos = Adr + 0x0A; InDataEnd = Adr + DataSize; InShift = 0; OutShift = (byte)(BitDec - BitCmp); // OutDataEnd = Bank.Data + Bank.DataSize; OutDataEnd = Bank.DataSize; //for (OutPos = Bank->Data; OutPos < OutDataEnd && InPos < InDataEnd; OutPos += ValSize) for (OutPos = 0; OutPos < OutDataEnd && InPos < InDataEnd; OutPos += ValSize) { //InVal = ReadBits(Data, InPos, &InShift, BitCmp); // inlined - is 30% faster OutBit = 0x00; InVal = 0x0000; BitsToRead = BitCmp; while (BitsToRead != 0) { BitReadVal = (byte)((BitsToRead >= 8) ? 8 : BitsToRead); BitsToRead -= BitReadVal; BitMask = (byte)((1 << BitReadVal) - 1); InShift += BitReadVal; //InValB = (byte)((vgmBuf[InPos] << InShift >> 8) & BitMask); InValB = (byte)((vgmBuf[InPos] << InShift >> 8) & BitMask); if (InShift >= 8) { InShift -= 8; InPos++; if (InShift != 0) { InValB |= (byte)((vgmBuf[InPos] << InShift >> 8) & BitMask); } } InVal |= (uint)(InValB << OutBit); OutBit += BitReadVal; } switch (CmpSubType) { case 0x00: // Copy OutVal = InVal + AddVal; break; case 0x01: // Shift Left OutVal = (InVal << OutShift) + AddVal; break; case 0x02: // Table switch (ValSize) { case 0x01: OutVal = PCMTbl.Entries[Ent1B + InVal]; break; case 0x02: //#ifndef BIG_ENDIAN // OutVal = Ent2B[InVal]; //#else OutVal = (uint)(PCMTbl.Entries[Ent2B + InVal * 2] + PCMTbl.Entries[Ent2B + InVal * 2 + 1] * 0x100); // ReadLE16((UINT8*)&Ent2B[InVal]); //#endif break; } break; } //#ifndef BIG_ENDIAN // //memcpy(OutPos, &OutVal, ValSize); // if (ValSize == 0x01) // *((UINT8*)OutPos) = (UINT8)OutVal; // else //if (ValSize == 0x02) // *((UINT16*)OutPos) = (UINT16)OutVal; //#else if (ValSize == 0x01) { Bank.Data[OutPos] = (byte)OutVal; } else //if (ValSize == 0x02) { Bank.Data[OutPos + 0x00] = (byte)((OutVal & 0x00FF) >> 0); Bank.Data[OutPos + 0x01] = (byte)((OutVal & 0xFF00) >> 8); } //#endif } break; case 0x01: // Delta-PCM BitDec = vgmBuf[Adr + 5]; // Data[0x05]; BitCmp = vgmBuf[Adr + 6]; // Data[0x06]; OutVal = getLE16(vgmBuf, Adr + 8); // ReadLE16(&Data[0x08]); Ent1B = 0; // (UINT8*)PCMTbl.Entries; Ent2B = 0; // (UINT16*)PCMTbl.Entries; if (PCMTbl.EntryCount == 0) { Bank.DataSize = 0x00; //printf("Error loading table-compressed data block! No table loaded!\n"); return(false); } else if (BitDec != PCMTbl.BitDec || BitCmp != PCMTbl.BitCmp) { Bank.DataSize = 0x00; //printf("Warning! Data block and loaded value table incompatible!\n"); return(false); } ValSize = (byte)((BitDec + 7) / 8); OutMask = (uint)((1 << BitDec) - 1); InPos = Adr + 0xa; InDataEnd = Adr + DataSize; InShift = 0; OutShift = (byte)(BitDec - BitCmp); OutDataEnd = Bank.DataSize; // Bank.Data + Bank.DataSize; AddVal = 0x0000; // for (OutPos = Bank.Data; OutPos < OutDataEnd && InPos < InDataEnd; OutPos += ValSize) for (OutPos = 0; OutPos < OutDataEnd && InPos < InDataEnd; OutPos += ValSize) { //InVal = ReadBits(Data, InPos, &InShift, BitCmp); // inlined - is 30% faster OutBit = 0x00; InVal = 0x0000; BitsToRead = BitCmp; while (BitsToRead != 0) { BitReadVal = (byte)((BitsToRead >= 8) ? 8 : BitsToRead); BitsToRead -= BitReadVal; BitMask = (byte)((1 << BitReadVal) - 1); InShift += BitReadVal; InValB = (byte)((vgmBuf[InPos] << InShift >> 8) & BitMask); if (InShift >= 8) { InShift -= 8; InPos++; if (InShift != 0) { InValB |= (byte)((vgmBuf[InPos] << InShift >> 8) & BitMask); } } InVal |= (byte)(InValB << OutBit); OutBit += BitReadVal; } switch (ValSize) { case 0x01: AddVal = PCMTbl.Entries[Ent1B + InVal]; OutVal += AddVal; OutVal &= OutMask; Bank.Data[OutPos] = (byte)OutVal; // *((UINT8*)OutPos) = (UINT8)OutVal; break; case 0x02: //#ifndef BIG_ENDIAN // AddVal = Ent2B[InVal]; //#else AddVal = (uint)(PCMTbl.Entries[Ent2B + InVal] + PCMTbl.Entries[Ent2B + InVal + 1] * 0x100); //AddVal = ReadLE16((UINT8*)&Ent2B[InVal]); //#endif OutVal += AddVal; OutVal &= OutMask; //#ifndef BIG_ENDIAN // *((UINT16*)OutPos) = (UINT16)OutVal; //#else Bank.Data[OutPos + 0x00] = (byte)((OutVal & 0x00FF) >> 0); Bank.Data[OutPos + 0x01] = (byte)((OutVal & 0xFF00) >> 8); //#endif break; } } break; default: //printf("Error: Unknown data block compression!\n"); return(false); } //#if defined(_DEBUG) && defined(WIN32) // Time = GetTickCount() - Time; // printf("Decompression Time: %lu\n", Time); //#endif return(true); }