示例#1
0
        //Coverted from C (ima_rejigger2)
        //https://bitbucket.org/anders/wwiseconv/wiki/WWise_format
        public static byte[] IMA_ADPCM(byte[] a, out string xex, bool pcm)
        {
            xex = "stream";
            Binboy bb = new Binboy(a);
            if(!bb.Open()) return a;

            if (bb.GetEncoding().GetString(bb.ReadBytes(4), 0, 4) != "RIFF") return a;
            int riffSize = bb.ReadInt32();
            if (bb.GetEncoding().GetString(bb.ReadBytes(4), 0, 4) != "WAVE") return a;

            int waveChunkStart = 12;
            int waveChunkEnd = 8 + riffSize;
            int chunkOffset = waveChunkStart;
            int channels = -1;
            int blockSize = -1;
            int samples = -1;
            int dataSize = -1;
            int dataPos = -1;

            bb.SetPosition(0);
            MemoryStream ms = new MemoryStream(bb.ReadAllBytes());
            BinaryWriter bw = new BinaryWriter(ms);

            while (chunkOffset < waveChunkEnd)
            {
                bb.SetPosition((int)chunkOffset);
                string chunkType = Encoding.ASCII.GetString(bb.ReadBytes(4), 0, 4);
                int chunkSize = bb.ReadInt32();

                if (chunkOffset + 8 + chunkSize < chunkOffset + 8 || chunkOffset + 8 + chunkSize > waveChunkEnd) return a;

                switch (chunkType)
                {
                    case "fmt ":
                        Bandaid.Debug("fmt");
                        if ((int)0xE > chunkSize) return a;
                        Bandaid.Debug("ChunkSize is correct");
                        ushort codec = bb.ReadUInt16(chunkOffset + 8);
                        if (codec == 0xFFFF)
                        {
                            xex = "stream";
                            return a;
                        }
                        if (0x2 != codec) return a;
                        Bandaid.Debug("Codec is correct");
                        channels = bb.ReadUInt16();
                        Bandaid.Debug("chunkOffset", chunkOffset);
                        samples = bb.ReadInt32();
                        bb.ReadUInt32();
                        ushort sblockSize = bb.ReadUInt16();
                        Bandaid.Debug("Channels", channels, "BlockSize", sblockSize);
                        blockSize = sblockSize;
                        bw.BaseStream.Position = chunkOffset + 8;
                        bw.Write((ushort)0x11);
                        break;
                    case "data":
                        Bandaid.Debug("Data");
                        if (channels < 1 || blockSize < 1) return a;
                        dataSize = chunkSize;
                        dataPos = chunkOffset + 8;
                        reinterleaveMS_IMA(bw, bb, dataPos, chunkSize, channels, blockSize);
                        break;
                }

                chunkOffset += 8 + chunkSize;
            }
            if (!pcm) return ms.ToArray();
            ms.Position = 0;
            IMA_ADPCM decode = new IMA_ADPCM(ms);
            xex = "wav";
            return decode.Decode();
        }
示例#2
0
        //https://bitbucket.org/anders/wwiseconv/wiki/WWise_format
        private static void reinterleaveMS_IMA(BinaryWriter bw, Binboy bb, int offset, int chunkSize, int channels, int blockSize)
        {
            int bytesPerChannel = blockSize / channels;
            if (chunkSize % blockSize > 0) return;
            if (blockSize % channels > 0) return;
            if (bytesPerChannel % 4 > 0) return;

            bb.SetPosition(offset);
            byte[] buf = new byte[blockSize+1];
            bw.BaseStream.Position = offset;

            while (chunkSize > 0)
            {
                bb.SetPosition(offset);
                bb.Stream.Read(buf, 0, blockSize);
                bb.SetPosition(offset);

                for (int i = 0; i < channels; ++i)
                {
                    bw.Write(buf, i * bytesPerChannel, 4);
                }

                for (int j = 0; j < bytesPerChannel - 4; j += 4)
                {
                    for (int i = 0; i < channels; ++i)
                    {
                        bw.Write(buf, (i * bytesPerChannel + 4) + j, 4);
                    }
                }
                chunkSize -= blockSize;
                offset += blockSize;
            }
        }