/// <summary> /// Update the file. /// </summary> public void Update(UInt16 endian) { //Update info. info.magic = "INFO".ToCharArray(); info.streamSoundInfoRef = new Reference(ReferenceTypes.STRM_Info_StreamSound, 0x18); //Stream sound info. UInt32 infoBaseOffet = 0x18; info.streamSoundInfo.channelCount = (byte)info.channels.Count; info.streamSoundInfo.regionCount = (byte)(region != null ? region.regions.Length : 0); info.streamSoundInfo.regionDataOffset = new Reference(0, 0x18); info.streamSoundInfo.regionInfoBytesize = 0x100; info.streamSoundInfo.sampleDataOffset = new Reference(ReferenceTypes.General_ByteStream, 0x18); info.streamSoundInfo.padding = 0; info.streamSoundInfo.sizeOfSeekInfo = 4; infoBaseOffet += 56; if (fileHeader.vMajor >= regionInfo) { infoBaseOffet += 12; } if (fileHeader.vMajor >= originalLoopInfo) { infoBaseOffet += 8; } if (fileHeader.vMajor >= secretInfo) { infoBaseOffet += 4; } //Reference table for track info ref. info.trackInfoTableRef = new Reference(0x0101, (int)infoBaseOffet); //Skip ref table coords. infoBaseOffet += (uint)(info.tracks != null ? (info.tracks.Count * 8 + 4) : 0); info.channelInfoTableRef = new Reference(0x0101, (int)infoBaseOffet); List <Reference> trackRefs = new List <Reference>(); //Track info. UInt32 trackBaseOffset = (uint)((info.tracks != null ? (info.tracks.Count * 8 + 4) : 0) + (info.channels.Count * 8 + 4)); if (info.tracks != null) { for (int i = 0; i < info.tracks.Count; i++) { trackRefs.Add(new Reference(ReferenceTypes.STRM_Info_Track, (int)trackBaseOffset)); infoBaseOffet += 12; trackBaseOffset += 12; if (info.tracks[i].globalChannelIndexTable != null) { info.tracks[i].globalChannelIndexTableRef = new Reference(0x100, 0xC); info.tracks[i].globalChannelIndexTable.count = (uint)info.tracks[i].globalChannelIndexTable.entries.Count; infoBaseOffet += 4 + info.tracks[i].globalChannelIndexTable.count; trackBaseOffset += 4 + info.tracks[i].globalChannelIndexTable.count; while (infoBaseOffet % 4 != 0) { infoBaseOffet++; trackBaseOffset++; } } else { info.tracks[i].globalChannelIndexTableRef = new Reference(0, Reference.NULL_PTR); } } info.trackInfoRefTable = new ReferenceTable(trackRefs); } else { info.trackInfoTableRef = new Reference(0, Reference.NULL_PTR); info.trackInfoRefTable = null; } //Channel info. UInt32 channelBaseOffset = (uint)(4 + 8 * info.channels.Count() + trackBaseOffset - ((uint)((info.tracks != null ? (info.tracks.Count * 8 + 4) : 0) + (info.channels.Count * 8 + 4)))); infoBaseOffet += (uint)(4 + 8 * info.channels.Count()); List <Reference> channelRefs = new List <Reference>(); for (int i = 0; i < info.channels.Count; i++) { channelRefs.Add(new Reference(ReferenceTypes.STRM_Info_Channel, (int)channelBaseOffset)); channelBaseOffset += 8; infoBaseOffet += 8; } info.channelInfoRefTable = new ReferenceTable(channelRefs); channelBaseOffset = (uint)(8 * info.channels.Count()); for (int i = 0; i < info.channels.Count; i++) { info.channels[i].dspAdpcmInfoRef = new Reference(0, Reference.NULL_PTR); if (info.channels[i].dspAdpcmInfo != null) { info.channels[i].dspAdpcmInfoRef = new Reference(0x300, (int)channelBaseOffset); channelBaseOffset += 0x2E; infoBaseOffet += 0x2E; } channelBaseOffset -= 8; } //Make offsets, depeding on what blocks exist, and on the sizes of the blocks. List <SizedReference> blocks = new List <SizedReference>(); //Can't forget about magic and size. infoBaseOffet += 8; while (infoBaseOffet % 0x20 != 0) { infoBaseOffet++; } info.blockSize = infoBaseOffet; blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Info, 0, info.blockSize)); if (seek != null) { blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Seek, (int)info.blockSize, seek.GetSize())); } if (region != null) { blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Region, (int)info.blockSize + (seek != null ? (int)seek.GetSize() : 0), region.GetSize())); } blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Data, (int)info.blockSize + (seek != null ? (int)seek.GetSize() : 0) + (region != null ? (int)region.GetSize() : 0), data.GetSize(info.streamSoundInfo.encoding, ref info))); fileHeader = new FileHeader(endian == ByteOrder.LittleEndian ? "CSTM" : "FSTM", endian, fileHeader.vMajor, fileHeader.vMinor, fileHeader.vRevision, (uint)(info.blockSize + (seek != null ? (int)seek.GetSize() : 0) + (region != null ? (int)region.GetSize() : 0) + data.GetSize(info.streamSoundInfo.encoding, ref info)), blocks); if (region == null) { info.streamSoundInfo.regionDataOffset = new Reference(0, Reference.NULL_PTR); } //Update stuff. MemoryStream o = new MemoryStream(); BinaryDataWriter bw = new BinaryDataWriter(o); if (seek != null) { seek.Write(ref bw, fileHeader); } if (region != null) { region.Write(ref bw); } data.WriteSTM(ref bw, info, info.streamSoundInfo.sampleCount); }
/// <summary> /// Update the file. /// </summary> public void Update(UInt16 byteOrder, Int32 wavOffset = 0x18) { //Find the size. UInt32 fileSize = 0; UInt32 infoSize = 32; UInt32 dataSize = data.GetSize(info.encoding, ref info, wavOffset); fileSize += dataSize; //Get size of info. info.magic = "INFO".ToCharArray(); info.channelInfoRefTable = new ReferenceTable(new List <Reference>()); info.channelInfoRefTable.count = (UInt32)info.channelInfo.Count(); //Ref pointer. Int32 refPointer = 4 + 8 * (Int32)info.channelInfoRefTable.count; infoSize += 8 * info.channelInfoRefTable.count; //Channel info. for (int i = 0; i < info.channelInfoRefTable.count; i++) { //Add pointer. info.channelInfoRefTable.references.Add(new Reference(ReferenceTypes.WAV_ItemInfos, refPointer)); refPointer += 20; infoSize += 20; } //Channel info. Int32 dspAdpcmOffset = 20 * info.channelInfo.Count(); for (int i = 0; i < info.channelInfoRefTable.count; i++) { if (info.channelInfo[i].dspAdpcmInfo != null) { info.channelInfo[i].dspAdpcmInfoRef = new Reference(0x300, dspAdpcmOffset); refPointer += 46; infoSize += 46; dspAdpcmOffset += 46; } else { info.channelInfo[i].dspAdpcmInfoRef = new Reference(0, Reference.NULL_PTR); } dspAdpcmOffset -= 20; } //Padding. while ((infoSize % 0x20) != 0) { infoSize += 1; } fileSize += infoSize; info.blockSize = infoSize; //Update the file header. string magic = "FWAV"; if (byteOrder == ByteOrder.LittleEndian) { magic = "CWAV"; } fileHeader = new FileHeader(magic, byteOrder, fileHeader.vMajor, fileHeader.vMinor, fileHeader.vRevision, fileSize, new List <SizedReference>() { new SizedReference(ReferenceTypes.WAV_Block_Info, 0, infoSize), new SizedReference(ReferenceTypes.WAV_Block_Data, (Int32)infoSize, dataSize) }); }