void ReadHeader(EriFile erif) { var section = erif.ReadSection(); if (section.Id != "Header " || section.Length <= 0 || section.Length > int.MaxValue) { return(null); } m_stream_pos = erif.BaseStream.Position + section.Length; section = erif.ReadSection(); if (section.Id != "FileHdr" || section.Length < 8) { return(null); } var file_hdr = new byte[section.Length]; erif.Read(file_hdr, 0, file_hdr.Length); if (0 == (file_hdr[5] & 1)) { return(null); } section = erif.ReadSection(); if (section.Id != "SoundInf" || section.Length < 0x24) { return(null); } var info = new EmsacSoundInfo(); info.Version = erif.ReadInt32(); info.Transformation = (CvType)erif.ReadInt32(); info.Architecture = (EriCode)erif.ReadInt32(); info.ChannelCount = erif.ReadInt32(); info.SamplesPerSec = erif.ReadUInt32(); info.BlocksetCount = erif.ReadUInt32(); info.SubbandDegree = erif.ReadInt32(); info.AllSampleCount = erif.ReadInt32(); info.LappedDegree = erif.ReadInt32(); SetSoundInfo(info); SetWaveFormat(info); erif.BaseStream.Position = m_stream_pos; var stream_size = erif.FindSection("Stream "); m_stream_pos = erif.BaseStream.Position; }
private Stream LoadChunks(EriFile erif) { uint current_sample = 0; List <MioChunk> chunks = new List <MioChunk>(); try { erif.BaseStream.Position = m_stream_pos; for (;;) { long chunk_length = erif.FindSection("SoundStm"); if (chunk_length > int.MaxValue) { throw new FileSizeException(); } var chunk = new MioChunk(); chunk.FirstSample = current_sample; chunk.Version = erif.ReadByte(); chunk.Flags = erif.ReadByte(); erif.ReadInt16(); chunk.SampleCount = erif.ReadUInt32(); chunk.Position = erif.BaseStream.Position; chunk.Size = (uint)(chunk_length - 8); current_sample += chunk.SampleCount; chunks.Add(chunk); erif.BaseStream.Seek(chunk.Size, SeekOrigin.Current); } } catch (EndOfStreamException) { /* ignore EOF errors */ } m_total_samples = current_sample; if (0 == m_total_samples) { m_decode_finished = true; return(Stream.Null); } uint sample_bytes = (uint)ChannelCount * BitsPerSample / 8; var total_bytes = m_total_samples * sample_bytes; m_wait_handles = new WaitHandle[2] { m_available_chunk, m_decode_complete }; m_chunk_queue = new ConcurrentQueue <byte[]>(); m_worker = new BackgroundWorker(); m_worker.WorkerSupportsCancellation = true; m_worker.DoWork += DoWork_Decode; m_worker.RunWorkerAsync(chunks); return(new MemoryStream((int)total_bytes)); }
public MioInput(Stream file) : base(file) { file.Position = 0x40; using (var erif = new EriFile(file)) { var section = erif.ReadSection(); if (section.Id != "Header " || section.Length <= 0 || section.Length > int.MaxValue) { throw new InvalidFormatException(); } m_stream_pos = 0x50 + section.Length; int header_size = (int)section.Length; while (header_size > 0x10) { section = erif.ReadSection(); header_size -= 0x10; if (section.Length <= 0 || section.Length > header_size) { break; } if ("SoundInf" == section.Id) { m_info = new MioInfoHeader(); m_info.Version = erif.ReadInt32(); m_info.Transformation = (CvType)erif.ReadInt32(); m_info.Architecture = (EriCode)erif.ReadInt32(); m_info.ChannelCount = erif.ReadInt32(); m_info.SamplesPerSec = erif.ReadUInt32(); m_info.BlocksetCount = erif.ReadUInt32(); m_info.SubbandDegree = erif.ReadInt32(); m_info.AllSampleCount = erif.ReadUInt32(); m_info.LappedDegree = erif.ReadUInt32(); m_info.BitsPerSample = erif.ReadUInt32(); break; } header_size -= (int)section.Length; erif.BaseStream.Seek(section.Length, SeekOrigin.Current); } if (null == m_info) { throw new InvalidFormatException("MIO sound header not found"); } erif.BaseStream.Position = m_stream_pos; var stream_size = erif.FindSection("Stream "); m_stream_pos = erif.BaseStream.Position; m_pmiod = new MioDecoder(m_info); if (EriCode.Nemesis != m_info.Architecture) { m_pmioc = new HuffmanDecodeContext(0x10000); } else { throw new NotImplementedException("MIO Nemesis encoding not implemented"); } int pcm_bitrate = (int)(m_info.SamplesPerSec * BitsPerSample * ChannelCount); var format = new GameRes.WaveFormat(); format.FormatTag = 1; format.Channels = (ushort)ChannelCount; format.SamplesPerSecond = m_info.SamplesPerSec; format.BitsPerSample = (ushort)BitsPerSample; format.BlockAlign = (ushort)(BitsPerSample / 8 * format.Channels); format.AverageBytesPerSecond = (uint)pcm_bitrate / 8; this.Format = format; m_decoded_stream = LoadChunks(erif); if (0 != m_total_samples) { m_bitrate = (int)(stream_size * 8 * m_info.SamplesPerSec / m_total_samples); } this.PcmSize = m_total_samples * ChannelCount * BitsPerSample / 8; m_decoded_stream.Position = 0; } }