Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }