예제 #1
0
        public static void ReadInstrumentSetList()
        {
            // traverse the whole audiobank index and grab details about every bank
            //  use those details to generate a list from the vanilla game that we can modify as needed
            List <InstrumentSetInfo> InstrumentSets = new List <InstrumentSetInfo>();

            for (int inst_set_num = 0; inst_set_num <= 0x28; ++inst_set_num)
            {
                // each bank has one 16 byte sentence of data, first word is address, second length, last 8 bytes metadata
                int    table_pointer_addr = Addresses.AudiobankTable + (16 * inst_set_num);
                int    bank_location      = (ReadWriteUtils.ReadU16(table_pointer_addr) << 16) + ReadWriteUtils.ReadU16(table_pointer_addr + 2);
                int    bank_length        = (ReadWriteUtils.ReadU16(table_pointer_addr + 4) << 16) + ReadWriteUtils.ReadU16(table_pointer_addr + 6);
                byte[] metadata           = new byte[8];
                for (int b = 0; b < 8; ++b)
                {
                    metadata[b] = ReadWriteUtils.Read(table_pointer_addr + 8 + b);
                }
                byte[] bank_data = new byte[bank_length];
                for (int b = 0; b < bank_length; ++b)
                {
                    bank_data[b] = ReadWriteUtils.Read(Addresses.Audiobank + bank_location + b);
                }

                InstrumentSetInfo new_bank = new InstrumentSetInfo
                {
                    BankSlot     = inst_set_num,
                    BankMetaData = metadata,
                    BankBinary   = bank_data
                };

                InstrumentSets.Add(new_bank);
            }
            RomData.InstrumentSetList = InstrumentSets;
        }
예제 #2
0
        public static void ReadInstrumentSetList()
        {
            /// traverse the whole audiobank index and grab details about every bank
            ///  use those details to generate a list from the vanilla game that we can modify as needed
            RomData.InstrumentSetList = new List <InstrumentSetInfo>();
            for (int audiobankIndex = 0; audiobankIndex <= 0x28; ++audiobankIndex)
            {
                // each bank has one 16 byte sentence of data, first word is address, second is length, last 2 words metadata
                int audiobankIndexAddr  = Addresses.AudiobankTable + (audiobankIndex * 0x10);
                int audiobankBankOffset = (ReadWriteUtils.ReadU16(audiobankIndexAddr) << 16) + ReadWriteUtils.ReadU16(audiobankIndexAddr + 2);
                int bankLength          = (ReadWriteUtils.ReadU16(audiobankIndexAddr + 4) << 16) + ReadWriteUtils.ReadU16(audiobankIndexAddr + 6);

                byte[] bankMetadata = new byte[8];
                for (int b = 0; b < 8; ++b)
                {
                    bankMetadata[b] = ReadWriteUtils.Read(audiobankIndexAddr + 8 + b);
                }

                byte[] bankData = new byte[bankLength];
                for (int b = 0; b < bankLength; ++b)
                {
                    bankData[b] = ReadWriteUtils.Read(Addresses.Audiobank + audiobankBankOffset + b);
                }

                var newInstrumentSet = new InstrumentSetInfo
                {
                    BankSlot     = audiobankIndex,
                    BankMetaData = bankMetadata,
                    BankBinary   = bankData
                };

                RomData.InstrumentSetList.Add(newInstrumentSet);
            }
        }
예제 #3
0
        public static void RebuildAudioBank(List <InstrumentSetInfo> InstrumentSetList)
        {
            // get index for the old audiobank, we're putting it back int the same spot but letting it expand into audioseq's spot, because the later is no longer there
            int f = RomUtils.GetFileIndexForWriting(Addresses.AudiobankTable);
            // the DMA table doesn't point directly to the table on the rom, its part of a larger yaz0 file, we have to use an offset to get the address in the file
            int audiobank_table_adjusted_addr = Addresses.AudiobankTable - RomData.MMFileList[RomUtils.GetFileIndexForWriting(Addresses.AudiobankTable)].Addr;

            int current_audiobank_addr = 0;

            byte[] new_audiobank = new byte[0];

            // for each bank, concat onto the new bank byte object, update the table to match the new instrument sets
            for (int inst_set_num = 0; inst_set_num <= 0x28; ++inst_set_num)
            {
                InstrumentSetInfo current_bank = InstrumentSetList[inst_set_num];   // not sure lists are sequential in C#
                int bank_len = current_bank.BankBinary.Length;
                new_audiobank = new_audiobank.Concat(current_bank.BankBinary).ToArray();

                // update address of the bank in the table
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16]     = (byte)((current_audiobank_addr & 0xFF000000) >> 24);
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 1] = (byte)((current_audiobank_addr & 0xFF0000) >> 16);
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 2] = (byte)((current_audiobank_addr & 0xFF00) >> 8);
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 3] = (byte)(current_audiobank_addr & 0xFF);

                // adjust the address for the next sequence to use
                current_audiobank_addr += bank_len;
                int remainder = bank_len % 16;
                if (remainder > 0)                                                              // in the event the user made an audiobank instrument set that isn't padded
                {
                    new_audiobank = new_audiobank.Concat(new byte[remainder + 0x10]).ToArray(); // padding with a spare 16 byte line sounds cheap enough to try
                    Debug.WriteLine("Bank " + inst_set_num + " wasn't padded to 16 bytes:" + bank_len.ToString("X"));
                    current_audiobank_addr += remainder;
                }

                // update length of the bank in the table
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 4] = (byte)((bank_len & 0xFF000000) >> 24);
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 5] = (byte)((bank_len & 0xFF0000) >> 16);
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 6] = (byte)((bank_len & 0xFF00) >> 8);
                RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + inst_set_num * 16 + 7] = (byte)(bank_len & 0xFF);

                // update metadata of the bank in the table
                for (int meta_iter = 0; meta_iter < 8; ++meta_iter)
                {
                    RomData.MMFileList[f].Data[audiobank_table_adjusted_addr + (inst_set_num * 16) + 8 + meta_iter] = current_bank.BankMetaData[meta_iter];
                }
            }

            // write audioseq as a new file
            f = RomUtils.GetFileIndexForWriting(Addresses.Audiobank);
            RomData.MMFileList[f].Data = new_audiobank;
        }
예제 #4
0
        public static void ScanZSEQUENCE(string directory) // TODO make this folder identifiable, add directory and list of banks from scanned directory to this
        {
            // check if files were added by user to directory
            // we're not going to check for non-zseq here until I find an easy way to do that
            //  Just going to trust users aren't stupid enough to think renaming a mp3 to zseq will work
            // format: FILENAME_InstrumentSet_Categories-separated-by-commas.zseq
            //  where the filename, instrumentset, and categories are separated by single underscore
            foreach (String filePath in Directory.GetFiles(directory, "*.zseq"))
            {
                String filename = Path.GetFileName(filePath);

                // test if file has enough delimiters to separate data into name_bank_formats
                String[] pieces = filename.Split('_');
                if (pieces.Length != 3)
                {
                    continue;
                }

                byte[] input_seq_data = null;
                using (BinaryReader bank_reader = new BinaryReader(File.Open(Path.Combine(directory, filename), FileMode.Open)))
                {
                    input_seq_data = new byte[((int)bank_reader.BaseStream.Length)];
                    bank_reader.Read(input_seq_data, 0, (int)bank_reader.BaseStream.Length);
                }


                SequenceBinaryData sequence_data   = null;
                InstrumentSetInfo  instrumnet_info = null;
                if (pieces[1].Contains("x")) //temporary, we can remove this now that we have MMRS, but maybe don't remove just yet
                {
                    // load the custom bank for this file
                    byte[] input_bank_data = null;
                    String bank_name       = filename.Substring(0, filename.LastIndexOf(".zseq")) + ".zbank";
                    using (BinaryReader bank_reader = new BinaryReader(File.Open(Path.Combine(directory, bank_name), FileMode.Open)))
                    {
                        input_bank_data = new byte[((int)bank_reader.BaseStream.Length)];
                        bank_reader.Read(input_bank_data, 0, (int)bank_reader.BaseStream.Length);
                    }

                    byte[] meta_data = new byte[8];
                    using (BinaryReader meta_reader = new BinaryReader(File.Open(Path.Combine(directory, bank_name.Substring(0, bank_name.LastIndexOf(".zbank")) + ".bankmeta"), FileMode.Open)))
                        meta_reader.Read(meta_data, 0, meta_data.Length);

                    pieces[1] = pieces[1].Replace("x", "");

                    instrumnet_info = new InstrumentSetInfo()
                    {
                        BankBinary   = input_bank_data,
                        BankMetaData = meta_data,
                        BankSlot     = Convert.ToInt32(pieces[1], 16),
                        Modified     = true
                    };
                }

                sequence_data = new SequenceBinaryData
                {
                    SequenceBinary = input_seq_data,
                    InstrumentSet  = instrumnet_info
                };


                var sourceName       = filename;
                var sourceTypeString = pieces[2].Substring(0, pieces[2].Length - 5);
                var sourceInstrument = Convert.ToInt32(pieces[1], 16);
                //var sourceType = Array.ConvertAll(sourceTypeString.Split('-'), int.Parse).ToList();
                List <int> sourceType = new List <int>();
                foreach (String part in sourceTypeString.Split('-'))
                {
                    sourceType.Add(Convert.ToInt32(part, 16));
                }

                SequenceInfo sourceSequence = new SequenceInfo
                {
                    Name               = sourceName,
                    Type               = sourceType,
                    Instrument         = sourceInstrument,
                    SequenceBinaryList = new List <SequenceBinaryData>()
                    {
                        sequence_data
                    }
                };


                RomData.SequenceList.Add(sourceSequence);
            }
        }