public NwaDecoder(IBinaryStream input, NwaMetaData info) { m_input = input; m_info = info; m_output = new byte[m_info.PcmSize]; m_sample = new short[2]; m_bits = new LsbBitStream(input.AsStream, true); }
public override SoundInput TryOpen(IBinaryStream file) { var header = file.ReadHeader(0x28); ushort channels = header.ToUInt16(0); if (0 == channels || channels > 2) { return(null); } ushort bps = header.ToUInt16(2); if (bps != 8 && bps != 16) { return(null); } var info = new NwaMetaData { Compression = header.ToInt32(8), RunLengthEncoded = 0 != header.ToInt32(0xC), BlockCount = header.ToInt32(0x10), PcmSize = header.ToInt32(0x14), PackedSize = header.ToInt32(0x18), SampleCount = header.ToInt32(0x1C), BlockSize = header.ToInt32(0x20), FinalBlockSize = header.ToInt32(0x24), }; if (info.PcmSize <= 0) { return(null); } info.Format.FormatTag = 1; info.Format.Channels = channels; info.Format.BitsPerSample = bps; info.Format.SamplesPerSecond = header.ToUInt32(4); info.Format.BlockAlign = (ushort)(channels * bps / 8); info.Format.AverageBytesPerSecond = info.Format.BlockAlign * info.Format.SamplesPerSecond; if (-1 == info.Compression) { if (info.PcmSize > file.Length - 0x2C) { return(null); } return(new RawPcmInput(new StreamRegion(file.AsStream, 0x2C, info.PcmSize), info.Format)); } if (info.Compression > 5) { return(null); } if (info.PcmSize != info.SampleCount * bps / 8) { return(null); } using (var decoder = new NwaDecoder(file, info)) { decoder.Decode(); var pcm = new MemoryStream(decoder.Output); var sound = new RawPcmInput(pcm, info.Format); file.Dispose(); return(sound); } }