/// <summary> /// Look up a WEM audio file object for the given file id /// </summary> /// <param name="WEMFileId">The identifier of the WEM file to retrieve</param> /// <returns>null on error, otherwise the object to access the file</returns> /// <remarks> /// The Data Index section is a table of file identifiers and their /// positions/sizes embedded in the data segment. /// </remarks> public WEMReader WEM(uint WEMFileId) { // Look up any record for sound file // This record, if it exists, will indicate whether we need to open a // different sound bank file, an external WEM file, or the one in this // file. However, I have not yet explored it enough to know that it // works well. objectId2Info.TryGetValue(WEMFileId, out var x); //if (null != x && x is FileInfo) { // Check to see if the file exits; if so, use that over whatever is in the file var fname = WEMFileId + ".wem"; if (null != subfolder) { fname = Path.Join(subfolder, fname); } var WEMStream = folderWrapper.Stream(fname); if (null != WEMStream) { var WEM = new WEMReader(WEMStream); WEM.Open(); return(WEM); } } if (null == x || !(x is FileInfo y)) { return(null); } // This doesn't actually seem to work. The internal WEM files usually // are just a bit of pre-roll if (0 == y.Offset && 0 == y.Size) { return(null); } lock (srcStream) { // create BinaryStream that can only read the given segment var data = new byte[y.Size]; srcStream.Position = DATA_ofs + y.Offset; srcStream.Read(data, 0, (int)y.Size); // Lets copy it to a memory stream var WEMStream = new MemoryStream(data); // And create a WEM reader var reader = new WEMReader(WEMStream); // If the file type isn't recognized, skip it if (!reader.Open()) { reader.Dispose(); return(null); } // return the reader return(reader); } }
/// <summary> /// Opens the file sound bank reader for the given sound bank name. The /// path to the file is looked up from the configuration file. /// </summary> /// <param name="soundBankName">The name of the sound bank file; a caseless /// match is used</param> /// <param name="language">A language specifier, to select from the /// alternatives; if NULL the first bank found (without regard to its /// language) is used. (Ignored for now).</param> /// <returns>null on error, otherwise the sound bank reader</returns> /// <remarks>The banks can be localized, but there isn't any reason here</remarks> public BNKReader SoundBank(string soundBankName, string language = null) { // Check the cache for the reader var key = soundBankName.ToUpper(); if (cache.TryGetValue(key, out var _reader)) { // increment the reference count so that when it calls Dispose() // things won't be out of sync _reader.Retain(); return(_reader); } // Try to get information about the location of the soundbank file if (!soundBank2Info.TryGetValue(key, out var entry)) { return(null); } // Try to get the path to the file if (null == entry.Path) { return(null); } // Get the file stream var bnkStream = folderWrapper.Stream(entry.Path); // Open the file var reader = new BNKReader(soundBankName, folderWrapper, bnkStream, entry.Events, entry.Files, Path.GetDirectoryName(entry.Path)); // Open the reader reader.Open(); // Cache the reader for resource reuse cache[key] = reader; // increment the reference count so that when it calls Dispose() // things won't be out of sync return(reader.Retain()); }