/// <summary> /// Write header to file. /// </summary> /// <param name="in_writer">Binary writer.</param> public void Write(FilePackageWriter in_writer) { // Header ID. in_writer.WriteAscii("AKPK"); // Header size. in_writer.Write((uint)m_uHeaderSize); // Version. in_writer.Write((uint)AK_FILE_PACKAGE_VERSION); }
public IEnumerable <NamedAction> ConcatenateFiles(FilePackageWriter in_writer, IProgressNotificationsDispatcher in_notifDispatcher) { List <NamedAction> actions = new List <NamedAction>(); foreach (OrganizedFile file in m_arOrganizedFileEntries) { string path = file.szPath; uint blockSize = file.uBlockSize; actions.Add(new NamedAction("Writing " + path, delegate() { // Add padding so that next file falls on a block boundary. PadToBlock(in_writer, blockSize, in_writer.Position); // At this point we know the file exists. System.Diagnostics.Debug.Assert(path.Length > 0 && System.IO.File.Exists(path)); in_notifDispatcher.NotifyLogMsg("Packing: " + path, Severity.Message); // Copy file. in_writer.Write(System.IO.File.ReadAllBytes(path)); })); } return(actions); }
/// <summary> /// File helper: Write a certain amount of padding zeros to file. /// </summary> /// <param name="in_writer">Binary writer.</param> /// <param name="in_uPadSize">Number of zeroed bytes to be written.</param> internal static void Pad(FilePackageWriter in_writer, uint in_uPadSize) { if (in_uPadSize > 0) { byte[] padding = new byte[in_uPadSize]; in_writer.Write(padding); } }
/// <summary> /// Write string map to file. /// </summary> /// <param name="in_writer">Binary writer.</param> public void Write(FilePackageWriter in_writer) { ulong uPositionBefore = in_writer.Position; in_writer.Write((uint)m_hashStrings.Count); List <string> sortedKeys = GetSortedKeys(); foreach (string szKey in sortedKeys) { in_writer.Write(m_hashStrings[szKey].Offset); in_writer.Write(m_hashStrings[szKey].ID); } foreach (string szKey in sortedKeys) { in_writer.Write(szKey, m_bPrintAsciiStrings); } // Pad for proper alignment of the rest of the data FileOrganizer.PadToBlock(in_writer, MapDataSizeAlignment, m_uTotalMapSize); System.Diagnostics.Debug.Assert(TotalSize == in_writer.Position - uPositionBefore); }
/// <summary> /// Write LUT to file. /// NOTE: If there are 0 files, the method writes 4 zeroed bytes. /// </summary> /// <param name="in_writer">Binary writer.</param> public void Write(FilePackageWriter in_writer) { ulong uPositionBefore = in_writer.Position; in_writer.Write(NumFiles); foreach (FileEntry file in m_arFiles) { if (m_fileIdType == typeof(UInt32)) { in_writer.Write((UInt32)file.uFileID); } else { in_writer.Write(file.uFileID); } in_writer.Write(file.uBlockSize); in_writer.Write((UInt32)file.uFileSize); in_writer.Write(file.uStartingBlock); in_writer.Write(file.uLanguageID); } System.Diagnostics.Debug.Assert(TotalSize == in_writer.Position - uPositionBefore); }
/// <summary> /// Generate the file package. /// Creates the package header: /// - Header /// - Map of language strings /// - Map of soundbank titles /// - Soundbank files LUT /// - Streamed audio files LUT /// Writes the header to file. /// Concatenates files referenced in the LUTs. /// </summary> /// <param name="in_soundbanksInfo">Soundbank data model.</param> /// <param name="in_settings">Generation settings.</param> /// <param name="in_writer">Binary writer.</param> /// <returns>Returns true when no files are missing.</returns> private IEnumerable <NamedAction> GeneratePackage( Context.GlobalInfo globalInfo, Context.PackageInfo packageInfo, FilePackageWriter in_writer, Results results) { List <NamedAction> actions = new List <NamedAction>(); // Header chunk. Header header = new Header(); // Language names map. // NOTE: As of Wwise 2009.1, language names are stored as ANSI strings when not on Windows (sync with type AkOSChar). bool bLanguageMapUsesAsciiStrings = true; switch (globalInfo.BasePlatform) { case AK.Wwise.InfoFile.SoundBanksInfoBasePlatform.Windows: case AK.Wwise.InfoFile.SoundBanksInfoBasePlatform.XboxOne: bLanguageMapUsesAsciiStrings = false; break; default: bLanguageMapUsesAsciiStrings = true; break; } IEnumerable <AK.Wwise.InfoFile.FileDescriptorType> descriptors = packageInfo.Files.Where(f => f.Descriptor != null).Select(f => f.Descriptor); IEnumerable <FilePackageGenerator.Context.ExternalSourceInfo> externals = packageInfo.Files.Where(f => f.ExternalSourceInfo != null).Select(f => f.ExternalSourceInfo); Dictionary <string, uint> mapLanguageIDs = FindAllLanguages(descriptors); LanguagesMap langMap = new LanguagesMap(mapLanguageIDs, bLanguageMapUsesAsciiStrings); // Add Banks files to LUT. FileLUT banksLUT = new FileLUT(globalInfo.SoundBanksRoot, packageInfo.BlockSize, typeof(UInt32)); foreach (AK.Wwise.InfoFile.FileDescriptorType soundbank in descriptors.OfType <AK.Wwise.InfoFile.SoundBanksInfoSoundBanksSoundBank>()) { if (!banksLUT.Add(soundbank, mapLanguageIDs)) { NotifyLogMsg("Missing soundbank: " + soundbank.ShortName + " (" + soundbank.Path + ")", Severity.Warning); results.HasMissingFiles = true; } } banksLUT.Sort(); // Add Steamed files to LUT. FileLUT streamsLUT = new FileLUT(globalInfo.SourceFilesRoot, packageInfo.BlockSize, typeof(UInt32)); foreach (AK.Wwise.InfoFile.FileDescriptorType stream in descriptors.Where(fd => (fd is AK.Wwise.InfoFile.SoundBanksInfoStreamedFilesFile || fd is AK.Wwise.InfoFile.SoundBanksInfoMediaFilesNotInAnyBankFile))) { if (!streamsLUT.Add(stream, mapLanguageIDs)) { NotifyLogMsg("Missing streamed or loose media file: " + stream.ShortName + " (" + stream.Path + ")", Severity.Warning); results.HasMissingFiles = true; } } streamsLUT.Sort(); // Add External Source files to LUT. FileLUT externalLUT = new FileLUT(globalInfo.SourceFilesRoot, packageInfo.BlockSize, typeof(UInt64)); foreach (FilePackageGenerator.Context.ExternalSourceInfo external in externals) { if (!externalLUT.Add(external, mapLanguageIDs)) { NotifyLogMsg("Missing external file: " + external.Name + " (" + external.Path + ")", Severity.Warning); results.HasMissingFiles = true; } } externalLUT.Sort(); // Find the header size. uint uHeaderSize = BaseHeaderSize + langMap.TotalSize + banksLUT.TotalSize + streamsLUT.TotalSize + externalLUT.TotalSize; // Prepare files for ordered concatenation. FileOrganizer organizer = new FileOrganizer(); organizer.AddLUT(FileOrganizer.FileCategory.SoundBank, banksLUT); organizer.AddLUT(FileOrganizer.FileCategory.MediaFile, streamsLUT); organizer.AddLUT(FileOrganizer.FileCategory.ExternalSource, externalLUT); organizer.OrganizeFiles(uHeaderSize, packageInfo.Files, mapLanguageIDs, this); // Set header size. header.HeaderSize = uHeaderSize; // Write to output file: actions.Add(new NamedAction("Writing header", delegate() { // Header. header.Write(in_writer); in_writer.Write(langMap.TotalSize); in_writer.Write(banksLUT.TotalSize); in_writer.Write(streamsLUT.TotalSize); in_writer.Write(externalLUT.TotalSize); langMap.Write(in_writer); banksLUT.Write(in_writer); streamsLUT.Write(in_writer); externalLUT.Write(in_writer); })); // Concatenated files. return(actions.Concat(organizer.ConcatenateFiles(in_writer, this))); }