Пример #1
0
        /// <summary>
        /// Set or remove a HCA loop.
        /// </summary>
        /// <param name="hcaBytes">The hca file.</param>
        /// <param name="loop">If false, any loop data in the hca file will be removed. If none exists then nothing will happen.</param>
        /// <param name="loopStart">The start of the desired loop, in seconds.</param>
        /// <param name="loopEnd">The end of the loop, in seconds.</param>
        /// <param name="numLoops">The number of loops. (The game seems to ignore this... so just use 0)</param>
        /// <returns></returns>
        public static byte[] SetLoop(byte[] hcaBytes, bool loop, double loopStart, double loopEnd, int numLoops = 0)
        {
            if (loopStart > loopEnd || numLoops < 0)
            {
                return(hcaBytes);
            }
            if (loopStart < 0.0)
            {
                loopStart = 0.0;
            }

            HcaMetadata metadata = new HcaMetadata(hcaBytes);

            if (!metadata.ValidHcaFile)
            {
                throw new InvalidOperationException("SetLoop: the provided file is not a valid HCA file.");
            }

            ushort dataOffset = BigEndianConverter.ReadUInt16(hcaBytes, 6);
            int    loopIndex  = hcaBytes.IndexOfValue(LOOP_SIGNATURE, 0, dataOffset, false);

            if (!loop)
            {
                if (loopIndex == -1)
                {
                    return(hcaBytes);
                }

                //Remove loop and return
                List <byte> bytes = hcaBytes.ToList();
                bytes.RemoveRange(loopIndex, 16);

                //Adjust dataOffset
                dataOffset -= 16;

                hcaBytes = bytes.ToArray();
            }
            else
            {
                uint loopStartBlocks = SecondsToBlocks(loopStart, metadata.SampleRate);
                uint loopEndBlocks   = SecondsToBlocks(loopEnd, metadata.SampleRate);

                if (loopEndBlocks >= metadata.BlockCount || loopEnd < 0)
                {
                    loopEndBlocks = (uint)(metadata.BlockCount - 1);
                }
                if (loopStartBlocks < 0 || loopStartBlocks > metadata.BlockCount)
                {
                    loopStartBlocks = 0;
                }

                int loopCount = (numLoops == 0 && numLoops < 0x80) ? 0x80 : numLoops;

                List <byte> newLoop = new List <byte>();
                newLoop.AddRange(BitConverter.GetBytes(LOOP_SIGNATURE));
                newLoop.AddRange(BigEndianConverter.GetBytes(loopStartBlocks));
                newLoop.AddRange(BigEndianConverter.GetBytes(loopEndBlocks));
                newLoop.AddRange(BigEndianConverter.GetBytes((ushort)loopCount));
                newLoop.AddRange(BigEndianConverter.GetBytes((ushort)0x400));


                if (loopIndex != -1)
                {
                    hcaBytes = Utils.ReplaceRange(hcaBytes, newLoop.ToArray(), loopIndex);
                }
                else
                {
                    List <byte> bytes = hcaBytes.ToList();
                    bytes.InsertRange(IndexOfLoopBlock(hcaBytes, dataOffset), newLoop);
                    hcaBytes = bytes.ToArray();

                    //Adjust dataOffset
                    dataOffset += 16;
                }
            }

            //Update header size
            hcaBytes = Utils.ReplaceRange(hcaBytes, BigEndianConverter.GetBytes((ushort)(dataOffset)), 6);

            //Set checksum
            hcaBytes = SetHeaderChecksum(hcaBytes);

            return(hcaBytes);
        }
 public byte[] GetBytes()
 {
     byte[] buffer = new byte[8];
     Array.Copy(BigEndianConverter.GetBytes(LogicalBlockLength), 1, buffer, 5, 3);
     return(buffer);
 }
 public static void WriteUInt24(byte[] buffer, int offset, uint value)
 {
     byte[] bytes = BigEndianConverter.GetBytes(value);
     Array.Copy(bytes, 1, buffer, offset, 3);
 }
Пример #4
0
        public byte[] GetBytes()
        {
            byte[] buffer = new byte[96];
            buffer[0] |= (byte)(PeripheralQualifier << 5);
            buffer[0] |= (byte)(PeripheralQualifier & 0x1F);
            if (RMB)
            {
                buffer[1] |= 0x80;
            }
            buffer[2] = Version;

            if (NormACA)
            {
                buffer[3] |= 0x20;
            }
            if (HiSup)
            {
                buffer[3] |= 0x10;
            }
            buffer[3] |= (byte)(ResponseDataFormat & 0x0F);

            buffer[4] = AdditionalLength;

            if (SCCS)
            {
                buffer[5] |= 0x80;
            }
            if (ACC)
            {
                buffer[5] |= 0x40;
            }
            buffer[5] |= (byte)((TPGS & 0x03) << 4);
            if (ThirdPartyCopy)
            {
                buffer[5] |= 0x08;
            }
            if (Protect)
            {
                buffer[5] |= 0x01;
            }

            if (EncServ)
            {
                buffer[6] |= 0x40;
            }
            if (VS1)
            {
                buffer[6] |= 0x20;
            }
            if (MultiP)
            {
                buffer[6] |= 0x10;
            }
            if (MChngr)
            {
                buffer[6] |= 0x08;
            }
            if (Addr16)
            {
                buffer[6] |= 0x01;
            }

            if (WBus16)
            {
                buffer[7] |= 0x20;
            }
            if (Sync)
            {
                buffer[7] |= 0x10;
            }
            if (CmdQue)
            {
                buffer[7] |= 0x02;
            }
            if (VS2)
            {
                buffer[7] |= 0x01;
            }

            Array.Copy(ASCIIEncoding.ASCII.GetBytes(VendorIdentification), 0, buffer, 8, Math.Min(VendorIdentification.Length, 8));
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(ProductIdentification), 0, buffer, 16, Math.Min(ProductIdentification.Length, 16));
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(ProductRevisionLevel), 0, buffer, 32, 4);
            Array.Copy(BigEndianConverter.GetBytes(DriveSerialNumber), 0, buffer, 36, 8);


            buffer[56] |= (byte)((Clocking & 0x03) << 2);
            if (QAS)
            {
                buffer[56] |= 0x02;
            }
            if (IUS)
            {
                buffer[56] |= 0x01;
            }

            for (int index = 0; index < 8; index++)
            {
                ushort versionDescriptor = 0;
                if (index < VersionDescriptors.Count)
                {
                    versionDescriptor = VersionDescriptors[index];
                }
                BigEndianWriter.WriteUInt16(buffer, 58 + index * 2, versionDescriptor);
            }

            return(buffer);
        }